Jolt Physics
A multi core friendly Game Physics Engine
Loading...
Searching...
No Matches
RTTI.h
Go to the documentation of this file.
1// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
2// SPDX-FileCopyrightText: 2021 Jorrit Rouwe
3// SPDX-License-Identifier: MIT
4
5#pragma once
6
10
12
14// RTTI
16
121class RTTI
122{
123public:
125 using pCreateObjectFunction = void *(*)();
126
128 using pDestructObjectFunction = void (*)(void *inObject);
129
131 using pCreateRTTIFunction = void (*)(RTTI &inRTTI);
132
134 RTTI(const char *inName, int inSize, pCreateObjectFunction inCreateObject, pDestructObjectFunction inDestructObject);
135 RTTI(const char *inName, int inSize, pCreateObjectFunction inCreateObject, pDestructObjectFunction inDestructObject, pCreateRTTIFunction inCreateRTTI);
136
137 // Properties
138 inline const char * GetName() const { return mName; }
139 void SetName(const char *inName) { mName = inName; }
140 inline int GetSize() const { return mSize; }
141 bool IsAbstract() const { return mCreate == nullptr || mDestruct == nullptr; }
142 int GetBaseClassCount() const;
143 const RTTI * GetBaseClass(int inIdx) const;
144 uint32 GetHash() const;
145
147 void * CreateObject() const;
148
150 void DestructObject(void *inObject) const;
151
153 void AddBaseClass(const RTTI *inRTTI, int inOffset);
154
156 bool operator == (const RTTI &inRHS) const;
157 bool operator != (const RTTI &inRHS) const { return !(*this == inRHS); }
158
160 bool IsKindOf(const RTTI *inRTTI) const;
161
163 const void * CastTo(const void *inObject, const RTTI *inRTTI) const;
164
166 void AddAttribute(const SerializableAttribute &inAttribute);
167 int GetAttributeCount() const;
168 const SerializableAttribute & GetAttribute(int inIdx) const;
169
170protected:
173 {
174 const RTTI * mRTTI;
176 };
177
178 const char * mName;
179 int mSize;
184};
185
187// Add run time type info to types that don't have virtual functions
189
190// JPH_DECLARE_RTTI_NON_VIRTUAL
191#define JPH_DECLARE_RTTI_NON_VIRTUAL(class_name) \
192public: \
193 JPH_OVERRIDE_NEW_DELETE \
194 friend RTTI * GetRTTIOfType(class_name *); \
195 friend inline const RTTI * GetRTTI(const class_name *inObject) { return GetRTTIOfType((class_name *)nullptr); }\
196 static void sCreateRTTI(RTTI &inRTTI); \
197
198// JPH_IMPLEMENT_RTTI_NON_VIRTUAL
199#define JPH_IMPLEMENT_RTTI_NON_VIRTUAL(class_name) \
200 RTTI * GetRTTIOfType(class_name *) \
201 { \
202 static RTTI rtti(#class_name, sizeof(class_name), []() -> void * { return new class_name; }, [](void *inObject) { delete (class_name *)inObject; }, &class_name::sCreateRTTI); \
203 return &rtti; \
204 } \
205 void class_name::sCreateRTTI(RTTI &inRTTI) \
206
208// Same as above, but when you cannot insert the declaration in the class
209// itself, for example for templates and third party classes
211
212// JPH_DECLARE_RTTI_OUTSIDE_CLASS
213#define JPH_DECLARE_RTTI_OUTSIDE_CLASS(class_name) \
214 RTTI * GetRTTIOfType(class_name *); \
215 inline const RTTI * GetRTTI(const class_name *inObject) { return GetRTTIOfType((class_name *)nullptr); }\
216 void CreateRTTI##class_name(RTTI &inRTTI); \
217
218// JPH_IMPLEMENT_RTTI_OUTSIDE_CLASS
219#define JPH_IMPLEMENT_RTTI_OUTSIDE_CLASS(class_name) \
220 RTTI * GetRTTIOfType(class_name *) \
221 { \
222 static RTTI rtti((const char *)#class_name, sizeof(class_name), []() -> void * { return new class_name; }, [](void *inObject) { delete (class_name *)inObject; }, &CreateRTTI##class_name); \
223 return &rtti; \
224 } \
225 void CreateRTTI##class_name(RTTI &inRTTI)
226
228// Same as above, but for classes that have virtual functions
230
231#define JPH_DECLARE_RTTI_HELPER(class_name, modifier) \
232public: \
233 JPH_OVERRIDE_NEW_DELETE \
234 friend RTTI * GetRTTIOfType(class_name *); \
235 friend inline const RTTI * GetRTTI(const class_name *inObject) { return inObject->GetRTTI(); } \
236 virtual const RTTI * GetRTTI() const modifier; \
237 virtual const void * CastTo(const RTTI *inRTTI) const modifier; \
238 static void sCreateRTTI(RTTI &inRTTI); \
239
240// JPH_DECLARE_RTTI_VIRTUAL - for derived classes with RTTI
241#define JPH_DECLARE_RTTI_VIRTUAL(class_name) \
242 JPH_DECLARE_RTTI_HELPER(class_name, override)
243
244// JPH_IMPLEMENT_RTTI_VIRTUAL
245#define JPH_IMPLEMENT_RTTI_VIRTUAL(class_name) \
246 RTTI * GetRTTIOfType(class_name *) \
247 { \
248 static RTTI rtti(#class_name, sizeof(class_name), []() -> void * { return new class_name; }, [](void *inObject) { delete (class_name *)inObject; }, &class_name::sCreateRTTI); \
249 return &rtti; \
250 } \
251 const RTTI * class_name::GetRTTI() const \
252 { \
253 return JPH_RTTI(class_name); \
254 } \
255 const void * class_name::CastTo(const RTTI *inRTTI) const \
256 { \
257 return JPH_RTTI(class_name)->CastTo((const void *)this, inRTTI); \
258 } \
259 void class_name::sCreateRTTI(RTTI &inRTTI) \
260
261// JPH_DECLARE_RTTI_VIRTUAL_BASE - for concrete base class that has RTTI
262#define JPH_DECLARE_RTTI_VIRTUAL_BASE(class_name) \
263 JPH_DECLARE_RTTI_HELPER(class_name, )
264
265// JPH_IMPLEMENT_RTTI_VIRTUAL_BASE
266#define JPH_IMPLEMENT_RTTI_VIRTUAL_BASE(class_name) \
267 JPH_IMPLEMENT_RTTI_VIRTUAL(class_name)
268
269// JPH_DECLARE_RTTI_ABSTRACT - for derived abstract class that have RTTI
270#define JPH_DECLARE_RTTI_ABSTRACT(class_name) \
271 JPH_DECLARE_RTTI_HELPER(class_name, override)
272
273// JPH_IMPLEMENT_RTTI_ABSTRACT
274#define JPH_IMPLEMENT_RTTI_ABSTRACT(class_name) \
275 RTTI * GetRTTIOfType(class_name *) \
276 { \
277 static RTTI rtti(#class_name, sizeof(class_name), nullptr, [](void *inObject) { delete (class_name *)inObject; }, &class_name::sCreateRTTI); \
278 return &rtti; \
279 } \
280 const RTTI * class_name::GetRTTI() const \
281 { \
282 return JPH_RTTI(class_name); \
283 } \
284 const void * class_name::CastTo(const RTTI *inRTTI) const \
285 { \
286 return JPH_RTTI(class_name)->CastTo((const void *)this, inRTTI); \
287 } \
288 void class_name::sCreateRTTI(RTTI &inRTTI) \
289
290// JPH_DECLARE_RTTI_ABSTRACT_BASE - for abstract base class that has RTTI
291#define JPH_DECLARE_RTTI_ABSTRACT_BASE(class_name) \
292 JPH_DECLARE_RTTI_HELPER(class_name, )
293
294// JPH_IMPLEMENT_RTTI_ABSTRACT_BASE
295#define JPH_IMPLEMENT_RTTI_ABSTRACT_BASE(class_name) \
296 JPH_IMPLEMENT_RTTI_ABSTRACT(class_name)
297
299// Declare an RTTI class for registering with the factory
301
302#define JPH_DECLARE_RTTI_FOR_FACTORY(class_name) \
303 RTTI * GetRTTIOfType(class class_name *);
304
305#define JPH_DECLARE_RTTI_WITH_NAMESPACE_FOR_FACTORY(name_space, class_name) \
306 namespace name_space { \
307 class class_name; \
308 RTTI * GetRTTIOfType(class class_name *); \
309 }
310
312// Find the RTTI of a class
314
315#define JPH_RTTI(class_name) GetRTTIOfType((class_name *)nullptr)
316
318// Macro to rename a class, useful for embedded classes:
319//
320// class A { class B { }; }
321//
322// Now use JPH_RENAME_CLASS(B, A::B) to avoid conflicts with other classes named B
324
325// JPH_RENAME_CLASS
326#define JPH_RENAME_CLASS(class_name, new_name) \
327 inRTTI.SetName(#new_name);
328
330// Macro to add base classes
332
334#define JPH_BASE_CLASS_OFFSET(inClass, inBaseClass) ((int(uint64((inBaseClass *)((inClass *)0x10000))))-0x10000)
335
336// JPH_ADD_BASE_CLASS
337#define JPH_ADD_BASE_CLASS(class_name, base_class_name) \
338 inRTTI.AddBaseClass(JPH_RTTI(base_class_name), JPH_BASE_CLASS_OFFSET(class_name, base_class_name));
339
341// Macros and templates to identify a class
343
345template <class Type>
346inline bool IsType(const Type *inObject, const RTTI *inRTTI)
347{
348 return inObject == nullptr || *inObject->GetRTTI() == *inRTTI;
349}
350
351template <class Type>
352inline bool IsType(const RefConst<Type> &inObject, const RTTI *inRTTI)
353{
354 return inObject == nullptr || *inObject->GetRTTI() == *inRTTI;
355}
356
357template <class Type>
358inline bool IsType(const Ref<Type> &inObject, const RTTI *inRTTI)
359{
360 return inObject == nullptr || *inObject->GetRTTI() == *inRTTI;
361}
362
364template <class Type>
365inline bool IsKindOf(const Type *inObject, const RTTI *inRTTI)
366{
367 return inObject == nullptr || inObject->GetRTTI()->IsKindOf(inRTTI);
368}
369
370template <class Type>
371inline bool IsKindOf(const RefConst<Type> &inObject, const RTTI *inRTTI)
372{
373 return inObject == nullptr || inObject->GetRTTI()->IsKindOf(inRTTI);
374}
375
376template <class Type>
377inline bool IsKindOf(const Ref<Type> &inObject, const RTTI *inRTTI)
378{
379 return inObject == nullptr || inObject->GetRTTI()->IsKindOf(inRTTI);
380}
381
383template <class DstType, class SrcType>
384inline const DstType *StaticCast(const SrcType *inObject)
385{
386 JPH_ASSERT(IsKindOf(inObject, JPH_RTTI(DstType)), "Invalid cast");
387 return static_cast<const DstType *>(inObject);
388}
389
390template <class DstType, class SrcType>
391inline DstType *StaticCast(SrcType *inObject)
392{
393 JPH_ASSERT(IsKindOf(inObject, JPH_RTTI(DstType)), "Invalid cast");
394 return static_cast<DstType *>(inObject);
395}
396
397template <class DstType, class SrcType>
399{
400 JPH_ASSERT(IsKindOf(inObject, JPH_RTTI(DstType)), "Invalid cast");
401 return static_cast<const DstType *>(inObject.GetPtr());
402}
403
404template <class DstType, class SrcType>
406{
407 JPH_ASSERT(IsKindOf(inObject, JPH_RTTI(DstType)), "Invalid cast");
408 return static_cast<DstType *>(inObject.GetPtr());
409}
410
412template <class DstType, class SrcType>
413inline const DstType *DynamicCast(const SrcType *inObject)
414{
415 return inObject != nullptr? reinterpret_cast<const DstType *>(inObject->CastTo(JPH_RTTI(DstType))) : nullptr;
416}
417
418template <class DstType, class SrcType>
419inline DstType *DynamicCast(SrcType *inObject)
420{
421 return inObject != nullptr? const_cast<DstType *>(reinterpret_cast<const DstType *>(inObject->CastTo(JPH_RTTI(DstType)))) : nullptr;
422}
423
424template <class DstType, class SrcType>
426{
427 return inObject != nullptr? reinterpret_cast<const DstType *>(inObject->CastTo(JPH_RTTI(DstType))) : nullptr;
428}
429
430template <class DstType, class SrcType>
432{
433 return inObject != nullptr? const_cast<DstType *>(reinterpret_cast<const DstType *>(inObject->CastTo(JPH_RTTI(DstType)))) : nullptr;
434}
435
uint32_t uint32
Definition: Core.h:312
#define JPH_NAMESPACE_END
Definition: Core.h:240
#define JPH_NAMESPACE_BEGIN
Definition: Core.h:234
#define JPH_ASSERT(...)
Definition: IssueReporting.h:33
const DstType * StaticCast(const SrcType *inObject)
Cast inObject to DstType, asserts on failure.
Definition: RTTI.h:384
bool IsType(const Type *inObject, const RTTI *inRTTI)
Check if inObject is of DstType.
Definition: RTTI.h:346
bool IsKindOf(const Type *inObject, const RTTI *inRTTI)
Check if inObject is or is derived from DstType.
Definition: RTTI.h:365
#define JPH_RTTI(class_name)
Definition: RTTI.h:315
const DstType * DynamicCast(const SrcType *inObject)
Cast inObject to DstType, returns nullptr on failure.
Definition: RTTI.h:413
Definition: RTTI.h:122
pDestructObjectFunction mDestruct
Pointer to a function that will destruct an object of this class.
Definition: RTTI.h:182
pCreateObjectFunction mCreate
Pointer to a function that will create a new instance of this class.
Definition: RTTI.h:181
const char * GetName() const
Definition: RTTI.h:138
int GetAttributeCount() const
Definition: RTTI.cpp:133
bool operator!=(const RTTI &inRHS) const
Definition: RTTI.h:157
StaticArray< SerializableAttribute, 32 > mAttributes
All attributes of this class.
Definition: RTTI.h:183
void DestructObject(void *inObject) const
Destruct object of this type (does nothing if the object is abstract)
Definition: RTTI.cpp:58
void *(*)() pCreateObjectFunction
Function to create an object.
Definition: RTTI.h:125
const RTTI * GetBaseClass(int inIdx) const
Definition: RTTI.cpp:41
void AddAttribute(const SerializableAttribute &inAttribute)
Attribute access.
Definition: RTTI.cpp:128
StaticArray< BaseClass, 4 > mBaseClasses
Names of base classes.
Definition: RTTI.h:180
const void * CastTo(const void *inObject, const RTTI *inRTTI) const
Cast inObject of this type to object of type inRTTI, returns nullptr if the cast is unsuccessful.
Definition: RTTI.cpp:104
int GetSize() const
Definition: RTTI.h:140
bool IsAbstract() const
Definition: RTTI.h:141
bool IsKindOf(const RTTI *inRTTI) const
Test if this class is derived from class of type inRTTI.
Definition: RTTI.cpp:90
void * CreateObject() const
Create an object of this type (returns nullptr if the object is abstract)
Definition: RTTI.cpp:53
int GetBaseClassCount() const
Definition: RTTI.cpp:36
void(*)(RTTI &inRTTI) pCreateRTTIFunction
Function to initialize the runtime type info structure.
Definition: RTTI.h:131
void(*)(void *inObject) pDestructObjectFunction
Function to destroy an object.
Definition: RTTI.h:128
void SetName(const char *inName)
Definition: RTTI.h:139
const char * mName
Class name.
Definition: RTTI.h:178
uint32 GetHash() const
Definition: RTTI.cpp:46
bool operator==(const RTTI &inRHS) const
Equality operators.
Definition: RTTI.cpp:78
int mSize
Class size.
Definition: RTTI.h:179
void AddBaseClass(const RTTI *inRTTI, int inOffset)
Add base class.
Definition: RTTI.cpp:63
const SerializableAttribute & GetAttribute(int inIdx) const
Definition: RTTI.cpp:138
Definition: Reference.h:154
const T * GetPtr() const
Get pointer.
Definition: Reference.h:188
Definition: Reference.h:101
T * GetPtr() const
Get pointer.
Definition: Reference.h:131
Attributes are members of classes that need to be serialized.
Definition: SerializableAttribute.h:35
Simple variable length array backed by a fixed size buffer.
Definition: StaticArray.h:12
Base class information.
Definition: RTTI.h:173
const RTTI * mRTTI
Definition: RTTI.h:174
int mOffset
Definition: RTTI.h:175