UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
TypedElementAttributeBindingProperty.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
6#include "Containers/Map.h"
9#include "Misc/Attribute.h"
10
12{
13 namespace Private
14 {
15 // Concept for a conversion function used by the attribute binder to bind a column data member to an attribute of a different type
16 template <typename FunctionType, typename ArgumentType>
17 concept AttributeBinderInvocable = std::is_invocable_v<std::decay_t<FunctionType>, const ArgumentType&>;
18
19 // Concept for a conversion function used by the attribute binder to bind a lambda to a TFunction accepting column arguments
20 template <typename FunctionType, typename ColumnType>
21 concept AttributeBinderColumnInvocable = std::is_invocable_v<std::decay_t<FunctionType>, const ColumnType&>;
22
23 // Concept for a conversion function used by the attribute binder to bind a lambda to a TFunction accepting column data arguments
24 template <typename FunctionType>
25 concept AttributeBinderColumnDataInvocable = std::is_invocable_v<std::decay_t<FunctionType>, const TWeakObjectPtr<const UScriptStruct>&, const void*>;
26
27 template <TColumnType ColumnType>
28 ColumnType* GetColumn(ICoreProvider* DataStorage, RowHandle Row)
29 {
30 return DataStorage->GetColumn<ColumnType>(Row);
31 }
32
33 template <TDynamicColumnTemplate ColumnType>
34 ColumnType* GetColumn(ICoreProvider* DataStorage, RowHandle Row, const FName& InIdentifier)
35 {
36 if(ensureMsgf(InIdentifier != NAME_None, TEXT("None identifier passed to dynamic column version of GetColumn. Will always return nullptr")))
37 {
38 return DataStorage->GetColumn<ColumnType>(Row, InIdentifier);
39 }
40
41 return nullptr;
42 }
43
44 template <typename PropertyType>
45 struct TEmptyProperty final
46 {
47 PropertyType* Get(void* Object) const;
48 const PropertyType* Get(const void* Object) const;
49 };
50
51 template <typename PropertyType>
52 struct TDirectProperty final
53 {
54 // Offset to a particular data member inside the object
55 size_t Offset;
56
57 PropertyType* Get(void* Object) const;
58 const PropertyType* Get(const void* Object) const;
59 };
60
61 // A property that goes through a conversion function before being accessed from the object
62 template <typename PropertyType>
64 {
65 // Conversion function
66 TFunction<PropertyType(const void*)> Converter;
67
68 // Cache to avoid a copy when returning if not necessary
69 mutable PropertyType Cache;
70
71 PropertyType* Get(void* Object) const;
72 const PropertyType* Get(const void* Object) const;
73 };
74
75 template<typename T>
80
81 template <typename PropertyType>
83 {
84 public:
85 // Bind this property directly
86 template <TDataColumnOrDynamicDataColumnTemplate ObjectType>
87 void Bind(PropertyType ObjectType::* Variable);
88
89 // Bind this property using a conversion function
90 template <typename InputType, TDataColumnOrDynamicDataColumnTemplate ObjectType>
91 void Bind(InputType ObjectType::* Variable, TFunction<PropertyType(const InputType&)> Converter);
92
93 // Get the bound property for the specified object
94 template <TDataColumnOrDynamicDataColumnTemplate ObjectType>
95 PropertyType& Get(ObjectType& Object) const;
96
97 // Get the bound property for the specified object
98 template <TDataColumnOrDynamicDataColumnTemplate ObjectType>
99 const PropertyType& Get(const ObjectType& Object) const;
100
101 // Get the bound property for this specified object ptr by providing type information about the object
102 PropertyType& Get(void* Object, TWeakObjectPtr<const UScriptStruct> Type) const;
103
104 // Get the bound property for this specified object ptr by providing type information about the object
105 const PropertyType& Get(const void* Object, TWeakObjectPtr<const UScriptStruct> Type) const;
106
107 // Returns the stored type information or null if no type was set.
109
110 // Whether or not this property has been bound.
111 bool IsBound() const;
112
113 private:
114 // Internally we could be storing a direct property or a convertible property
119
120 // The actual property
121 InternalPropertyType InternalProperty;
122
123 // The type of the object we are bound to
124 TWeakObjectPtr<const UScriptStruct> ObjectTypeInfo = nullptr;
125 };
126
127 //
128 // TEmptyProperty
129 //
130 template <typename PropertyType>
131 PropertyType* TEmptyProperty<PropertyType>::Get(void* Object) const
132 {
133 checkf(false, TEXT("Empty properties shouldn't be accessed."));
134 return nullptr;
135 }
136
137 template <typename PropertyType>
138 const PropertyType* TEmptyProperty<PropertyType>::Get(const void* Object) const
139 {
140 checkf(false, TEXT("Empty properties shouldn't be accessed."));
141 return nullptr;
142 }
143
144
145 //
146 // TDirectProperty
147 //
148
149 template <typename PropertyType>
150 PropertyType* TDirectProperty<PropertyType>::Get(void* Object) const
151 {
152 return reinterpret_cast<PropertyType*>((reinterpret_cast<char*>(Object) + Offset));
153 }
154
155 template <typename PropertyType>
156 const PropertyType* TDirectProperty<PropertyType>::Get(const void* Object) const
157 {
158 return reinterpret_cast<const PropertyType*>((reinterpret_cast<const char*>(Object) + Offset));
159 }
160
161
162 //
163 // TConvertibleProperty
164 //
165
166 template <typename PropertyType>
167 PropertyType* TConvertibleProperty<PropertyType>::Get(void* Object) const
168 {
169 Cache = Converter(Object);
170 return &Cache;
171 }
172
173 template <typename PropertyType>
174 const PropertyType* TConvertibleProperty<PropertyType>::Get(const void* Object) const
175 {
176 Cache = Converter(Object);
177 return &Cache;
178 }
179
180
181 //
182 // TProperty
183 //
184
185 template <typename PropertyType>
186 template <TDataColumnOrDynamicDataColumnTemplate ObjectType>
187 void TProperty<PropertyType>::Bind(PropertyType ObjectType::* Variable)
188 {
190 Result.Offset = reinterpret_cast<size_t>(&(reinterpret_cast<const ObjectType*>(0)->*Variable));
191
192 ObjectTypeInfo = ObjectType::StaticStruct();
194 }
195
196 template <typename PropertyType>
197 template <typename InputType, TDataColumnOrDynamicDataColumnTemplate ObjectType>
198 void TProperty<PropertyType>::Bind(InputType ObjectType::* Variable, TFunction<PropertyType(const InputType&)> Converter)
199 {
201 Result.Converter = [Converter = MoveTemp(Converter), Variable](const void* Object)
202 {
203 return Converter(reinterpret_cast<const ObjectType*>(Object)->*Variable);
204 };
205
206 ObjectTypeInfo = ObjectType::StaticStruct();
208 }
209
210 template <typename PropertyType>
211 template <TDataColumnOrDynamicDataColumnTemplate ObjectType>
212 PropertyType& TProperty<PropertyType>::Get(ObjectType& Object) const
213 {
214 return Get(&Object, ObjectType::StaticStruct());
215 }
216
217 template <typename PropertyType>
218 template <TDataColumnOrDynamicDataColumnTemplate ObjectType>
219 const PropertyType& TProperty<PropertyType>::Get(const ObjectType& Object) const
220 {
221 return Get(&Object, ObjectType::StaticStruct());
222 }
223
224 template <typename PropertyType>
226 {
227 checkf(Object, TEXT("Nullptr pointer provided to Object while trying to retrieve a property value."));
228 checkf(Type.IsValid(), TEXT("Nullptr pointer provided to Type while trying to retrieve a property value."));
229 checkf(IsBound(), TEXT("Attempting to retrieve the value of object type (%s) from a property that wasn't bound."),
230 *Type->GetFName().ToString());
231 ensureMsgf(Type == ObjectTypeInfo, TEXT("Provided object type (%s) did not match bound object type (%s)."),
232 *Type->GetFName().ToString(), ObjectTypeInfo.IsValid() ? *ObjectTypeInfo->GetFName().ToString() : TEXT("<no type>"));
233
234 return *Visit([Object](auto&& Prop) { return Prop.Get(Object); }, InternalProperty);
235 }
236
237 template <typename PropertyType>
238 const PropertyType& TProperty<PropertyType>::Get(const void* Object, TWeakObjectPtr<const UScriptStruct> Type) const
239 {
240 checkf(Object, TEXT("Nullptr pointer provided to Object while trying to retrieve a property value."));
241 checkf(Type.IsValid(), TEXT("Nullptr pointer provided to Type while trying to retrieve a property value."));
242 checkf(IsBound(), TEXT("Attempting to retrieve the value of object type (%s) from a property that wasn't bound."),
243 *Type->GetFName().ToString());
244 ensureMsgf(Type == ObjectTypeInfo, TEXT("Provided object type (%s) did not match bound object type (%s)."),
245 *Type->GetFName().ToString(), ObjectTypeInfo.IsValid() ? *ObjectTypeInfo->GetFName().ToString() : TEXT("<no type>"));
246
247 return *Visit([Object](auto&& Prop) { return Prop.Get(Object); }, InternalProperty);
248 }
249
250 template <typename PropertyType>
255
256 template <typename PropertyType>
258 {
259 return !InternalProperty.template IsType<TEmptyProperty<PropertyType>>();
260 }
261 } // namespace Private
262}
#define ensureMsgf( InExpression, InFormat,...)
Definition AssertionMacros.h:465
#define checkf(expr, format,...)
Definition AssertionMacros.h:315
#define TEXT(x)
Definition Platform.h:1272
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
decltype(auto) Visit(Func &&Callable, Variants &&... Args)
Definition TVariant.h:271
UE_INTRINSIC_CAST UE_REWRITE constexpr std::remove_reference_t< T > && MoveTemp(T &&Obj) noexcept
Definition UnrealTemplate.h:520
uint32 Offset
Definition VulkanMemory.cpp:4033
Definition NameTypes.h:617
Definition AndroidPlatformMisc.h:14
Definition TypedElementDataStorageInterface.h:65
ColumnType * GetColumn(RowHandle Row)
Definition TypedElementDataStorageInterface.h:802
Definition TypedElementAttributeBindingProperty.h:83
void Bind(PropertyType ObjectType::*Variable)
Definition TypedElementAttributeBindingProperty.h:187
PropertyType & Get(ObjectType &Object) const
Definition TypedElementAttributeBindingProperty.h:212
const PropertyType & Get(const void *Object, TWeakObjectPtr< const UScriptStruct > Type) const
Definition TypedElementAttributeBindingProperty.h:238
void Bind(InputType ObjectType::*Variable, TFunction< PropertyType(const InputType &)> Converter)
Definition TypedElementAttributeBindingProperty.h:198
const PropertyType & Get(const ObjectType &Object) const
Definition TypedElementAttributeBindingProperty.h:219
TWeakObjectPtr< const UScriptStruct > GetObjectTypeInfo() const
Definition TypedElementAttributeBindingProperty.h:251
bool IsBound() const
Definition TypedElementAttributeBindingProperty.h:257
PropertyType & Get(void *Object, TWeakObjectPtr< const UScriptStruct > Type) const
Definition TypedElementAttributeBindingProperty.h:225
Definition TypedElementAttributeBindingProperty.h:25
Definition TypedElementAttributeBindingProperty.h:21
Definition TypedElementAttributeBindingProperty.h:17
Definition TypedElementAttributeBindingProperty.h:76
Definition CommonTypes.h:95
Definition OverriddenPropertySet.cpp:45
ColumnType * GetColumn(ICoreProvider *DataStorage, RowHandle Row)
Definition TypedElementAttributeBindingProperty.h:28
Definition CommonTypes.cpp:10
uint64 RowHandle
Definition Handles.h:15
Definition TVariant.h:13
Definition WeakObjectPtrTemplates.h:25
Definition TypedElementAttributeBindingProperty.h:64
PropertyType * Get(void *Object) const
Definition TypedElementAttributeBindingProperty.h:167
PropertyType Cache
Definition TypedElementAttributeBindingProperty.h:69
TFunction< PropertyType(const void *)> Converter
Definition TypedElementAttributeBindingProperty.h:66
Definition TypedElementAttributeBindingProperty.h:53
PropertyType * Get(void *Object) const
Definition TypedElementAttributeBindingProperty.h:150
size_t Offset
Definition TypedElementAttributeBindingProperty.h:55
Definition TypedElementAttributeBindingProperty.h:46
PropertyType * Get(void *Object) const
Definition TypedElementAttributeBindingProperty.h:131