5#include <Foundation/Basics.h>
6#include <Foundation/Configuration/Plugin.h>
7#include <Foundation/Memory/Allocator.h>
8#include <Foundation/Reflection/Implementation/StaticRTTI.h>
20using plMessageId = plUInt16;
33 plRTTI(
plStringView sName,
const plRTTI* pParentType, plUInt32 uiTypeSize, plUInt32 uiTypeVersion, plUInt8 uiVariantType,
42 void VerifyCorrectness()
const;
45 static void VerifyCorrectnessForAllTypes();
62 const plUInt32 thisGeneration = m_ParentHierarchy.GetCount();
63 const plUInt32 baseGeneration = pBaseType->m_ParentHierarchy.
GetCount();
64 PL_ASSERT_DEBUG(thisGeneration > 0 && baseGeneration > 0,
"SetupParentHierarchy() has not been called");
65 return thisGeneration >= baseGeneration && m_ParentHierarchy.GetData()[thisGeneration - baseGeneration] == pBaseType;
69 template <
typename BASE>
72 return IsDerivedFrom(plGetStaticRTTI<BASE>());
86 template <
typename Type>
87 const Type* GetAttributeByType()
const;
93 PL_ALWAYS_INLINE plUInt32
GetTypeSize()
const {
return m_uiTypeSize; }
105 static const plRTTI* FindTypeByNameHash(plUInt64 uiNameHash);
106 static const plRTTI* FindTypeByNameHash32(plUInt32 uiNameHash);
110 static const plRTTI* FindTypeIf(PredicateFunc func);
123 bool DispatchMessage(
void* pInstance,
plMessage& ref_msg)
const;
127 bool DispatchMessage(
const void* pInstance,
plMessage& ref_msg)
const;
130 template <
typename MessageType>
133 return CanHandleMessage(MessageType::GetTypeMsgId());
139 PL_ASSERT_DEBUG(m_uiMsgIdOffset != plSmallInvalidIndex,
"Message handler table should have been gathered at this point.\n"
140 "If this assert is triggered for a type loaded from a dynamic plugin,\n"
141 "you may have forgotten to instantiate an plPlugin object inside your plugin DLL.");
143 const plUInt32 uiIndex =
id - m_uiMsgIdOffset;
144 return uiIndex < m_DynamicMessageHandlers.GetCount() && m_DynamicMessageHandlers.GetData()[uiIndex] !=
nullptr;
151 using StorageType = plUInt8;
156 ExcludeNonAllocatable = PL_BIT(0),
157 ExcludeAbstract = PL_BIT(1),
158 ExcludeNotConcrete = ExcludeNonAllocatable | ExcludeAbstract,
165 plUInt8 ExcludeNonAllocatable : 1;
166 plUInt8 ExcludeAbstract : 1;
175 template <
typename T>
178 ForEachDerivedType(plGetStaticRTTI<T>(), func, options);
187 void UpdateType(
const plRTTI* pParentType, plUInt32 uiTypeSize, plUInt32 uiTypeVersion, plUInt8 uiVariantType,
plBitflags<plTypeFlags> flags);
189 void UnregisterType();
191 void GatherDynamicMessageHandlers();
192 void SetupParentHierarchy();
194 const plRTTI* m_pParentType =
nullptr;
197 plUInt32 m_uiTypeSize = 0;
198 plUInt32 m_uiTypeVersion = 0;
199 plUInt64 m_uiTypeNameHash = 0;
200 plUInt32 m_uiTypeIndex = 0;
202 plUInt8 m_uiVariantType = 0;
203 plUInt16 m_uiMsgIdOffset = plSmallInvalidIndex;
205 const plRTTI* (*m_VerifyParent)();
214 PL_MAKE_SUBSYSTEM_STARTUP_FRIEND(Foundation, Reflection);
219 static void SanityCheckType(
plRTTI* pType);
222 static void PluginEventHandler(
const plPluginEvent& EventData);
241 template <
typename T>
244 return AllocateInternal(pAllocator).Cast<T>();
248 template <
typename T>
251 return CloneInternal(pObject, pAllocator).Cast<T>();
261 PL_REPORT_FAILURE(
"Cloning is not supported by this allocator.");
275 PL_REPORT_FAILURE(
"This function should never be called.");
282 PL_REPORT_FAILURE(
"This function should never be called.");
287template <
typename CLASS,
typename AllocatorWrapper = plDefaultAllocatorWrapper>
293 if (pAllocator ==
nullptr)
295 pAllocator = AllocatorWrapper::GetAllocator();
298 return PL_NEW(pAllocator, CLASS);
304 if (pAllocator ==
nullptr)
306 pAllocator = AllocatorWrapper::GetAllocator();
309 return CloneImpl(pObject, pAllocator,
plTraitInt<std::is_copy_constructible<CLASS>::value>());
315 if (pAllocator ==
nullptr)
317 pAllocator = AllocatorWrapper::GetAllocator();
320 CLASS* pPointer =
static_cast<CLASS*
>(pObject);
321 PL_DELETE(pAllocator, pPointer);
327 PL_REPORT_FAILURE(
"Clone failed since the type is not copy constructible");
333 return PL_NEW(pAllocator, CLASS, *
static_cast<const CLASS*
>(pObject));
The base class for a property that represents a function.
Definition AbstractProperty.h:535
The base class for all message handlers that a type provides.
Definition MessageHandler.h:12
This is the base interface for all properties in the reflection system. It provides enough informatio...
Definition AbstractProperty.h:150
Base class for all memory allocators.
Definition Allocator.h:23
This class encapsulates an array and it's size. It is recommended to use this class instead of plain ...
Definition ArrayPtr.h:37
Definition DynamicArray.h:81
Base class for all message types. Each message type has it's own id which is used to dispatch message...
Definition Message.h:22
Base class of all attributes can be used to decorate a RTTI property.
Definition PropertyAttributes.h:11
This class holds information about reflected types. Each instance represents one type that is known t...
Definition RTTI.h:30
PL_ALWAYS_INLINE const plRTTI * GetParentType() const
Returns the type that is the base class of this type. May be nullptr if this type has no base class.
Definition RTTI.h:54
PL_ALWAYS_INLINE bool IsDerivedFrom() const
Returns true if this type is derived from or identical to the given type.
Definition RTTI.h:70
PL_ALWAYS_INLINE const plBitflags< plTypeFlags > & GetTypeFlags() const
Returns the type flags.
Definition RTTI.h:99
PL_ALWAYS_INLINE bool CanHandleMessage() const
Returns whether this type can handle the given message type.
Definition RTTI.h:131
PL_ALWAYS_INLINE plStringView GetPluginName() const
Returns the name of the plugin which this type is declared in.
Definition RTTI.h:116
PL_ALWAYS_INLINE plUInt32 GetTypeVersion() const
Returns the version number of this type.
Definition RTTI.h:96
PL_ALWAYS_INLINE plUInt32 GetTypeSize() const
Returns the size (in bytes) of an instance of this type.
Definition RTTI.h:93
PL_ALWAYS_INLINE plRTTIAllocator * GetAllocator() const
Returns the object through which instances of this type can be allocated.
Definition RTTI.h:76
PL_ALWAYS_INLINE plStringView GetTypeName() const
Returns the name of this type.
Definition RTTI.h:48
PL_ALWAYS_INLINE plArrayPtr< const plAbstractProperty *const > GetProperties() const
Returns the array of properties that this type has. Does NOT include properties from base classes.
Definition RTTI.h:79
PL_ALWAYS_INLINE plUInt64 GetTypeNameHash() const
Returns the hash of the name of this type.
Definition RTTI.h:51
bool CanHandleMessage(plMessageId id) const
Returns whether this type can handle the message type with the given id.
Definition RTTI.h:137
PL_ALWAYS_INLINE plVariantType::Enum GetVariantType() const
Returns the corresponding variant type for this type or Invalid if there is none.
Definition RTTI.h:57
PL_ALWAYS_INLINE const plArrayPtr< plAbstractMessageHandler * > & GetMessageHandlers() const
Returns the array of message handlers that this type has.
Definition RTTI.h:119
PL_ALWAYS_INLINE bool IsDerivedFrom(const plRTTI *pBaseType) const
Returns true if this type is derived from the given type (or of the same type).
Definition RTTI.h:60
plUInt32 GetCount() const
Returns the number of active elements in the array.
Definition SmallArray_inl.h:210
Definition SmallArray.h:219
plStringView represent a read-only sub-string of a larger string, as it can store a dedicated string ...
Definition StringView.h:34
The plBitflags class allows you to work with type-safe bitflags.
Definition Bitflags.h:82
A generic delegate class which supports static functions and member functions.
Definition Delegate.h:76
Definition Allocator_inl.h:18
Definition MessageHandler.h:42
The data that is broadcast whenever a plugin is (un-) loaded.
Definition Plugin.h:11
Enum
Definition RTTI.h:154
The interface for an allocator that creates instances of reflected types.
Definition RTTI.h:234
virtual void Deallocate(void *pObject, plAllocator *pAllocator=nullptr)=0
Deallocates the given instance.
plInternal::NewInstance< T > Allocate(plAllocator *pAllocator=nullptr)
Allocates one instance.
Definition RTTI.h:242
virtual bool CanAllocate() const
Returns whether the type that is represented by this allocator, can be dynamically allocated at runti...
Definition RTTI.h:238
plInternal::NewInstance< T > Clone(const void *pObject, plAllocator *pAllocator=nullptr)
Clones the given instance.
Definition RTTI.h:249
Default implementation of plRTTIAllocator that allocates instances via the given allocator.
Definition RTTI.h:289
virtual plInternal::NewInstance< void > CloneInternal(const void *pObject, plAllocator *pAllocator) override
Clones the given instance with the given allocator.
Definition RTTI.h:302
virtual plInternal::NewInstance< void > AllocateInternal(plAllocator *pAllocator) override
Returns a new instance that was allocated with the given allocator.
Definition RTTI.h:291
virtual void Deallocate(void *pObject, plAllocator *pAllocator) override
Deletes the given instance with the given allocator.
Definition RTTI.h:313
Dummy Allocator for types that should not be allocatable through the reflection system.
Definition RTTI.h:268
virtual plInternal::NewInstance< void > AllocateInternal(plAllocator *pAllocator) override
Will trigger an assert.
Definition RTTI.h:273
virtual void Deallocate(void *pObject, plAllocator *pAllocator) override
Will trigger an assert.
Definition RTTI.h:280
virtual bool CanAllocate() const override
Returns false, because this type of allocator is used for classes that shall not be allocated dynamic...
Definition RTTI.h:270
Type traits.
Definition TypeTraits.h:12
Enum
This enum describes the type of data that is currently stored inside the variant. Note that changes t...
Definition VariantType.h:26