void ULinker::Serialize( FArchive& Ar ) { Super::Serialize( Ar ); if( Ar.IsCountingMemory() ) { // Can't use CountBytes as ExportMap is array of structs of arrays. Ar << ImportMap; Ar << ExportMap; Ar << DependsMap; if (Ar.IsSaving() || Ar.UE4Ver() >= VER_UE4_ADD_STRING_ASSET_REFERENCES_MAP) { Ar << StringAssetReferencesMap; } } // Prevent garbage collecting of linker's names and package. Ar << NameMap << LinkerRoot; { for( int32 i=0; i<ExportMap.Num(); i++ ) { FObjectExport& E = ExportMap[i]; Ar << E.ObjectName; } } { for( int32 i=0; i<ImportMap.Num(); i++ ) { FObjectImport& I = ImportMap[i]; Ar << (UObject*&)I.SourceLinker; Ar << I.ClassPackage << I.ClassName; } } }
void FObjectReplicator::Serialize(FArchive& Ar) { if (Ar.IsCountingMemory()) { Retirement.CountBytes(Ar); } }
bool FLevelSequenceObjectReferenceMap::Serialize(FArchive& Ar) { int32 Num = Map.Num(); Ar << Num; if (Ar.IsLoading()) { while(Num-- > 0) { FGuid Key; Ar << Key; FLevelSequenceObjectReference Value; Ar << Value; Map.Add(Key, Value); } } else if (Ar.IsSaving() || Ar.IsCountingMemory() || Ar.IsObjectReferenceCollector()) { for (auto& Pair : Map) { Ar << Pair.Key; Ar << Pair.Value; } } return true; }
void FLazyObjectPtr::PossiblySerializeObjectGuid(UObject *Object, FArchive& Ar) { if (Ar.IsSaving() || Ar.IsCountingMemory()) { FUniqueObjectGuid Guid = GuidAnnotation.GetAnnotation(Object); bool HasGuid = Guid.IsValid(); Ar << HasGuid; if (HasGuid) { if (Ar.GetPortFlags() & PPF_DuplicateForPIE) { check(GPlayInEditorID != -1); FGuid &FoundGuid = PIEGuidMap[GPlayInEditorID % MAX_PIE_INSTANCES].FindOrAdd(Guid.GetGuid()); if (!FoundGuid.IsValid()) { Guid = FoundGuid = FGuid::NewGuid(); } else { Guid = FoundGuid; } } Ar << Guid; } } else if (Ar.IsLoading()) { bool HasGuid = false; Ar << HasGuid; if (HasGuid) { FUniqueObjectGuid Guid; Ar << Guid; // Don't try and resolve GUIDs when loading a package for diff'ing const UPackage* Package = Object->GetOutermost(); const bool bLoadedForDiff = (Package && Package->HasAnyPackageFlags(PKG_ForDiffing)); if (!bLoadedForDiff && (!(Ar.GetPortFlags() & PPF_Duplicate) || (Ar.GetPortFlags() & PPF_DuplicateForPIE))) { check(!Guid.IsDefault()); UObject* OtherObject = Guid.ResolveObject(); if (OtherObject != Object) // on undo/redo, the object (potentially) already exists { if (OtherObject != NULL) { UE_CLOG(!((FApp::IsGame() || GIsPlayInEditorWorld) && Package && Package->ContainsMap()), LogUObjectGlobals, Warning, TEXT("Guid is in use by %s and %s, which should never happen in the editor but could happen at runtime with duplicate level loading or PIE"), *OtherObject->GetFullName(), !!Object ? *Object->GetFullName() : TEXT("NULL")); // This guid is in use, which should never happen in the editor but could happen at runtime with duplicate level loading or PIE. If so give it an invalid GUID and don't add to the annotation map. Guid = FGuid(); } else { GuidAnnotation.AddAnnotation(Object, Guid); } FUniqueObjectGuid::InvalidateTag(); } } } } }
/** * Serializer * * @param Ar Archive to serialize with * @param bNeedsCPUAccess Whether the elements need to be accessed by the CPU */ void FColorVertexBuffer::Serialize( FArchive& Ar, bool bNeedsCPUAccess ) { FStripDataFlags StripFlags(Ar, 0, VER_UE4_STATIC_SKELETAL_MESH_SERIALIZATION_FIX); if (Ar.IsSaving() && NumVertices > 0 && VertexData == NULL) { // ...serialize as if the vertex count were zero. Else on load serialization breaks. // This situation should never occur because VertexData should not be null if NumVertices // is greater than zero. So really this should be a checkf but I don't want to crash // the Editor when saving a package. UE_LOG(LogStaticMesh, Warning, TEXT("Color vertex buffer being saved with NumVertices=%d Stride=%d VertexData=NULL. This should never happen."), NumVertices, Stride ); int32 SerializedStride = 0; int32 SerializedNumVertices = 0; Ar << SerializedStride << SerializedNumVertices; } else { Ar << Stride << NumVertices; if (Ar.IsLoading() && NumVertices > 0) { // Allocate the vertex data storage type. AllocateData(bNeedsCPUAccess); } if (!StripFlags.IsDataStrippedForServer() || Ar.IsCountingMemory()) { if (VertexData != NULL) { // Serialize the vertex data. VertexData->Serialize(Ar); if (VertexData->Num() > 0) { // Make a copy of the vertex data pointer. Data = VertexData->GetDataPointer(); } } } } }
void FLinker::Serialize( FArchive& Ar ) { if( Ar.IsCountingMemory() ) { // Can't use CountBytes as ExportMap is array of structs of arrays. Ar << ImportMap; Ar << ExportMap; Ar << DependsMap; if (Ar.IsSaving() || Ar.UE4Ver() >= VER_UE4_ADD_STRING_ASSET_REFERENCES_MAP) { Ar << StringAssetReferencesMap; } } if (Ar.IsSaving() || Ar.UE4Ver() >= VER_UE4_SERIALIZE_TEXT_IN_PACKAGES) { Ar << GatherableTextDataMap; } // Prevent garbage collecting of linker's names and package. Ar << NameMap << LinkerRoot; { for (auto& E : ExportMap) { Ar << E.ObjectName; } } { for (auto& I : ImportMap) { UObject* LegacyLinkerObject = nullptr; Ar << LegacyLinkerObject; Ar << I.ClassPackage << I.ClassName; } } }