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
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
165#ifdef JPH_OBJECT_STREAM
167 void AddAttribute(const SerializableAttribute &inAttribute);
168 int GetAttributeCount() const;
169 const SerializableAttribute & GetAttribute(int inIdx) const;
170#endif // JPH_OBJECT_STREAM
171
172protected:
175 {
176 const RTTI * mRTTI;
178 };
179
180 const char * mName;
181 int mSize;
185#ifdef JPH_OBJECT_STREAM
187#endif // JPH_OBJECT_STREAM
188};
189
191// Add run time type info to types that don't have virtual functions
193
194// JPH_DECLARE_RTTI_NON_VIRTUAL
195#define JPH_DECLARE_RTTI_NON_VIRTUAL(linkage, class_name) \
196public: \
197 JPH_OVERRIDE_NEW_DELETE \
198 friend linkage RTTI * GetRTTIOfType(class_name *); \
199 friend inline const RTTI * GetRTTI([[maybe_unused]] const class_name *inObject) { return GetRTTIOfType(static_cast<class_name *>(nullptr)); }\
200 static void sCreateRTTI(RTTI &inRTTI); \
201
202// JPH_IMPLEMENT_RTTI_NON_VIRTUAL
203#define JPH_IMPLEMENT_RTTI_NON_VIRTUAL(class_name) \
204 RTTI * GetRTTIOfType(class_name *) \
205 { \
206 static RTTI rtti(#class_name, sizeof(class_name), []() -> void * { return new class_name; }, [](void *inObject) { delete (class_name *)inObject; }, &class_name::sCreateRTTI); \
207 return &rtti; \
208 } \
209 void class_name::sCreateRTTI(RTTI &inRTTI) \
210
212// Same as above, but when you cannot insert the declaration in the class
213// itself, for example for templates and third party classes
215
216// JPH_DECLARE_RTTI_OUTSIDE_CLASS
217#define JPH_DECLARE_RTTI_OUTSIDE_CLASS(linkage, class_name) \
218 linkage RTTI * GetRTTIOfType(class_name *); \
219 inline const RTTI * GetRTTI(const class_name *inObject) { return GetRTTIOfType((class_name *)nullptr); }\
220 void CreateRTTI##class_name(RTTI &inRTTI); \
221
222// JPH_IMPLEMENT_RTTI_OUTSIDE_CLASS
223#define JPH_IMPLEMENT_RTTI_OUTSIDE_CLASS(class_name) \
224 RTTI * GetRTTIOfType(class_name *) \
225 { \
226 static RTTI rtti((const char *)#class_name, sizeof(class_name), []() -> void * { return new class_name; }, [](void *inObject) { delete (class_name *)inObject; }, &CreateRTTI##class_name); \
227 return &rtti; \
228 } \
229 void CreateRTTI##class_name(RTTI &inRTTI)
230
232// Same as above, but for classes that have virtual functions
234
235#define JPH_DECLARE_RTTI_HELPER(linkage, class_name, modifier) \
236public: \
237 JPH_OVERRIDE_NEW_DELETE \
238 friend linkage RTTI * GetRTTIOfType(class_name *); \
239 friend inline const RTTI * GetRTTI(const class_name *inObject) { return inObject->GetRTTI(); } \
240 virtual const RTTI * GetRTTI() const modifier; \
241 virtual const void * CastTo(const RTTI *inRTTI) const modifier; \
242 static void sCreateRTTI(RTTI &inRTTI); \
243
244// JPH_DECLARE_RTTI_VIRTUAL - for derived classes with RTTI
245#define JPH_DECLARE_RTTI_VIRTUAL(linkage, class_name) \
246 JPH_DECLARE_RTTI_HELPER(linkage, class_name, override)
247
248// JPH_IMPLEMENT_RTTI_VIRTUAL
249#define JPH_IMPLEMENT_RTTI_VIRTUAL(class_name) \
250 RTTI * GetRTTIOfType(class_name *) \
251 { \
252 static RTTI rtti(#class_name, sizeof(class_name), []() -> void * { return new class_name; }, [](void *inObject) { delete (class_name *)inObject; }, &class_name::sCreateRTTI); \
253 return &rtti; \
254 } \
255 const RTTI * class_name::GetRTTI() const \
256 { \
257 return JPH_RTTI(class_name); \
258 } \
259 const void * class_name::CastTo(const RTTI *inRTTI) const \
260 { \
261 return JPH_RTTI(class_name)->CastTo((const void *)this, inRTTI); \
262 } \
263 void class_name::sCreateRTTI(RTTI &inRTTI) \
264
265// JPH_DECLARE_RTTI_VIRTUAL_BASE - for concrete base class that has RTTI
266#define JPH_DECLARE_RTTI_VIRTUAL_BASE(linkage, class_name) \
267 JPH_DECLARE_RTTI_HELPER(linkage, class_name, )
268
269// JPH_IMPLEMENT_RTTI_VIRTUAL_BASE
270#define JPH_IMPLEMENT_RTTI_VIRTUAL_BASE(class_name) \
271 JPH_IMPLEMENT_RTTI_VIRTUAL(class_name)
272
273// JPH_DECLARE_RTTI_ABSTRACT - for derived abstract class that have RTTI
274#define JPH_DECLARE_RTTI_ABSTRACT(linkage, class_name) \
275 JPH_DECLARE_RTTI_HELPER(linkage, class_name, override)
276
277// JPH_IMPLEMENT_RTTI_ABSTRACT
278#define JPH_IMPLEMENT_RTTI_ABSTRACT(class_name) \
279 RTTI * GetRTTIOfType(class_name *) \
280 { \
281 static RTTI rtti(#class_name, sizeof(class_name), nullptr, [](void *inObject) { delete (class_name *)inObject; }, &class_name::sCreateRTTI); \
282 return &rtti; \
283 } \
284 const RTTI * class_name::GetRTTI() const \
285 { \
286 return JPH_RTTI(class_name); \
287 } \
288 const void * class_name::CastTo(const RTTI *inRTTI) const \
289 { \
290 return JPH_RTTI(class_name)->CastTo((const void *)this, inRTTI); \
291 } \
292 void class_name::sCreateRTTI(RTTI &inRTTI) \
293
294// JPH_DECLARE_RTTI_ABSTRACT_BASE - for abstract base class that has RTTI
295#define JPH_DECLARE_RTTI_ABSTRACT_BASE(linkage, class_name) \
296 JPH_DECLARE_RTTI_HELPER(linkage, class_name, )
297
298// JPH_IMPLEMENT_RTTI_ABSTRACT_BASE
299#define JPH_IMPLEMENT_RTTI_ABSTRACT_BASE(class_name) \
300 JPH_IMPLEMENT_RTTI_ABSTRACT(class_name)
301
303// Declare an RTTI class for registering with the factory
305
306#define JPH_DECLARE_RTTI_FOR_FACTORY(linkage, class_name) \
307 linkage RTTI * GetRTTIOfType(class class_name *);
308
309#define JPH_DECLARE_RTTI_WITH_NAMESPACE_FOR_FACTORY(linkage, name_space, class_name) \
310 namespace name_space { \
311 class class_name; \
312 linkage RTTI * GetRTTIOfType(class class_name *); \
313 }
314
316// Find the RTTI of a class
318
319#define JPH_RTTI(class_name) GetRTTIOfType(static_cast<class_name *>(nullptr))
320
322// Macro to rename a class, useful for embedded classes:
323//
324// class A { class B { }; }
325//
326// Now use JPH_RENAME_CLASS(B, A::B) to avoid conflicts with other classes named B
328
329// JPH_RENAME_CLASS
330#define JPH_RENAME_CLASS(class_name, new_name) \
331 inRTTI.SetName(#new_name);
332
334// Macro to add base classes
336
338#define JPH_BASE_CLASS_OFFSET(inClass, inBaseClass) ((int(uint64((inBaseClass *)((inClass *)0x10000))))-0x10000)
339
340// JPH_ADD_BASE_CLASS
341#define JPH_ADD_BASE_CLASS(class_name, base_class_name) \
342 inRTTI.AddBaseClass(JPH_RTTI(base_class_name), JPH_BASE_CLASS_OFFSET(class_name, base_class_name));
343
345// Macros and templates to identify a class
347
349template <class Type>
350inline bool IsType(const Type *inObject, const RTTI *inRTTI)
351{
352 return inObject == nullptr || *inObject->GetRTTI() == *inRTTI;
353}
354
355template <class Type>
356inline bool IsType(const RefConst<Type> &inObject, const RTTI *inRTTI)
357{
358 return inObject == nullptr || *inObject->GetRTTI() == *inRTTI;
359}
360
361template <class Type>
362inline bool IsType(const Ref<Type> &inObject, const RTTI *inRTTI)
363{
364 return inObject == nullptr || *inObject->GetRTTI() == *inRTTI;
365}
366
368template <class Type>
369inline bool IsKindOf(const Type *inObject, const RTTI *inRTTI)
370{
371 return inObject == nullptr || inObject->GetRTTI()->IsKindOf(inRTTI);
372}
373
374template <class Type>
375inline bool IsKindOf(const RefConst<Type> &inObject, const RTTI *inRTTI)
376{
377 return inObject == nullptr || inObject->GetRTTI()->IsKindOf(inRTTI);
378}
379
380template <class Type>
381inline bool IsKindOf(const Ref<Type> &inObject, const RTTI *inRTTI)
382{
383 return inObject == nullptr || inObject->GetRTTI()->IsKindOf(inRTTI);
384}
385
387template <class DstType, class SrcType, std::enable_if_t<std::is_base_of_v<DstType, SrcType> || std::is_base_of_v<SrcType, DstType>, bool> = true>
388inline const DstType *StaticCast(const SrcType *inObject)
389{
390 return static_cast<const DstType *>(inObject);
391}
392
393template <class DstType, class SrcType, std::enable_if_t<std::is_base_of_v<DstType, SrcType> || std::is_base_of_v<SrcType, DstType>, bool> = true>
394inline DstType *StaticCast(SrcType *inObject)
395{
396 return static_cast<DstType *>(inObject);
397}
398
399template <class DstType, class SrcType, std::enable_if_t<std::is_base_of_v<DstType, SrcType> || std::is_base_of_v<SrcType, DstType>, bool> = true>
400inline const DstType *StaticCast(const RefConst<SrcType> &inObject)
401{
402 return static_cast<const DstType *>(inObject.GetPtr());
403}
404
405template <class DstType, class SrcType, std::enable_if_t<std::is_base_of_v<DstType, SrcType> || std::is_base_of_v<SrcType, DstType>, bool> = true>
406inline DstType *StaticCast(const Ref<SrcType> &inObject)
407{
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>
425inline const DstType *DynamicCast(const RefConst<SrcType> &inObject)
426{
427 return inObject != nullptr? reinterpret_cast<const DstType *>(inObject->CastTo(JPH_RTTI(DstType))) : nullptr;
428}
429
430template <class DstType, class SrcType>
431inline DstType *DynamicCast(const Ref<SrcType> &inObject)
432{
433 return inObject != nullptr? const_cast<DstType *>(reinterpret_cast<const DstType *>(inObject->CastTo(JPH_RTTI(DstType)))) : nullptr;
434}
435
#define JPH_EXPORT
Definition Core.h:236
#define JPH_NAMESPACE_END
Definition Core.h:379
std::uint32_t uint32
Definition Core.h:449
#define JPH_NAMESPACE_BEGIN
Definition Core.h:373
const DstType * StaticCast(const SrcType *inObject)
Cast inObject to DstType, asserts on failure.
Definition RTTI.h:388
bool IsType(const Type *inObject, const RTTI *inRTTI)
Check if inObject is of DstType.
Definition RTTI.h:350
bool IsKindOf(const Type *inObject, const RTTI *inRTTI)
Check if inObject is or is derived from DstType.
Definition RTTI.h:369
#define JPH_RTTI(class_name)
Definition RTTI.h:319
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:184
pCreateObjectFunction mCreate
Pointer to a function that will create a new instance of this class.
Definition RTTI.h:183
const char * GetName() const
Definition RTTI.h:138
StaticArray< SerializableAttribute, 32 > mAttributes
All attributes of this class.
Definition RTTI.h:186
void *(*)() pCreateObjectFunction
Function to create an object.
Definition RTTI.h:125
StaticArray< BaseClass, 4 > mBaseClasses
Names of base classes.
Definition RTTI.h:182
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:92
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:180
int mSize
Class size.
Definition RTTI.h:181
Definition Reference.h:163
const T * GetPtr() const
Get pointer.
Definition Reference.h:197
Definition Reference.h:107
T * GetPtr() const
Get pointer.
Definition Reference.h:135
Attributes are members of classes that need to be serialized.
Definition SerializableAttribute.h:37
Simple variable length array backed by a fixed size buffer.
Definition StaticArray.h:14
Base class information.
Definition RTTI.h:175
const RTTI * mRTTI
Definition RTTI.h:176
int mOffset
Definition RTTI.h:177