Plasma Engine  2.0
Loading...
Searching...
No Matches
VisualScriptNodeUserData.h
1#pragma once
2
3#include <Foundation/CodeUtils/Expression/ExpressionByteCode.h>
4#include <Foundation/Reflection/ReflectionUtils.h>
5#include <VisualScriptPlugin/Runtime/VisualScript.h>
6
7using SerializeFunction = plResult (*)(const plVisualScriptNodeDescription& nodeDesc, plStreamWriter& inout_stream, plUInt32& out_Size, plUInt32& out_alignment);
8using DeserializeFunction = plResult (*)(plVisualScriptGraphDescription::Node& node, plStreamReader& inout_stream, plUInt8*& inout_pAdditionalData);
9using ToStringFunction = void (*)(const plVisualScriptNodeDescription& nodeDesc, plStringBuilder& out_sResult);
10
11namespace
12{
13 template <typename T, typename U>
14 static plUInt32 GetDynamicSize(plUInt32 uiCount)
15 {
16 plUInt32 uiSize = sizeof(T);
17 if (uiCount > 1)
18 {
19 uiSize += sizeof(U) * (uiCount - 1);
20 }
21 return uiSize;
22 }
23
24 struct NodeUserData_Type
25 {
26 const plRTTI* m_pType = nullptr;
27
28#if PL_ENABLED(PL_PLATFORM_32BIT)
29 plUInt32 m_uiPadding;
30#endif
31
32 static plResult Serialize(const plVisualScriptNodeDescription& nodeDesc, plStreamWriter& inout_stream, plUInt32& out_uiSize, plUInt32& out_uiAlignment)
33 {
34 inout_stream << nodeDesc.m_sTargetTypeName;
35
36 out_uiSize = sizeof(NodeUserData_Type);
37 out_uiAlignment = PL_ALIGNMENT_OF(NodeUserData_Type);
38 return PL_SUCCESS;
39 }
40
41 static plResult ReadType(plStreamReader& inout_stream, const plRTTI*& out_pType)
42 {
43 plStringBuilder sTypeName;
44 inout_stream >> sTypeName;
45
46 out_pType = plRTTI::FindTypeByName(sTypeName);
47 if (out_pType == nullptr)
48 {
49 plLog::Error("Unknown type '{}'", sTypeName);
50 return PL_FAILURE;
51 }
52
53 return PL_SUCCESS;
54 }
55
56 static plResult Deserialize(plVisualScriptGraphDescription::Node& ref_node, plStreamReader& inout_stream, plUInt8*& inout_pAdditionalData)
57 {
58 auto& userData = ref_node.InitUserData<NodeUserData_Type>(inout_pAdditionalData);
59 PL_SUCCEED_OR_RETURN(ReadType(inout_stream, userData.m_pType));
60 return PL_SUCCESS;
61 }
62
63 static void ToString(const plVisualScriptNodeDescription& nodeDesc, plStringBuilder& out_sResult)
64 {
65 if (nodeDesc.m_sTargetTypeName.IsEmpty() == false)
66 {
67 out_sResult.Append(nodeDesc.m_sTargetTypeName);
68 }
69 }
70 };
71
72 static_assert(sizeof(NodeUserData_Type) == 8);
73
75
76 struct NodeUserData_TypeAndProperty : public NodeUserData_Type
77 {
78 const plAbstractProperty* m_pProperty = nullptr;
79
80#if PL_ENABLED(PL_PLATFORM_32BIT)
81 plUInt32 m_uiPadding;
82#endif
83
84 static plResult Serialize(const plVisualScriptNodeDescription& nodeDesc, plStreamWriter& inout_stream, plUInt32& out_uiSize, plUInt32& out_uiAlignment)
85 {
86 PL_SUCCEED_OR_RETURN(NodeUserData_Type::Serialize(nodeDesc, inout_stream, out_uiSize, out_uiAlignment));
87
88 const plVariantArray& propertiesVar = nodeDesc.m_Value.Get<plVariantArray>();
89 PL_ASSERT_DEBUG(propertiesVar.GetCount() == 1, "Invalid number of properties");
90
91 inout_stream << propertiesVar[0].Get<plHashedString>();
92
93 out_uiSize = sizeof(NodeUserData_TypeAndProperty);
94 out_uiAlignment = PL_ALIGNMENT_OF(NodeUserData_TypeAndProperty);
95 return PL_SUCCESS;
96 }
97
98 template <typename T>
99 static plResult ReadProperty(plStreamReader& inout_stream, const plRTTI* pType, plArrayPtr<T> properties, const plAbstractProperty*& out_pProp)
100 {
101 plStringBuilder sPropName;
102 inout_stream >> sPropName;
103
104 out_pProp = nullptr;
105 for (auto& pProp : properties)
106 {
107 if (sPropName == pProp->GetPropertyName())
108 {
109 out_pProp = pProp;
110 break;
111 }
112 }
113
114 if (out_pProp == nullptr)
115 {
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());
118 return PL_FAILURE;
119 }
120
121 return PL_SUCCESS;
122 }
123
124 template <bool PropIsFunction>
125 static plResult Deserialize(plVisualScriptGraphDescription::Node& ref_node, plStreamReader& inout_stream, plUInt8*& inout_pAdditionalData)
126 {
127 auto& userData = ref_node.InitUserData<NodeUserData_TypeAndProperty>(inout_pAdditionalData);
128 PL_SUCCEED_OR_RETURN(ReadType(inout_stream, userData.m_pType));
129
130 if constexpr (PropIsFunction)
131 {
132 PL_SUCCEED_OR_RETURN(ReadProperty(inout_stream, userData.m_pType, userData.m_pType->GetFunctions(), userData.m_pProperty));
133 }
134 else
135 {
136 PL_SUCCEED_OR_RETURN(ReadProperty(inout_stream, userData.m_pType, userData.m_pType->GetProperties(), userData.m_pProperty));
137 }
138
139 return PL_SUCCESS;
140 }
141
142 static void ToString(const plVisualScriptNodeDescription& nodeDesc, plStringBuilder& out_sResult)
143 {
144 NodeUserData_Type::ToString(nodeDesc, out_sResult);
145
146 if (nodeDesc.m_Value.IsA<plVariantArray>())
147 {
148 const plVariantArray& propertiesVar = nodeDesc.m_Value.Get<plVariantArray>();
149 if (propertiesVar.IsEmpty() == false)
150 {
151 out_sResult.Append(".", propertiesVar[0].Get<plHashedString>());
152 }
153 }
154 }
155 };
156
157 static_assert(sizeof(NodeUserData_TypeAndProperty) == 16);
158
160
161 struct NodeUserData_TypeAndProperties : public NodeUserData_Type
162 {
163 plUInt32 m_uiNumProperties = 0;
164
165#if PL_ENABLED(PL_PLATFORM_32BIT)
166 plUInt32 m_uiPadding0;
167#endif
168
169 // This struct is allocated with enough space behind it to hold an array with m_uiNumProperties size.
170 const plAbstractProperty* m_Properties[1];
171
172#if PL_ENABLED(PL_PLATFORM_32BIT)
173 plUInt32 m_uiPadding1;
174#endif
175
176 static plResult Serialize(const plVisualScriptNodeDescription& nodeDesc, plStreamWriter& inout_stream, plUInt32& out_uiSize, plUInt32& out_uiAlignment)
177 {
178 PL_SUCCEED_OR_RETURN(NodeUserData_Type::Serialize(nodeDesc, inout_stream, out_uiSize, out_uiAlignment));
179
180 const plVariantArray& propertiesVar = nodeDesc.m_Value.Get<plVariantArray>();
181
182 plUInt32 uiCount = propertiesVar.GetCount();
183 inout_stream << uiCount;
184
185 for (auto& var : propertiesVar)
186 {
187 plHashedString sPropName = var.Get<plHashedString>();
188 inout_stream << sPropName;
189 }
190
191 static_assert(sizeof(void*) <= sizeof(plUInt64));
192 out_uiSize = GetDynamicSize<NodeUserData_TypeAndProperties, plUInt64>(uiCount);
193 out_uiAlignment = PL_ALIGNMENT_OF(NodeUserData_TypeAndProperties);
194 return PL_SUCCESS;
195 }
196
197 static plResult Deserialize(plVisualScriptGraphDescription::Node& ref_node, plStreamReader& inout_stream, plUInt8*& inout_pAdditionalData)
198 {
199 const plRTTI* pType = nullptr;
200 PL_SUCCEED_OR_RETURN(ReadType(inout_stream, pType));
201
202 plUInt32 uiCount = 0;
203 inout_stream >> uiCount;
204
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;
209
211 userData.m_pType->GetAllProperties(properties);
212
213 for (plUInt32 i = 0; i < uiCount; ++i)
214 {
215 const plAbstractProperty* pProperty = nullptr;
216 PL_SUCCEED_OR_RETURN(NodeUserData_TypeAndProperty::ReadProperty(inout_stream, userData.m_pType, properties.GetArrayPtr(), pProperty));
217 userData.m_Properties[i] = pProperty;
218 }
219
220 return PL_SUCCESS;
221 }
222
223 static void ToString(const plVisualScriptNodeDescription& nodeDesc, plStringBuilder& out_sResult)
224 {
225 NodeUserData_TypeAndProperty::ToString(nodeDesc, out_sResult);
226 }
227 };
228
229 static_assert(sizeof(NodeUserData_TypeAndProperties) == 24);
230
232
233 struct NodeUserData_Switch
234 {
235 plUInt32 m_uiNumCases = 0;
236
237 // This struct is allocated with enough space behind it to hold an array with m_uiNumCases size.
238 plInt64 m_Cases[1];
239
240 static plResult Serialize(const plVisualScriptNodeDescription& nodeDesc, plStreamWriter& inout_stream, plUInt32& out_uiSize, plUInt32& out_uiAlignment)
241 {
242 const plVariantArray& casesVar = nodeDesc.m_Value.Get<plVariantArray>();
243
244 plUInt32 uiCount = casesVar.GetCount();
245 inout_stream << uiCount;
246
247 for (auto& var : casesVar)
248 {
249 plInt64 iCaseValue = var.ConvertTo<plInt64>();
250 inout_stream << iCaseValue;
251 }
252
253 out_uiSize = GetDynamicSize<NodeUserData_Switch, plInt64>(uiCount);
254 out_uiAlignment = PL_ALIGNMENT_OF(NodeUserData_Switch);
255 return PL_SUCCESS;
256 }
257
258 static plResult Deserialize(plVisualScriptGraphDescription::Node& ref_node, plStreamReader& inout_stream, plUInt8*& inout_pAdditionalData)
259 {
260 plUInt32 uiCount = 0;
261 inout_stream >> uiCount;
262
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;
266
267 for (plUInt32 i = 0; i < uiCount; ++i)
268 {
269 inout_stream >> userData.m_Cases[i];
270 }
271
272 return PL_SUCCESS;
273 }
274
275 static void ToString(const plVisualScriptNodeDescription& nodeDesc, plStringBuilder& out_sResult)
276 {
277 // Nothing to add here
278 }
279 };
280
282
283 struct NodeUserData_Comparison
284 {
285 plEnum<plComparisonOperator> m_ComparisonOperator;
286
287 static plResult Serialize(const plVisualScriptNodeDescription& nodeDesc, plStreamWriter& inout_stream, plUInt32& out_uiSize, plUInt32& out_uiAlignment)
288 {
289 plEnum<plComparisonOperator> compOp = static_cast<plComparisonOperator::Enum>(nodeDesc.m_Value.Get<plInt64>());
290 inout_stream << compOp;
291
292 out_uiSize = sizeof(NodeUserData_Comparison);
293 out_uiAlignment = PL_ALIGNMENT_OF(NodeUserData_Comparison);
294 return PL_SUCCESS;
295 }
296
297 static plResult Deserialize(plVisualScriptGraphDescription::Node& ref_node, plStreamReader& inout_stream, plUInt8*& inout_pAdditionalData)
298 {
299 auto& userData = ref_node.InitUserData<NodeUserData_Comparison>(inout_pAdditionalData);
300 inout_stream >> userData.m_ComparisonOperator;
301
302 return PL_SUCCESS;
303 }
304
305 static void ToString(const plVisualScriptNodeDescription& nodeDesc, plStringBuilder& out_sResult)
306 {
307 plStringBuilder sCompOp;
308 plReflectionUtils::EnumerationToString(plGetStaticRTTI<plComparisonOperator>(), nodeDesc.m_Value.Get<plInt64>(), sCompOp, plReflectionUtils::EnumConversionMode::ValueNameOnly);
309
310 out_sResult.Append(" ", sCompOp);
311 }
312 };
313
315
316 struct NodeUserData_Expression
317 {
318 plExpressionByteCode m_ByteCode;
319
320 static plResult Serialize(const plVisualScriptNodeDescription& nodeDesc, plStreamWriter& inout_stream, plUInt32& out_uiSize, plUInt32& out_uiAlignment)
321 {
322 const plExpressionByteCode& byteCode = nodeDesc.m_Value.Get<plExpressionByteCode>();
323
324 plUInt32 uiDataSize = static_cast<plUInt32>(byteCode.GetDataBlob().GetCount());
325 inout_stream << uiDataSize;
326
327 PL_SUCCEED_OR_RETURN(byteCode.Save(inout_stream));
328
329 out_uiSize = sizeof(NodeUserData_Expression) + uiDataSize;
330 out_uiAlignment = PL_ALIGNMENT_OF(NodeUserData_Expression);
331 return PL_SUCCESS;
332 }
333
334 static plResult Deserialize(plVisualScriptGraphDescription::Node& ref_node, plStreamReader& inout_stream, plUInt8*& inout_pAdditionalData)
335 {
336 auto& userData = ref_node.InitUserData<NodeUserData_Expression>(inout_pAdditionalData);
337
338 plUInt32 uiDataSize = 0;
339 inout_stream >> uiDataSize;
340
341 auto externalMemory = plMakeArrayPtr(inout_pAdditionalData, uiDataSize);
342 inout_pAdditionalData += uiDataSize;
343
344 PL_SUCCEED_OR_RETURN(userData.m_ByteCode.Load(inout_stream, externalMemory));
345
346 return PL_SUCCESS;
347 }
348
349 static void ToString(const plVisualScriptNodeDescription& nodeDesc, plStringBuilder& out_sResult)
350 {
351 // Nothing to add here
352 }
353 };
354
356
357 struct NodeUserData_StartCoroutine : public NodeUserData_Type
358 {
360
361 static plResult Serialize(const plVisualScriptNodeDescription& nodeDesc, plStreamWriter& inout_stream, plUInt32& out_uiSize, plUInt32& out_uiAlignment)
362 {
363 PL_SUCCEED_OR_RETURN(NodeUserData_Type::Serialize(nodeDesc, inout_stream, out_uiSize, out_uiAlignment));
364
365 plEnum<plScriptCoroutineCreationMode> creationMode = static_cast<plScriptCoroutineCreationMode::Enum>(nodeDesc.m_Value.Get<plInt64>());
366 inout_stream << creationMode;
367
368 out_uiSize = sizeof(NodeUserData_StartCoroutine);
369 out_uiAlignment = PL_ALIGNMENT_OF(NodeUserData_StartCoroutine);
370 return PL_SUCCESS;
371 }
372
373 static plResult Deserialize(plVisualScriptGraphDescription::Node& ref_node, plStreamReader& inout_stream, plUInt8*& inout_pAdditionalData)
374 {
375 auto& userData = ref_node.InitUserData<NodeUserData_StartCoroutine>(inout_pAdditionalData);
376 PL_SUCCEED_OR_RETURN(ReadType(inout_stream, userData.m_pType));
377
378 inout_stream >> userData.m_CreationMode;
379
380 return PL_SUCCESS;
381 }
382
383 static void ToString(const plVisualScriptNodeDescription& nodeDesc, plStringBuilder& out_sResult)
384 {
385 NodeUserData_Type::ToString(nodeDesc, out_sResult);
386
387 plStringBuilder sCreationMode;
388 plReflectionUtils::EnumerationToString(plGetStaticRTTI<plScriptCoroutineCreationMode>(), nodeDesc.m_Value.Get<plInt64>(), sCreationMode, plReflectionUtils::EnumConversionMode::ValueNameOnly);
389
390 out_sResult.Append(" ", sCreationMode);
391 }
392 };
393
394 static_assert(sizeof(NodeUserData_StartCoroutine) == 16);
395
397
398 struct UserDataContext
399 {
400 SerializeFunction m_SerializeFunc = nullptr;
401 DeserializeFunction m_DeserializeFunc = nullptr;
402 ToStringFunction m_ToStringFunc = nullptr;
403 };
404
405 inline UserDataContext s_TypeToUserDataContexts[] = {
406 {}, // Invalid,
407 {}, // EntryCall,
408 {}, // EntryCall_Coroutine,
409 {&NodeUserData_TypeAndProperties::Serialize,
410 &NodeUserData_TypeAndProperties::Deserialize,
411 &NodeUserData_TypeAndProperties::ToString}, // MessageHandler,
412 {&NodeUserData_TypeAndProperties::Serialize,
413 &NodeUserData_TypeAndProperties::Deserialize,
414 &NodeUserData_TypeAndProperties::ToString}, // MessageHandler_Coroutine,
415 {&NodeUserData_TypeAndProperty::Serialize,
416 &NodeUserData_TypeAndProperty::Deserialize<true>,
417 &NodeUserData_TypeAndProperty::ToString}, // ReflectedFunction,
418 {&NodeUserData_TypeAndProperty::Serialize,
419 &NodeUserData_TypeAndProperty::Deserialize<false>,
420 &NodeUserData_TypeAndProperty::ToString}, // GetReflectedProperty,
421 {&NodeUserData_TypeAndProperty::Serialize,
422 &NodeUserData_TypeAndProperty::Deserialize<false>,
423 &NodeUserData_TypeAndProperty::ToString}, // SetReflectedProperty,
424 {&NodeUserData_TypeAndProperty::Serialize,
425 &NodeUserData_TypeAndProperty::Deserialize<true>,
426 &NodeUserData_TypeAndProperty::ToString}, // InplaceCoroutine,
427 {}, // GetScriptOwner,
428 {&NodeUserData_TypeAndProperties::Serialize,
429 &NodeUserData_TypeAndProperties::Deserialize,
430 &NodeUserData_TypeAndProperties::ToString}, // SendMessage,
431
432 {}, // FirstBuiltin,
433
434 {}, // Builtin_Constant,
435 {}, // Builtin_GetVariable,
436 {}, // Builtin_SetVariable,
437 {}, // Builtin_IncVariable,
438 {}, // Builtin_DecVariable,
439
440 {}, // Builtin_Branch,
441 {&NodeUserData_Switch::Serialize,
442 &NodeUserData_Switch::Deserialize,
443 &NodeUserData_Switch::ToString}, // Builtin_Switch,
444 {}, // Builtin_WhileLoop,
445 {}, // Builtin_ForLoop,
446 {}, // Builtin_ForEachLoop,
447 {}, // Builtin_ReverseForEachLoop,
448 {}, // Builtin_Break,
449 {}, // Builtin_Jump,
450
451 {}, // Builtin_And,
452 {}, // Builtin_Or,
453 {}, // Builtin_Not,
454 {&NodeUserData_Comparison::Serialize,
455 &NodeUserData_Comparison::Deserialize,
456 &NodeUserData_Comparison::ToString}, // Builtin_Compare,
457 {}, // Builtin_CompareExec,
458 {}, // Builtin_IsValid,
459 {}, // Builtin_Select,
460
461 {}, // Builtin_Add,
462 {}, // Builtin_Subtract,
463 {}, // Builtin_Multiply,
464 {}, // Builtin_Divide,
465 {&NodeUserData_Expression::Serialize,
466 &NodeUserData_Expression::Deserialize,
467 &NodeUserData_Expression::ToString}, // Builtin_Expression,
468
469 {}, // Builtin_ToBool,
470 {}, // Builtin_ToByte,
471 {}, // Builtin_ToInt,
472 {}, // Builtin_ToInt64,
473 {}, // Builtin_ToFloat,
474 {}, // Builtin_ToDouble,
475 {}, // Builtin_ToString,
476 {}, // Builtin_String_Format,
477 {}, // Builtin_ToHashedString,
478 {}, // Builtin_ToVariant,
479 {}, // Builtin_Variant_ConvertTo,
480
481 {}, // Builtin_MakeArray
482 {}, // Builtin_Array_GetElement,
483 {}, // Builtin_Array_SetElement,
484 {}, // Builtin_Array_GetCount,
485 {}, // Builtin_Array_IsEmpty,
486 {}, // Builtin_Array_Clear,
487 {}, // Builtin_Array_Contains,
488 {}, // Builtin_Array_IndexOf,
489 {}, // Builtin_Array_Insert,
490 {}, // Builtin_Array_PushBack,
491 {}, // Builtin_Array_Remove,
492 {}, // Builtin_Array_RemoveAt,
493
494 {&NodeUserData_Type::Serialize,
495 &NodeUserData_Type::Deserialize,
496 &NodeUserData_Type::ToString}, // Builtin_TryGetComponentOfBaseType
497
498 {&NodeUserData_StartCoroutine::Serialize,
499 &NodeUserData_StartCoroutine::Deserialize,
500 &NodeUserData_StartCoroutine::ToString}, // Builtin_StartCoroutine,
501 {}, // Builtin_StopCoroutine,
502 {}, // Builtin_StopAllCoroutines,
503 {}, // Builtin_WaitForAll,
504 {}, // Builtin_WaitForAny,
505 {}, // Builtin_Yield,
506
507 {}, // LastBuiltin,
508 };
509
510 static_assert(PL_ARRAY_SIZE(s_TypeToUserDataContexts) == plVisualScriptNodeDescription::Type::Count);
511} // namespace
512
513const UserDataContext& GetUserDataContext(plVisualScriptNodeDescription::Type::Enum nodeType)
514{
515 PL_ASSERT_DEBUG(nodeType >= 0 && nodeType < PL_ARRAY_SIZE(s_TypeToUserDataContexts), "Out of bounds access");
516 return s_TypeToUserDataContexts[nodeType];
517}
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