UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
ChaosArchive.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2#pragma once
3
4#include "Chaos/Real.h"
5#include "CoreMinimal.h"
6#include "Serializable.h"
7#include "ShapeInstanceFwd.h"
10#include "Templates/Models.h"
11
12namespace Chaos
13{
14
15#if CHAOS_MEMORY_TRACKING
17{
18 FName Name;
21 bool bAbsorbChildren;
22};
23
25{
30};
31
33{
34public:
38
40 {
41 check(SectionStack.Num() == 0);
42 }
43
46
47 void PushSection(const FName& SectionName, const int64 MemoryLocation, const bool bAbsorbChildren);
48
50
52
54
55private:
56
57 static const FName UntrackedName;
58
60
62};
63
64class FChaosArchive;
65
66#endif
67
68
69
73#endif
74{
75public:
80
81
83
85
86 template <typename T, ESPMode Mode>
88 {
89 T* RawPtr = const_cast<T*>(Obj.Get());
90 if (FSharedPtrHolder* BaseHolder = ObjToSharedPtrHolder.FindRef(RawPtr))
91 {
93 return ConcreteHolder->SP;
94 }
95 else
96 {
97 auto NewHolder = new TSharedPtrHolder<T, Mode>(RawPtr);
99 ObjToSharedPtrHolder.Add((void*)RawPtr, NewHolder);
100 return NewSP;
101 }
102 }
103
104 template <typename T>
106 {
107 T* RawPtr = const_cast<T*>(Obj.Get());
108 if (FRefCountPtrHolder* BaseHolder = ObjToRefCountPtrHolder.FindRef(RawPtr))
109 {
110 auto ConcreteHolder = static_cast<TRefCountPtrHolder<T>*>(BaseHolder);
111 return ConcreteHolder->RCP;
112 }
113 else
114 {
115 auto NewHolder = new TRefCountPtrHolder<T>(RawPtr);
117 ObjToRefCountPtrHolder.Add((void*)RawPtr, NewHolder);
118 return NewRCP;
119 }
120 }
121
122 int32 GetObjectTag(const void* ObjectPtr) const
123 {
124 if (const int32* SerializedObjectPtrTag = ObjToTag.Find(ObjectPtr))
125 {
127 }
128 return INDEX_NONE;
129 }
130
131private:
132 class FSharedPtrHolder
133 {
134 public:
135 FSharedPtrHolder() = default;
136 virtual ~FSharedPtrHolder() {}
137 };
138
139 template <typename T, ESPMode Mode>
140 class TSharedPtrHolder : public FSharedPtrHolder
141 {
142 public:
143 TSharedPtrHolder(T* Obj) : SP(Obj) {}
145 };
146
147 class FRefCountPtrHolder
148 {
149 public:
150 FRefCountPtrHolder() = default;
151 virtual ~FRefCountPtrHolder() {}
152 };
153
154 template <typename T>
155 class TRefCountPtrHolder : public FRefCountPtrHolder
156 {
157 public:
158 TRefCountPtrHolder(T* Obj) : RCP(Obj) {}
159 TRefCountPtr<T> RCP;
160 };
161
162 TMap<void*, FSharedPtrHolder*> ObjToSharedPtrHolder;
163 TMap<void*, FRefCountPtrHolder*> ObjToRefCountPtrHolder;
164};
165
167{
168public:
174
175 template <typename T>
177 {
178 bool bExists = Obj.Get() != nullptr;
179 InnerArchive << bExists;
180 if (!bExists)
181 {
182 Obj.Reset();
183 return;
184 }
185
187 {
188 int32 Tag;
189 InnerArchive << Tag;
190
191 if (Tag < 0)
192 {
194 return;
195 }
196
197 const int32 SlotsNeeded = Tag + 1 - Context->TagToObject.Num();
198 if (SlotsNeeded > 0)
199 {
200 Context->TagToObject.AddZeroed(SlotsNeeded);
201 }
202
203 if (!Context->TagToObject.IsValidIndex(Tag))
204 {
206 return;
207 }
208
209 if (Context->TagToObject[Tag])
210 {
211 Obj.SetFromRawLowLevel((const T*)(Context->TagToObject[Tag]));
212 }
213 else
214 {
215 StaticSerialize(Obj);
216 Context->TagToObject[Tag] = (void*)Obj.Get();
217 Context->ObjToTag.Add((void*)Obj.Get(), Tag);
218 }
219 }
221 {
222 void* ObjRaw = (void*)Obj.Get();
223 check(Context->PendingAdds.Contains(ObjRaw) == false); //catch dependency cycles. Not supported
224 if (Context->ObjToTag.Contains(ObjRaw))
225 {
226 InnerArchive << Context->ObjToTag[ObjRaw];
227 }
228 else
229 {
230 Context->PendingAdds.Add(ObjRaw);
231
232 int32 Tag = Context->TagCount++;
233 Context->ObjToTag.Add(ObjRaw, Tag);
234
235 InnerArchive << Tag;
236 StaticSerialize(Obj);
237
238 Context->PendingAdds.Remove(ObjRaw);
239 }
240 }
241 }
242
243 template <typename T>
245 {
248 {
249 SerializeLegacy(Obj);
250 }
251 else
252 {
255
257 {
258 //check(!Obj); sometimes we have a default object. Maybe we shouldn't?
259 Obj.Reset(const_cast<T*>(Copy.Get()));
260 }
261 }
262 }
263
264 template <typename T>
266 {
269 if (IsLoading())
270 {
271 Obj = Context->ToRefCountPointerHelper<T>(Copy);
272 }
273 }
274
275 template <typename T>
277 {
280 if (IsLoading())
281 {
282 Obj = Context->ToRefCountPointerHelper<T>(Copy);
283 }
284 }
285
286 template <typename T, ESPMode Mode>
288 {
291 if (IsLoading())
292 {
293 Obj = Context->ToSharedPointerHelper<T,Mode>(Copy);
294 }
295 }
296
297 template <typename T, ESPMode Mode>
299 {
302 if (IsLoading())
303 {
304 Obj = Context->ToSharedPointerHelper<T, Mode>(Copy);
305 }
306 }
307
308#if CHAOS_MEMORY_TRACKING
309 virtual void Serialize(void* V, int64 Length) override
310 {
311 if (Context) { Context->BeginSerialize(Tell()); }
313 if (Context) { Context->EndSerialize(Tell()); }
314 }
315#endif
316
321
327
328private:
329
330 template <typename T>
331 void SerializeLegacy(TUniquePtr<T>& Obj)
332 {
333 check(false);
334 }
335 CHAOS_API void SerializeLegacy(TUniquePtr<FImplicitObject>& Obj);
336
337 template <typename T>
338 void StaticSerialize(TSerializablePtr<T>& Serializable)
339 {
340 T* RawPtr = const_cast<T*>(Serializable.Get());
341 FChaosArchive& Ar = *this;
342 if (auto CreatedObj = T::SerializationFactory(Ar, RawPtr))
343 {
344 check(Ar.IsLoading()); //SerializationFactory should only create objects on load
345 RawPtr = static_cast<T*>(CreatedObj);
346 Serializable.SetFromRawLowLevel(RawPtr);
347 }
348 else
349 {
350 check(!Ar.IsLoading()) //SerializationFactory must construct new object on load
351 }
352
353 RawPtr->Serialize(Ar);
354 }
355
357
358#if CHAOS_MEMORY_TRACKING
359 friend class FChaosArchiveScopedMemory;
360#endif
361};
362
364{
365public:
366 FChaosArchiveScopedMemory(FChaosArchive& ArIn, const FName& SectionName, const bool bAbsorbChildren = true)
367#if CHAOS_MEMORY_TRACKING
368 : Ar(ArIn)
369 { if (Ar.Context) { Ar.Context->PushSection(SectionName, Ar.Tell(), bAbsorbChildren); } }
371 { if (Ar.Context) { Ar.Context->PopSection(Ar.Tell()); } }
372private:
373 FChaosArchive& Ar;
374#else
375 { }
376#endif
377};
378
379template <typename T, typename TAllocator>
381{
382 Array.CountBytes(Ar);
383
384 int32 ArrayNum = Array.Num();
385 Ar << ArrayNum;
386 Array.Reserve(ArrayNum);
387 Array.SetNum(ArrayNum);
388
389 for (int32 Idx = 0; Idx < ArrayNum; ++Idx)
390 {
391 Ar << Array[Idx];
392 }
393
394 return Ar;
395}
396
398{
399 // we need to check if we are storing doubles or floats
401 {
402 // normal umodified type path
403 operator<<((FArchive&)Ar, Real);
404 }
405 else
406 {
407 // in that case data is stored as float and we need to read it as such
408 //ensure(Ar.IsLoading()); // this case should normally only happening when reading
411 if(Ar.IsLoading())
412 {
413 Real = (FReal)RealSingle;
414 }
415 }
416 return Ar;
417}
418
420{
421 template<typename T>
422 auto Requires(T* InType, FChaosArchive& InAr) -> decltype(T::SerializationFactory(InAr, (T*)nullptr));
423};
424
425template <typename T>
427{
428 return true;
429}
430
431template <typename T>
433{
434 Ar.SerializePtr(Obj);
435 return Ar;
436}
437
438template <typename T>
440{
441 Ar.SerializePtr(Obj);
442 return Ar;
443}
444
445template <typename T, ESPMode Mode>
447{
448 Ar.SerializePtr(Obj);
449 return Ar;
450}
451
452template <typename T>
458
459template <typename T>
461{
463 return Ar;
464}
465
466template <typename T, typename TAllocator>
472
473template <typename T, typename TAllocator>
475{
476 int32 ArrayNum = Array.Num();
477 Ar << ArrayNum;
478 Array.Reserve(ArrayNum);
479 Array.SetNum(ArrayNum);
480
481 for (int32 Idx = 0; Idx < ArrayNum; ++Idx)
482 {
483 Ar << Array[Idx];
484 }
485
486 return Ar;
487}
488
489template <typename T, typename TAllocator, typename TAllocator2>
491{
492 int32 ArrayNum = Array.Num();
493 Ar << ArrayNum;
494 Array.Reserve(ArrayNum);
495 Array.SetNum(ArrayNum);
496
497 for (int32 Idx = 0; Idx < ArrayNum; ++Idx)
498 {
499 Ar << Array[Idx];
500 }
501
502 return Ar;
503}
504
505template <typename T, typename TAllocator>
507{
508 int32 ArrayNum = Array.Num();
509 Ar << ArrayNum;
510 Array.Reserve(ArrayNum);
511 Array.SetNum(ArrayNum);
512
513 for (int32 Idx = 0; Idx < ArrayNum; ++Idx)
514 {
515 Ar << Array[Idx];
516 }
517
518 return Ar;
519}
520
521template <typename T, typename TAllocator, typename TAllocator2>
523{
524 int32 ArrayNum = Array.Num();
525 Ar << ArrayNum;
526 Array.Reserve(ArrayNum);
527 Array.SetNum(ArrayNum);
528
529 for (int32 Idx = 0; Idx < ArrayNum; ++Idx)
530 {
531 Ar << Array[Idx];
532 }
533
534 return Ar;
535}
536
537template <typename T, typename TAllocator, ESPMode Mode>
539{
540 int32 ArrayNum = Array.Num();
541 Ar << ArrayNum;
542 Array.Reserve(ArrayNum);
543 Array.SetNum(ArrayNum);
544
545 for (int32 Idx = 0; Idx < ArrayNum; ++Idx)
546 {
547 Ar << Array[Idx];
548 }
549
550 return Ar;
551}
552
553template <typename T, typename TAllocator, typename TAllocator2, ESPMode Mode>
555{
556 int32 ArrayNum = Array.Num();
557 Ar << ArrayNum;
558 Array.Reserve(ArrayNum);
559 Array.SetNum(ArrayNum);
560
561 for (int32 Idx = 0; Idx < ArrayNum; ++Idx)
562 {
563 Ar << Array[Idx];
564 }
565
566 return Ar;
567}
568
569template <typename T, typename TAllocator>
571{
572 int32 ArrayNum = Array.Num();
573 Ar << ArrayNum;
574 Array.SetNum(ArrayNum);
575
576 for (int32 Idx = 0; Idx < ArrayNum; ++Idx)
577 {
578 Ar << Array[Idx];
579 }
580
581 return Ar;
582}
583
584template <typename T, typename TAllocator, typename TAllocator2>
586{
587 int32 ArrayNum = Array.Num();
588 Ar << ArrayNum;
589 Array.Reserve(ArrayNum);
590 Array.SetNum(ArrayNum);
591
592 for (int32 Idx = 0; Idx < ArrayNum; ++Idx)
593 {
594 Ar << Array[Idx];
595 }
596
597 return Ar;
598}
599
600}
#define FORCEINLINE
Definition AndroidPlatform.h:140
#define check(expr)
Definition AssertionMacros.h:314
@ INDEX_NONE
Definition CoreMiscDefines.h:150
FPlatformTypes::int64 int64
A 64-bit signed integer.
Definition Platform.h:1127
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
UE_FORCEINLINE_HINT TUniquePtr< T > MakeUnique(TArgs &&... Args)
Definition UniquePtr.h:918
UE_INTRINSIC_CAST UE_REWRITE constexpr std::remove_reference_t< T > && MoveTemp(T &&Obj) noexcept
Definition UnrealTemplate.h:520
if(Failed) console_printf("Failed.\n")
Definition ChaosArchive.h:74
TArray< void * > TagToObject
Definition ChaosArchive.h:76
TMap< void *, int32 > ObjToTag
Definition ChaosArchive.h:77
CHAOS_API ~FChaosArchiveContext()
Definition ChaosArchive.cpp:13
int32 TagCount
Definition ChaosArchive.h:79
TRefCountPtr< T > & ToRefCountPointerHelper(TSerializablePtr< T > &Obj)
Definition ChaosArchive.h:105
int32 GetObjectTag(const void *ObjectPtr) const
Definition ChaosArchive.h:122
TSet< void * > PendingAdds
Definition ChaosArchive.h:78
CHAOS_API FChaosArchiveContext()
Definition ChaosArchive.cpp:9
TSharedPtr< T, Mode > & ToSharedPointerHelper(TSerializablePtr< T > &Obj)
Definition ChaosArchive.h:87
Definition ChaosArchive.h:364
FChaosArchiveScopedMemory(FChaosArchive &ArIn, const FName &SectionName, const bool bAbsorbChildren=true)
Definition ChaosArchive.h:366
Definition ChaosArchive.h:167
void SerializePtr(TSerializablePtr< T > &Obj)
Definition ChaosArchive.h:176
void SerializePtr(TRefCountPtr< T > &Obj)
Definition ChaosArchive.h:265
FChaosArchive(FArchive &ArIn)
Definition ChaosArchive.h:169
void SerializePtr(TSharedPtr< T, Mode > &Obj)
Definition ChaosArchive.h:287
void SerializePtr(TUniquePtr< T > &Obj)
Definition ChaosArchive.h:244
void SerializeConstPtr(TSharedPtr< const T, Mode > &Obj)
Definition ChaosArchive.h:298
void SerializeConstPtr(TRefCountPtr< const T > &Obj)
Definition ChaosArchive.h:276
void SetContext(TUniquePtr< FChaosArchiveContext > &&InContext)
Definition ChaosArchive.h:317
TUniquePtr< FChaosArchiveContext > StealContext()
Definition ChaosArchive.h:322
Definition Serializable.h:10
void Reset()
Definition Serializable.h:29
const T * Get() const
Definition Serializable.h:26
void SetFromRawLowLevel(const T *InPtr)
Definition Serializable.h:46
Definition ArchiveProxy.h:19
virtual void CountBytes(SIZE_T InNum, SIZE_T InMax) override
Definition ArchiveProxy.h:122
FArchive & InnerArchive
Definition ArchiveProxy.h:327
virtual void Serialize(void *V, int64 Length) override
Definition ArchiveProxy.h:97
virtual int64 Tell() override
Definition ArchiveProxy.h:139
Definition Archive.h:1208
CORE_API void SetCriticalError()
Definition Archive.cpp:319
virtual CORE_API void UsingCustomVersion(const struct FGuid &Guid)
Definition Archive.cpp:590
UE_FORCEINLINE_HINT bool IsLoading() const
Definition Archive.h:236
CORE_API int32 CustomVer(const struct FGuid &Key) const
Definition Archive.cpp:602
UE_FORCEINLINE_HINT bool IsSaving() const
Definition Archive.h:248
UE_FORCEINLINE_HINT FPackageFileVersion UEVer() const
Definition Archive.h:204
UE_FORCEINLINE_HINT bool IsCountingMemory() const
Definition Archive.h:468
Definition NameTypes.h:617
Definition Array.h:670
Definition EnableIf.h:20
Definition UnrealString.h.inl:34
Definition RefCounting.h:454
Definition SharedPointer.h:692
Definition UniquePtr.h:107
void Reset(T *InPtr=nullptr)
Definition UniquePtr.h:346
Definition SkeletalMeshComponent.h:307
constexpr TEnableIf< TModels_V< CSerializablePtr, T >, bool >::Type IsSerializablePtr()
Definition ChaosArchive.h:426
TEnableIf< T::AlwaysSerializable, TArray< TSerializablePtr< T > > >::Type & AsAlwaysSerializableArray(TArray< T * > &Ptrs)
Definition Serializable.h:104
FChaosArchive & operator<<(FChaosArchive &Ar, FRigidParticleControlFlags &Flags)
Definition RigidParticleControlFlags.cpp:15
FRealDouble FReal
Definition Real.h:22
TSerializablePtr< T > MakeSerializable(const TUniquePtr< T > &Unique)
Definition Serializable.h:60
float FRealSingle
Definition Real.h:14
TEnableIf< T::AlwaysSerializable, TSerializablePtr< T > >::Type & AsAlwaysSerializable(T *&Ptr)
Definition Serializable.h:97
Definition ChaosArchive.h:420
auto Requires(T *InType, FChaosArchive &InAr) -> decltype(T::SerializationFactory(InAr,(T *) nullptr))
CORE_API static const FGuid GUID
Definition DestructionObjectVersion.h:52
@ ChaosArchiveAdded
Definition DestructionObjectVersion.h:28