3#include <Foundation/CodeUtils/Expression/ExpressionByteCode.h>
4#include <Foundation/Reflection/ReflectionUtils.h>
5#include <VisualScriptPlugin/Runtime/VisualScript.h>
13 template <
typename T,
typename U>
14 static plUInt32 GetDynamicSize(plUInt32 uiCount)
16 plUInt32 uiSize =
sizeof(T);
19 uiSize +=
sizeof(U) * (uiCount - 1);
24 struct NodeUserData_Type
26 const plRTTI* m_pType =
nullptr;
28#if PL_ENABLED(PL_PLATFORM_32BIT)
34 inout_stream << nodeDesc.m_sTargetTypeName;
36 out_uiSize =
sizeof(NodeUserData_Type);
37 out_uiAlignment = PL_ALIGNMENT_OF(NodeUserData_Type);
44 inout_stream >> sTypeName;
47 if (out_pType ==
nullptr)
58 auto& userData = ref_node.InitUserData<NodeUserData_Type>(inout_pAdditionalData);
59 PL_SUCCEED_OR_RETURN(ReadType(inout_stream, userData.m_pType));
65 if (nodeDesc.m_sTargetTypeName.
IsEmpty() ==
false)
67 out_sResult.
Append(nodeDesc.m_sTargetTypeName);
72 static_assert(
sizeof(NodeUserData_Type) == 8);
76 struct NodeUserData_TypeAndProperty :
public NodeUserData_Type
80#if PL_ENABLED(PL_PLATFORM_32BIT)
86 PL_SUCCEED_OR_RETURN(NodeUserData_Type::Serialize(nodeDesc, inout_stream, out_uiSize, out_uiAlignment));
89 PL_ASSERT_DEBUG(propertiesVar.
GetCount() == 1,
"Invalid number of properties");
93 out_uiSize =
sizeof(NodeUserData_TypeAndProperty);
94 out_uiAlignment = PL_ALIGNMENT_OF(NodeUserData_TypeAndProperty);
102 inout_stream >> sPropName;
105 for (
auto& pProp : properties)
107 if (sPropName == pProp->GetPropertyName())
114 if (out_pProp ==
nullptr)
116 constexpr bool isFunction = std::is_same_v<T, const plAbstractFunctionProperty* const>;
117 plLog::Error(
"{} '{}' not found on type '{}'", isFunction ?
"Function" :
"Property", sPropName, pType->GetTypeName());
124 template <
bool PropIsFunction>
127 auto& userData = ref_node.InitUserData<NodeUserData_TypeAndProperty>(inout_pAdditionalData);
128 PL_SUCCEED_OR_RETURN(ReadType(inout_stream, userData.m_pType));
130 if constexpr (PropIsFunction)
132 PL_SUCCEED_OR_RETURN(ReadProperty(inout_stream, userData.m_pType, userData.m_pType->GetFunctions(), userData.m_pProperty));
136 PL_SUCCEED_OR_RETURN(ReadProperty(inout_stream, userData.m_pType, userData.m_pType->GetProperties(), userData.m_pProperty));
144 NodeUserData_Type::ToString(nodeDesc, out_sResult);
149 if (propertiesVar.
IsEmpty() ==
false)
151 out_sResult.
Append(
".", propertiesVar[0].Get<plHashedString>());
157 static_assert(
sizeof(NodeUserData_TypeAndProperty) == 16);
161 struct NodeUserData_TypeAndProperties :
public NodeUserData_Type
163 plUInt32 m_uiNumProperties = 0;
165#if PL_ENABLED(PL_PLATFORM_32BIT)
166 plUInt32 m_uiPadding0;
172#if PL_ENABLED(PL_PLATFORM_32BIT)
173 plUInt32 m_uiPadding1;
178 PL_SUCCEED_OR_RETURN(NodeUserData_Type::Serialize(nodeDesc, inout_stream, out_uiSize, out_uiAlignment));
182 plUInt32 uiCount = propertiesVar.
GetCount();
183 inout_stream << uiCount;
185 for (
auto& var : propertiesVar)
188 inout_stream << sPropName;
191 static_assert(
sizeof(
void*) <=
sizeof(plUInt64));
192 out_uiSize = GetDynamicSize<NodeUserData_TypeAndProperties, plUInt64>(uiCount);
193 out_uiAlignment = PL_ALIGNMENT_OF(NodeUserData_TypeAndProperties);
199 const plRTTI* pType =
nullptr;
200 PL_SUCCEED_OR_RETURN(ReadType(inout_stream, pType));
202 plUInt32 uiCount = 0;
203 inout_stream >> uiCount;
205 const plUInt32 uiByteSize = GetDynamicSize<NodeUserData_TypeAndProperties, plUInt64>(uiCount);
206 auto& userData = ref_node.InitUserData<NodeUserData_TypeAndProperties>(inout_pAdditionalData, uiByteSize);
207 userData.m_pType = pType;
208 userData.m_uiNumProperties = uiCount;
211 userData.m_pType->GetAllProperties(properties);
213 for (plUInt32 i = 0; i < uiCount; ++i)
216 PL_SUCCEED_OR_RETURN(NodeUserData_TypeAndProperty::ReadProperty(inout_stream, userData.m_pType, properties.
GetArrayPtr(), pProperty));
217 userData.m_Properties[i] = pProperty;
225 NodeUserData_TypeAndProperty::ToString(nodeDesc, out_sResult);
229 static_assert(
sizeof(NodeUserData_TypeAndProperties) == 24);
233 struct NodeUserData_Switch
235 plUInt32 m_uiNumCases = 0;
244 plUInt32 uiCount = casesVar.
GetCount();
245 inout_stream << uiCount;
247 for (
auto& var : casesVar)
249 plInt64 iCaseValue = var.ConvertTo<plInt64>();
250 inout_stream << iCaseValue;
253 out_uiSize = GetDynamicSize<NodeUserData_Switch, plInt64>(uiCount);
254 out_uiAlignment = PL_ALIGNMENT_OF(NodeUserData_Switch);
260 plUInt32 uiCount = 0;
261 inout_stream >> uiCount;
263 const plUInt32 uiByteSize = GetDynamicSize<NodeUserData_Switch, plInt64>(uiCount);
264 auto& userData = ref_node.InitUserData<NodeUserData_Switch>(inout_pAdditionalData, uiByteSize);
265 userData.m_uiNumCases = uiCount;
267 for (plUInt32 i = 0; i < uiCount; ++i)
269 inout_stream >> userData.m_Cases[i];
283 struct NodeUserData_Comparison
290 inout_stream << compOp;
292 out_uiSize =
sizeof(NodeUserData_Comparison);
293 out_uiAlignment = PL_ALIGNMENT_OF(NodeUserData_Comparison);
299 auto& userData = ref_node.InitUserData<NodeUserData_Comparison>(inout_pAdditionalData);
300 inout_stream >> userData.m_ComparisonOperator;
310 out_sResult.
Append(
" ", sCompOp);
316 struct NodeUserData_Expression
324 plUInt32 uiDataSize =
static_cast<plUInt32
>(byteCode.GetDataBlob().
GetCount());
325 inout_stream << uiDataSize;
327 PL_SUCCEED_OR_RETURN(byteCode.Save(inout_stream));
329 out_uiSize =
sizeof(NodeUserData_Expression) + uiDataSize;
330 out_uiAlignment = PL_ALIGNMENT_OF(NodeUserData_Expression);
336 auto& userData = ref_node.InitUserData<NodeUserData_Expression>(inout_pAdditionalData);
338 plUInt32 uiDataSize = 0;
339 inout_stream >> uiDataSize;
341 auto externalMemory = plMakeArrayPtr(inout_pAdditionalData, uiDataSize);
342 inout_pAdditionalData += uiDataSize;
344 PL_SUCCEED_OR_RETURN(userData.m_ByteCode.Load(inout_stream, externalMemory));
357 struct NodeUserData_StartCoroutine :
public NodeUserData_Type
363 PL_SUCCEED_OR_RETURN(NodeUserData_Type::Serialize(nodeDesc, inout_stream, out_uiSize, out_uiAlignment));
366 inout_stream << creationMode;
368 out_uiSize =
sizeof(NodeUserData_StartCoroutine);
369 out_uiAlignment = PL_ALIGNMENT_OF(NodeUserData_StartCoroutine);
375 auto& userData = ref_node.InitUserData<NodeUserData_StartCoroutine>(inout_pAdditionalData);
376 PL_SUCCEED_OR_RETURN(ReadType(inout_stream, userData.m_pType));
378 inout_stream >> userData.m_CreationMode;
385 NodeUserData_Type::ToString(nodeDesc, out_sResult);
390 out_sResult.
Append(
" ", sCreationMode);
394 static_assert(
sizeof(NodeUserData_StartCoroutine) == 16);
398 struct UserDataContext
400 SerializeFunction m_SerializeFunc =
nullptr;
401 DeserializeFunction m_DeserializeFunc =
nullptr;
402 ToStringFunction m_ToStringFunc =
nullptr;
405 inline UserDataContext s_TypeToUserDataContexts[] = {
409 {&NodeUserData_TypeAndProperties::Serialize,
410 &NodeUserData_TypeAndProperties::Deserialize,
411 &NodeUserData_TypeAndProperties::ToString},
412 {&NodeUserData_TypeAndProperties::Serialize,
413 &NodeUserData_TypeAndProperties::Deserialize,
414 &NodeUserData_TypeAndProperties::ToString},
415 {&NodeUserData_TypeAndProperty::Serialize,
416 &NodeUserData_TypeAndProperty::Deserialize<true>,
417 &NodeUserData_TypeAndProperty::ToString},
418 {&NodeUserData_TypeAndProperty::Serialize,
419 &NodeUserData_TypeAndProperty::Deserialize<false>,
420 &NodeUserData_TypeAndProperty::ToString},
421 {&NodeUserData_TypeAndProperty::Serialize,
422 &NodeUserData_TypeAndProperty::Deserialize<false>,
423 &NodeUserData_TypeAndProperty::ToString},
424 {&NodeUserData_TypeAndProperty::Serialize,
425 &NodeUserData_TypeAndProperty::Deserialize<true>,
426 &NodeUserData_TypeAndProperty::ToString},
428 {&NodeUserData_TypeAndProperties::Serialize,
429 &NodeUserData_TypeAndProperties::Deserialize,
430 &NodeUserData_TypeAndProperties::ToString},
441 {&NodeUserData_Switch::Serialize,
442 &NodeUserData_Switch::Deserialize,
443 &NodeUserData_Switch::ToString},
454 {&NodeUserData_Comparison::Serialize,
455 &NodeUserData_Comparison::Deserialize,
456 &NodeUserData_Comparison::ToString},
465 {&NodeUserData_Expression::Serialize,
466 &NodeUserData_Expression::Deserialize,
467 &NodeUserData_Expression::ToString},
494 {&NodeUserData_Type::Serialize,
495 &NodeUserData_Type::Deserialize,
496 &NodeUserData_Type::ToString},
498 {&NodeUserData_StartCoroutine::Serialize,
499 &NodeUserData_StartCoroutine::Deserialize,
500 &NodeUserData_StartCoroutine::ToString},
510 static_assert(PL_ARRAY_SIZE(s_TypeToUserDataContexts) == plVisualScriptNodeDescription::Type::Count);
513const UserDataContext& GetUserDataContext(plVisualScriptNodeDescription::Type::Enum nodeType)
515 PL_ASSERT_DEBUG(nodeType >= 0 && nodeType < PL_ARRAY_SIZE(s_TypeToUserDataContexts),
"Out of bounds access");
516 return s_TypeToUserDataContexts[nodeType];
This is the base interface for all properties in the reflection system. It provides enough informatio...
Definition AbstractProperty.h:150
bool IsEmpty() const
Returns true, if the array does not contain any elements.
Definition ArrayBase_inl.h:178
plArrayPtr< T > GetArrayPtr()
Returns an array pointer to the array data, or an empty array pointer if the array is empty.
Definition ArrayBase_inl.h:441
plUInt32 GetCount() const
Returns the number of active elements in the array.
Definition ArrayBase_inl.h:172
This class encapsulates an array and it's size. It is recommended to use this class instead of plain ...
Definition ArrayPtr.h:37
PL_ALWAYS_INLINE plUInt64 GetCount() const
Returns the number of elements in the array.
Definition Blob.h:95
Definition ExpressionByteCode.h:10
This class is optimized to take nearly no memory (sizeof(void*)) and to allow very fast checks whethe...
Definition HashedString.h:25
bool IsEmpty() const
Returns whether the string is empty.
Definition HashedString.cpp:121
A hybrid array uses in-place storage to handle the first few elements without any allocation....
Definition HybridArray.h:12
static void Error(plLogInterface *pInterface, const plFormatString &string)
An error that needs to be fixed as soon as possible.
Definition Log.cpp:375
This class holds information about reflected types. Each instance represents one type that is known t...
Definition RTTI.h:30
static const plRTTI * FindTypeByName(plStringView sName)
Searches all plRTTI instances for the one with the given name, or nullptr if no such type exists.
Definition RTTI.cpp:250
static bool EnumerationToString(const plRTTI *pEnumerationRtti, plInt64 iValue, plStringBuilder &out_sOutput, plEnum< EnumConversionMode > conversionMode=EnumConversionMode::Default)
Converts an enum or bitfield value into its string representation.
Definition ReflectionUtils.cpp:926
Interface for binary in (read) streams.
Definition Stream.h:22
Interface for binary out (write) streams.
Definition Stream.h:107
plStringBuilder is a class that is meant for creating and modifying strings.
Definition StringBuilder.h:35
void Append(plUInt32 uiChar)
Appends a single Utf32 character.
Definition StringBuilder_inl.h:94
const T & Get() const
Returns the variants value as the provided type.
bool IsA() const
Returns whether the stored type is exactly the given type.
PL_ALWAYS_INLINE const plStringBuilder & ToString(bool value, plStringBuilder &out_sResult)
Converts a bool to a string.
Definition ConversionUtils.h:176
A custom enum implementation that allows to define the underlying storage type to control its memory ...
Definition Enum.h:37
Default enum for returning failure or success, instead of using a bool.
Definition Types.h:54
Enum
Definition ScriptCoroutine.h:122
Definition VisualScript.h:187
Definition VisualScript.h:10