Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #ifndef __REFLECTION__H__
- #define __REFLECTION__H__
- #include <string>
- #include <vector>
- #include <iostream>
- #include "Core/DllDef.h"
- namespace Engine
- {
- namespace Reflection
- {
- // Base class for type descriptors
- class TypeDescriptor
- {
- public:
- std::string mName;
- size_t mSize;
- TypeDescriptor(const std::string& name, size_t size)
- {
- mName = name;
- mSize = size;
- }
- virtual ~TypeDescriptor()
- {
- }
- virtual std::string GetFullName()
- {
- return mName;
- }
- virtual void Dump(const void* obj, int identLvl = 0) const = 0;
- };
- // Function template for handling primitive types (int, float, std::string)
- template <typename T> TypeDescriptor* GetPrimitiveDescriptor();
- // Helper class to find type descriptors
- class DefaultResolver
- {
- public:
- template <typename T> static char mFunc(decltype(&T::Reflection));
- template <typename T> static int mFunc(...);
- template <typename T> struct IsReflected { enum { value = (sizeof(mFunc<T>(nullptr)) == sizeof(char)) }; };
- // This version is called when T has static member Reflection
- template <typename T, typename std::enable_if<IsReflected<T>::value, int>::type = 0>
- static TypeDescriptor* Get()
- {
- return &T::Reflection;
- }
- // This version is called otherwise
- template <typename T, typename std::enable_if<!IsReflected<T>::value, int>::type = 0>
- static TypeDescriptor* Get()
- {
- return GetPrimitiveDescriptor<T>();
- }
- };
- // Primary class template to find all type descriptors
- template <typename T>
- class TypeResolver
- {
- public:
- static TypeDescriptor* Get()
- {
- return DefaultResolver::Get<T>();
- }
- };
- // Type descriptors for classes/structs
- class TypeDescriptor_Struct : public TypeDescriptor
- {
- public:
- class Member
- {
- public:
- std::string mName;
- size_t mOffset;
- TypeDescriptor* mType;
- };
- std::vector<Member> mMembers;
- TypeDescriptor_Struct(void (*init)(TypeDescriptor_Struct*)) : TypeDescriptor("", 0)
- {
- init(this);
- }
- TypeDescriptor_Struct(const std::string& name, size_t size, const std::initializer_list<Member>& init) : TypeDescriptor("", 0), mMembers(init)
- {
- }
- virtual void Dump(const void* obj, int indentLvl) const
- {
- std::cout << std::string(4 * (indentLvl), ' ') << mName << std::endl;
- std::cout << std::string(4 * (indentLvl), ' ') << "{" << std::endl;
- for (const Member& member : mMembers)
- {
- std::cout << std::string(4 * (indentLvl + 1), ' ') << member.mName << " = ";
- member.mType->Dump((char*)obj + member.mOffset, indentLvl + 1);
- std::cout << std::endl;
- }
- std::cout << std::string(4 * (indentLvl), ' ') << "}" << std::endl;
- }
- };
- };
- }
- #define REFLECT() \
- friend class Engine::Reflection::DefaultResolver; \
- static Engine::Reflection::TypeDescriptor_Struct Reflection; \
- static void InitReflection(Engine::Reflection::TypeDescriptor_Struct*); \
- #define REFLECT_STRUCT_BEGIN(type) \
- Engine::Reflection::TypeDescriptor_Struct type::Reflection{type::InitReflection}; \
- void type::InitReflection(Engine::Reflection::TypeDescriptor_Struct* typeDesc) { \
- using T = type; \
- typeDesc->mName = #type; \
- typeDesc->mSize = sizeof(T); \
- typeDesc->mMembers = {
- #define REFLECT_STRUCT_MEMBER(name) \
- {#name, offsetof(T, name), Engine::Reflection::TypeResolver<decltype(T::name)>::Get()},
- #define REFLECT_STRUCT_END() \
- }; \
- }
- #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement