NAP
typeinfo.h
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this
3  * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4 
5 #pragma once
6 
7 #include <rttr/type>
8 #include <rttr/registration>
9 #include <utility/dllexport.h>
10 #include <string.h>
11 #include <utility/module.h>
12 
134 namespace nap
135 {
136  namespace rtti
137  {
141  using TypeInfo = rttr::type;
142  using Enum = rttr::enumeration;
143  using Property = rttr::property;
144  using Variant = rttr::variant;
145  using Instance = rttr::instance;
146  using VariantArray = rttr::variant_array_view;
147  using VariantMap = rttr::variant_associative_view;
148 
152  namespace method
153  {
154  constexpr const char* description = "description";
155  constexpr const char* moduleDescription = "moduleDescription";
156  constexpr const char* assign = "assign";
157  constexpr const char* toObject = "toObject";
158  constexpr const char* toString = "toString";
159  constexpr const char* translateTargetID = "translateTargetID";
160  }
161 
165  enum class EPropertyMetaData : uint8_t
166  {
167  Default = 0,
168  Required = 1,
169  FileLink = 2,
170  Embedded = 4,
171  ReadOnly = 8
172  };
173 
177  enum class EPropertyFileType : uint8_t
178  {
179  Any = 0,
180  Image = 1,
181  FragShader = 2,
182  VertShader = 3,
183  ComputeShader = 4,
184  Mesh = 6,
185  Video = 7,
186  ImageSequence = 8,
187  Audio = 9,
188  Font = 10
189  };
190 
192  {
193  return static_cast<EPropertyMetaData>(static_cast<uint8_t>(a) & static_cast<uint8_t>(b));
194  }
195 
197  {
198  return static_cast<EPropertyMetaData>(static_cast<uint8_t>(a) | static_cast<uint8_t>(b));
199  }
200 
204  inline bool isPrimitive(const rtti::TypeInfo& type)
205  {
206  return type.is_arithmetic() || type.is_enumeration() || type == rtti::TypeInfo::get<std::string>();
207  }
208 
212  inline bool hasFlag(const rtti::Property& property, EPropertyMetaData flags)
213  {
214  const rtti::Variant& meta_data = property.get_metadata("flags");
215  if (!meta_data.is_valid())
216  return false;
217 
218  uint8_t current_flags = meta_data.convert<uint8_t>();
219  return (current_flags & (uint8_t)flags) != 0;
220  }
221 
226  inline bool isFileType(const rtti::Property &property, EPropertyFileType filetype)
227  {
228  const rtti::Variant& meta_data = property.get_metadata("filetype");
229  return meta_data.is_valid() ?
230  meta_data.convert<uint8_t>() == (uint8_t)filetype : false;
231  }
232 
237  enum class ETypeCheck : uint8_t
238  {
239  EXACT_MATCH,
241  };
242 
246  inline bool isTypeMatch(const rtti::TypeInfo& typeA, const rtti::TypeInfo& typeB, ETypeCheck typeCheck)
247  {
248  return typeCheck == ETypeCheck::EXACT_MATCH ? typeA == typeB : typeA.is_derived_from(typeB);
249  }
250 
258  inline rttr::method findMethodRecursive(const rtti::TypeInfo& type, const std::string& methodName)
259  {
260  for (const rtti::TypeInfo& base : type.get_base_classes())
261  {
262  auto result = base.get_method(methodName);
263  if (result.is_valid())
264  return result;
265  }
266  return type.get_method(methodName);
267  }
268  }
269 }
270 
271 
273 // RTTI Macros
275 
279 #define RTTI_OF(Type) nap::rtti::TypeInfo::get<Type>()
280 
281 
283  // RTTI_ENABLE
285 
291 #define RTTI_ENABLE(...) \
292  RTTR_ENABLE(__VA_ARGS__) \
293  RTTR_REGISTRATION_FRIEND
294 
295 
297 // RTTI_BEGIN_CLASS_NO_DEFAULT_CONSTRUCTOR
299 
300 #define CONCAT_UNIQUE_NAMESPACE(x, y) namespace x##y
301 #define UNIQUE_REGISTRATION_NAMESPACE(id) CONCAT_UNIQUE_NAMESPACE(__rtti_registration_, id)
302 
310 #define RTTI_BEGIN_CLASS_NO_DEFAULT_CONSTRUCTOR_1(Type) \
311 UNIQUE_REGISTRATION_NAMESPACE(__COUNTER__) \
312 { \
313  static nap::ModuleDescriptor* getModuleDescriptor() { return NAP_MODULE_DESCIPTOR_HANDLE; } \
314  RTTR_REGISTRATION \
315  { \
316  using namespace rttr; \
317  std::string rtti_class_type_name = #Type; \
318  registration::class_<Type> rtti_class_type(#Type); \
319  rtti_class_type.method(nap::rtti::method::moduleDescription, &getModuleDescriptor);
320 
321 
329 #define RTTI_BEGIN_CLASS_NO_DEFAULT_CONSTRUCTOR_2(Type, Description) \
330  UNIQUE_REGISTRATION_NAMESPACE(__COUNTER__) \
331  { \
332  static const char* getTypeDescription() { return Description; } \
333  static nap::ModuleDescriptor* getModuleDescriptor() { return NAP_MODULE_DESCIPTOR_HANDLE; } \
334  RTTR_REGISTRATION \
335  { \
336  using namespace rttr; \
337  std::string rtti_class_type_name = #Type; \
338  registration::class_<Type> rtti_class_type(#Type); \
339  rtti_class_type.method(nap::rtti::method::description, &getTypeDescription); \
340  rtti_class_type.method(nap::rtti::method::moduleDescription, &getModuleDescriptor);
341 
342 // Selector
343 #define GET_BEGIN_CLASS_NO_DEFAULT_CONSTRUCTOR_MACRO(_1,_2,NAME,...) NAME
344 
352 #define RTTI_BEGIN_CLASS_NO_DEFAULT_CONSTRUCTOR(...) GET_BEGIN_CLASS_NO_DEFAULT_CONSTRUCTOR_MACRO(__VA_ARGS__, RTTI_BEGIN_CLASS_NO_DEFAULT_CONSTRUCTOR_2, RTTI_BEGIN_CLASS_NO_DEFAULT_CONSTRUCTOR_1)(__VA_ARGS__)
353 
354 
356 // RTTI_PROPERTY
358 
366 #define RTTI_PROPERTY_3(Name, Member, Flags) \
367  rtti_class_type.property(Name, Member)( metadata("flags", (uint8_t)(Flags)));
368 
377 #define RTTI_PROPERTY_4(Name, Member, Flags, Description) \
378  rtti_class_type.property(Name, Member)( \
379  metadata("flags", (uint8_t)(Flags)), \
380  metadata("description", (const char*)(Description)));
381 
382 #define GET_PROPERTY_MACRO(_1,_2,_3,_4,NAME,...) NAME
383 
393 #define RTTI_PROPERTY(...) GET_PROPERTY_MACRO(__VA_ARGS__, RTTI_PROPERTY_4, RTTI_PROPERTY_3)(__VA_ARGS__)
394 
395 
397 // RTTI_PROPERTY_FILELINK
399 
408 #define RTTI_PROPERTY_FILELINK_4(Name, Member, Flags, FileType) \
409  rtti_class_type.property(Name, Member)( \
410  metadata("flags", (uint8_t)(nap::rtti::EPropertyMetaData::FileLink | Flags)), \
411  metadata("filetype", (uint8_t)(FileType)));
412 
422 #define RTTI_PROPERTY_FILELINK_5(Name, Member, Flags, FileType, Description) \
423  rtti_class_type.property(Name, Member)( \
424  metadata("flags", (uint8_t)(nap::rtti::EPropertyMetaData::FileLink | Flags)), \
425  metadata("filetype", (uint8_t)(FileType)), \
426  metadata("description", (const char*)(Description)));
427 
428 #define GET_PROPERTY_FILELINK_MACRO(_1,_2,_3,_4,_5,NAME,...) NAME
429 
439 #define RTTI_PROPERTY_FILELINK(...) GET_PROPERTY_FILELINK_MACRO(__VA_ARGS__, RTTI_PROPERTY_FILELINK_5, RTTI_PROPERTY_FILELINK_4)(__VA_ARGS__)
440 
441 
443 // RTTI_FUNCTION
445 
452 #define RTTI_FUNCTION(Name, Member) \
453  rtti_class_type.method(Name, Member);
454 
460 #define RTTI_CUSTOM_REGISTRATION_FUNCTION(Func)
461 
462 
464 // RTTI_CONSTRUCTOR
466 
467 #define RTTI_CONSTRUCTOR(...) \
468  rtti_class_type.constructor<__VA_ARGS__>()(policy::ctor::as_raw_ptr);
469 
470 
472  // RTTI_VALUE_CONSTRUCTOR
474 
483 #define RTTI_VALUE_CONSTRUCTOR(...) \
484  rtti_class_type.constructor<__VA_ARGS__>()(policy::ctor::as_object);
485 
486 
488 // RTTI_END_CLASS
490 
495 #define RTTI_END_CLASS \
496  } \
497  }
498 
499 
501 // RTTI_BEGIN_STRUCT_NO_DEFAULT_CONSTRUCTOR
503 
511 #define RTTI_BEGIN_STRUCT_NO_DEFAULT_CONSTRUCTOR_1(Type) \
512  RTTI_BEGIN_CLASS_NO_DEFAULT_CONSTRUCTOR(Type)
513 
522 #define RTTI_BEGIN_STRUCT_NO_DEFAULT_CONSTRUCTOR_2(Type, Description) \
523  RTTI_BEGIN_CLASS_NO_DEFAULT_CONSTRUCTOR(Type, Description)
524 
525 #define GET_RTTI_BEGIN_STRUCT_NO_DEFAULT_CONSTRUCTOR_MACRO(_1,_2,NAME,...) NAME
526 
535 #define RTTI_BEGIN_STRUCT_NO_DEFAULT_CONSTRUCTOR(...) GET_RTTI_BEGIN_STRUCT_NO_DEFAULT_CONSTRUCTOR_MACRO(__VA_ARGS__, RTTI_BEGIN_STRUCT_NO_DEFAULT_CONSTRUCTOR_2, RTTI_BEGIN_STRUCT_NO_DEFAULT_CONSTRUCTOR_1)(__VA_ARGS__)
536 
537 
539  // RTTI_END_STRUCT
541 
547 #define RTTI_END_STRUCT \
548  RTTI_END_CLASS
549 
550 
552  // RTTI_BEGIN_CLASS
554 
561 #define RTTI_BEGIN_CLASS_1(Type) \
562  RTTI_BEGIN_CLASS_NO_DEFAULT_CONSTRUCTOR(Type) \
563  RTTI_CONSTRUCTOR()
564 
572 #define RTTI_BEGIN_CLASS_2(Type, Description) \
573  RTTI_BEGIN_CLASS_NO_DEFAULT_CONSTRUCTOR(Type, Description) \
574  RTTI_CONSTRUCTOR()
575 
576 #define GET_RTTI_BEGIN_CLASS_MACRO(_1,_2,NAME,...) NAME
577 
585 #define RTTI_BEGIN_CLASS(...) GET_RTTI_BEGIN_CLASS_MACRO(__VA_ARGS__, RTTI_BEGIN_CLASS_2, RTTI_BEGIN_CLASS_1)(__VA_ARGS__)
586 
587 
589 // RTTI_BEGIN_STRUCT
591 
599 #define RTTI_BEGIN_STRUCT_1(Type) \
600  RTTI_BEGIN_STRUCT_NO_DEFAULT_CONSTRUCTOR(Type) \
601  RTTI_VALUE_CONSTRUCTOR()
602 
611 #define RTTI_BEGIN_STRUCT_2(Type, Description) \
612  RTTI_BEGIN_STRUCT_NO_DEFAULT_CONSTRUCTOR(Type, Description) \
613  RTTI_VALUE_CONSTRUCTOR()
614 
615 #define GET_RTTI_BEGIN_STRUCT_MACRO(_1,_2,NAME,...) NAME
616 
624 #define RTTI_BEGIN_STRUCT(...) GET_RTTI_BEGIN_STRUCT_MACRO(__VA_ARGS__, RTTI_BEGIN_STRUCT_2, RTTI_BEGIN_STRUCT_1)(__VA_ARGS__)
625 
626 
628  // RTTI_BEGIN_ENUM
630 
635 #define RTTI_BEGIN_ENUM(Type) \
636  UNIQUE_REGISTRATION_NAMESPACE(__COUNTER__) \
637  { \
638  RTTR_REGISTRATION \
639  { \
640  using namespace rttr; \
641  registration::enumeration<Type>(#Type) \
642  (
643 
649 #define RTTI_ENUM_VALUE(Value, String) \
650  value(String, Value)
651 
655 #define RTTI_END_ENUM \
656  ); \
657  } \
658  }
659 
660 
662 // RTTI_DEFINE_BASE
664 
671 #define RTTI_DEFINE_BASE_1(Type) \
672  RTTI_BEGIN_CLASS_NO_DEFAULT_CONSTRUCTOR(Type) \
673  RTTI_END_CLASS
674 
682 #define RTTI_DEFINE_BASE_2(Type, Description) \
683  RTTI_BEGIN_CLASS_NO_DEFAULT_CONSTRUCTOR(Type, Description) \
684  RTTI_END_CLASS
685 
686 #define GET_RTTI_DEFINE_BASE_MACRO(_1,_2,NAME,...) NAME
687 
695 #define RTTI_DEFINE_BASE(...) GET_RTTI_DEFINE_BASE_MACRO(__VA_ARGS__, RTTI_DEFINE_BASE_2, RTTI_DEFINE_BASE_1)(__VA_ARGS__)
696 
697 
699 // RTTI_DEFINE_CLASS
701 
706 #define RTTI_DEFINE_CLASS_1(Type) \
707  RTTI_BEGIN_CLASS(Type) \
708  RTTI_END_CLASS
709 
715 #define RTTI_DEFINE_CLASS_2(Type, Description) \
716  RTTI_BEGIN_CLASS(Type, Description) \
717  RTTI_END_CLASS
718 
719 #define GET_RTTI_DEFINE_CLASS_MACRO(_1,_2,NAME,...) NAME
720 
726 #define RTTI_DEFINE_CLASS(...) GET_RTTI_DEFINE_CLASS_MACRO(__VA_ARGS__, RTTI_DEFINE_CLASS_2, RTTI_DEFINE_CLASS_1)(__VA_ARGS__)
727 
728 
730 // RTTI_DEFINE_STRUCT
732 
737 #define RTTI_DEFINE_STRUCT_1(Type) \
738  RTTI_BEGIN_STRUCT(Type) \
739  RTTI_END_STRUCT
740 
746 #define RTTI_DEFINE_STRUCT_2(Type, Description) \
747  RTTI_BEGIN_STRUCT(Type, Description) \
748  RTTI_END_STRUCT
749 
750 #define GET_RTTI_DEFINE_STRUCT_MACRO(_1,_2,NAME,...) NAME
751 
757 #define RTTI_DEFINE_STRUCT(...) GET_RTTI_DEFINE_STRUCT_MACRO(__VA_ARGS__, RTTI_DEFINE_STRUCT_2, RTTI_DEFINE_STRUCT_1)(__VA_ARGS__)
nap::ComputeShader
Definition: shader.h:176
nap::rtti::EPropertyMetaData
EPropertyMetaData
Definition: typeinfo.h:165
nap::rtti::method::toObject
constexpr const char * toObject
to object pointer
Definition: typeinfo.h:157
nap::rtti::method::assign
constexpr const char * assign
assignment
Definition: typeinfo.h:156
nap::rtti::EPropertyMetaData::Embedded
@ Embedded
An embedded pointer.
nap::rtti::EPropertyFileType::VertShader
@ VertShader
Points to a .frag file, must be used with EPropertyMetaData::FileLink.
nap::rtti::VariantArray
rttr::variant_array_view VariantArray
Definition: typeinfo.h:146
nap::rtti::EPropertyFileType::ImageSequence
@ ImageSequence
Points to a an image sequence, must be used with EPropertyMetaData::FileLink.
nap::rtti::EPropertyMetaData::Required
@ Required
Load will fail if the property isn't set.
nap::rtti::EPropertyFileType::FragShader
@ FragShader
Points to a .vert file, must be used with EPropertyMetaData::FileLink.
nap::rtti::VariantMap
rttr::variant_associative_view VariantMap
Definition: typeinfo.h:147
nap::Video
Definition: video.h:399
nap::rtti::method::description
constexpr const char * description
rtti type description
Definition: typeinfo.h:154
nap::rtti::isTypeMatch
bool isTypeMatch(const rtti::TypeInfo &typeA, const rtti::TypeInfo &typeB, ETypeCheck typeCheck)
Definition: typeinfo.h:246
nap::rtti::isFileType
bool isFileType(const rtti::Property &property, EPropertyFileType filetype)
Definition: typeinfo.h:226
nap::rtti::Enum
rttr::enumeration Enum
Definition: typeinfo.h:142
nap::rtti::Property
rttr::property Property
Definition: typeinfo.h:143
nap::Image
Definition: image.h:18
nap::rtti::method::toString
constexpr const char * toString
to object path
Definition: typeinfo.h:158
nap::rtti::method::translateTargetID
constexpr const char * translateTargetID
transform id
Definition: typeinfo.h:159
nap::rtti::EPropertyFileType::Any
@ Any
Can point to any file, default.
nap::rtti::hasFlag
bool hasFlag(const rtti::Property &property, EPropertyMetaData flags)
Definition: typeinfo.h:212
nap::rtti::EPropertyMetaData::ReadOnly
@ ReadOnly
A read only property.
nap::rtti::EPropertyMetaData::Default
@ Default
Uses the (class) default if the property isn't set.
nap::rtti::isPrimitive
bool isPrimitive(const rtti::TypeInfo &type)
Definition: typeinfo.h:204
nap::Font
Definition: font.h:64
nap::rtti::findMethodRecursive
rttr::method findMethodRecursive(const rtti::TypeInfo &type, const std::string &methodName)
Definition: typeinfo.h:258
nap
Definition: templateapp.h:17
nap::rtti::method::moduleDescription
constexpr const char * moduleDescription
nap module description
Definition: typeinfo.h:155
nap::rtti::ETypeCheck::EXACT_MATCH
@ EXACT_MATCH
The type needs to be of the exact same kind.
nap::rtti::Instance
rttr::instance Instance
Definition: typeinfo.h:145
nap::rtti::EPropertyFileType
EPropertyFileType
Definition: typeinfo.h:177
nap::rtti::Variant
rttr::variant Variant
Definition: typeinfo.h:144
nap::rtti::ETypeCheck::IS_DERIVED_FROM
@ IS_DERIVED_FROM
The type is derived from the specified type.
nap::rtti::TypeInfo
rttr::type TypeInfo
Definition: typeinfo.h:141
nap::rtti::ETypeCheck
ETypeCheck
Definition: typeinfo.h:237
nap::rtti::operator&
EPropertyMetaData operator&(EPropertyMetaData a, EPropertyMetaData b)
Definition: typeinfo.h:191
nap::rtti::operator|
EPropertyMetaData operator|(EPropertyMetaData a, EPropertyMetaData b)
Definition: typeinfo.h:196
nap::Mesh
Definition: mesh.h:431
nap::rtti::EPropertyFileType::Audio
@ Audio
Points to an audio file, must be used with EPropertyMetaData::FileLink.