const TCHAR* UClassProperty::ImportText_Internal( const TCHAR* Buffer, void* Data, int32 PortFlags, UObject* Parent, FOutputDevice* ErrorText ) const { const TCHAR* Result = UObjectProperty::ImportText_Internal( Buffer, Data, PortFlags, Parent, ErrorText ); if( Result ) { CheckValidObject(Data); if (UClass* AssignedPropertyClass = dynamic_cast<UClass*>(GetObjectPropertyValue(Data))) { #if USE_CIRCULAR_DEPENDENCY_LOAD_DEFERRING FLinkerLoad* PropertyLinker = GetLinker(); bool const bIsDeferringValueLoad = ((PropertyLinker == nullptr) || (PropertyLinker->LoadFlags & LOAD_DeferDependencyLoads)) && Cast<ULinkerPlaceholderClass>(MetaClass); #if USE_DEFERRED_DEPENDENCY_CHECK_VERIFICATION_TESTS check(bIsDeferringValueLoad || !Cast<ULinkerPlaceholderClass>(MetaClass)); #endif // USE_DEFERRED_DEPENDENCY_CHECK_VERIFICATION_TESTS #else // USE_CIRCULAR_DEPENDENCY_LOAD_DEFERRING bool const bIsDeferringValueLoad = false; #endif // USE_CIRCULAR_DEPENDENCY_LOAD_DEFERRING // Validate metaclass. if ((!AssignedPropertyClass->IsChildOf(MetaClass)) && !bIsDeferringValueLoad) { // the object we imported doesn't implement our interface class ErrorText->Logf(TEXT("Invalid object '%s' specified for property '%s'"), *AssignedPropertyClass->GetFullName(), *GetName()); SetObjectPropertyValue(Data, NULL); Result = NULL; } } } return Result; }
void UObjectProperty::SerializeItem( FArchive& Ar, void* Value, int32 MaxReadBytes, void const* Defaults ) const { UObject* ObjectValue = GetObjectPropertyValue(Value); Ar << ObjectValue; UObject* CurrentValue = GetObjectPropertyValue(Value); if (ObjectValue != CurrentValue) { #if USE_CIRCULAR_DEPENDENCY_LOAD_DEFERRING if (ULinkerPlaceholderExportObject* PlaceholderVal = Cast<ULinkerPlaceholderExportObject>(ObjectValue)) { PlaceholderVal->AddReferencingProperty(this); } // NOTE: we don't remove this from CurrentValue if it is a // ULinkerPlaceholderExportObject; this is because this property // could be an array inner, and another member of that array (also // referenced through this property)... if this becomes a problem, // then we could inc/decrement a ref count per referencing property // // @TODO: if this becomes problematic (because ObjectValue doesn't match // this property's PropertyClass), then we could spawn another // placeholder object (of PropertyClass's type), or use null; but // we'd have to modify ULinkerPlaceholderExportObject::ReplaceReferencingObjectValues() // to accommodate this (as it depends on finding itself as the set value) #endif // USE_CIRCULAR_DEPENDENCY_LOAD_DEFERRING SetObjectPropertyValue(Value, ObjectValue); CheckValidObject(Value); } }
void UWeakObjectProperty::SerializeItem( FArchive& Ar, void* Value, int32 MaxReadBytes, void const* Defaults ) const { UObject* ObjectValue = GetObjectPropertyValue(Value); Ar << *(FWeakObjectPtr*)Value; if ((Ar.IsLoading() || Ar.IsModifyingWeakAndStrongReferences()) && ObjectValue != GetObjectPropertyValue(Value)) { CheckValidObject(Value); } }
void ULazyObjectProperty::SerializeItem( FArchive& Ar, void* Value, void const* Defaults ) const { // We never serialize our reference while the garbage collector is harvesting references // to objects, because we don't want lazy pointers to keep objects from being garbage collected if( !Ar.IsObjectReferenceCollector() || Ar.IsModifyingWeakAndStrongReferences() ) { UObject* ObjectValue = GetObjectPropertyValue(Value); Ar << *(FLazyObjectPtr*)Value; if ((Ar.IsLoading() || Ar.IsModifyingWeakAndStrongReferences()) && ObjectValue != GetObjectPropertyValue(Value)) { CheckValidObject(Value); } } }
void UAssetObjectProperty::SerializeItem( FArchive& Ar, void* Value, int32 MaxReadBytes, void const* Defaults ) const { // We never serialize our reference while the garbage collector is harvesting references // to objects, because we don't want asset pointers to keep objects from being garbage collected if( !Ar.IsObjectReferenceCollector() || Ar.IsModifyingWeakAndStrongReferences() ) { FAssetPtr OldValue = *(FAssetPtr*)Value; Ar << *(FAssetPtr*)Value; if (Ar.IsLoading() || Ar.IsModifyingWeakAndStrongReferences()) { if (OldValue.GetUniqueID() != ((FAssetPtr*)Value)->GetUniqueID()) { CheckValidObject(Value); } } } }
void UAssetObjectProperty::SerializeItem( FArchive& Ar, void* Value, void const* Defaults ) const { // We never serialize our reference while the garbage collector is harvesting references // to objects, because we don't want asset pointers to keep objects from being garbage collected // Allow persistent archives so they can keep track of string references. (e.g. FArchiveSaveTagImports) if( !Ar.IsObjectReferenceCollector() || Ar.IsModifyingWeakAndStrongReferences() || Ar.IsPersistent() ) { FAssetPtr OldValue = *(FAssetPtr*)Value; Ar << *(FAssetPtr*)Value; if (Ar.IsLoading() || Ar.IsModifyingWeakAndStrongReferences()) { if (OldValue.GetUniqueID() != ((FAssetPtr*)Value)->GetUniqueID()) { CheckValidObject(Value); } } } }