#pragma once
#include <string>
#include "type.h"
namespace refl {
	class UClass;
	class FieldPtr;
	class ObjectView {
	public:
		const char* ptr;
		const UClass* cls;
		const FieldPtr* cache{nullptr};
		ObjectView(const void* ptr, const UClass* cls) : ptr((const char*)ptr), cls(cls){}
	public:

		template<typename T>
		bool Get(const Name& name, T& t);

		template<typename T>
		bool Set(const Name& name, const T& t);

		template<typename ...Args>
		bool Invoke(const Name& name, Args&&... args);

		template<_ReflCheck_Ctor R, typename ...Args>
		R Invoke(const Name& name, Args&&... args);

		ObjectView Parent();
	};
	//生命周期短，适用于传参，不建议保存数据
	//这里类型丢失了呀，存入的都是指针数据
	struct ArgsView {
	public:
		const void* val;
		const UClass* cls;
		ArgsView(const void* val = nullptr, const UClass* cls = nullptr) : val(val), cls(cls) {}
		//右值=>右值压入栈，caller入栈地址
		//左值=>caller变量地址
		template<typename T>
		ArgsView(T&& v): val(&v), cls(&TypeInfo<typename std::remove_reference_t<T>*>::StaticClass){
			if constexpr (std::is_same_v<std::remove_reference_t<T>, ArgsView>) {
				val = v.val;
				cls = v.cls;
			}
		}
		template<typename T>
		constexpr inline T cast_to() {
			if constexpr (std::is_pointer_v<T>) {
				return (T)val;
			}
			else if constexpr (std::is_reference_v<T>){
				using RT = std::remove_reference_t<T>;
				return *(RT*)val;
			}else{
				return *(T*)val;
			}
		}
		bool ConvertTo(const UClass* toClass);
	};
	//存入的是真实的数据类型,type用于拷贝数据
	struct ArgsValue : public ArgsView {
		const UClass* type;
		template<typename T>
		ArgsValue(T&& t) : ArgsView(t), type(&TypeInfo<T>::StaticClass){}
	};
	struct ArgsValueList{
		void* data{ nullptr };
		ArgsView* ptr{nullptr};
		int num{ 0 };
		ArgsValueList(const std::vector<ArgsValue>& args);
		~ArgsValueList();
	};
}