Advertisement
Zgragselus

Reflection

Jan 2nd, 2022
1,214
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.53 KB | None | 0 0
  1. #ifndef __REFLECTION__H__
  2. #define __REFLECTION__H__
  3.  
  4. #include <string>
  5. #include <vector>
  6. #include <iostream>
  7. #include "Core/DllDef.h"
  8.  
  9. namespace Engine
  10. {
  11.     namespace Reflection
  12.     {
  13.         // Base class for type descriptors
  14.         class TypeDescriptor
  15.         {
  16.         public:
  17.             std::string mName;
  18.             size_t mSize;
  19.  
  20.             TypeDescriptor(const std::string& name, size_t size)
  21.             {
  22.                 mName = name;
  23.                 mSize = size;
  24.             }
  25.  
  26.             virtual ~TypeDescriptor()
  27.             {
  28.  
  29.             }
  30.  
  31.             virtual std::string GetFullName()
  32.             {
  33.                 return mName;
  34.             }
  35.  
  36.             virtual void Dump(const void* obj, int identLvl = 0) const = 0;
  37.         };
  38.  
  39.         // Function template for handling primitive types (int, float, std::string)
  40.         template <typename T> TypeDescriptor* GetPrimitiveDescriptor();
  41.  
  42.         // Helper class to find type descriptors
  43.         class DefaultResolver
  44.         {
  45.         public:
  46.             template <typename T> static char mFunc(decltype(&T::Reflection));
  47.             template <typename T> static int mFunc(...);
  48.             template <typename T> struct IsReflected { enum { value = (sizeof(mFunc<T>(nullptr)) == sizeof(char)) }; };
  49.  
  50.             // This version is called when T has static member Reflection
  51.             template <typename T, typename std::enable_if<IsReflected<T>::value, int>::type = 0>
  52.             static TypeDescriptor* Get()
  53.             {
  54.                 return &T::Reflection;
  55.             }
  56.  
  57.             // This version is called otherwise
  58.             template <typename T, typename std::enable_if<!IsReflected<T>::value, int>::type = 0>
  59.             static TypeDescriptor* Get()
  60.             {
  61.                 return GetPrimitiveDescriptor<T>();
  62.             }
  63.         };
  64.  
  65.         // Primary class template to find all type descriptors
  66.         template <typename T>
  67.         class TypeResolver
  68.         {
  69.         public:
  70.             static TypeDescriptor* Get()
  71.             {
  72.                 return DefaultResolver::Get<T>();
  73.             }
  74.         };
  75.  
  76.         // Type descriptors for classes/structs
  77.         class TypeDescriptor_Struct : public TypeDescriptor
  78.         {
  79.         public:
  80.             class Member
  81.             {
  82.             public:
  83.                 std::string mName;
  84.                 size_t mOffset;
  85.                 TypeDescriptor* mType;
  86.             };
  87.  
  88.             std::vector<Member> mMembers;
  89.  
  90.             TypeDescriptor_Struct(void (*init)(TypeDescriptor_Struct*)) : TypeDescriptor("", 0)
  91.             {
  92.                 init(this);
  93.             }
  94.  
  95.             TypeDescriptor_Struct(const std::string& name, size_t size, const std::initializer_list<Member>& init) : TypeDescriptor("", 0), mMembers(init)
  96.             {
  97.  
  98.             }
  99.  
  100.             virtual void Dump(const void* obj, int indentLvl) const
  101.             {
  102.                 std::cout << std::string(4 * (indentLvl), ' ') << mName << std::endl;
  103.                 std::cout << std::string(4 * (indentLvl), ' ') << "{" << std::endl;
  104.                 for (const Member& member : mMembers)
  105.                 {
  106.                     std::cout << std::string(4 * (indentLvl + 1), ' ') << member.mName << " = ";
  107.                     member.mType->Dump((char*)obj + member.mOffset, indentLvl + 1);
  108.                     std::cout << std::endl;
  109.                 }
  110.                 std::cout << std::string(4 * (indentLvl), ' ') << "}" << std::endl;
  111.             }
  112.         };
  113.     };
  114. }
  115.  
  116. #define REFLECT() \
  117.     friend class Engine::Reflection::DefaultResolver; \
  118.     static Engine::Reflection::TypeDescriptor_Struct Reflection; \
  119.     static void InitReflection(Engine::Reflection::TypeDescriptor_Struct*); \
  120.  
  121. #define REFLECT_STRUCT_BEGIN(type) \
  122.     Engine::Reflection::TypeDescriptor_Struct type::Reflection{type::InitReflection}; \
  123.     void type::InitReflection(Engine::Reflection::TypeDescriptor_Struct* typeDesc) { \
  124.         using T = type; \
  125.         typeDesc->mName = #type; \
  126.         typeDesc->mSize = sizeof(T); \
  127.         typeDesc->mMembers = {
  128.  
  129. #define REFLECT_STRUCT_MEMBER(name) \
  130.             {#name, offsetof(T, name), Engine::Reflection::TypeResolver<decltype(T::name)>::Get()},
  131.  
  132. #define REFLECT_STRUCT_END() \
  133.         }; \
  134.     }
  135.  
  136. #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement