126 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			126 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
#pragma once
 | 
						|
#include "field.h"
 | 
						|
#include "view.h"
 | 
						|
#include "meta.h"
 | 
						|
namespace refl {
 | 
						|
	enum ClassFlag :uint32_t {
 | 
						|
		CLASS_NONE_FLAG = 0,
 | 
						|
		CLASS_TRIVIAL_FLAG = 1 << 0,
 | 
						|
		CLASS_POINTER_FLAG = 1 << 1,
 | 
						|
		CLASS_ARRAY_FLAG   = 1 << 2,
 | 
						|
	};
 | 
						|
	using enum ClassFlag;
 | 
						|
	struct vtable_uclass
 | 
						|
	{
 | 
						|
		//class
 | 
						|
		const FieldPtr* (*GetField)(const UClass*, const Name&, int);
 | 
						|
		//function
 | 
						|
		sarray<const UClass*>(*GetParams)(const UClass*);
 | 
						|
		//function
 | 
						|
		void (*Call)(const FieldPtr*, const sarray<Any>& ArgsList);
 | 
						|
		//meta
 | 
						|
		const UClass* (*GetMeta)(const Name&);
 | 
						|
		//object
 | 
						|
		void (*InitObject)(void*);
 | 
						|
		void (*CopyObject)(void*, const void*);
 | 
						|
		void (*DestObject)(void*);
 | 
						|
	};
 | 
						|
	class UClass{
 | 
						|
	public:
 | 
						|
		Name name;
 | 
						|
		uint32_t size;
 | 
						|
		uint32_t flag{0};
 | 
						|
		const UClass* parent;
 | 
						|
		Meta* meta{nullptr};
 | 
						|
		vtable_uclass vtable{};
 | 
						|
	public:
 | 
						|
		constexpr UClass(std::string_view name, uint32_t size, const UClass* parent = nullptr)
 | 
						|
			:name(name), size(size), parent(parent){}
 | 
						|
		AnyView New(void* ptr = nullptr) const{
 | 
						|
			if (ptr == nullptr) {
 | 
						|
				ptr = malloc(size);
 | 
						|
				InitObject(ptr);
 | 
						|
			}
 | 
						|
			return { ptr , this };
 | 
						|
		}
 | 
						|
		template<typename T>
 | 
						|
		T* New(T* ptr = nullptr) const{
 | 
						|
			if (!IsChildOf<T>()) {
 | 
						|
				return nullptr;
 | 
						|
			}
 | 
						|
			if (ptr == nullptr) {
 | 
						|
				ptr = (T*)malloc(size);
 | 
						|
			}
 | 
						|
			InitObject(ptr);
 | 
						|
			return ptr;
 | 
						|
		}
 | 
						|
		bool IsChildOf(const UClass* cls) const {
 | 
						|
			const UClass* _parent = parent;
 | 
						|
			while (_parent != nullptr) {
 | 
						|
				if (_parent == cls) {
 | 
						|
					return true;
 | 
						|
				}
 | 
						|
				_parent = _parent->parent;
 | 
						|
			}
 | 
						|
			return false;
 | 
						|
		}
 | 
						|
		template<typename T>
 | 
						|
		bool IsChildOf(bool bthis = false) const {
 | 
						|
			return IsChildOf(&TypeInfo<T>::StaticClass);
 | 
						|
		}
 | 
						|
	public:
 | 
						|
		const FieldPtr* GetField(const Name& name, int index)const {
 | 
						|
			if (vtable.GetField) {
 | 
						|
				return vtable.GetField(this, name, index);
 | 
						|
			}
 | 
						|
			return nullptr; 
 | 
						|
		}
 | 
						|
		void InitObject(void* ptr)const {
 | 
						|
			if (vtable.InitObject) {
 | 
						|
				vtable.InitObject(ptr);
 | 
						|
			}
 | 
						|
			else {
 | 
						|
				memset(ptr, 0, size);
 | 
						|
			}
 | 
						|
		}
 | 
						|
		void CopyObject(void* dst, const void* src)const {
 | 
						|
			if (vtable.CopyObject) {
 | 
						|
				vtable.CopyObject(dst, src);
 | 
						|
			}
 | 
						|
			else {
 | 
						|
				memcpy(dst, src, size);
 | 
						|
			}
 | 
						|
		}
 | 
						|
		void DestObject(void* ptr)const {
 | 
						|
			if (vtable.DestObject) {
 | 
						|
				vtable.DestObject(ptr);
 | 
						|
			}
 | 
						|
		}
 | 
						|
	public:
 | 
						|
		template<_ReflCheck_Ctor T>
 | 
						|
		static void InitObject(void* ptr) {
 | 
						|
			T obj{};
 | 
						|
			std::construct_at((T*)ptr, obj);
 | 
						|
		}
 | 
						|
		template<typename T>
 | 
						|
		static void CopyObject(void* dst, const void* src) {
 | 
						|
			*(T*)dst = *(T*)src;
 | 
						|
		}
 | 
						|
		template<_ReflCheck_Ctor T, int N>
 | 
						|
		static void InitObject(void* ptr) {
 | 
						|
			T* tptr = (T*)ptr;
 | 
						|
			T obj{};
 | 
						|
			for (int i = 0; i < N; i++) {
 | 
						|
				std::construct_at(tptr++, obj);
 | 
						|
			}
 | 
						|
		}
 | 
						|
		template<typename T, int N>
 | 
						|
		static void CopyObject(void* dst, const void* src) {
 | 
						|
			T* tdst = (T*)dst;
 | 
						|
			const T* tsrc = (const T*)src;
 | 
						|
			for (int i = 0; i < N; i++) {
 | 
						|
				*tdst++ = *tsrc++;
 | 
						|
			}
 | 
						|
		}
 | 
						|
	};
 | 
						|
} |