5#include <Foundation/Basics.h>
6#include <Foundation/Types/Bitflags.h>
7#include <Foundation/Types/VariantType.h>
17 using StorageType = plUInt8;
34 StorageType StandardType : 1;
35 StorageType IsEnum : 1;
36 StorageType Bitflags : 1;
37 StorageType Class : 1;
38 StorageType Abstract : 1;
39 StorageType Phantom : 1;
61 static const plRTTI* GetRTTI() {
return nullptr; }
68 static const plRTTI* GetRTTI() {
return nullptr; }
74 return T::GetStaticRTTI();
83 return plStaticRTTI<T>::GetRTTI();
86 template <
typename Type>
97 if (std::is_abstract<Type>::value)
109 template <
typename T>
112 static_assert(
sizeof(T) == 0,
"Type has not been declared as reflectable (use PL_DECLARE_REFLECTABLE_TYPE macro)");
118PL_ALWAYS_INLINE
const plRTTI* plGetStaticRTTI()
130#define PL_DECLARE_REFLECTABLE_TYPE(Linkage, TYPE) \
131 namespace plInternal \
134 struct Linkage plStaticRTTIWrapper<TYPE> \
136 static plRTTI s_RTTI; \
143 struct plStaticRTTI<TYPE> \
145 PL_ALWAYS_INLINE static const plRTTI* GetRTTI() \
147 return &plStaticRTTIWrapper<TYPE>::s_RTTI; \
154#define PL_ALLOW_PRIVATE_PROPERTIES(SELF) friend plRTTI GetRTTI(SELF*)
158#define PL_RTTIINFO_DECL(Type, BaseType, Version) \
160 plStringView GetTypeName(Type*) \
164 plUInt32 GetTypeVersion(Type*) \
169 plRTTI GetRTTI(Type*);
172#define PL_RTTIINFO_GETRTTI_IMPL_BEGIN(Type, BaseType, AllocatorType) \
173 plRTTI GetRTTI(Type*) \
175 using OwnType = Type; \
176 using OwnBaseType = BaseType; \
177 static AllocatorType Allocator; \
178 static plBitflags<plTypeFlags> flags = plInternal::DetermineTypeFlags<Type>(); \
179 static plArrayPtr<const plAbstractProperty*> Properties; \
180 static plArrayPtr<const plAbstractFunctionProperty*> Functions; \
181 static plArrayPtr<const plPropertyAttribute*> Attributes; \
182 static plArrayPtr<plAbstractMessageHandler*> MessageHandlers; \
183 static plArrayPtr<plMessageSenderInfo> MessageSenders;
200#define PL_BEGIN_STATIC_REFLECTED_TYPE(Type, BaseType, Version, AllocatorType) \
201 PL_RTTIINFO_DECL(Type, BaseType, Version) \
202 plRTTI plInternal::plStaticRTTIWrapper<Type>::s_RTTI = GetRTTI((Type*)0); \
203 PL_RTTIINFO_GETRTTI_IMPL_BEGIN(Type, BaseType, AllocatorType)
207#define PL_END_STATIC_REFLECTED_TYPE \
209 return plRTTI(GetTypeName((OwnType*)0), plGetStaticRTTI<OwnBaseType>(), sizeof(OwnType), GetTypeVersion((OwnType*)0), \
210 plVariantTypeDeduction<OwnType>::value, flags, &Allocator, Properties, Functions, Attributes, MessageHandlers, MessageSenders, nullptr); \
215#define PL_BEGIN_PROPERTIES static const plAbstractProperty* PropertyList[] =
220#define PL_END_PROPERTIES \
222 Properties = PropertyList
225#define PL_BEGIN_FUNCTIONS static const plAbstractFunctionProperty* FunctionList[] =
230#define PL_END_FUNCTIONS \
232 Functions = FunctionList
235#define PL_BEGIN_ATTRIBUTES static const plPropertyAttribute* AttributeList[] =
240#define PL_END_ATTRIBUTES \
242 Attributes = AttributeList
249#define PL_FUNCTION_PROPERTY(Function) (new plFunctionProperty<decltype(&OwnType::Function)>(PL_PP_STRINGIFY(Function), &OwnType::Function))
259#define PL_FUNCTION_PROPERTY_EX(PropertyName, Function) (new plFunctionProperty<decltype(&Function)>(PropertyName, &Function))
262#define _PL_SCRIPT_FUNCTION_PARAM(type, name) plScriptableFunctionAttribute::ArgType::type, name
277#define PL_SCRIPT_FUNCTION_PROPERTY(Function, ...) \
278 PL_FUNCTION_PROPERTY(Function)->AddAttributes(new plScriptableFunctionAttribute(PL_EXPAND_ARGS_PAIR_COMMA(_PL_SCRIPT_FUNCTION_PARAM, ##__VA_ARGS__)))
284#define PL_CONSTRUCTOR_PROPERTY(...) (new plConstructorFunctionProperty<OwnType, ##__VA_ARGS__>())
288#define PL_GETTER_TYPE(Class, GetterFunc) decltype(std::declval<Class>().GetterFunc())
301#define PL_ACCESSOR_PROPERTY(PropertyName, Getter, Setter) \
302 (new plAccessorProperty<OwnType, PL_GETTER_TYPE(OwnType, OwnType::Getter)>(PropertyName, &OwnType::Getter, &OwnType::Setter))
305#define PL_ACCESSOR_PROPERTY_READ_ONLY(PropertyName, Getter) \
306 (new plAccessorProperty<OwnType, PL_GETTER_TYPE(OwnType, OwnType::Getter)>(PropertyName, &OwnType::Getter, nullptr))
309#define PL_ARRAY_GETTER_TYPE(Class, GetterFunc) decltype(std::declval<Class>().GetterFunc(0))
325#define PL_ARRAY_ACCESSOR_PROPERTY(PropertyName, GetCount, Getter, Setter, Insert, Remove) \
326 (new plAccessorArrayProperty<OwnType, PL_ARRAY_GETTER_TYPE(OwnType, OwnType::Getter)>( \
327 PropertyName, &OwnType::GetCount, &OwnType::Getter, &OwnType::Setter, &OwnType::Insert, &OwnType::Remove))
330#define PL_ARRAY_ACCESSOR_PROPERTY_READ_ONLY(PropertyName, GetCount, Getter) \
331 (new plAccessorArrayProperty<OwnType, PL_ARRAY_GETTER_TYPE(OwnType, OwnType::Getter)>( \
332 PropertyName, &OwnType::GetCount, &OwnType::Getter, nullptr, nullptr, nullptr))
334#define PL_SET_CONTAINER_TYPE(Class, GetterFunc) decltype(std::declval<Class>().GetterFunc())
336#define PL_SET_CONTAINER_SUB_TYPE(Class, GetterFunc) \
337 plContainerSubTypeResolver<plTypeTraits<decltype(std::declval<Class>().GetterFunc())>::NonConstReferenceType>::Type
351#define PL_SET_ACCESSOR_PROPERTY(PropertyName, GetValues, Insert, Remove) \
352 (new plAccessorSetProperty<OwnType, plFunctionParameterTypeResolver<0, decltype(&OwnType::Insert)>::ParameterType, \
353 PL_SET_CONTAINER_TYPE(OwnType, GetValues)>(PropertyName, &OwnType::GetValues, &OwnType::Insert, &OwnType::Remove))
356#define PL_SET_ACCESSOR_PROPERTY_READ_ONLY(PropertyName, GetValues) \
357 (new plAccessorSetProperty<OwnType, PL_SET_CONTAINER_SUB_TYPE(OwnType, GetValues), PL_SET_CONTAINER_TYPE(OwnType, GetValues)>( \
358 PropertyName, &OwnType::GetValues, nullptr, nullptr))
374#define PL_MAP_WRITE_ACCESSOR_PROPERTY(PropertyName, GetContainer, Insert, Remove) \
375 (new plWriteAccessorMapProperty<OwnType, plFunctionParameterTypeResolver<1, decltype(&OwnType::Insert)>::ParameterType, \
376 PL_SET_CONTAINER_TYPE(OwnType, GetContainer)>(PropertyName, &OwnType::GetContainer, &OwnType::Insert, &OwnType::Remove))
397#define PL_MAP_ACCESSOR_PROPERTY(PropertyName, GetKeyRange, GetValue, Insert, Remove) \
398 (new plAccessorMapProperty<OwnType, plFunctionParameterTypeResolver<1, decltype(&OwnType::Insert)>::ParameterType, \
399 PL_SET_CONTAINER_TYPE(OwnType, GetKeyRange)>(PropertyName, &OwnType::GetKeyRange, &OwnType::GetValue, &OwnType::Insert, &OwnType::Remove))
402#define PL_MAP_ACCESSOR_PROPERTY_READ_ONLY(PropertyName, GetKeyRange, GetValue) \
403 (new plAccessorMapProperty<OwnType, \
404 plTypeTraits<plFunctionParameterTypeResolver<1, decltype(&OwnType::GetValue)>::ParameterType>::NonConstReferenceType, \
405 PL_SET_CONTAINER_TYPE(OwnType, GetKeyRange)>(PropertyName, &OwnType::GetKeyRange, &OwnType::GetValue, nullptr, nullptr))
419#define PL_ENUM_ACCESSOR_PROPERTY(PropertyName, EnumType, Getter, Setter) \
420 (new plEnumAccessorProperty<OwnType, EnumType, PL_GETTER_TYPE(OwnType, OwnType::Getter)>(PropertyName, &OwnType::Getter, &OwnType::Setter))
423#define PL_ENUM_ACCESSOR_PROPERTY_READ_ONLY(PropertyName, EnumType, Getter) \
424 (new plEnumAccessorProperty<OwnType, EnumType, PL_GETTER_TYPE(OwnType, OwnType::Getter)>(PropertyName, &OwnType::Getter, nullptr))
427#define PL_BITFLAGS_ACCESSOR_PROPERTY(PropertyName, BitflagsType, Getter, Setter) \
428 (new plBitflagsAccessorProperty<OwnType, BitflagsType, PL_GETTER_TYPE(OwnType, OwnType::Getter)>(PropertyName, &OwnType::Getter, &OwnType::Setter))
431#define PL_BITFLAGS_ACCESSOR_PROPERTY_READ_ONLY(PropertyName, BitflagsType, Getter) \
432 (new plBitflagsAccessorProperty<OwnType, BitflagsType, PL_GETTER_TYPE(OwnType, OwnType::Getter)>(PropertyName, &OwnType::Getter, nullptr))
436#define PL_MEMBER_TYPE(Class, Member) decltype(std::declval<Class>().Member)
438#define PL_MEMBER_CONTAINER_SUB_TYPE(Class, Member) \
439 plContainerSubTypeResolver<plTypeTraits<decltype(std::declval<Class>().Member)>::NonConstReferenceType>::Type
451#define PL_MEMBER_PROPERTY(PropertyName, MemberName) \
452 (new plMemberProperty<OwnType, PL_MEMBER_TYPE(OwnType, MemberName)>(PropertyName, \
453 &plPropertyAccessor<OwnType, PL_MEMBER_TYPE(OwnType, MemberName), &OwnType::MemberName>::GetValue, \
454 &plPropertyAccessor<OwnType, PL_MEMBER_TYPE(OwnType, MemberName), &OwnType::MemberName>::SetValue, \
455 &plPropertyAccessor<OwnType, PL_MEMBER_TYPE(OwnType, MemberName), &OwnType::MemberName>::GetPropertyPointer))
458#define PL_MEMBER_PROPERTY_READ_ONLY(PropertyName, MemberName) \
459 (new plMemberProperty<OwnType, PL_MEMBER_TYPE(OwnType, MemberName)>(PropertyName, \
460 &plPropertyAccessor<OwnType, PL_MEMBER_TYPE(OwnType, MemberName), &OwnType::MemberName>::GetValue, nullptr, \
461 &plPropertyAccessor<OwnType, PL_MEMBER_TYPE(OwnType, MemberName), &OwnType::MemberName>::GetPropertyPointer))
464#define PL_ARRAY_MEMBER_PROPERTY(PropertyName, MemberName) \
465 (new plMemberArrayProperty<OwnType, PL_MEMBER_TYPE(OwnType, MemberName), PL_MEMBER_CONTAINER_SUB_TYPE(OwnType, MemberName)>(PropertyName, \
466 &plArrayPropertyAccessor<OwnType, PL_MEMBER_TYPE(OwnType, MemberName), &OwnType::MemberName>::GetConstContainer, \
467 &plArrayPropertyAccessor<OwnType, PL_MEMBER_TYPE(OwnType, MemberName), &OwnType::MemberName>::GetContainer))
470#define PL_ARRAY_MEMBER_PROPERTY_READ_ONLY(PropertyName, MemberName) \
471 (new plMemberArrayReadOnlyProperty<OwnType, PL_MEMBER_TYPE(OwnType, MemberName), PL_MEMBER_CONTAINER_SUB_TYPE(OwnType, MemberName)>( \
472 PropertyName, &plArrayPropertyAccessor<OwnType, PL_MEMBER_TYPE(OwnType, MemberName), &OwnType::MemberName>::GetConstContainer))
475#define PL_SET_MEMBER_PROPERTY(PropertyName, MemberName) \
476 (new plMemberSetProperty<OwnType, PL_MEMBER_TYPE(OwnType, MemberName), PL_MEMBER_CONTAINER_SUB_TYPE(OwnType, MemberName)>(PropertyName, \
477 &plSetPropertyAccessor<OwnType, PL_MEMBER_TYPE(OwnType, MemberName), &OwnType::MemberName>::GetConstContainer, \
478 &plSetPropertyAccessor<OwnType, PL_MEMBER_TYPE(OwnType, MemberName), &OwnType::MemberName>::GetContainer))
481#define PL_SET_MEMBER_PROPERTY_READ_ONLY(PropertyName, MemberName) \
482 (new plMemberSetProperty<OwnType, PL_MEMBER_TYPE(OwnType, MemberName), PL_MEMBER_CONTAINER_SUB_TYPE(OwnType, MemberName)>( \
483 PropertyName, &plSetPropertyAccessor<OwnType, PL_MEMBER_TYPE(OwnType, MemberName), &OwnType::MemberName>::GetConstContainer, nullptr))
486#define PL_MAP_MEMBER_PROPERTY(PropertyName, MemberName) \
487 (new plMemberMapProperty<OwnType, PL_MEMBER_TYPE(OwnType, MemberName), PL_MEMBER_CONTAINER_SUB_TYPE(OwnType, MemberName)>(PropertyName, \
488 &plMapPropertyAccessor<OwnType, PL_MEMBER_TYPE(OwnType, MemberName), &OwnType::MemberName>::GetConstContainer, \
489 &plMapPropertyAccessor<OwnType, PL_MEMBER_TYPE(OwnType, MemberName), &OwnType::MemberName>::GetContainer))
492#define PL_MAP_MEMBER_PROPERTY_READ_ONLY(PropertyName, MemberName) \
493 (new plMemberMapProperty<OwnType, PL_MEMBER_TYPE(OwnType, MemberName), PL_MEMBER_CONTAINER_SUB_TYPE(OwnType, MemberName)>( \
494 PropertyName, &plMapPropertyAccessor<OwnType, PL_MEMBER_TYPE(OwnType, MemberName), &OwnType::MemberName>::GetConstContainer, nullptr))
508#define PL_ENUM_MEMBER_PROPERTY(PropertyName, EnumType, MemberName) \
509 (new plEnumMemberProperty<OwnType, EnumType, PL_MEMBER_TYPE(OwnType, MemberName)>(PropertyName, \
510 &plPropertyAccessor<OwnType, PL_MEMBER_TYPE(OwnType, MemberName), &OwnType::MemberName>::GetValue, \
511 &plPropertyAccessor<OwnType, PL_MEMBER_TYPE(OwnType, MemberName), &OwnType::MemberName>::SetValue, \
512 &plPropertyAccessor<OwnType, PL_MEMBER_TYPE(OwnType, MemberName), &OwnType::MemberName>::GetPropertyPointer))
515#define PL_ENUM_MEMBER_PROPERTY_READ_ONLY(PropertyName, EnumType, MemberName) \
516 (new plEnumMemberProperty<OwnType, EnumType, PL_MEMBER_TYPE(OwnType, MemberName)>(PropertyName, \
517 &plPropertyAccessor<OwnType, PL_MEMBER_TYPE(OwnType, MemberName), &OwnType::MemberName>::GetValue, nullptr, \
518 &plPropertyAccessor<OwnType, PL_MEMBER_TYPE(OwnType, MemberName), &OwnType::MemberName>::GetPropertyPointer))
521#define PL_BITFLAGS_MEMBER_PROPERTY(PropertyName, BitflagsType, MemberName) \
522 (new plBitflagsMemberProperty<OwnType, BitflagsType, PL_MEMBER_TYPE(OwnType, MemberName)>(PropertyName, \
523 &plPropertyAccessor<OwnType, PL_MEMBER_TYPE(OwnType, MemberName), &OwnType::MemberName>::GetValue, \
524 &plPropertyAccessor<OwnType, PL_MEMBER_TYPE(OwnType, MemberName), &OwnType::MemberName>::SetValue, \
525 &plPropertyAccessor<OwnType, PL_MEMBER_TYPE(OwnType, MemberName), &OwnType::MemberName>::GetPropertyPointer))
528#define PL_BITFLAGS_MEMBER_PROPERTY_READ_ONLY(PropertyName, BitflagsType, MemberName) \
529 (new plBitflagsMemberProperty<OwnType, BitflagsType, PL_MEMBER_TYPE(OwnType, MemberName)>(PropertyName, \
530 &plPropertyAccessor<OwnType, PL_MEMBER_TYPE(OwnType, MemberName), &OwnType::MemberName>::GetValue, nullptr, \
531 &plPropertyAccessor<OwnType, PL_MEMBER_TYPE(OwnType, MemberName), &OwnType::MemberName>::GetPropertyPointer))
541#define PL_CONSTANT_PROPERTY(PropertyName, Value) (new plConstantProperty<decltype(Value)>(PropertyName, Value))
546#define PL_ENUM_VALUE_TO_CONSTANT_PROPERTY(name) PL_CONSTANT_PROPERTY(PL_PP_STRINGIFY(name), (Storage)name),
550#define PL_ENUM_CONSTANTS(...) PL_EXPAND_ARGS(PL_ENUM_VALUE_TO_CONSTANT_PROPERTY, ##__VA_ARGS__)
554#define PL_ENUM_CONSTANT(Value) PL_CONSTANT_PROPERTY(PL_PP_STRINGIFY(Value), (Storage)Value)
558#define PL_BITFLAGS_CONSTANTS(...) PL_EXPAND_ARGS(PL_ENUM_VALUE_TO_CONSTANT_PROPERTY, ##__VA_ARGS__)
562#define PL_BITFLAGS_CONSTANT(Value) PL_CONSTANT_PROPERTY(PL_PP_STRINGIFY(Value), (Storage)Value)
572#define PL_BEGIN_STATIC_REFLECTED_ENUM(Type, Version) \
573 PL_BEGIN_STATIC_REFLECTED_TYPE(Type, plEnumBase, Version, plRTTINoAllocator) \
575 using Storage = Type::StorageType; \
576 PL_BEGIN_PROPERTIES \
578 PL_CONSTANT_PROPERTY(PL_PP_STRINGIFY(Type::Default), (Storage)Type::Default),
580#define PL_END_STATIC_REFLECTED_ENUM \
584 flags |= plTypeFlags::IsEnum; \
585 flags.Remove(plTypeFlags::Class); \
586 PL_END_STATIC_REFLECTED_TYPE
595#define PL_BEGIN_STATIC_REFLECTED_BITFLAGS(Type, Version) \
596 PL_BEGIN_STATIC_REFLECTED_TYPE(Type, plBitflagsBase, Version, plRTTINoAllocator) \
598 using Storage = Type::StorageType; \
599 PL_BEGIN_PROPERTIES \
601 PL_CONSTANT_PROPERTY(PL_PP_STRINGIFY(Type::Default), (Storage)Type::Default),
603#define PL_END_STATIC_REFLECTED_BITFLAGS \
607 flags |= plTypeFlags::Bitflags; \
608 flags.Remove(plTypeFlags::Class); \
609 PL_END_STATIC_REFLECTED_TYPE
615#define PL_BEGIN_MESSAGEHANDLERS static plAbstractMessageHandler* HandlerList[] =
619#define PL_END_MESSAGEHANDLERS \
621 MessageHandlers = HandlerList
632#define PL_MESSAGE_HANDLER(MessageType, FunctionName) \
633 new plInternal::MessageHandler<PL_IS_CONST_MESSAGE_HANDLER(OwnType, MessageType, &OwnType::FunctionName)>::Impl<OwnType, MessageType, \
634 &OwnType::FunctionName>()
639#define PL_BEGIN_MESSAGESENDERS static plMessageSenderInfo SenderList[] =
643#define PL_END_MESSAGESENDERS \
645 MessageSenders = SenderList;
653#define PL_MESSAGE_SENDER(MemberName) \
655 #MemberName, plGetStaticRTTI<PL_MEMBER_TYPE(OwnType, MemberName)::MessageType>() \
Dummy type to pass to templates and macros that expect a base type for a class that has no base.
Definition Types.h:133
This class holds information about reflected types. Each instance represents one type that is known t...
Definition RTTI.h:30
All classes that should be dynamically reflectable, need to be derived from this base class.
Definition DynamicRTTI.h:86
plVariant is a class that can store different types of variables, which is useful in situations where...
Definition Variant.h:44
The plBitflags class allows you to work with type-safe bitflags.
Definition Bitflags.h:82
PL_ALWAYS_INLINE void Add(const plBitflags< T > &rhs)
Sets the given flag.
Definition Bitflags.h:151
[internal] Helper struct for accessing static RTTI data.
Definition StaticRTTI.h:54
Definition StaticRTTI.h:111
Type traits.
Definition TypeTraits.h:12
Definition StaticRTTI.h:33
Flags that describe a reflected type.
Definition StaticRTTI.h:16
Enum
Definition StaticRTTI.h:20
@ Minimal
Does not contain any property, function or attribute information. Used only for versioning.
Definition StaticRTTI.h:28
@ Bitflags
bitflags struct used for plBitflags.
Definition StaticRTTI.h:23
@ IsEnum
enum struct used for plEnum.
Definition StaticRTTI.h:22
@ Abstract
Type is abstract.
Definition StaticRTTI.h:26
@ StandardType
Anything that can be stored inside an plVariant except for pointers and containers.
Definition StaticRTTI.h:21
@ Class
A class or struct. The above flags are mutually exclusive.
Definition StaticRTTI.h:24
@ Phantom
De-serialized type information that cannot be created on this process.
Definition StaticRTTI.h:27
A helper struct to convert the C++ type, which is passed as the template argument,...
Definition VariantType.h:97
Enum
This enum describes the type of data that is currently stored inside the variant. Note that changes t...
Definition VariantType.h:26
@ FirstStandardType
*** Types that are flagged as 'StandardTypes' (see DetermineTypeFlags) ***
Definition VariantType.h:30