bool UObjectPropertyBase::NetSerializeItem( FArchive& Ar, UPackageMap* Map, void* Data, TArray<uint8> * MetaData ) const
{
	UObject* Object = GetObjectPropertyValue(Data);
	bool Result = Map->SerializeObject( Ar, PropertyClass, Object );
	SetObjectPropertyValue(Data, Object);
	return Result;
}
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;
}
Пример #3
0
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);
	}
}
const TCHAR* UObjectPropertyBase::ImportText_Internal( const TCHAR* InBuffer, void* Data, int32 PortFlags, UObject* Parent, FOutputDevice* ErrorText ) const
{
	const TCHAR* Buffer = InBuffer;
	UObject* Result = NULL;

	bool bOk = ParseObjectPropertyValue(this, Parent, PropertyClass, PortFlags, Buffer, Result);

	SetObjectPropertyValue(Data, Result);
	return Buffer;
}
Пример #5
0
void UClassProperty::CheckValidObject(void* Value) const
{
#if WITH_EDITOR
	// Ugly hack to replace Blueprint references with Class references.

	struct FReplaceBlueprintWithClassHelper
	{
		bool bShouldReplace;
		UClass* BlueprintClass;
		UClassProperty* BPGeneratedClassProp;

		FReplaceBlueprintWithClassHelper() : bShouldReplace(false), BlueprintClass(NULL), BPGeneratedClassProp(NULL)
		{
			GConfig->GetBool(TEXT("EditoronlyBP"), TEXT("bReplaceBlueprintWithClass"), bShouldReplace, GEditorIni);
			if (bShouldReplace)
			{
				BlueprintClass = FindObject<UClass>(NULL, TEXT("/Script/Engine.Blueprint"));
				ensure(BlueprintClass);
				BPGeneratedClassProp = BlueprintClass ? FindField<UClassProperty>(BlueprintClass, TEXT("GeneratedClass")) : NULL;
				ensure(BPGeneratedClassProp);
			}
		}

		bool CanReplace() const
		{
			return bShouldReplace && BlueprintClass && BPGeneratedClassProp;
		}
	};
	static FReplaceBlueprintWithClassHelper Helper;

	const UObject* Object = GetObjectPropertyValue(Value);
	Super::CheckValidObject(Value);
	const UObject* CurrentObject = GetObjectPropertyValue(Value);

	if (Helper.CanReplace()
		&& !CurrentObject
		&& Object 
		&& Object->IsA(Helper.BlueprintClass)
		&& (UObject::StaticClass() == MetaClass))
	{
		UObject* RecoveredObject = Helper.BPGeneratedClassProp->GetPropertyValue_InContainer(Object);
		SetObjectPropertyValue(Value, RecoveredObject);
		UE_LOG(LogProperty, Log,
			TEXT("Blueprint '%s' is replaced with class '%s' in property '%s'"),
			*Object->GetFullName(),
			*RecoveredObject->GetFullName(),
			*GetFullName());
	}
#else	// WITH_EDITOR
	Super::CheckValidObject(Value);
#endif	// WITH_EDITOR
}
void UObjectPropertyBase::InstanceSubobjects(void* Data, void const* DefaultData, UObject* Owner, FObjectInstancingGraph* InstanceGraph )
{
	for ( int32 ArrayIndex = 0; ArrayIndex < ArrayDim; ArrayIndex++ )
	{
		UObject* CurrentValue = GetObjectPropertyValue((uint8*)Data + ArrayIndex * ElementSize);
		if ( CurrentValue )
		{
			UObject *SubobjectTemplate = DefaultData ? GetObjectPropertyValue((uint8*)DefaultData + ArrayIndex * ElementSize): NULL;
			UObject* NewValue = InstanceGraph->InstancePropertyValue(SubobjectTemplate, CurrentValue, Owner, HasAnyPropertyFlags(CPF_Transient), HasAnyPropertyFlags(CPF_InstancedReference));
			SetObjectPropertyValue((uint8*)Data + ArrayIndex * ElementSize, NewValue);
		}
	}
}
Пример #7
0
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 )
	{
		// Validate metaclass.
		UClass* C = (UClass*)GetObjectPropertyValue(Data);
		if (C && (!dynamic_cast<UClass*>(C) || !C->IsChildOf(MetaClass)))
		{
			// the object we imported doesn't implement our interface class
			ErrorText->Logf(TEXT("Invalid object '%s' specified for property '%s'"), *C->GetFullName(), *GetName());
			SetObjectPropertyValue(Data, NULL);
			Result = NULL;
		}
	}
	return Result;
}
void UObjectPropertyBase::CheckValidObject(void* Value) const
{
	UObject *Object = GetObjectPropertyValue(Value);
	if (Object)
	{
		//
		// here we want to make sure the the object value still matches the 
		// object type expected by the property...

		UClass* ObjectClass = Object->GetClass();
		// we could be in the middle of replacing references to the 
		// PropertyClass itself (in the middle of an FArchiveReplaceObjectRef 
		// pass)... if this is the case, then we might have already replaced 
		// the object's class, but not the PropertyClass yet (or vise-versa)... 
		// so we use this to ensure, in that situation, that we don't clear the 
		// object value (if CLASS_NewerVersionExists is set, then we are likely 
		// in the middle of an FArchiveReplaceObjectRef pass)
		bool bIsReplacingClassRefs = PropertyClass && PropertyClass->HasAnyClassFlags(CLASS_NewerVersionExists) != ObjectClass->HasAnyClassFlags(CLASS_NewerVersionExists);
		
#if USE_CIRCULAR_DEPENDENCY_LOAD_DEFERRING
		FLinkerLoad* PropertyLinker = GetLinker();
		bool const bIsDeferringValueLoad = ((PropertyLinker == nullptr) || (PropertyLinker->LoadFlags & LOAD_DeferDependencyLoads)) &&
			(Object->IsA<ULinkerPlaceholderExportObject>() || Object->IsA<ULinkerPlaceholderClass>());

#if USE_DEFERRED_DEPENDENCY_CHECK_VERIFICATION_TESTS
		check( bIsDeferringValueLoad || (!Object->IsA<ULinkerPlaceholderExportObject>() && !Object->IsA<ULinkerPlaceholderClass>()) );
#endif // USE_DEFERRED_DEPENDENCY_CHECK_VERIFICATION_TESTS

#else  // USE_CIRCULAR_DEPENDENCY_LOAD_DEFERRING 
		bool const bIsDeferringValueLoad = false;
#endif // USE_CIRCULAR_DEPENDENCY_LOAD_DEFERRING

		if ((PropertyClass != nullptr) && !ObjectClass->IsChildOf(PropertyClass) && !bIsReplacingClassRefs && !bIsDeferringValueLoad)
		{
			UE_LOG(LogProperty, Warning,
				TEXT("Serialized %s for a property of %s. Reference will be NULLed.\n    Property = %s\n    Item = %s"),
				*Object->GetClass()->GetFullName(),
				*PropertyClass->GetFullName(),
				*GetFullName(),
				*Object->GetFullName()
				);
			SetObjectPropertyValue(Value, NULL);
		}
	}
}