UE4 UObject to Noesis Derrived Object Reflective copy
Thought I would drop this post to share a little knowledge that I thought might be useful to others.
A big shout out to Sergio from the Noesis team for helping me!
In UE4 using Noesis, this is my reflection approach for copying UProperties values from a bound UObject within the DataContext to a derived BaseComponent data object.
I did this so that my game code didn't have to know about complex component types within my custom Noesis component. Values would be copied across on DependencyProperty PropertyChanged callback by simply having matching property names.
A big shout out to Sergio from the Noesis team for helping me!
In UE4 using Noesis, this is my reflection approach for copying UProperties values from a bound UObject within the DataContext to a derived BaseComponent data object.
I did this so that my game code didn't have to know about complex component types within my custom Noesis component. Values would be copied across on DependencyProperty PropertyChanged callback by simply having matching property names.
Code: Select all
class UObjectToNsReflection
{
public:
static void CopyProperties(Noesis::Ptr<Noesis::BaseComponent> FromObject, Noesis::Ptr<Noesis::BaseComponent> TargetObject)
{
if (FromObject && TargetObject)
{
UObject* UObj = NoesisCreateUObjectForComponent(FromObject);
const Noesis::TypeClass* TypeClass = TargetObject->GetClassType();
if (UObj && TypeClass)
{
//UE4 Reflection to copy properties across
for (TFieldIterator<FProperty> It(UObj->GetClass()); It; ++It)
{
FProperty* Property = *It;
Noesis::String NsSymbolString = TCHARToNsString(*Property->GetNameCPP());
Noesis::Symbol Symb = Noesis::Symbol(NsSymbolString.Str());
Noesis::TypeClassProperty FindPropertyResult = Noesis::FindProperty(TypeClass, Symb);
if (FindPropertyResult.property != nullptr)
{
Noesis::Ptr<Noesis::BaseComponent> BoxedValue;
if (FBoolProperty* BoolPropertyPtr = CastField<FBoolProperty>(Property))
{
BoxedValue = Noesis::Boxing::Box(*BoolPropertyPtr->ContainerPtrToValuePtr<bool>(UObj));
}
else if (FStrProperty* StrPropertyPtr = CastField<FStrProperty>(Property))
{
FString* StrVal = StrPropertyPtr->ContainerPtrToValuePtr<FString>(UObj);
BoxedValue = Noesis::Boxing::Box(TCHARToNsString(**StrVal));
}
else if (FIntProperty* IntPropertyPtr = CastField<FIntProperty>(Property))
{
BoxedValue = Noesis::Boxing::Box(IntPropertyPtr->ContainerPtrToValuePtr<int>(UObj));
}
else if (FStructProperty* StructPropertyPtr = CastField<FStructProperty>(Property))
{
if (StructPropertyPtr->Struct->GetName() == TEXT("Timespan"))
{
FTimespan* Ts = It->ContainerPtrToValuePtr<FTimespan>(UObj);
BoxedValue = Noesis::Boxing::Box(Noesis::TimeSpan(Ts->GetTicks()));
// .. More UE4 FStruct types
}
}
// Set property using boxed value
FindPropertyResult.property->SetComponent(TargetObject.GetPtr(), BoxedValue);
}
}
}
}
}
};
Who is online
Users browsing this forum: Bing [Bot], Google [Bot] and 5 guests