diff --git a/src/refl/Gen.cs b/src/refl/Gen.cs index b087c1c..ff82ab7 100644 --- a/src/refl/Gen.cs +++ b/src/refl/Gen.cs @@ -11,27 +11,18 @@ namespace refl public static Dictionary FileList = new Dictionary(); public static StringBuilder Meta = new StringBuilder(); public static StringBuilder Output = new StringBuilder(); - private ClassMetaData data = new ClassMetaData(); + private ClassMetaImplData data = new ClassMetaImplData(); private GenMeta meta = new GenMeta(); private GenMetaImpl metaImpl = new GenMetaImpl(); - private GenMultyMeta multyMeta = new GenMultyMeta(); private Stack nameSpaces = new Stack(); public Gen() { } - - public static string PreprocessTemplate(string template, string indent, string newline) - { - // 替换占位符 - return template.Replace("{{ Indent }}", indent); - } public static bool InitTemplate(string dir) { string meta_file = Path.Combine(dir, "meta.liquid"); string meta_impl_file = Path.Combine(dir, "meta_impl.liquid"); - string multy_meta_file = Path.Combine(dir, "multy_meta.liquid"); var parser = new FluidParser(); return GenMeta.InitTemplate(meta_file, parser) - && GenMetaImpl.InitTemplate(meta_impl_file, parser) - && GenMultyMeta.InitTemplate(multy_meta_file, parser); + && GenMetaImpl.InitTemplate(meta_impl_file, parser); } public void CheckDir(string? dir) { @@ -43,12 +34,10 @@ namespace refl public void InitFile(string file_name) { Meta.AppendLine("#pragma once"); - Meta.AppendLine("namespace refl_impl{"); foreach (var name in ModuleMeta.NameSet) { var build = new StringBuilder(); build.AppendLine("#pragma once"); - build.AppendLine("namespace refl_impl{"); FileList.Add(name, build); } } @@ -63,8 +52,6 @@ namespace refl } public void OutFile(string file_name, string? dir,string target) { - Meta.AppendLine(""); - Output.AppendLine("}"); foreach (var pair in FileList) { string path = $"{pair.Key}_{file_name}".ToLower(); @@ -72,7 +59,6 @@ namespace refl { path = Path.Combine(dir, path); } - pair.Value.AppendLine("}"); File.WriteAllText(path, pair.Value.ToString()); if (pair.Key == "Meta") { @@ -119,19 +105,13 @@ namespace refl } return ""; } - public void GenClassMeta(ClassMeta cls, ClassMetaData data) + public void GenClassMeta(ClassMeta cls, ClassMetaImplData data) { string fullName = GenPrefix() + cls.Name; data.FullName = fullName; - bool isMulty = meta.GenClassMeta(cls, data); - Meta.Append(metaImpl.GenClassMeta(cls, fullName, isMulty)); + bool isMulty = metaImpl.GenClassMeta(cls, data); + Meta.Append(meta.GenClassMeta(cls, fullName, isMulty)); Meta.AppendLine(""); - if (isMulty) - { - var res = multyMeta.GenClassMeta(cls, fullName); - Output.Append(res); - Output.AppendLine(""); - } } } } diff --git a/src/refl/GenMeta.cs b/src/refl/GenMeta.cs index a6fd2ed..6c4006d 100644 --- a/src/refl/GenMeta.cs +++ b/src/refl/GenMeta.cs @@ -1,48 +1,32 @@ -using System.IO; +using Fluid; +using System; +using System.Collections.Generic; +using System.Linq; using System.Text; -using System.Xml.Linq; -using Fluid; +using System.Threading.Tasks; +using static System.Runtime.InteropServices.JavaScript.JSType; namespace refl { - internal class FieldMetaData - { - public string Name { get; set; } - public string Meta { get; set; } - public string Ref { get; set; } - public int Type { get; set; } - - public FieldMetaData(FieldData data, int type) - { - Name = data.Name; - Meta = data.Meta; - Ref = data.Ref; - Type = type; - } - } - internal class ClassMetaData + internal class MetaClassData { public string Name { get; set; } = ""; public string ParentName { get; set; } = ""; public string FullName { get; set; } = ""; - public string MetaName { get; set; } = ""; - public int MetaType { get; set; } = 0; - public int MemberCount { get; set; } = 0; - public int CtorCount { get; set; } = 0; - - public List FieldList = new List(); + public bool IsMultyMeta { get; set; } = false; + public bool HasMeta { get; set; } = false; + public bool HasParent { get; set; } = false; + public List MetaList = new List(); } - internal class GenMeta { private static IFluidTemplate? template; private static TemplateOptions options = new TemplateOptions(); + private MetaClassData meta = new MetaClassData(); public static bool InitTemplate(string path, FluidParser parser) { var meta_string = File.ReadAllText(path); - meta_string = Gen.PreprocessTemplate(meta_string, "\t", "\r\n"); parser.TryParse(meta_string, out template, out var error); - options.MemberAccessStrategy.Register(); if (!string.IsNullOrEmpty(error)) { Console.WriteLine(error); @@ -50,45 +34,24 @@ namespace refl } return true; } - public bool GenClassMeta(ClassMeta cls, ClassMetaData data) + public string GenClassMeta(ClassMeta cls, string fullName, bool isMulty) { - data.Name = cls.Name; - data.ParentName = cls.ParentName; - bool isMulty = cls.Fields.Count > 1; - if(cls.Fields.Count == 1) - { - isMulty = cls.Fields.Keys.First() != "Meta"; - } + meta.ParentName = cls.ParentName; + meta.Name = cls.Name; + meta.FullName = fullName; + meta.IsMultyMeta = isMulty; + meta.HasMeta = false; + meta.HasParent = cls.ParentName != "void"; foreach (var pair in cls.Fields) { - data.FieldList.Clear(); - foreach (var field in pair.Value.MemberList) + if (pair.Key.Equals("Meta")) { - data.FieldList.Add(new FieldMetaData(field, 1)); + meta.HasMeta = true; } - foreach (var field in pair.Value.CtorList) - { - data.FieldList.Add(new FieldMetaData(field, 2)); - } - foreach (var field in pair.Value.MethodList) - { - int type = string.IsNullOrEmpty(field.Ref) ? 3 : 4; - data.FieldList.Add(new FieldMetaData(field, type)); - } - data.MemberCount = pair.Value.MemberList.Count; - data.CtorCount = pair.Value.CtorList.Count; - data.MetaType = isMulty ? 1 : 0; - if (isMulty && pair.Key.Equals("Meta")) - { - data.MetaType = 2; - } - data.MetaName = pair.Key; - var context = new TemplateContext(data, options); - var res = template.Render(context); - Gen.FileList[pair.Key].Append(res); - Gen.FileList[pair.Key].AppendLine(""); + meta.MetaList.Add(pair.Key); } - return isMulty; + var context = new TemplateContext(meta, options); + return template.Render(context); } } -} +} \ No newline at end of file diff --git a/src/refl/GenMetaImpl.cs b/src/refl/GenMetaImpl.cs index 8669b95..64fce8f 100644 --- a/src/refl/GenMetaImpl.cs +++ b/src/refl/GenMetaImpl.cs @@ -1,31 +1,46 @@ -using Fluid; -using System; -using System.Collections.Generic; -using System.Linq; +using System.IO; using System.Text; -using System.Threading.Tasks; -using static System.Runtime.InteropServices.JavaScript.JSType; +using System.Xml.Linq; +using Fluid; namespace refl { - internal class MetaImplClassData + internal class FieldMetaImplData + { + public string Name { get; set; } + public string Meta { get; set; } + public string Ref { get; set; } + public int Type { get; set; } + + public FieldMetaImplData(FieldData data, int type) + { + Name = data.Name; + Meta = data.Meta; + Ref = data.Ref; + Type = type; + } + } + internal class ClassMetaImplData { public string Name { get; set; } = ""; - public string FullName { get; set; } = ""; - public bool IsMultyMeta { get; set; } = false; - public bool HasMeta { get; set; } = false; + public string MetaName { get; set; } = ""; + public int MetaType { get; set; } = 0; + public int MemberCount { get; set; } = 0; + public int CtorCount { get; set; } = 0; + + public List FieldList = new List(); } + internal class GenMetaImpl { private static IFluidTemplate? template; private static TemplateOptions options = new TemplateOptions(); - private MetaImplClassData impl = new MetaImplClassData(); public static bool InitTemplate(string path, FluidParser parser) { var meta_string = File.ReadAllText(path); - meta_string = Gen.PreprocessTemplate(meta_string, "\t", "\r\n"); parser.TryParse(meta_string, out template, out var error); + options.MemberAccessStrategy.Register(); if (!string.IsNullOrEmpty(error)) { Console.WriteLine(error); @@ -33,21 +48,44 @@ namespace refl } return true; } - public string GenClassMeta(ClassMeta cls,string fullName, bool isMulty) + public bool GenClassMeta(ClassMeta cls, ClassMetaImplData data) { - impl.Name = cls.Name; - impl.FullName = fullName; - impl.IsMultyMeta = isMulty; - impl.HasMeta = false; + data.Name = cls.Name; + bool isMulty = cls.Fields.Count > 1; + if (cls.Fields.Count == 1) + { + isMulty = cls.Fields.Keys.First() != "Meta"; + } foreach (var pair in cls.Fields) { - if (pair.Key.Equals("Meta")) + data.FieldList.Clear(); + foreach (var field in pair.Value.MemberList) { - impl.HasMeta = true; + data.FieldList.Add(new FieldMetaImplData(field, 1)); } + foreach (var field in pair.Value.CtorList) + { + data.FieldList.Add(new FieldMetaImplData(field, 2)); + } + foreach (var field in pair.Value.MethodList) + { + int type = string.IsNullOrEmpty(field.Ref) ? 3 : 4; + data.FieldList.Add(new FieldMetaImplData(field, type)); + } + data.MemberCount = pair.Value.MemberList.Count; + data.CtorCount = pair.Value.CtorList.Count; + data.MetaType = isMulty ? 1 : 0; + if (isMulty && pair.Key.Equals("Meta")) + { + data.MetaType = 2; + } + data.MetaName = pair.Key; + var context = new TemplateContext(data, options); + var res = template.Render(context); + Gen.FileList[pair.Key].Append(res); + Gen.FileList[pair.Key].AppendLine(""); } - var context = new TemplateContext(impl, options); - return template.Render(context); + return isMulty; } } } diff --git a/src/refl/GenMultyMeta.cs b/src/refl/GenMultyMeta.cs deleted file mode 100644 index 73451e8..0000000 --- a/src/refl/GenMultyMeta.cs +++ /dev/null @@ -1,46 +0,0 @@ -using Fluid; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace refl -{ - internal class MultyMetaClassData - { - public string Name { get; set; } = ""; - public string FullName { get; set; } = ""; - - public List MetaList = new List(); - } - internal class GenMultyMeta - { - private static IFluidTemplate? template; - private static TemplateOptions options = new TemplateOptions(); - public static bool InitTemplate(string path, FluidParser parser) - { - var meta_string = File.ReadAllText(path); - meta_string = Gen.PreprocessTemplate(meta_string, "\t", "\r\n"); - parser.TryParse(meta_string, out template, out var error); - if (!string.IsNullOrEmpty(error)) - { - Console.WriteLine(error); - return false; - } - return true; - } - public string GenClassMeta(ClassMeta cls, string fullName) - { - MultyMetaClassData data = new MultyMetaClassData(); - data.Name = cls.Name; - data.FullName = fullName; - foreach (var pair in cls.Fields) - { - data.MetaList.Add(pair.Key); - } - var context = new TemplateContext(data, options); - return template.Render(context); - } - } -} diff --git a/src/refl/_install.bat b/src/refl/_install.bat index dd9c6eb..cb5e27c 100644 --- a/src/refl/_install.bat +++ b/src/refl/_install.bat @@ -1,6 +1,6 @@ @echo off set "source_dir=%CD%" REM 当前目录 -set "destination_dir=F:\ouczbs\zengine\tools\refl" REM 指定目标目录 +set "destination_dir=F:\engine\zengine\tools\refl" REM 指定目标目录 xcopy "%source_dir%\bin\Release\net8.0\win-x64\*" "%destination_dir%\" /Y xcopy "%source_dir%\template\*" "%destination_dir%\template\" /Y pause \ No newline at end of file diff --git a/src/refl/cpp/macro.h b/src/refl/cpp/macro.h index 9e75781..f0a25bb 100644 --- a/src/refl/cpp/macro.h +++ b/src/refl/cpp/macro.h @@ -1,9 +1,7 @@ #pragma once #if !defined(__cppast) #define __cppast(...) -#else #endif - #define __Meta(...) __cppast(Meta=__VA_ARGS__) #define UPROPERTY(...) __Meta(__VA_ARGS__) #define UFUNCTION(...) __Meta(__VA_ARGS__) @@ -38,9 +36,4 @@ struct vec3{ UFUNCTION({},ref = USING_CTOR_NAME) vec3(){} } -*/ -namespace refl_impl { - struct Meta {}; - struct vkMeta {}; - struct dxMeta {}; -} \ No newline at end of file +*/ \ No newline at end of file diff --git a/src/refl/cpp/vertex.h b/src/refl/cpp/vertex.h index 88ae6d2..611bfc5 100644 --- a/src/refl/cpp/vertex.h +++ b/src/refl/cpp/vertex.h @@ -2,10 +2,42 @@ #include "type.h" #include "guid.h" #include "resource_bundle.h" +namespace api { + using pmr::Name; + enum class EModuleFlag : uint32_t { + Reload = 1, + }; + ENABLE_BITMASK_OPERATORS(EModuleFlag); + struct ModuleInfo { + UPROPERTY() + EModuleFlag flag{ 0 }; + UPROPERTY() + Name name; //!< name of the plugin + UPROPERTY() + Name prettyname; //!< formatted name of the plugin + UPROPERTY() + Name core_version; //!< version of the engine + UPROPERTY() + Name version; // !< version of the plugin + UPROPERTY() + Name linking; // !< linking of the plugin + UPROPERTY() + Name license; //!< license of the plugin + UPROPERTY() + Name url; //!< url of the plugin + UPROPERTY() + Name copyright; //!< copyright of the plugin + public: + bool IsReload() { + return !!(flag & EModuleFlag::Reload); + } + }; +} namespace engineapi -{ +{ struct SerializedMeta { + UPROPERTY_vk({}) UPROPERTY({}) Guid guid; UPROPERTY({}) @@ -13,10 +45,12 @@ namespace engineapi UPROPERTY({}) string t_hash{}; UPROPERTY({}) - string metadata; + refl::Any meta; + bool operator==(const SerializedMeta& other)const { + return guid == other.guid && name == other.name && t_hash == other.t_hash; + } }; struct ResourceBundle; - struct MetaBundle { UPROPERTY({}) @@ -26,6 +60,12 @@ namespace engineapi template const SerializedMeta* FetchMeta() const; + template + const SerializedMeta* FetchMeta(const string_view& asset_name) const; + template + void Add(RscHandle); + bool operator==(const MetaBundle& other)const; + bool operator!=(const MetaBundle& other)const; }; } #include "meta_bundle.inl" diff --git a/src/refl/template/meta.liquid b/src/refl/template/meta.liquid index 75a5429..421f970 100644 --- a/src/refl/template/meta.liquid +++ b/src/refl/template/meta.liquid @@ -1,66 +1,24 @@ -{{ Indent }}template<> struct _Static<{{FullName}},{{MetaName}}> { -{{ Indent }} using T = {{FullName}}; -{{ Indent }} consteval static auto __MakeStaticFields() { -{{ Indent }} return std::array{ -{{ Indent }} {%- for field in FieldList %} -{{ Indent }} {%- if field.Type == 1 %} -{{ Indent }} refl::StaticMemberField(&T::{{field.Name}}, FName("{{field.Name}}"), {{field.Meta}}), -{{ Indent }} {%- elsif field.Type == 2 %} -{{ Indent }} refl::StaticCtorField((T::{{field.Ref}})nullptr,{{field.Meta}}), -{{ Indent }} {%- elsif field.Type == 3 %} -{{ Indent }} refl::StaticMethodField(&T::{{field.Name}}, FName("{{field.Name}}"), {{field.Meta}}), -{{ Indent }} {%- else %} -{{ Indent }} refl::StaticMethodField((T::{{field.Ref}})&T::{{field.Name}}, FName("{{field.Name}}"), {{field.Meta}}), -{{ Indent }} {%- endif %} -{{ Indent }} {%- endfor %} -{{ Indent }} }; -{{ Indent }} }; -{{ Indent }} -{{ Indent }} consteval static int Size() { -{{ Indent }} return refl::fetch_meta_size<_Static>(); -{{ Indent }} }; -{{ Indent }} consteval static int MemberCount() { -{{ Indent }} return {{MemberCount}}; -{{ Indent }} }; -{{ Indent }} consteval static int CtorCount() { -{{ Indent }} return {{CtorCount}}; -{{ Indent }} }; -{{ Indent }}}; -{{ Indent }} -{{ Indent }}template<> struct _Meta<{{FullName}},{{MetaName}}> : public refl::MetaHelp { -{{ Indent }} using T = {{FullName}}; -{{ Indent }} using MyParent = {{ ParentName }}; -{{ Indent }} using MyStatic = _Static; -{{ Indent }}{%-if IsMultyMeta %} -{{ Indent }} using MyMetas = class _Multy; -{{ Indent }}{%- endif %} -{{ Indent }} inline static char s_data[MyStatic::Size()]{}; -{{ Indent }} static auto __MakeFields() { -{{ Indent }} char* memory = &s_data[0]; -{{ Indent }} return std::array{ -{{ Indent }} {%- for field in FieldList %} -{{ Indent }} {%- if field.Type == 1 %} -{{ Indent }} MemberField(&T::{{field.Name}}, FName("{{field.Name}}"), memory, {{field.Meta}}), -{{ Indent }} {%- elsif field.Type == 2 %} -{{ Indent }} CtorField((T::{{field.Ref}})nullptr, memory, {{field.Meta}}), -{{ Indent }} {%- elsif field.Type == 3 %} -{{ Indent }} MethodField(&T::{{field.Name}}, FName("{{field.Name}}"), memory, {{field.Meta}}), -{{ Indent }} {%- else %} -{{ Indent }} MethodField((T::{{field.Ref}})&T::{{field.Name}}, FName("{{field.Name}}"), memory, {{field.Meta}}), -{{ Indent }} {%- endif %} -{{ Indent }} {%- endfor %} -{{ Indent }} }; -{{ Indent }} }; -{{ Indent }}}; -{{ Indent }}{%- if MetaType == 1 %} -{{ Indent }}const refl::UClass* _Multy<{{FullName}}>::get_{{ MetaName }}() -{{ Indent }}{ -{{ Indent }} static const auto s_cls = refl::UClass_Meta>(); -{{ Indent }} return &s_cls; -{{ Indent }}}; -{{ Indent }}{%- elsif MetaType == 2 %} -{{ Indent }}inline const refl::UClass* _Multy<{{FullName}}>::get_{{ MetaName }}() -{{ Indent }}{ -{{ Indent }} return &refl::TypeInfo::StaticClass; -{{ Indent }}}; -{{ Indent }}{%- endif %} \ No newline at end of file +namespace refl{ + template<> struct Meta<{{FullName}}>{ + {%- if HasParent %} + using Parent = {{ ParentName }}; + {%- endif %} + using T = {{FullName}}; + {%- if HasMeta %} + using Impl = gen::MetaImpl; + {%- endif %} + {%- if IsMultyMeta %} + {%- for Meta in MetaList %} + static const UClass* get_{{Meta}}(); + {%- endfor %} + static const UClass* GetMeta(Name name) { + {%- for Meta in MetaList %} + if (name == string_hash("{{Meta}}")) { + return get_{{Meta}}(); + } + {%- endfor %} + return nullptr; + } + {%- endif %} + }; +} \ No newline at end of file diff --git a/src/refl/template/meta_impl.liquid b/src/refl/template/meta_impl.liquid index d808ab1..1577660 100644 --- a/src/refl/template/meta_impl.liquid +++ b/src/refl/template/meta_impl.liquid @@ -1,9 +1,41 @@ -{{ Indent }}template<> struct MetaImpl<{{FullName}}>{ -{{ Indent }} using T = {{FullName}}; -{{ Indent }}{%- if HasMeta %} -{{ Indent }} using MyMeta = _Meta; -{{ Indent }}{%- endif %} -{{ Indent }}{%- if IsMultyMeta %} -{{ Indent }} using MyMetas = _Multy; -{{ Indent }}{%- endif %} -{{ Indent }}}; \ No newline at end of file +namespace gen{ + template<> struct MetaImpl<{{FullName}}, string_hash("{{MetaName}}")> : public refl::MetaHelp { + using T = {{FullName}}; + consteval static int MemberCount() { return {{MemberCount}}; }; + consteval static int CtorCount() { return {{CtorCount}}; }; + consteval static auto Fields(){ + return std::make_tuple({% for field in FieldList %}FProperty(&T::{{field.Name}},"{{field.Name}}"){% unless forloop.last %}, {% endunless %}{% endfor %}); + } + static auto MakeFields() { + return std::array{ + {%- for field in FieldList %} + {%- if field.Type == 1 %} + MemberField(&T::{{field.Name}}, FName("{{field.Name}}"), {{field.Meta}}), + {%- elsif field.Type == 2 %} + CtorField((T::{{field.Ref}})nullptr, {{field.Meta}}), + {%- elsif field.Type == 3 %} + MethodField(&T::{{field.Name}}, FName("{{field.Name}}"), {{field.Meta}}), + {%- else %} + MethodField((T::{{field.Ref}})&T::{{field.Name}}, FName("{{field.Name}}"), {{field.Meta}}), + {%- endif %} + {%- endfor %} + }; + }; + }; +} +{%- if MetaType == 1 %} +namespace refl{ + const UClass* Meta<{{FullName}}>::get_{{ MetaName }}() + { + static const UClass_Meta> s_cls{}; + return &s_cls; + }; +} +{%- elsif MetaType == 2 %} +namespace refl{ + inline const UClass* Meta<{{FullName}}>::get_{{ MetaName }}() + { + return &TypeInfo::StaticClass; + }; +} +{%- endif %} \ No newline at end of file diff --git a/src/refl/template/multy_meta.liquid b/src/refl/template/multy_meta.liquid deleted file mode 100644 index df111ea..0000000 --- a/src/refl/template/multy_meta.liquid +++ /dev/null @@ -1,14 +0,0 @@ -{{ Indent }}template<> struct _Multy<{{FullName}}>{ -{{ Indent }} using T = {{FullName}}; -{{ Indent }}{%- for Meta in MetaList %} -{{ Indent }} static const refl::UClass* get_{{Meta}}(); -{{ Indent }}{%- endfor %} -{{ Indent }} static const refl::UClass* GetMeta(const Name& name) { -{{ Indent }}{%- for Meta in MetaList %} -{{ Indent }} if (name == FName("{{Meta}}")) { -{{ Indent }} return get_{{Meta}}(); -{{ Indent }} } -{{ Indent }}{%- endfor %} -{{ Indent }} return nullptr; -{{ Indent }} } -{{ Indent }}}; \ No newline at end of file