// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include "EntitySystem/MovieScenePropertySystemTypes.h" #include "EntitySystem/MovieSceneOperationalTypeConversions.h" #include "MovieSceneCommonHelpers.h" namespace UE { namespace MovieScene { /** * Property accessor traits that talk directly to the reflected UObject property type */ template struct TPropertyMetaData { static constexpr int32 Num = sizeof...(MetaDataTypes); }; /** * Property accessor traits that talk directly to the reflected UObject property type */ template struct TDirectPropertyTraits { static constexpr bool bIsComposite = bInIsComposite; using StorageType = UObjectPropertyType; using MetaDataType = TPropertyMetaData<>; using TraitsType = TDirectPropertyTraits; using ParamType = typename TCallTraits::ParamType; /** Property Value Getters */ static void GetObjectPropertyValue(const UObject* InObject, const FCustomPropertyAccessor& BaseCustomAccessor, StorageType& OutValue) { const TCustomPropertyAccessor& CustomAccessor = static_cast&>(BaseCustomAccessor); OutValue = (*CustomAccessor.Functions.Getter)(InObject); } static void GetObjectPropertyValue(const UObject* InObject, uint16 PropertyOffset, StorageType& OutValue) { const UObjectPropertyType* PropertyAddress = reinterpret_cast( reinterpret_cast(InObject) + PropertyOffset ); OutValue = *PropertyAddress; } static void GetObjectPropertyValue(const UObject* InObject, FTrackInstancePropertyBindings* PropertyBindings, StorageType& OutValue) { OutValue = PropertyBindings->GetCurrentValue(*InObject); } static void GetObjectPropertyValue(const UObject* InObject, const FName& PropertyPath, StorageType& OutValue) { TOptional Property = FTrackInstancePropertyBindings::StaticValue(InObject, *PropertyPath.ToString()); if (Property) { OutValue = MoveTemp(Property.GetValue()); } } /** Property Value Setters */ static void SetObjectPropertyValue(UObject* InObject, const FCustomPropertyAccessor& BaseCustomAccessor, ParamType InValue) { const TCustomPropertyAccessor& CustomAccessor = static_cast&>(BaseCustomAccessor); (*CustomAccessor.Functions.Setter)(InObject, InValue); } static void SetObjectPropertyValue(UObject* InObject, uint16 PropertyOffset, ParamType InValue) { UObjectPropertyType* PropertyAddress = reinterpret_cast( reinterpret_cast(InObject) + PropertyOffset ); *PropertyAddress = InValue; } static void SetObjectPropertyValue(UObject* InObject, FTrackInstancePropertyBindings* PropertyBindings, ParamType InValue) { PropertyBindings->CallFunction(*InObject, InValue); } template static StorageType CombineComposites(T&&... InComposites) { return StorageType{ Forward(InComposites)... }; } }; /** * Property accessor traits that talk directly to the reflected UObject property type */ template struct TIndirectPropertyTraits { static constexpr bool bIsComposite = bInIsComposite; using StorageType = InMemoryType; using MetaDataType = TPropertyMetaData<>; using TraitsType = TIndirectPropertyTraits; using PropertyParamType = typename TCallTraits::ParamType; using OperationalParamType = typename TCallTraits::ParamType; /** Property Value Getters */ static void GetObjectPropertyValue(const UObject* InObject, const FCustomPropertyAccessor& BaseCustomAccessor, StorageType& OutValue) { const TCustomPropertyAccessor& CustomAccessor = static_cast&>(BaseCustomAccessor); OutValue = (*CustomAccessor.Functions.Getter)(InObject); } static void GetObjectPropertyValue(const UObject* InObject, uint16 PropertyOffset, StorageType& OutValue) { const UObjectPropertyType* PropertyAddress = reinterpret_cast( reinterpret_cast(InObject) + PropertyOffset ); ConvertOperationalProperty(*PropertyAddress, OutValue); } static void GetObjectPropertyValue(const UObject* InObject, FTrackInstancePropertyBindings* PropertyBindings, StorageType& OutValue) { UObjectPropertyType Value = PropertyBindings->GetCurrentValue(*InObject); ConvertOperationalProperty(Value, OutValue); } static void GetObjectPropertyValue(const UObject* InObject, const FName& PropertyPath, StorageType& OutValue) { TOptional Property = FTrackInstancePropertyBindings::StaticValue(InObject, *PropertyPath.ToString()); if (Property) { ConvertOperationalProperty(Property.GetValue(), OutValue); } } /** Property Value Setters */ static void SetObjectPropertyValue(UObject* InObject, const FCustomPropertyAccessor& BaseCustomAccessor, OperationalParamType InValue) { const TCustomPropertyAccessor& CustomAccessor = static_cast&>(BaseCustomAccessor); (*CustomAccessor.Functions.Setter)(InObject, InValue); } static void SetObjectPropertyValue(UObject* InObject, uint16 PropertyOffset, OperationalParamType InValue) { UObjectPropertyType* PropertyAddress = reinterpret_cast( reinterpret_cast(InObject) + PropertyOffset ); ConvertOperationalProperty(InValue, *PropertyAddress); } static void SetObjectPropertyValue(UObject* InObject, FTrackInstancePropertyBindings* PropertyBindings, OperationalParamType InValue) { UObjectPropertyType NewValue{}; ConvertOperationalProperty(InValue, NewValue); PropertyBindings->CallFunction(*InObject, NewValue); } template static StorageType CombineComposites(T&&... InComposites) { return StorageType{ Forward(InComposites)... }; } }; /** * Property accessor traits that do not know the underlying UObjectPropertyType until runtime */ template struct TRuntimePropertyTraits { using StorageType = RuntimeType; using MetaDataType = TPropertyMetaData; using OperationalParamType = typename TCallTraits::ParamType; /** Property Value Getters */ static void GetObjectPropertyValue(const UObject* InObject, const FCustomPropertyAccessor& BaseCustomAccessor, typename TCallTraits::ParamType... MetaData, StorageType& OutValue) {} static void GetObjectPropertyValue(const UObject* InObject, uint16 PropertyOffset, typename TCallTraits::ParamType... MetaData, StorageType& OutValue) {} static void GetObjectPropertyValue(const UObject* InObject, FTrackInstancePropertyBindings* PropertyBindings, typename TCallTraits::ParamType... MetaData, StorageType& OutValue) {} static void GetObjectPropertyValue(const UObject* InObject, const FName& PropertyPath, StorageType& OutValue) {} /** Property Value Setters */ static void SetObjectPropertyValue(UObject* InObject, const FCustomPropertyAccessor& BaseCustomAccessor, typename TCallTraits::ParamType... MetaData, OperationalParamType InValue) {} static void SetObjectPropertyValue(UObject* InObject, uint16 PropertyOffset, typename TCallTraits::ParamType... MetaData, OperationalParamType InValue) {} static void SetObjectPropertyValue(UObject* InObject, FTrackInstancePropertyBindings* PropertyBindings, typename TCallTraits::ParamType... MetaData, OperationalParamType InValue) {} }; } // namespace MovieScene } // namespace UE