void FTextHistory_AsTime::Serialize(FArchive& Ar) { if(Ar.IsSaving()) { int8 HistoryType = (int8)ETextHistoryType::AsTime; Ar << HistoryType; } Ar << SourceDateTime; int8 TimeStyleInt8 = (int8)TimeStyle; Ar << TimeStyleInt8; TimeStyle = (EDateTimeStyle::Type)TimeStyleInt8; Ar << TimeZone; if(Ar.IsSaving()) { FString CultureName = TargetCulture.IsValid()? TargetCulture->GetName() : FString(); Ar << CultureName; } else if(Ar.IsLoading()) { FString CultureName; Ar << CultureName; if(!CultureName.IsEmpty()) { TargetCulture = FInternationalization::Get().GetCulture(CultureName); } } }
void FTextHistory_AsDate::Serialize(FArchive& Ar) { if(Ar.IsSaving()) { int8 HistoryType = (int8)ETextHistoryType::AsDate; Ar << HistoryType; } Ar << SourceDateTime; int8 DateStyleInt8 = (int8)DateStyle; Ar << DateStyleInt8; DateStyle = (EDateTimeStyle::Type)DateStyleInt8; if( Ar.UE4Ver() >= VER_UE4_FTEXT_HISTORY_DATE_TIMEZONE ) { Ar << TimeZone; } if(Ar.IsSaving()) { FString CultureName = TargetCulture.IsValid()? TargetCulture->GetName() : FString(); Ar << CultureName; } else if(Ar.IsLoading()) { FString CultureName; Ar << CultureName; if(!CultureName.IsEmpty()) { TargetCulture = FInternationalization::Get().GetCulture(CultureName); } } }
void UPhysicsConstraintTemplate::Serialize(FArchive& Ar) { #if WITH_EDITOR FConstraintProfileProperties CurrentProfile = DefaultInstance.ProfileInstance; //Save off current profile in case they save in editor and we don't want to lose their work if(Ar.IsSaving() && !Ar.IsTransacting()) { DefaultInstance.ProfileInstance = DefaultProfile; } #endif Super::Serialize(Ar); // If old content, copy properties out of setup into instance if(Ar.UE4Ver() < VER_UE4_ALL_PROPS_TO_CONSTRAINTINSTANCE) { CopySetupPropsToInstance(&DefaultInstance); } if(!Ar.IsTransacting()) { //Make sure to keep default profile and instance in sync if (Ar.IsLoading()) { DefaultProfile = DefaultInstance.ProfileInstance; } #if WITH_EDITOR else if(Ar.IsSaving()) { DefaultInstance.ProfileInstance = CurrentProfile; //recover their settings before we saved } #endif } }
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 UK2Node_VariableGet::Serialize(FArchive& Ar) { // The following code is to attempt to log info related to UE-19729 if (Ar.IsSaving() && !Ar.IsTransacting()) { if (UEdGraph* Graph = Cast<UEdGraph>(GetOuter())) { if (UBlueprint* Blueprint = FBlueprintEditorUtils::FindBlueprintForGraph(Graph)) { if (!Blueprint->bBeingCompiled) { FString VariableName = GetVarNameString(); FString BlueprintPath = Blueprint->GetPathName(); FString SetupStyle = bIsPureGet? TEXT("pure") : TEXT("validated"); UE_LOG(LogBlueprintUserMessages, Log, TEXT("Serialization for Get node for variable '%s' in Blueprint '%s' which is setup as %s"), *VariableName, *BlueprintPath, *SetupStyle); // The following line may spur the crash noted in UE-19729 and will confirm that the crash happens before the FiB gather. GetNodeTitle(ENodeTitleType::ListView); } } } } Super::Serialize(Ar); }
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 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(); } } } } }
bool FGameplayTagContainer::NetSerialize(FArchive& Ar, class UPackageMap* Map, bool& bOutSuccess) { uint8 NumTags; if (Ar.IsSaving()) { NumTags = GameplayTags.Num(); Ar << NumTags; for (FGameplayTag& Tag : GameplayTags) { Tag.NetSerialize(Ar, Map, bOutSuccess); } } else { Ar << NumTags; GameplayTags.Empty(NumTags); GameplayTags.AddDefaulted(NumTags); for (uint8 idx = 0; idx < NumTags; ++idx) { GameplayTags[idx].NetSerialize(Ar, Map, bOutSuccess); } } bOutSuccess = true; return true; }
void USubstanceImageInput::Serialize(FArchive& Ar) { Super::Serialize(Ar); Ar.UsingCustomVersion(FSubstanceCoreCustomVersion::GUID); //! todo: remove image date if all consumers are freezed if (Ar.IsSaving()) { ImageRGB.StoreCompressedOnDisk(0 == CompressionRGB ? COMPRESS_ZLIB : COMPRESS_None); ImageA.StoreCompressedOnDisk(0 == CompressionAlpha ? COMPRESS_ZLIB : COMPRESS_None); } ImageRGB.Serialize(Ar, this); ImageA.Serialize(Ar, this); // image inputs can be used multiple times ImageRGB.ClearBulkDataFlags(BULKDATA_SingleUse); ImageA.ClearBulkDataFlags(BULKDATA_SingleUse); Ar << CompressionRGB; Ar << CompressionAlpha; if (Ar.IsCooking()) { SourceFilePath = FString(); SourceFileTimestamp = FString(); } }
void FTextHistory_FormatNumber::Serialize(FArchive& Ar) { Ar << SourceValue; bool bHasFormatOptions = FormatOptions != nullptr; Ar << bHasFormatOptions; if(bHasFormatOptions) { if(Ar.IsLoading()) { FormatOptions = new FNumberFormattingOptions; } CA_SUPPRESS(6011) Ar << *FormatOptions; } if(Ar.IsSaving()) { FString CultureName = TargetCulture.IsValid()? TargetCulture->GetName() : FString(); Ar << CultureName; } else if(Ar.IsLoading()) { FString CultureName; Ar << CultureName; if(!CultureName.IsEmpty()) { TargetCulture = FInternationalization::Get().GetCulture(CultureName); } } }
void USoundCue::Serialize(FArchive& Ar) { // Always force the duration to be updated when we are saving or cooking if (Ar.IsSaving() || Ar.IsCooking()) { Duration = (FirstNode ? FirstNode->GetDuration() : 0.f); } Super::Serialize(Ar); if (Ar.UE4Ver() >= VER_UE4_COOKED_ASSETS_IN_EDITOR_SUPPORT) { FStripDataFlags StripFlags(Ar); #if WITH_EDITORONLY_DATA if (!StripFlags.IsEditorDataStripped()) { Ar << SoundCueGraph; } #endif } #if WITH_EDITOR else { Ar << SoundCueGraph; } #endif }
void FLocMetadataValueBoolean::Serialize( const FLocMetadataValueBoolean& Value, FArchive& Archive ) { check(Archive.IsSaving()); bool BoolValue = Value.Value; Archive << BoolValue; }
PRAGMA_POP bool FStringAssetReference::Serialize(FArchive& Ar) { #if WITH_EDITOR if (Ar.IsSaving() && Ar.IsPersistent() && FCoreUObjectDelegates::StringAssetReferenceSaving.IsBound()) { SetPath(FCoreUObjectDelegates::StringAssetReferenceSaving.Execute(ToString())); } #endif // WITH_EDITOR Ar << *this; #if WITH_EDITOR if (Ar.IsLoading() && Ar.IsPersistent() && FCoreUObjectDelegates::StringAssetReferenceLoaded.IsBound()) { FCoreUObjectDelegates::StringAssetReferenceLoaded.Execute(ToString()); } #endif // WITH_EDITOR if (Ar.IsLoading() && (Ar.GetPortFlags()&PPF_DuplicateForPIE)) { // Remap unique ID if necessary FixupForPIE(); } return true; }
void FLocMetadataValueString::Serialize( const FLocMetadataValueString& Value, FArchive& Archive ) { check(Archive.IsSaving()); FString StringValue = Value.Value; Archive << StringValue; }
void UPendingNetGame::Serialize( FArchive& Ar ) { Super::Serialize(Ar); if( !Ar.IsLoading() && !Ar.IsSaving() ) { Ar << NetDriver; } }
bool FMinimalReplicationTagCountMap::NetSerialize(FArchive& Ar, class UPackageMap* Map, bool& bOutSuccess) { const int32 CountBits = UAbilitySystemGlobals::Get().MinimalReplicationTagCountBits; const int32 MaxCount = ((1 << CountBits)-1); if (Ar.IsSaving()) { int32 Count = TagMap.Num(); if (Count > MaxCount) { ABILITY_LOG(Error, TEXT("FMinimapReplicationTagCountMap has too many tags (%d). This will cause tags to not replicate. See FMinimapReplicationTagCountMap::NetSerialize"), TagMap.Num()); Count = MaxCount; } Ar.SerializeBits(&Count, CountBits); for(auto& It : TagMap) { FGameplayTag& Tag = It.Key; Tag.NetSerialize(Ar, Map, bOutSuccess); if (--Count <= 0) { break; } } } else { int32 Count = TagMap.Num(); Ar.SerializeBits(&Count, CountBits); // Reset our local map for(auto& It : TagMap) { It.Value = 0; } // See what we have while(Count-- > 0) { FGameplayTag Tag; Tag.NetSerialize(Ar, Map, bOutSuccess); TagMap.FindOrAdd(Tag) = 1; } if (Owner) { // Update our tags with owner tags for(auto& It : TagMap) { Owner->SetTagMapCount(It.Key, It.Value); } } } bOutSuccess = true; return true; }
bool operator<<(FArchive& Ar,FVertexFactoryParameterRef& Ref) { bool bShaderHasOutdatedParameters = false; Ar << Ref.VertexFactoryType; uint8 ShaderFrequencyByte = Ref.ShaderFrequency; Ar << ShaderFrequencyByte; if(Ar.IsLoading()) { Ref.ShaderFrequency = (EShaderFrequency)ShaderFrequencyByte; } Ar << Ref.VFHash; if (Ar.IsLoading()) { delete Ref.Parameters; if (Ref.VertexFactoryType) { Ref.Parameters = Ref.VertexFactoryType->CreateShaderParameters(Ref.ShaderFrequency); } else { bShaderHasOutdatedParameters = true; Ref.Parameters = NULL; } } // Need to be able to skip over parameters for no longer existing vertex factories. int32 SkipOffset = Ar.Tell(); { FArchive::FScopeSetDebugSerializationFlags S(Ar, DSF_IgnoreDiff); // Write placeholder. Ar << SkipOffset; } if(Ref.Parameters) { Ref.Parameters->Serialize(Ar); } else if(Ar.IsLoading()) { Ar.Seek( SkipOffset ); } if( Ar.IsSaving() ) { int32 EndOffset = Ar.Tell(); Ar.Seek( SkipOffset ); Ar << EndOffset; Ar.Seek( EndOffset ); } return bShaderHasOutdatedParameters; }
/*----------------------------------------------------------------------------- UByteProperty. -----------------------------------------------------------------------------*/ void UByteProperty::SerializeItem( FArchive& Ar, void* Value, void const* Defaults ) const { if(Enum && Ar.UseToResolveEnumerators()) { const int32 ResolvedIndex = Enum->ResolveEnumerator(Ar, *(uint8*)Value); *(uint8*)Value = static_cast<uint8>(ResolvedIndex); return; } // Serialize enum values by name unless we're not saving or loading OR for backwards compatibility const bool bUseBinarySerialization = (Enum == NULL) || (!Ar.IsLoading() && !Ar.IsSaving()); if( bUseBinarySerialization ) { Super::SerializeItem(Ar, Value, Defaults); } // Loading else if (Ar.IsLoading()) { FName EnumValueName; Ar << EnumValueName; // Make sure enum is properly populated if( Enum->HasAnyFlags(RF_NeedLoad) ) { Ar.Preload(Enum); } // There's no guarantee EnumValueName is still present in Enum, in which case Value will be set to the enum's max value. // On save, it will then be serialized as NAME_None. int32 EnumIndex = Enum->FindEnumIndex(EnumValueName); if (EnumIndex == INDEX_NONE) { *(uint8*)Value = Enum->GetMaxEnumValue(); } else { *(uint8*)Value = Enum->GetValueByIndex(EnumIndex); } } // Saving else { FName EnumValueName; uint8 ByteValue = *(uint8*)Value; // subtract 1 because the last entry in the enum's Names array // is the _MAX entry if ( Enum->IsValidEnumValue(ByteValue) ) { EnumValueName = Enum->GetNameByValue(ByteValue); } else { EnumValueName = NAME_None; } Ar << EnumValueName; } }
void FTextHistory_Base::Serialize( FArchive& Ar ) { // If I serialize out the Namespace and Key HERE, then we can load it up. if(Ar.IsSaving()) { int8 HistoryType = (int8)ETextHistoryType::Base; Ar << HistoryType; } }
void FAssetDataGatherer::SerializeCache(FArchive& Ar) { double SerializeStartTime = FPlatformTime::Seconds(); // serialize number of objects int32 LocalNumAssets = NewCachedAssetDataMap.Num(); Ar << LocalNumAssets; if (Ar.IsSaving()) { // save out by walking the TMap for (auto CacheIt = NewCachedAssetDataMap.CreateConstIterator(); CacheIt; ++CacheIt) { FName PackageName = CacheIt.Key(); Ar << PackageName; Ar << *CacheIt.Value(); } } else { // allocate one single block for all asset data structs (to reduce tens of thousands of heap allocations) DiskCachedAssetDataMap.Empty(LocalNumAssets); for (int32 AssetIndex = 0; AssetIndex < LocalNumAssets; ++AssetIndex) { // Load the name first to add the entry to the tmap below FName PackageName; Ar << PackageName; if (Ar.IsError()) { // There was an error reading the cache. Bail out. break; } // Add to the cached map FDiskCachedAssetData& CachedAssetData = DiskCachedAssetDataMap.Add(PackageName); // Now load the data Ar << CachedAssetData; if (Ar.IsError()) { // There was an error reading the cache. Bail out. break; } } // If there was an error loading the cache, abandon all data loaded from it so we can build a clean one. if (Ar.IsError()) { UE_LOG(LogAssetRegistry, Error, TEXT("There was an error loading the asset registry cache. Generating a new one.")); DiskCachedAssetDataMap.Empty(); } } UE_LOG(LogAssetRegistry, Verbose, TEXT("Asset data gatherer serialized in %0.6f seconds"), FPlatformTime::Seconds() - SerializeStartTime); }
void ULandscapeInfoMap::Serialize(FArchive& Ar) { Super::Serialize(Ar); if (!Ar.IsLoading() && !Ar.IsSaving()) { Ar << Map; } }
void UNavArea::Serialize(FArchive& Ar) { if (Ar.IsSaving() && !SupportedAgents.IsInitialized()) { SupportedAgents.MarkInitialized(); } Super::Serialize(Ar); }
void UAnimInstance::Serialize(FArchive& Ar) { Super::Serialize(Ar); if (!Ar.IsLoading() || !Ar.IsSaving()) { Ar << RequiredBones; } }
void FTextHistory_AsPercent::Serialize( FArchive& Ar ) { if(Ar.IsSaving()) { int8 HistoryType = (int8)ETextHistoryType::AsPercent; Ar << HistoryType; } FTextHistory_FormatNumber::Serialize(Ar); }
void FTextHistory_ArgumentDataFormat::Serialize( FArchive& Ar ) { if(Ar.IsSaving()) { int8 HistoryType = (int8)ETextHistoryType::ArgumentFormat; Ar << HistoryType; } Ar << SourceText; Ar << Arguments; }
void UTextProperty::SerializeItem( FArchive& Ar, void* Value, int32 MaxReadBytes, void const* Defaults ) const { const TCppType PropertyValue = GetPropertyValue(Value); if ( Ar.IsSaving() && Ar.IsPersistent() && PropertyValue.IsTransient() ) { const FText ErrorMessage = FText::Format( FText::SerializationFailureError, FText::FromString( FTextInspector::GetDisplayString(PropertyValue) ) ); UE_LOG( LogProperty, Warning, TEXT("%s"), *ErrorMessage.ToString()); SetPropertyValue(Value, ErrorMessage); } Ar << *GetPropertyValuePtr(Value); }
void FAssetDataGatherer::SerializeCache(FArchive& Ar) { double SerializeStartTime = FPlatformTime::Seconds(); // serialize number of objects int32 LocalNumAssets = NewCachedAssetDataMap.Num(); Ar << LocalNumAssets; if (Ar.IsSaving()) { // save out by walking the TMap for (auto CacheIt = NewCachedAssetDataMap.CreateConstIterator(); CacheIt; ++CacheIt) { Ar << *CacheIt.Value(); } } else { // allocate one single block for all asset data structs (to reduce tens of thousands of heap allocations) DiskCachedAssetDataMap.Empty(LocalNumAssets); DiskCachedAssetDataBuffer = new FDiskCachedAssetData[LocalNumAssets]; for (int32 AssetIndex = 0; AssetIndex < LocalNumAssets; ++AssetIndex) { // make a new asset data object FDiskCachedAssetData* NewCachedAssetDataPtr = &DiskCachedAssetDataBuffer[AssetIndex]; // load it Ar << *NewCachedAssetDataPtr; if (Ar.IsError()) { // There was an error reading the cache. Bail out. break; } // hash it DiskCachedAssetDataMap.Add(NewCachedAssetDataPtr->PackageName, NewCachedAssetDataPtr); } // If there was an error loading the cache, abandon all data loaded from it so we can build a clean one. if (Ar.IsError()) { UE_LOG(LogAssetRegistry, Error, TEXT("There was an error loading the asset registry cache. Generating a new one.")); DiskCachedAssetDataMap.Empty(); delete DiskCachedAssetDataBuffer; DiskCachedAssetDataBuffer = nullptr; } } UE_LOG(LogAssetRegistry, Verbose, TEXT("Asset data gatherer serialized in %0.6f seconds"), FPlatformTime::Seconds() - SerializeStartTime); }
void FLocMetadataValueArray::Serialize( const FLocMetadataValueArray& Value, FArchive& Archive ) { check(Archive.IsSaving()); int32 ElementCount = Value.Value.Num(); Archive << ElementCount; for (const TSharedPtr<FLocMetadataValue>& Element : Value.Value) { FLocMetadataValue* ElementRawPointer = Element.Get(); SerializeLocMetadataValue(Archive, ElementRawPointer); } }
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; } } }
void AAFCueActor::Serialize(FArchive& Ar) { if (Ar.IsSaving()) { UpdateAssetRegistryInfo(); } Super::Serialize(Ar); if (Ar.IsLoading()) { UpdateAssetRegistryInfo(); } }