112 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			112 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
#pragma once
 | 
						|
#include "field.h"
 | 
						|
#include "view.h"
 | 
						|
#include "meta.h"
 | 
						|
#include "convert.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;
 | 
						|
	enum EFieldFind :uint32_t {
 | 
						|
		FIND_ALL_FIELD = 0,
 | 
						|
		FIND_ALL_MEMBER,
 | 
						|
		FIND_ALL_METHOD,
 | 
						|
		FIND_FIELD,
 | 
						|
		FIND_CTOR,
 | 
						|
		FIND_MEMBER,
 | 
						|
		FIND_METHOD,
 | 
						|
		FIND_METHODS,//函数重载 特别是构造函数
 | 
						|
	};
 | 
						|
	struct vtable_uclass
 | 
						|
	{
 | 
						|
		//class
 | 
						|
		const sarray<const FieldPtr> (*GetFields)(const UClass*, EFieldFind find, const Name& name);
 | 
						|
		//function
 | 
						|
		sarray<const UClass*>(*GetParams)(const UClass*);
 | 
						|
		//function
 | 
						|
		void (*Call)(const FieldPtr*, const sarray<Any>& ArgsList);
 | 
						|
		//meta
 | 
						|
		const UClass* (*GetMeta)(const Name&);
 | 
						|
		//object
 | 
						|
		bool (*CtorObject)(void* ptr,const UClass* cls, const sarray<Any>& ArgsList);
 | 
						|
		bool (*DestObject)(void*);
 | 
						|
	};
 | 
						|
	class UClass{
 | 
						|
	public:
 | 
						|
		Name name;
 | 
						|
		uint32_t size;
 | 
						|
		uint32_t flag{0};
 | 
						|
		const UClass* parent;
 | 
						|
		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 sarray<Any>& ArgsList = {}) const {
 | 
						|
			if (ptr == nullptr) {
 | 
						|
				ptr = malloc(size);
 | 
						|
				CtorObject(ptr, ArgsList);
 | 
						|
			}
 | 
						|
			return { ptr , this };
 | 
						|
		}
 | 
						|
		template<typename T>
 | 
						|
		T* New(T* ptr = nullptr, const sarray<Any>& ArgsList = {}) const{
 | 
						|
			if (!IsChildOf<T>(true)) {
 | 
						|
				return nullptr;
 | 
						|
			}
 | 
						|
			if (ptr == nullptr) {
 | 
						|
				ptr = (T*)malloc(size);
 | 
						|
			}
 | 
						|
			
 | 
						|
			CtorObject(ptr, ArgsList);
 | 
						|
			return ptr;
 | 
						|
		}
 | 
						|
		bool IsChildOf(const UClass* cls, bool bthis = false) const {
 | 
						|
			const UClass* _parent = bthis ? this : 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, bthis);
 | 
						|
		}
 | 
						|
	public:
 | 
						|
		const sarray<const FieldPtr> GetFields(EFieldFind find, const Name& name)const {
 | 
						|
			if (vtable.GetFields) {
 | 
						|
				return vtable.GetFields(this, find, name);
 | 
						|
			}
 | 
						|
			return {};
 | 
						|
		}
 | 
						|
		bool CtorObject(void* ptr, const sarray<Any>& ArgsList = {})const;
 | 
						|
		void DestObject(void* ptr)const {
 | 
						|
			if (vtable.DestObject) {
 | 
						|
				vtable.DestObject(ptr);
 | 
						|
			}
 | 
						|
		}
 | 
						|
	public:
 | 
						|
		template<typename T>
 | 
						|
		static bool CtorObject(void* ptr, const UClass* cls, const sarray<Any>& ArgsList = {}) {
 | 
						|
			int argsSize = ArgsList.size();
 | 
						|
			if (argsSize == 0) {
 | 
						|
				if constexpr (std::is_trivially_constructible_v<T>) {
 | 
						|
					std::construct_at((T*)ptr);
 | 
						|
					return true;
 | 
						|
				}
 | 
						|
				return false;
 | 
						|
			}
 | 
						|
			if (argsSize == 1 && ArgsList[0]->Check(cls)) {
 | 
						|
				*(T*)ptr = *(const T*)ArgsList[0]->ptr;
 | 
						|
				return true;
 | 
						|
			}
 | 
						|
			return false;
 | 
						|
		}
 | 
						|
	};
 | 
						|
} |