UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
GenericStateStream.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
6#include "Misc/Optional.h"
7#include "Misc/ScopeRWLock.h"
8#include "StateStream.h"
11#include "StateStreamStore.h"
12
14// Settings struct - Can be inherited to set settings on statestream
15
16template<typename TInterfaceType, typename TUserDataType = void>
18{
21 enum { Id = InterfaceType::Id };
22 static inline constexpr const TCHAR* DebugName = InterfaceType::Handle::DebugName;
23 static inline constexpr bool SkipCreatingDeletes = false;
24};
25
26
28// TStateStream is a generic implementation of IStateStream that contains all the boiler plate code
29// related to ticks, interpolation, etc. Should be the default goto implementation.
30// Inherit this class for each type of state stream
31// Provide a subclass of TStateStreamSettings as template parameter
32
33template<typename Settings>
34class TStateStream : public IStateStream, public Settings::InterfaceType, public IStateStreamHandleOwner
35{
36public:
37 using InterfaceType = typename Settings::InterfaceType;
38 using FHandle = typename InterfaceType::Handle;
39 using FStaticState = typename InterfaceType::StaticState;
40 using FDynamicState = typename InterfaceType::DynamicState;
41 using FUserDataType = typename Settings::UserDataType;
42 enum { Id = Settings::Id };
43
44 // InterfaceType
45 virtual FHandle Game_CreateInstance(const FStaticState& Ss, const FDynamicState& Ds) override final;
46
47 // IStateStreamHandleOwner (used by state stream handles on game side)
48 virtual void Game_AddRef(uint32 HandleId) override final;
49 virtual void Game_Release(uint32 HandleId) override final;
50 virtual void Game_Update(uint32 HandleId, const void* Ds, double TimeFactor, uint64 UserData) override;
51 virtual void* Game_Edit(uint32 HandleId, double TimeFactor, uint64 UserData) override;
52 virtual void* Render_GetUserData(uint32 HandleId) override final;
53
54 // IStateStream (used by StateStreamManagerImpl)
55 virtual void Game_BeginTick() override;
56 virtual void Game_EndTick(StateStreamTime AbsoluteTime) override;
57 virtual void Game_Exit() override;
58 virtual void* Game_GetVoidPointer() override;
59 virtual uint32 GetId() override;
60 virtual void Render_Update(StateStreamTime AbsoluteTime) override;
61 virtual void Render_PostUpdate() override;
62 virtual void Render_Exit() override;
63 virtual void Render_GarbageCollect() override;
64
65 virtual const TCHAR* GetDebugName() override;
67
68
71
72
73 // Specialize to do custom things
74 virtual void Render_OnCreate(const FStaticState& Ss, const FDynamicState& Ds, FUserDataType*& UserData, bool IsDestroyedInSameFrame) {}
75 virtual void Render_OnUpdate(const FStaticState& Ss, const FDynamicState& Ds, FUserDataType*& UserData) {}
76 virtual void Render_OnDestroy(const FStaticState& Ss, const FDynamicState& Ds, FUserDataType*& UserData) {}
77
78 // ... or use template specialization to avoid virtual calls
80 void Render_OnUpdateInline(const FStaticState& Ss, const FDynamicState& Ds, FUserDataType*& UserData) { Render_OnUpdate(Ss, Ds, UserData); }
81 void Render_OnDestroyInline(const FStaticState& Ss, const FDynamicState& Ds, FUserDataType*& UserData) { Render_OnDestroy(Ss, Ds, UserData); }
82
83 // For unit tests
84 uint32 GetUsedInstancesCount() const { return Instances.GetUsedCount(); }
85 uint32 GetUsedDynamicstatesCount() const { return DynamicStates.GetUsedCount(); }
86
87 TStateStream() = default;
88 ~TStateStream() = default;
89
90protected:
91 FDynamicState& Edit(uint32 HandleId, double TimeFactor);
92
93 template<typename InDynamicState>
94 void Update(uint32 HandleId, const InDynamicState& Ds, double TimeFactor);
95
96private:
97 struct FTick;
98
99 void ApplyChanges(const FTick& Tick, StateStreamTime Time, uint32 PrevTickIndex, StateStreamTime PrevTime, const TBitArray<>& ModifiedInstances);
100
101 template<typename T>
102 void MakeInternal(T& State);
103
104 // Information about instance.
105 struct FInstance
106 {
107 FInstance() = default;
108 FInstance(const FStaticState& Ss, uint32 Rc, uint32 Ct) : StaticState(Ss), RefCount(Rc), CreateTick(Ct) {}
109 FStaticState StaticState;
110 uint32 RefCount = 0;
111 uint32 CreateTick = 0;
112 uint32 DeleteTick = ~0u;
113 TOptional<FDynamicState> RendDynamicState;
114 FUserDataType* UserData = nullptr;
115 };
116
118
119 // Tick produced by game side.
120 struct FTick
121 {
122 TArray<uint32> DynamicStates; // Contains index of all instances existing in tick (some might have been destroyed but index not reused)
123 TBitArray<> ModifiedInstances; // Contains bits saying which of the instances that have been modified in this tick.
124 FTick* PrevTick = nullptr; // Tick with earlier time
125 FTick* NextTick = nullptr; // Tick with newer time
126 StateStreamTime Time = 0; // Time Tick finished
127 uint32 Index = 0; // Index of tick (created by TickCounter)
128 };
129
130 FRWLock CurrentTickLock;
131 FTick* CurrentTick = nullptr; // Tick being worked on in game
132 FTick* OldestAvailableTick = nullptr; // Newest finished tick available to rendering
133 FTick* NewestAvailableTick = nullptr; // Newest finished tick available to rendering
134
135 TStateStreamStore<FDynamicState> DynamicStates; // Store for dynamic states.
136
137 uint32 TickCounter = 1;
138
139 FTick* RendTick = nullptr; // Last used tick for rendering.
140 StateStreamTime RendTime = 0; // Last used time for rendering
141
142 TArray<FInstance*> DeferredDestroys;
143
144 TStateStream(const TStateStream&) = delete;
145 TStateStream& operator=(const TStateStream&) = delete;
146};
147
148
150// Implementation
151
152template<typename Settings>
154{
155 check(CurrentTick);
156
157 uint32 InstanceIndex = Instances.Emplace(Ss, 1, CurrentTick->Index);
158
159 uint32 DynamicStateIndex = DynamicStates.Add(Ds);
160
161 CurrentTickLock.WriteLock();
162
163 if (uint32(CurrentTick->DynamicStates.Num()) <= InstanceIndex)
164 {
165 CurrentTick->DynamicStates.SetNum(InstanceIndex + 1);
166 CurrentTick->ModifiedInstances.SetNum(InstanceIndex + 1, false);
167 }
168 CurrentTick->ModifiedInstances[InstanceIndex] = true;
169 CurrentTick->DynamicStates[InstanceIndex] = DynamicStateIndex;
170
171 CurrentTickLock.WriteUnlock();
172
173 return { *this, InstanceIndex + 1 };
174}
175
176template<typename Settings>
178{
179 check(CurrentTick);
180 check(HandleId != 0);
181 uint32 InstanceIndex = HandleId - 1;
182 FInstance& Instance = Instances[InstanceIndex];
183 check(Instance.RefCount);
184 ++Instance.RefCount;
185}
186
187template<typename Settings>
189{
190 check(CurrentTick);
191 check(HandleId != 0);
192 uint32 InstanceIndex = HandleId - 1;
193 FInstance& Instance = Instances[InstanceIndex];
194 check(Instance.RefCount);
195 if (--Instance.RefCount)
196 {
197 return;
198 }
199
200 Instance.DeleteTick = CurrentTick->Index;
201 MakeInternal(Instance.StaticState);
202
203 CurrentTickLock.ReadLock();
204
205 CurrentTick->ModifiedInstances[InstanceIndex] = true;
206 uint32 DsIndex = CurrentTick->DynamicStates[InstanceIndex];
207
208 CurrentTickLock.ReadUnlock();
209
210 MakeInternal(DynamicStates[DsIndex]);
211}
212
213template<typename Settings>
214void TStateStream<Settings>::Game_Update(uint32 HandleId, const void* Ds, double TimeFactor, uint64 UserData)
215{
216 FDynamicState& DsState = Edit(HandleId, TimeFactor);
219 DsState.Apply(Context, *static_cast<const FDynamicState*>(Ds));
220}
221
222template<typename Settings>
224{
225 return &Edit(HandleId, TimeFactor);
226}
227
228
229template<typename Settings>
231{
232 check(HandleId != 0);
233 uint32 InstanceIndex = HandleId - 1;
234
235 check(CurrentTick);
236 check(InstanceIndex < uint32(CurrentTick->DynamicStates.Num()));
237
238 CurrentTickLock.ReadLock();
239
241
242 if (CurrentTick->ModifiedInstances[InstanceIndex])
243 {
244 uint32 DsIndex = CurrentTick->DynamicStates[InstanceIndex];
245 CurrentTickLock.ReadUnlock();
246 DsState = &DynamicStates[DsIndex];
247 }
248 else
249 {
250 uint32& IndexRef = CurrentTick->DynamicStates[InstanceIndex];
251 uint32 OldIndex = IndexRef;
252 CurrentTick->ModifiedInstances[InstanceIndex] = true;
254 void* DsPtr = DynamicStates.AddUninitialized(DsIndex);
256 CurrentTickLock.ReadUnlock();
257
258 FDynamicState& OldDs = DynamicStates[OldIndex];
260 MakeInternal(OldDs);
261 }
262 return *DsState;
263}
264
265template<typename Settings>
266template<typename InDynamicState>
268{
269 /*
270 check(HandleId != 0);
271 uint32 InstanceIndex = HandleId - 1;
272
273 check(CurrentTick);
274 check(InstanceIndex < uint32(CurrentTick->DynamicStates.Num()));
275
276 CurrentTickLock.ReadLock();
277 uint32 DsIndex = CurrentTick->DynamicStates[InstanceIndex];
278 auto& CurrentState = *(decltype(InDynamicState)*)DynamicStates[DsIndex];
279 if (!CurrentState.Diff(InDs)) // TODO
280 {
281 return;
282 }
283 */
286 InDynamicState& DsState = Edit(HandleId, TimeFactor);
287 DsState.Apply(Context, Ds);
288}
289
290template<typename Settings>
292{
293 check(HandleId);
294 uint32 InstanceIndex = HandleId - 1;
295 return Instances[InstanceIndex].UserData;
296}
297
298template<typename Settings>
300{
301 check(!CurrentTick);
302 CurrentTick = new FTick();
303 CurrentTick->Index = TickCounter++;
304 if (NewestAvailableTick)
305 {
306 CurrentTick->DynamicStates = NewestAvailableTick->DynamicStates;
307 CurrentTick->ModifiedInstances.SetNum(CurrentTick->DynamicStates.Num(), false);
308 }
309}
310
311template<typename Settings>
313{
314 check(CurrentTick);
315
316 CurrentTick->Time = AbsoluteTime;
317 CurrentTick->PrevTick = NewestAvailableTick;
318 if (NewestAvailableTick)
319 {
320 check(NewestAvailableTick->Time <= AbsoluteTime);
321 NewestAvailableTick->NextTick = CurrentTick;
322 }
323 else
324 {
325 OldestAvailableTick = CurrentTick;
326 }
327
328 NewestAvailableTick = CurrentTick;
329 CurrentTick = nullptr;
330}
331
332template<typename Settings>
334{
335 check(!CurrentTick);
336 /*
337 for (TConstSetBitIterator<> It(NewestAvailableTick->Modif); It; ++It)
338 {
339
340 }
341 */
342}
343
344template<typename Settings>
346{
347 return static_cast<InterfaceType*>(this);
348}
349
350template<typename Settings>
355
356template<typename Settings>
358{
359 if (!NewestAvailableTick || AbsoluteTime == RendTime)
360 return;
361 check(AbsoluteTime > RendTime); // Only play forward for now
362
363 uint32 PrevTick = 0;
364 bool IsFirstTick = false;
365 if (RendTick)
366 {
367 PrevTick = RendTick->Index;
368 }
369 else
370 {
371 RendTick = OldestAvailableTick;
372 IsFirstTick = true;
373 }
374
375 StateStreamTime PrevTime = RendTime;
376 RendTime = AbsoluteTime;
377
378 // We are still inside the same tick
380 {
381 // Just interpolate or apply RendTick
382 ApplyChanges(*RendTick, RendTime, PrevTick, PrevTime, RendTick->ModifiedInstances);
383 return;
384 }
385
386 // We were at exact end of last handled tick.. move into next
387 if (PrevTime == RendTick->Time)
388 {
389 FTick* NewRendTick = RendTick->NextTick;
390
391 if (!NewRendTick) // We've caught up with game.. set RendTime back to PrevTime and return
392 {
393 RendTime = PrevTime;
394 return;
395 }
396
397 if (!IsFirstTick)
398 RendTick = NewRendTick;
399
400 // We don't need to include RendTick Modifications.
402 {
403 // Just interpolate or apply RendTick
404 ApplyChanges(*RendTick, RendTime, PrevTick, PrevTime, RendTick->ModifiedInstances);
405 return;
406 }
407 }
408
409 // We are overlapping between two or more ticks
410 TBitArray<> ModifiedInstances(RendTick->ModifiedInstances);
411 while (RendTick->Time < RendTime)
412 {
413 if (!RendTick->NextTick)
414 {
415 RendTime = RendTick->Time;
416 break;
417 }
418 RendTick = RendTick->NextTick;
419 ModifiedInstances.CombineWithBitwiseOR(RendTick->ModifiedInstances, EBitwiseOperatorFlags::MaxSize);
420 }
421
422 ApplyChanges(*RendTick, RendTime, PrevTick, PrevTime, ModifiedInstances);
423}
424
425template<typename Settings>
427{
428 for (FInstance* Instance : DeferredDestroys)
429 {
430 Render_OnDestroyInline(Instance->StaticState, *Instance->RendDynamicState, Instance->UserData);
431 Instance->RendDynamicState.Reset();
432 }
433 DeferredDestroys.SetNum(0);
434}
435
436template<typename Settings>
438{
439 if (NewestAvailableTick)
440 {
441 StateStreamTime maxTime = (StateStreamTime)std::numeric_limits<StateStreamTime>::max();
442 Render_Update(maxTime);
443 //Render_GarbageCollect();
444 }
445}
446
447template<typename Settings>
449{
450 if (!OldestAvailableTick)
451 {
452 return;
453 }
454
455 FTick* RendTickUsed = RendTick;
456 if (RendTick && RendTick->Time != RendTime && RendTick->PrevTick)
457 RendTickUsed = RendTick->PrevTick;
458
459 FTick* Tick = OldestAvailableTick;
460 while (Tick != RendTickUsed)
461 {
462 FTick* Next = Tick->NextTick;
463 check (Next);
464
465 // We can remove all DynamicStates that are different in Next tick since we know this is the last tick using the state
466 for (TConstSetBitIterator<> It(Next->ModifiedInstances); It; ++It)
467 {
468 uint32 InstanceIndex = It.GetIndex();
469 if (InstanceIndex >= uint32(Tick->DynamicStates.Num()))
470 {
471 continue;
472 }
473
474 // If instance was created in next tick we ignore this. If instance is deleted in tick we handle it further down
475 FInstance& Instance = Instances[InstanceIndex];
476 if (Instance.DeleteTick == Tick->Index || Instance.CreateTick == Next->Index)
477 {
478 continue;
479 }
480
481 uint32 DynamicStateIndex = Tick->DynamicStates[InstanceIndex];
482 if (DynamicStateIndex == Next->DynamicStates[InstanceIndex])
483 {
484 continue;
485 }
486
487 DynamicStates.Remove(DynamicStateIndex);
488 }
489
490 // Remove all instances who was deleted in Tick
491 for (TConstSetBitIterator<> It(Tick->ModifiedInstances); It; ++It)
492 {
493 uint32 InstanceIndex = It.GetIndex();
494 FInstance& Instance = Instances[InstanceIndex];
495
496 if (Instance.DeleteTick != Tick->Index)
497 {
498 continue;
499 }
500
501 DynamicStates.Remove(Tick->DynamicStates[InstanceIndex]);
502 Instance.RendDynamicState.Reset();
503 Instances.Remove(InstanceIndex);
504 }
505
506 delete Tick;
507 Tick = Next;
508 }
509 OldestAvailableTick = Tick;
510
511}
512
513template<typename Settings>
515{
516 return Settings::DebugName;
517}
518
519template<typename Settings>
521{
522 TStringBuilder<1024> DebugLine;
524 if (FTick* Tick = NewestAvailableTick)
525 {
526 ModifiedCount = Tick->ModifiedInstances.CountSetBits();
527 }
528 DebugLine.Appendf(TEXT("%s Num: %u Changed: %u"), GetDebugName(), Instances.GetUsedCount(), ModifiedCount);
529 Renderer.DrawText(*DebugLine);
530}
531
532template<typename Settings>
534{
535 uint32 Id = Handle.GetId();
536 check(Id);
537 uint32 InstanceIndex = Id - 1;
538 return Instances[InstanceIndex].UserData;
539}
540
541template<typename Settings>
543{
544 uint32 Id = Handle.GetId();
545 check(Id);
546 uint32 InstanceIndex = Id - 1;
547 return *Instances[InstanceIndex].RendDynamicState;
548}
549
550template<typename Settings>
552{
553 // TODO: This will do lots of allocations
554 struct FCreateInfo { FInstance* Instance; bool IsDestroyInSameFrame; };
556 TArray<FInstance*> Updates;
558
559 for (TConstSetBitIterator<> It(ModifiedInstances); It; ++It)
560 {
561 uint32 InstanceIndex = It.GetIndex();
562 FInstance& Instance = Instances[InstanceIndex];
563
564 if (Instance.DeleteTick <= PrevTickIndex) // Already deleted
565 {
566 continue;
567 }
568
569 FStaticState& Ss = Instance.StaticState;
570
571 bool IsCreate = Instance.CreateTick > PrevTickIndex && Instance.CreateTick <= Tick.Index;
572 bool IsDestroy = Instance.DeleteTick > PrevTickIndex && Instance.DeleteTick <= Tick.Index;
573
574 if (IsCreate)
575 {
576 if (Settings::SkipCreatingDeletes && IsDestroy)
577 {
578 continue;
579 }
580
581 check(!Instance.RendDynamicState.IsSet());
582 uint32 DynamicStateIndex = Tick.DynamicStates[InstanceIndex];
584 Instance.RendDynamicState.Emplace(Context, DynamicStates[DynamicStateIndex]);
585 }
586 else if (Instance.CreateTick == Tick.Index) // Still in the tick it was created, no interpolation possible
587 {
588 continue;
589 }
590
591 FDynamicState& Ds = *Instance.RendDynamicState;
592
593 if (Tick.Time == Time || !Tick.PrevTick)
594 {
595 if (!IsCreate)
596 {
598 Ds.Apply(Context, DynamicStates[Tick.DynamicStates[InstanceIndex]]);
599 }
600 }
601 else
602 {
603 const FTick& PrevTick = *Tick.PrevTick;
604 uint32 FromIndex = PrevTick.DynamicStates[InstanceIndex];
605 uint32 ToIndex = Tick.DynamicStates[InstanceIndex];
606
607 StateStreamTime DeltaTime = Tick.Time - PrevTick.Time;
608 StateStreamTime TimeInTo = Time - PrevTick.Time;
609 double Factor = double(TimeInTo) / DeltaTime;
610
611 FDynamicState& From = DynamicStates[FromIndex];
612 FDynamicState& To = DynamicStates[ToIndex];
613
615 Context.Factor = Factor;
616 Ds.Interpolate(Context, From, To);
617 }
618
619 if (IsCreate)
620 {
621 Creates.Add({&Instance, IsDestroy});
622 }
623
624 if (IsDestroy)
625 {
626 if (IsCreate)
627 {
628 DeferredDestroys.Add(&Instance);
629 }
630 else
631 {
632 Destroys.Add(&Instance);
633 }
634 continue;
635 }
636
637 if (!IsCreate)
638 {
639 Updates.Add(&Instance);
640 }
641 }
642
643 for (FCreateInfo& Info : Creates)
644 {
645 FInstance& Instance = *Info.Instance;
646 Render_OnCreateInline(Instance.StaticState, *Instance.RendDynamicState, Instance.UserData, Info.IsDestroyInSameFrame);
647 }
648
649 for (FInstance* Instance : Updates)
650 {
651 Render_OnUpdateInline(Instance->StaticState, *Instance->RendDynamicState, Instance->UserData);
652 }
653
654 for (FInstance* Instance : Destroys)
655 {
656 Render_OnDestroyInline(Instance->StaticState, *Instance->RendDynamicState, Instance->UserData);
657 Instance->RendDynamicState.Reset();
658 }
659}
660
661template<typename Settings>
662template<typename T>
664{
666 for (uint32 I=0, E=State.GetDependencies(Deps, UE_ARRAY_COUNT(Deps)); I!=E; ++I)
667 {
668 Deps[I]->MakeInternal();
669 }
670}
671
#define check(expr)
Definition AssertionMacros.h:314
#define TEXT(x)
Definition Platform.h:1272
FPlatformTypes::TCHAR TCHAR
Either ANSICHAR or WIDECHAR, depending on whether the platform supports wide characters or the requir...
Definition Platform.h:1135
FPlatformTypes::uint64 uint64
A 64-bit unsigned integer.
Definition Platform.h:1117
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
FORCEINLINE uint32 ToIndex(FHairStrandsTiles::ETileType Type)
Definition HairStrandsData.h:93
UE_STATESTREAM_TIME_TYPE StateStreamTime
Definition StateStreamDefinitions.h:21
#define UE_ARRAY_COUNT(array)
Definition UnrealTemplate.h:212
uint32_t uint32
Definition binka_ue_file_header.h:6
Definition StateStreamDebugRenderer.h:10
Definition StateStreamHandle.h:57
Definition StateStream.h:14
Definition Renderer.Build.cs:6
Definition Array.h:670
UE_NODEBUG UE_FORCEINLINE_HINT SizeType Add(ElementType &&Item)
Definition Array.h:2696
TBitArray & CombineWithBitwiseOR(const TBitArray< OtherAllocator > &InOther, EBitwiseOperatorFlags InFlags)
Definition BitArray.h:1337
Definition BitArray.h:1944
Definition StateStreamStore.h:15
uint32 GetUsedCount() const
Definition StateStreamStore.h:114
Definition GenericStateStream.h:35
void Render_OnDestroyInline(const FStaticState &Ss, const FDynamicState &Ds, FUserDataType *&UserData)
Definition GenericStateStream.h:81
virtual const TCHAR * GetDebugName() override
Definition GenericStateStream.h:514
void Render_OnCreateInline(const FStaticState &Ss, const FDynamicState &Ds, FUserDataType *&UserData, bool IsDestroyedInSameFrame)
Definition GenericStateStream.h:79
TStateStream()=default
virtual void Game_Exit() override
Definition GenericStateStream.h:333
typename InterfaceType::Handle FHandle
Definition GenericStateStream.h:38
virtual void Render_GarbageCollect() override
Definition GenericStateStream.h:448
~TStateStream()=default
virtual void Render_OnCreate(const FStaticState &Ss, const FDynamicState &Ds, FUserDataType *&UserData, bool IsDestroyedInSameFrame)
Definition GenericStateStream.h:74
virtual void Game_EndTick(StateStreamTime AbsoluteTime) override
Definition GenericStateStream.h:312
typename Settings::InterfaceType InterfaceType
Definition GenericStateStream.h:37
virtual void Game_AddRef(uint32 HandleId) override final
Definition GenericStateStream.h:177
void Render_OnUpdateInline(const FStaticState &Ss, const FDynamicState &Ds, FUserDataType *&UserData)
Definition GenericStateStream.h:80
FUserDataType *& Render_GetUserData(const FHandle &Handle)
Definition GenericStateStream.h:533
uint32 GetUsedDynamicstatesCount() const
Definition GenericStateStream.h:85
virtual void * Game_GetVoidPointer() override
Definition GenericStateStream.h:345
virtual void Render_OnUpdate(const FStaticState &Ss, const FDynamicState &Ds, FUserDataType *&UserData)
Definition GenericStateStream.h:75
virtual FHandle Game_CreateInstance(const FStaticState &Ss, const FDynamicState &Ds) override final
Definition GenericStateStream.h:153
virtual void * Render_GetUserData(uint32 HandleId) override final
Definition GenericStateStream.h:291
virtual void Game_Update(uint32 HandleId, const void *Ds, double TimeFactor, uint64 UserData) override
Definition GenericStateStream.h:214
typename Settings::UserDataType FUserDataType
Definition GenericStateStream.h:41
uint32 GetUsedInstancesCount() const
Definition GenericStateStream.h:84
FDynamicState & Edit(uint32 HandleId, double TimeFactor)
Definition GenericStateStream.h:230
virtual void Game_Release(uint32 HandleId) override final
Definition GenericStateStream.h:188
virtual void Game_BeginTick() override
Definition GenericStateStream.h:299
virtual void Render_PostUpdate() override
Definition GenericStateStream.h:426
typename InterfaceType::DynamicState FDynamicState
Definition GenericStateStream.h:40
virtual void Render_Exit() override
Definition GenericStateStream.h:437
void Update(uint32 HandleId, const InDynamicState &Ds, double TimeFactor)
Definition GenericStateStream.h:267
@ Id
Definition GenericStateStream.h:42
virtual void DebugRender(IStateStreamDebugRenderer &Renderer) override
Definition GenericStateStream.h:520
virtual void Render_Update(StateStreamTime AbsoluteTime) override
Definition GenericStateStream.h:357
virtual uint32 GetId() override
Definition GenericStateStream.h:351
virtual void Render_OnDestroy(const FStaticState &Ss, const FDynamicState &Ds, FUserDataType *&UserData)
Definition GenericStateStream.h:76
typename InterfaceType::StaticState FStaticState
Definition GenericStateStream.h:39
virtual void * Game_Edit(uint32 HandleId, double TimeFactor, uint64 UserData) override
Definition GenericStateStream.h:223
const FDynamicState & Render_GetDynamicState(const FHandle &Handle)
Definition GenericStateStream.h:542
BuilderType & Appendf(const FmtType &Fmt, Types... Args)
Definition StringBuilder.h:419
Definition StringBuilder.h:509
Definition CriticalSection.h:14
State
Definition PacketHandler.h:88
U16 Index
Definition radfft.cpp:71
Definition StateStreamHandle.h:71
uint32 IsInternal
Definition StateStreamHandle.h:72
Definition StateStreamHandle.h:25
UE_API void MakeInternal()
Definition StateStreamHandle.cpp:120
Definition StateStreamDefinitions.h:27
double Factor
Definition StateStreamDefinitions.h:28
Definition Optional.h:131
Definition GenericStateStream.h:18
@ Id
Definition GenericStateStream.h:21
static constexpr const TCHAR * DebugName
Definition GenericStateStream.h:22
TUserDataType UserDataType
Definition GenericStateStream.h:20
TInterfaceType InterfaceType
Definition GenericStateStream.h:19
static constexpr bool SkipCreatingDeletes
Definition GenericStateStream.h:23