static void GenCPP_StructTemplate(this StringBuilder sb, string templateName, List <Type> cs, TemplateLibrary.Filter <TemplateLibrary.CppFilter> filter) { cs = cs._GetStructs(); if (cs.Count == 0) { return; } sb.Append(@" namespace xx {"); foreach (var c in cs) { if (filter != null && !filter.Contains(c)) { continue; } sb.GenCPP_Serialize(templateName, c, false); sb.GenCPP_Deserialize(templateName, c, false); sb.GenCPP_StrAppends(templateName, c, false); sb.GenCPP_Cascades(templateName, c, false); } sb.Append(@" }"); // namespace xx sb.Append(@" namespace " + templateName + @" {"); for (int i = 0; i < cs.Count; ++i) { var c = cs[i]; if (filter != null && !filter.Contains(c)) { continue; } // namespace c_ns { if (c.Namespace != null && (i == 0 || (i > 0 && cs[i - 1].Namespace != c.Namespace))) // namespace 去重 { sb.Append(@" namespace " + c.Namespace.Replace(".", "::") + @" {"); } sb.GenCPP_CopyAssign(templateName, c); // namespace } if (c.Namespace != null && ((i < cs.Count - 1 && cs[i + 1].Namespace != c.Namespace) || i == cs.Count - 1)) { sb.Append(@" }"); } } sb.Append(@" }"); // namespace templateName }
static void GenH_StructTemplates(this StringBuilder sb, List <Type> cs, TemplateLibrary.TypeIds typeIds, TemplateLibrary.Filter <TemplateLibrary.CppFilter> filter, string templateName) { sb.Append(@" namespace xx {"); cs = cs._GetStructs(); foreach (var c in cs) { if (filter != null && !filter.Contains(c)) { continue; } var ctn = c._GetTypeDecl_Cpp(templateName); sb.Append(@" template<> struct BFuncs<" + ctn + @", void> { static void Serialize(Serializer& bb, " + ctn + @" const& in) noexcept; static int Deserialize(Deserializer& bb, " + ctn + @"& out) noexcept; }; template<> struct SFuncs<" + ctn + @", void> { static void Append(std::string& s, " + ctn + @" const& in) noexcept; static void AppendCore(std::string& s, " + ctn + @" const& in) noexcept; }; template<> struct CFuncs<" + ctn + @", void> { static int Cascade(void* const& o, " + ctn + @" const& in) noexcept; static int CascadeCore(void* const& o, " + ctn + @" const& in) noexcept; };"); } // 遍历所有 type 及成员数据类型 生成 Deserializer.Register< T >( typeId ) 函数组 foreach (var kv in typeIds.types) { if (filter != null && !filter.Contains(kv.Key)) { continue; } var ct = kv.Key; if (ct._IsString() || ct._IsData() || ct._IsExternal() && !ct._GetExternalSerializable()) { continue; } var typeId = kv.Value; var ctn = ct._GetTypeDecl_Cpp(templateName); sb.Append(@" template<> struct TypeId<" + ctn + @"> { static const uint16_t value = " + typeId + @"; };"); } sb.Append(@" }"); }
static void GenCpp_Registers(this StringBuilder sb, string templateName, TemplateLibrary.Filter <TemplateLibrary.CppFilter> filter, TemplateLibrary.TypeIds typeIds) { sb.Append(@" namespace " + templateName + @" { AllTypesRegister::AllTypesRegister() {" ); foreach (var kv in typeIds.types) { var ct = kv.Key; if (filter != null && !filter.Contains(ct)) { continue; } if (ct._IsString() || ct._IsData() || ct._IsExternal() && !ct._GetExternalSerializable()) { continue; } var ctn = ct._GetTypeDecl_Cpp(templateName); sb.Append(@" xx::Deserializer::Register<" + ctn + @">(" + kv.Value + @");"); } sb.Append(@" } } "); }
static void GenH_Predeclare(this StringBuilder sb, List <Type> cs, TemplateLibrary.Filter <TemplateLibrary.CppFilter> filter) { for (int i = 0; i < cs.Count; ++i) { var c = cs[i]; if (filter != null && !filter.Contains(c)) { continue; } if (c.Namespace != null && (i == 0 || (i > 0 && cs[i - 1].Namespace != c.Namespace))) // namespace 去重 { sb.Append(@" namespace " + c.Namespace.Replace(".", "::") + @" {"); } sb.Append(c._GetDesc()._GetComment_Cpp(4) + @" struct " + c.Name + @";"); // if (c._IsUserClass()) // { // sb.Append(@" // using " + c.Name + @"_s = std::shared_ptr<" + c.Name + @">; // using " + c.Name + @"_w = std::weak_ptr<" + c.Name + @">; //"); // } if (c.Namespace != null && ((i < cs.Count - 1 && cs[i + 1].Namespace != c.Namespace) || i == cs.Count - 1)) { sb.Append(@" }"); } } }
static void GenH_ClassAndStruct(this StringBuilder sb, List <Type> cs, string templateName, TemplateLibrary.Filter <TemplateLibrary.CppFilter> filter, Assembly asm) { for (int i = 0; i < cs.Count; ++i) { var c = cs[i]; if (filter != null && !filter.Contains(c)) { continue; } var o = asm.CreateInstance(c.FullName); if (c.Namespace != null && (i == 0 || (i > 0 && cs[i - 1].Namespace != c.Namespace))) // namespace 去重 { sb.Append(@" namespace " + c.Namespace.Replace(".", "::") + @" {"); } if (c._IsUserClass()) { sb.GenH_Class(c, templateName, o); } else { sb.GenH_Struct(c, templateName, o); } if (c.Namespace != null && ((i < cs.Count - 1 && cs[i + 1].Namespace != c.Namespace) || i == cs.Count - 1)) { sb.Append(@" }"); } } }
static void GenCPP_FuncImpls(this StringBuilder sb, string templateName, List <Type> cs, TemplateLibrary.Filter <TemplateLibrary.CppFilter> filter, TemplateLibrary.TypeIds typeIds) { sb.Append(@" namespace " + templateName + @" {"); cs = cs._GetClasss(); for (int i = 0; i < cs.Count; ++i) { var c = cs[i]; if (filter != null && !filter.Contains(c)) { continue; } // namespace c_ns { if (c.Namespace != null && (i == 0 || (i > 0 && cs[i - 1].Namespace != c.Namespace))) // namespace 去重 { sb.Append(@" namespace " + c.Namespace.Replace(".", "::") + @" {"); } sb.Append(@" uint16_t " + c.Name + @"::GetTypeId() const noexcept { return " + typeIds.types[c] + @"; }"); sb.GenCPP_CopyAssign(templateName, c); sb.GenCPP_Serialize(templateName, c); sb.GenCPP_Deserialize(templateName, c); sb.GenCPP_StrAppends(templateName, c); sb.GenCPP_Cascades(templateName, c); // namespace } if (c.Namespace != null && ((i < cs.Count - 1 && cs[i + 1].Namespace != c.Namespace) || i == cs.Count - 1)) { sb.Append(@" }"); } } sb.Append(@" }"); // namespace templateName }
static void GenH_Enums(this StringBuilder sb, List <Type> ts, TemplateLibrary.Filter <TemplateLibrary.CppFilter> filter) { var es = ts._GetEnums(); for (int i = 0; i < es.Count; ++i) { var e = es[i]; if (filter != null && !filter.Contains(e)) { continue; } if (e.Namespace != null && (i == 0 || (i > 0 && es[i - 1].Namespace != e.Namespace))) // namespace 去重 { sb.Append(@" namespace " + e.Namespace.Replace(".", "::") + @" {"); } sb.Append(e._GetDesc()._GetComment_Cpp(4) + @" enum class " + e.Name + @" : " + e._GetEnumUnderlyingTypeName_Cpp() + @" {"); var fs = e._GetEnumFields(); foreach (var f in fs) { sb.Append(f._GetDesc()._GetComment_Cpp(8) + @" " + f.Name + " = " + f._GetEnumValue(e) + ","); } sb.Append(@" };"); if (e.Namespace != null && ((i < es.Count - 1 && es[i + 1].Namespace != e.Namespace) || i == es.Count - 1)) { sb.Append(@" }"); } } }
public static bool Gen(Assembly asm, string outDir, string templateName, string md5, TemplateLibrary.Filter <TemplateLibrary.CppFilter> filter = null, bool generateBak = false) { var ts = asm._GetTypes(); var typeIds = new TemplateLibrary.TypeIds(asm); var sb = new StringBuilder(); var sb2 = new StringBuilder(); // template namespace sb.Append(@"#pragma once #include ""xx_bbuffer.h"" #include ""xx_pos.h"" #include ""xx_random.h"" #include """ + templateName + @"_class_partial.h"" namespace " + templateName + @" { struct PkgGenMd5 { inline static const std::string value = """ + md5 + @"""; }; struct AllTypesRegister { AllTypesRegister(); }; inline AllTypesRegister allTypesRegisterInstance; // for auto register at program startup "); var cs = ts._GetClasssStructs(); #if true for (int i = 0; i < cs.Count; ++i) { var c = cs[i]; if (filter != null && !filter.Contains(c)) { continue; } // namespace e_ns { if (c.Namespace != null && (i == 0 || (i > 0 && cs[i - 1].Namespace != c.Namespace))) // namespace 去重 { sb.Append(@" namespace " + c.Namespace.Replace(".", "::") + @" {"); } // desc // enum class xxxxxxxxx : underlyingType sb.Append(c._GetDesc()._GetComment_Cpp(4) + @" " + (c.IsValueType ? "struct" : "struct") + @" " + c.Name + @"; using " + c.Name + @"_s = std::shared_ptr<" + c.Name + @">; using " + c.Name + @"_w = std::weak_ptr<" + c.Name + @">; "); // namespace } if (c.Namespace != null && ((i < cs.Count - 1 && cs[i + 1].Namespace != c.Namespace) || i == cs.Count - 1)) { sb.Append(@" }"); } } #endif var es = ts._GetEnums(); for (int i = 0; i < es.Count; ++i) { var e = es[i]; if (filter != null && !filter.Contains(e)) { continue; } // namespace e_ns { if (e.Namespace != null && (i == 0 || (i > 0 && es[i - 1].Namespace != e.Namespace))) // namespace 去重 { sb.Append(@" namespace " + e.Namespace.Replace(".", "::") + @" {"); } // desc // enum class xxxxxxxxx : underlyingType sb.Append(e._GetDesc()._GetComment_Cpp(4) + @" enum class " + e.Name + @" : " + e._GetEnumUnderlyingTypeName_Cpp() + @" {"); // desc // xxxxxx = val var fs = e._GetEnumFields(); foreach (var f in fs) { sb.Append(f._GetDesc()._GetComment_Cpp(8) + @" " + f.Name + " = " + f._GetEnumValue(e) + ","); } // enum / sb.Append(@" };"); // namespace } if (e.Namespace != null && ((i < es.Count - 1 && es[i + 1].Namespace != e.Namespace) || i == es.Count - 1)) { sb.Append(@" }"); } } var ss = ts._GetStructs(); if (!generateBak) { ss._SortByInheritRelation(); } else { ss._SortByFullName(); } for (int i = 0; i < ss.Count; ++i) { var c = ss[i]; if (filter != null && !filter.Contains(c)) { continue; } var o = asm.CreateInstance(c.FullName); // namespace e_ns { if (c.Namespace != null && (i == 0 || (i > 0 && ss[i - 1].Namespace != c.Namespace))) // namespace 去重 { sb.Append(@" namespace " + c.Namespace.Replace(".", "::") + @" {"); } // desc // struct xxxxxxxxx sb.Append(c._GetDesc()._GetComment_Cpp(4) + @" struct " + c.Name + @" {"); // desc // T xxxxxx = val // consts( static ) / fields var fs = c._GetFieldsConsts(); foreach (var f in fs) { var ft = f.FieldType; var ftn = ft._GetTypeDecl_Cpp(templateName); sb.Append(f._GetDesc()._GetComment_Cpp(8) + @" " + (f.IsStatic ? "constexpr " : "") + ftn + " " + f.Name); var v = f.GetValue(f.IsStatic ? null : o); var dv = v._GetDefaultValueDecl_Cpp(templateName); if (dv != "" && !ft._IsList() && !ft._IsUserClass() && !ft._IsString() && !ft._IsObject() && !ft._IsWeak()) // 当前还无法正确处理 String 数据类型的默认值 { sb.Append(" = " + dv + ";"); } else { sb.Append(";"); } } if (c._Has <TemplateLibrary.AttachInclude>()) { sb.Append(@" #include<" + c._GetTypeDecl_Lua(templateName) + @".inc>"); } // struct / sb.Append(@" };"); // namespace } if (c.Namespace != null && ((i < ss.Count - 1 && ss[i + 1].Namespace != c.Namespace) || i == ss.Count - 1)) { sb.Append(@" }"); } } cs = ts._GetClasss(); if (!generateBak) { cs._SortByInheritRelation(); } else { cs._SortByFullName(); } // 预声明 for (int i = 0; i < cs.Count; ++i) { var c = cs[i]; if (filter != null && !filter.Contains(c)) { continue; } var o = asm.CreateInstance(c.FullName); // namespace c_ns { if (c.Namespace != null && (i == 0 || (i > 0 && cs[i - 1].Namespace != c.Namespace))) // namespace 去重 { sb.Append(@" namespace " + c.Namespace.Replace(".", "::") + @" {"); } // 定位到基类 var bt = c.BaseType; var btn = c._HasBaseType() ? bt._GetTypeDecl_Cpp(templateName) : "xx::Object"; // desc // T xxxxxxxxx = defaultValue // constexpr T xxxxxxxxx = defaultValue sb.Append(c._GetDesc()._GetComment_Cpp(4) + @" struct " + c.Name + @" : " + btn + @" {"); // consts( static ) / fields var fs = c._GetFieldsConsts(); foreach (var f in fs) { var ft = f.FieldType; var ftn = ft._GetTypeDecl_Cpp(templateName, "_s"); sb.Append(f._GetDesc()._GetComment_Cpp(8) + @" " + (f.IsStatic ? "constexpr " : "") + ftn + " " + f.Name); if (ft._IsExternal() && !ft._GetExternalSerializable() && !string.IsNullOrEmpty(ft._GetExternalCppDefaultValue())) { sb.Append(" = " + ft._GetExternalCppDefaultValue() + ";"); } else { var v = f.GetValue(f.IsStatic ? null : o); var dv = v._GetDefaultValueDecl_Cpp(templateName); if (dv != "" && !ft._IsList() && !(ft._IsUserClass()) && !ft._IsString() && !ft._IsNullable() && !ft._IsObject() && !ft._IsWeak()) // 当前还无法正确处理 String 数据类型的默认值 { sb.Append(" = " + dv + ";"); } else { sb.Append(";"); } } } var ms = c._GetMethods(); foreach (var m in ms) { var ps = m.GetParameters(); var rt = m.ReturnType; var rtn = rt._GetTypeDecl_Cpp(templateName, "_s"); sb.Append(m._GetDesc()._GetComment_Cpp(8) + @" virtual " + rtn + " " + m.Name + "("); foreach (var p in ps) { string attr = " "; if (p._Has <TemplateLibrary.ConstRef>()) { attr = " const& "; } if (p._Has <TemplateLibrary.PointerConstRef>()) { attr = "* const& "; } sb.Append(p._GetDesc()._GetComment_Cpp(12) + @" " + (p != ps[0] ? ", " : "") + p.ParameterType._GetTypeDecl_Cpp(templateName) + attr + p.Name); } sb.Append(") noexcept;"); } #if false sb.Append(@" typedef " + c.Name + @" ThisType; typedef " + btn + @" BaseType; " + c.Name + @"() = default; " + c.Name + @"(" + c.Name + @" const&) = delete; " + c.Name + @"& operator=(" + c.Name + @" const&) = delete; void ToString(std::string& s) const noexcept override; void ToStringCore(std::string& s) const noexcept override; uint16_t GetTypeId() const noexcept override; void ToBBuffer(xx::BBuffer& bb) const noexcept override; int FromBBuffer(xx::BBuffer& bb) noexcept override;"); if (c._Has <TemplateLibrary.CustomInitCascade>()) { sb.Append(@" int InitCascadeCore(void* const& o = nullptr) noexcept;"); } else { sb.Append(@" int InitCascade(void* const& o = nullptr) noexcept override;"); } #else if (c._Has <TemplateLibrary.CustomInitCascade>()) { sb.Append(@" XX_CODEGEN_CLASS_HEADER_CASCADE_CORE(" + c.Name + ", " + btn + @")"); } else { sb.Append(@" XX_CODEGEN_CLASS_HEADER_CASCADE(" + c.Name + ", " + btn + @")"); } #endif if (c._Has <TemplateLibrary.AttachInclude>()) { sb.Append(@" #include<" + c._GetTypeDecl_Lua(templateName) + @".inc>"); } sb.Append(@" };"); // class } // namespace } if (c.Namespace != null && ((i < cs.Count - 1 && cs[i + 1].Namespace != c.Namespace) || i == cs.Count - 1)) { sb.Append(@" }"); } } sb.Append(@" }"); // 结构体 Object 接口适配 sb.Append(@" namespace xx {"); cs = ts._GetStructs(); foreach (var c in cs) { if (filter != null && !filter.Contains(c)) { continue; } var ctn = c._GetTypeDecl_Cpp(templateName); var fs = c._GetFields(); sb.Append(@" template<> struct BFuncs<" + ctn + @", void> { static inline void WriteTo(BBuffer& bb, " + ctn + @" const& in) noexcept { bb.Write(" ); foreach (var f in fs) { if (!f._Has <TemplateLibrary.NotSerialize>()) { sb.Append((f == fs.First() ? "" : @", ") + "in." + f.Name); } else { sb.Append((f == fs.First() ? "" : @", ") + "decltype(in." + f.Name + ")()"); } } sb.Append(@"); } static inline int ReadFrom(BBuffer& bb, " + ctn + @"& out) noexcept { return bb.Read(" ); foreach (var f in fs) { sb.Append((f == fs.First() ? "" : @", ") + "out." + f.Name); } sb.Append(@"); } }; template<> struct SFuncs<" + ctn + @", void> { static inline void WriteTo(std::string& s, " + ctn + @" const& in) noexcept { xx::Append(s, ""{ \""structTypeName\"":\""" + (string.IsNullOrEmpty(c.Namespace) ? c.Name : c.Namespace + "." + c.Name) + @"\"""""); foreach (var f in fs) { sb.Append(@", "", \""" + f.Name + @"\"":"", in." + f.Name); } sb.Append(@", "" }""); } };"); } // 遍历所有 type 及成员数据类型 生成 BBuffer.Register< T >( typeId ) 函数组. 0 不能占. String 占掉 1. BBuffer 占掉 2. ( 这两个不生成 ) // 在基础命名空间中造一个静态类 AllTypes 静态方法 Register foreach (var kv in typeIds.types) { if (filter != null && !filter.Contains(kv.Key)) { continue; } var ct = kv.Key; if (ct._IsString() || ct._IsBBuffer() || ct._IsExternal() && !ct._GetExternalSerializable()) { continue; } var typeId = kv.Value; var ctn = ct._GetTypeDecl_Cpp(templateName); sb.Append(@" template<> struct TypeId<" + ctn + @"> { static const uint16_t value = " + typeId + @"; };"); } sb.Append(@" } #include ""xx_random.hpp"" "); // defines ( cpp ) sb2.Append(@"#include """ + templateName + "_class" + (filter != null ? "_filter" : "") + ".h" + @""" #include """ + templateName + @"_class_partial.hpp"" namespace " + templateName + @" {"); cs = ts._GetClasss(); //._SortByInheritRelation(); // 实现 for (int i = 0; i < cs.Count; ++i) { var c = cs[i]; if (filter != null && !filter.Contains(c)) { continue; } // namespace c_ns { if (c.Namespace != null && (i == 0 || (i > 0 && cs[i - 1].Namespace != c.Namespace))) // namespace 去重 { sb2.Append(@" namespace " + c.Namespace.Replace(".", "::") + @" {"); } var ms = c._GetMethods(); foreach (var m in ms) { var ps = m.GetParameters(); var rt = m.ReturnType; var rtn = rt._GetTypeDecl_Cpp(templateName, "_s"); sb2.Append(@" " + rtn + " " + c.Name + "::" + m.Name + "("); foreach (var p in ps) { string attr = " "; if (p._Has <TemplateLibrary.ConstRef>()) { attr = " const& "; } if (p._Has <TemplateLibrary.PointerConstRef>()) { attr = "* const& "; } sb2.Append(p._GetDesc()._GetComment_Cpp(12) + @" " + (p != ps[0] ? ", " : "") + p.ParameterType._GetTypeDecl_Cpp(templateName) + attr + p.Name); } sb2.Append(") noexcept {" + (rtn != "void" ? (" return " + rtn + "(); ") : "") + "}"); } // 定位到基类 var bt = c.BaseType; var fs = c._GetFields(); sb2.Append(@" uint16_t " + c.Name + @"::GetTypeId() const noexcept { return " + typeIds.types[c] + @"; } void " + c.Name + @"::ToBBuffer(xx::BBuffer& bb) const noexcept {"); if (c._HasBaseType()) { sb2.Append(@" this->BaseType::ToBBuffer(bb);"); } fs = c._GetFields(); foreach (var f in fs) { var ft = f.FieldType; if (ft._IsExternal() && !ft._GetExternalSerializable()) { continue; } if (f._Has <TemplateLibrary.NotSerialize>()) { sb2.Append(@" bb.Write(decltype(this->" + f.Name + ")());"); } else if (f._Has <TemplateLibrary.CustomSerialize>()) { // sb2.Append(@" //bb.CustomWrite(bb, (void*)this, _offsetof(ThisType, " + f.Name + "));"); throw new NotImplementedException(); } else { sb2.Append(@" bb.Write(this->" + f.Name + ");"); } } sb2.Append(@" } int " + c.Name + @"::FromBBuffer(xx::BBuffer& bb) noexcept {"); if (c._HasBaseType()) { sb2.Append(@" if (int r = this->BaseType::FromBBuffer(bb)) return r;"); } fs = c._GetFields(); foreach (var f in fs) { if (f.FieldType._IsExternal() && !f.FieldType._GetExternalSerializable()) { continue; } if (f.FieldType._IsContainer()) { sb2.Append(@" bb.readLengthLimit = " + f._GetLimit() + ";"); } sb2.Append(@" if (int r = bb.Read(this->" + f.Name + @")) return r;"); } sb2.Append(@" return 0; }"); if (c._Has <TemplateLibrary.CustomInitCascade>()) { sb2.Append(@" int " + c.Name + @"::InitCascadeCore(void* const& o) noexcept {"); } else { sb2.Append(@" int " + c.Name + @"::InitCascade(void* const& o) noexcept {"); } if (c._HasBaseType()) { sb2.Append(@" if (int r = this->BaseType::InitCascade(o)) return r;"); } fs = c._GetFields(); foreach (var f in fs) { var ft = f.FieldType; if (!ft._IsList() && !ft._IsUserClass() || ft._IsWeak() || ft._IsExternal() && !ft._GetExternalSerializable()) { continue; } sb2.Append(@" if (this->" + f.Name + @") { if (int r = this->" + f.Name + @"->InitCascade(o)) return r; }"); } sb2.Append(@" return 0; }"); sb2.Append(@" void " + c.Name + @"::ToString(std::string& s) const noexcept { if (this->toStringFlag) { xx::Append(s, ""[ \""***** recursived *****\"" ]""); return; } else this->SetToStringFlag(); xx::Append(s, ""{ \""pkgTypeName\"":\""" + (string.IsNullOrEmpty(c.Namespace) ? c.Name : c.Namespace + "." + c.Name) + @"\"", \""pkgTypeId\"":"", GetTypeId()); ToStringCore(s); xx::Append(s, "" }""); this->SetToStringFlag(false); } void " + c.Name + @"::ToStringCore(std::string& s) const noexcept { this->BaseType::ToStringCore(s);"); foreach (var f in fs) { if (f.FieldType._IsExternal() && !f.FieldType._GetExternalSerializable()) { continue; } if (f.FieldType._IsString()) { sb2.Append(@" if (this->" + f.Name + @") xx::Append(s, "", \""" + f.Name + @"\"":\"""", this->" + f.Name + @", ""\""""); else xx::Append(s, "", \""" + f.Name + @"\"":nil"");"); } else { sb2.Append(@" xx::Append(s, "", \""" + f.Name + @"\"":"", this->" + f.Name + @");"); } } sb2.Append(@" }"); // namespace } if (c.Namespace != null && ((i < cs.Count - 1 && cs[i + 1].Namespace != c.Namespace) || i == cs.Count - 1)) { sb2.Append(@" }"); } } sb2.Append(@" }"); sb2.Append(@" namespace " + templateName + @" { AllTypesRegister::AllTypesRegister() {" ); foreach (var kv in typeIds.types) { var ct = kv.Key; if (filter != null && !filter.Contains(ct)) { continue; } if (ct._IsString() || ct._IsBBuffer() || ct._IsExternal() && !ct._GetExternalSerializable()) { continue; } var ctn = ct._GetTypeDecl_Cpp(templateName); var bt = ct.BaseType; var btn = ct._HasBaseType() ? bt._GetTypeDecl_Cpp(templateName) : "xx::Object"; sb2.Append(@" xx::BBuffer::Register<" + ctn + @">(" + kv.Value + @");"); } sb2.Append(@" } } "); // 以命名空间排序版生成备份文件 用以对比是否发生改变. 如果.bak 经过生成对比发现无差异,就不必再生成了 if (generateBak) { var sb3 = new StringBuilder(); sb3.Append(sb); sb3.Append(sb2); return(sb3._WriteToFile(Path.Combine(outDir, templateName + "_class" + (filter != null ? "_filter" : "") + ".h.bak"))); } else if (!Gen(asm, outDir, templateName, "", filter, true)) { return(false); } // 如果无变化就退出。后面的都不必做了 // 开始写文件 // 追加子包含文件 foreach (var c in cs) { if (c._Has <TemplateLibrary.AttachInclude>()) { sb2.Append(@"#include <" + c._GetTypeDecl_Lua(templateName) + @".hpp> "); } } sb._WriteToFile(Path.Combine(outDir, templateName + "_class" + (filter != null ? "_filter" : "") + ".h")); sb2._WriteToFile(Path.Combine(outDir, templateName + "_class" + (filter != null ? "_filter" : "") + ".cpp")); sb.Clear(); foreach (var c in cs) { if (c._Has <TemplateLibrary.AttachInclude>()) { sb._WriteToFile(Path.Combine(outDir, c._GetTypeDecl_Lua(templateName) + ".inc")); sb._WriteToFile(Path.Combine(outDir, c._GetTypeDecl_Lua(templateName) + ".hpp")); } } sb._WriteToFile(Path.Combine(outDir, templateName + "_class_partial.h")); sb._WriteToFile(Path.Combine(outDir, templateName + "_class_partial.hpp")); return(true); }
public static void Gen(Assembly asm, string outDir, string templateName, string md5) { var filter = new TemplateLibrary.Filter <TemplateLibrary.LuaFilter>(asm); var sb = new StringBuilder(); sb.Append(@" " + templateName + @"_PkgGenMd5_Value = '" + md5 + @"' "); var ts = asm._GetTypes(); var es = ts._GetEnums(); for (int i = 0; i < es.Count; ++i) { var e = es[i]; if (!filter.Contains(e)) { continue; } var en = e._GetTypeDecl_Lua(templateName); sb.Append(e._GetDesc()._GetComment_Lua(0) + @" " + en + @" = {"); var fs = e._GetEnumFields(); foreach (var f in fs) { sb.Append(f._GetDesc()._GetComment_Lua(4) + @" " + f.Name + " = " + f._GetEnumValue(e) + ","); } sb.Length--; // enum / sb.Append(@" }"); } // 遍历所有 type 及成员数据类型 生成 typeId. 0 不能占. string 占掉 1. BBuffer 占掉 2. var typeIds = new TemplateLibrary.TypeIds(asm); foreach (var kv in typeIds.types) { if (kv.Key == typeof(string) || kv.Key == typeof(TemplateLibrary.BBuffer)) { continue; } var c = kv.Key; if (!filter.Contains(c)) { continue; } var typeId = (ushort)kv.Value; var cn = c._GetTypeDecl_Lua(templateName); var o = asm.CreateInstance(c.FullName); var fs = c._GetFieldsConsts(); sb.Append(c._GetDesc()._GetComment_Lua(0) + @" " + cn + @" = { typeName = """ + cn + @""", typeId = " + typeId + @", Create = function() local o = {} o.__proto = " + cn + @" o.__index = o o.__newindex = o o.__isReleased = false o.Release = function() o.__isReleased = true end "); if (!c._IsList()) { sb.Append(@" "); } foreach (var f in fs) { var ft = f.FieldType; if (o == null) { sb.Append(@" o." + f.Name + " = null"); } else { var v = f.GetValue(f.IsStatic ? null : o); var dv = v._GetDefaultValueDecl_Lua(templateName); sb.Append(f._GetDesc()._GetComment_Lua(8)); if (ft._IsWeak()) { sb.Append(@" o." + f.Name + @" = MakeWeak()"); } else if (dv != "") { sb.Append(@" o." + f.Name + @" = " + dv); } else { sb.Append(@" o." + f.Name + " = null"); } } sb.Append(" -- " + ft._GetTypeDecl_Lua(templateName)); } if (c._HasBaseType()) { var bt = c.BaseType._GetTypeDecl_Lua(templateName); sb.Append(@" setmetatable( o, " + bt + @".Create() )"); } sb.Append(@" return o end, FromBBuffer = function( bb, o )"); if (c._HasBaseType()) { var bt = c.BaseType._GetTypeDecl_Lua(templateName); sb.Append(@" local p = getmetatable( o ) p.__proto.FromBBuffer( bb, p )"); } var ftns = new Dictionary <string, int>(); foreach (var f in fs) { var ft = f.FieldType; var ftn = ft.IsEnum ? ft.GetEnumUnderlyingType().Name : ft._IsNumeric() ? ft.Name : "Object"; if (ft._IsBBuffer() || ft._IsString() || ft._IsWeak()) { ftn = "Object"; } if (ftn != "Object" && ft._IsNullable()) { ftn = "Nullable" + ftn; } if (ftns.ContainsKey(ftn)) { ftns[ftn]++; } else { ftns.Add(ftn, 1); } } foreach (var kvp in ftns) { if (kvp.Value > 1) { sb.Append(@" local Read" + kvp.Key + @" = bb.Read" + kvp.Key); } } foreach (var f in fs) { var ft = f.FieldType; var ftn = ft.IsEnum ? ft.GetEnumUnderlyingType().Name : ft._IsNumeric() ? ft.Name : "Object"; if (ft._IsBBuffer() || ft._IsString() || ft._IsWeak()) { ftn = "Object"; } if (ftn != "Object" && ft._IsNullable()) { ftn = "Nullable" + ftn; } if (ftns[ftn] > 1) { if (ft._IsWeak()) { sb.Append(@" o." + f.Name + @" = MakeWeak( Read" + ftn + @"( bb ) )"); } else { sb.Append(@" o." + f.Name + @" = Read" + ftn + @"( bb )"); } } else { if (ft._IsWeak()) { sb.Append(@" o." + f.Name + @" = MakeWeak( Read" + ftn + @"( bb ) )"); } else { sb.Append(@" o." + f.Name + @" = bb:Read" + ftn + @"()"); } } } if (c._IsList()) { var fn = "ReadObject"; var ct = c.GenericTypeArguments[0]; if (!ct._IsUserClass() && !ct._IsBBuffer() && !ct._IsString() && !ct._IsWeak()) { if (ct.IsEnum) { var ctn = ct.GetEnumUnderlyingType().Name; fn = "Read" + ctn; } else { if (ct._IsNullable()) { fn = "ReadNullable" + ct.GenericTypeArguments[0].Name; } else { fn = "Read" + ct.Name; } } } sb.Append(@" local len = bb:ReadUInt32() local f = BBuffer." + fn + @" for i = 1, len do o[ i ] = " + (ct._IsWeak() ? "MakeWeak( f( bb ) )" : "f( bb )") + @" end" ); } sb.Append(@" end, ToBBuffer = function( bb, o )"); if (c._HasBaseType()) { var bt = c.BaseType._GetTypeDecl_Lua(templateName); sb.Append(@" local p = getmetatable( o ) p.__proto.ToBBuffer( bb, p )"); } foreach (var kvp in ftns) { if (kvp.Value > 1) { sb.Append(@" local Write" + kvp.Key + @" = bb.Write" + kvp.Key); } } foreach (var f in fs) { var ft = f.FieldType; var ftn = ft.IsEnum ? ft.GetEnumUnderlyingType().Name : ft._IsNumeric() ? ft.Name : "Object"; if (ft._IsBBuffer() || ft._IsString() || ft._IsWeak()) { ftn = "Object"; } if (ftn != "Object" && ft._IsNullable()) { ftn = "Nullable" + ftn; } if (ftns[ftn] > 1) { sb.Append(@" Write" + ftn + @"( bb, o." + f.Name + (ft._IsWeak() ? ".Lock()" : "") + @" )"); } else { sb.Append(@" bb:Write" + ftn + @"( o." + f.Name + (ft._IsWeak() ? ".Lock()" : "") + @" )"); } } if (c._IsList()) { var fn = "WriteObject"; var ct = c.GenericTypeArguments[0]; if (!ct._IsUserClass() && !ct._IsBBuffer() && !ct._IsString() && !ct._IsWeak()) { if (ct.IsEnum) { var ctn = ct.GetEnumUnderlyingType().Name; fn = "Write" + ctn; } else { var ctn = ct.Name; fn = "Write" + ctn; } } sb.Append(@" local len = #o bb:WriteUInt32( len ) local f = BBuffer." + fn + @" for i = 1, len do f( bb, o[ i ]" + (ct._IsWeak() ? ".Lock()" : "") + @" ) end" ); } sb.Append(@" end } BBuffer.Register( " + cn + @" )"); } // 临时方案 sb.Replace("`1", ""); sb._WriteToFile(Path.Combine(outDir, templateName + "_class.lua"), 1); }
public static void Gen(Assembly asm, string outDir, string templateName, TemplateLibrary.Filter <TemplateLibrary.LuaFilter> filter) { var sb = new StringBuilder(); sb.Append(@" " + templateName + @"_PkgGenMd5_Value = '" + StringHelpers.MD5PlaceHolder + @"' "); var ts = asm._GetTypes(); var es = ts._GetEnums(); for (int i = 0; i < es.Count; ++i) { var e = es[i]; if (!filter.Contains(e)) { continue; } var en = e._GetTypeDecl_Lua(templateName); sb.Append(e._GetDesc()._GetComment_Lua(0) + @" " + en + @" = {"); var fs = e._GetEnumFields(); foreach (var f in fs) { sb.Append(f._GetDesc()._GetComment_Lua(4) + @" " + f.Name + " = " + f._GetEnumValue(e) + ","); } sb.Length--; // enum / sb.Append(@" }"); } // 遍历所有 type 及成员数据类型 生成 typeId var typeIds = new TemplateLibrary.TypeIds(asm); foreach (var kv in typeIds.types) { //if (kv.Key._IsString() || kv.Key._IsBBuffer()) continue; var c = kv.Key; if (!filter.Contains(c)) { continue; } var typeId = (ushort)kv.Value; var cn = c._GetTypeDecl_Lua(templateName); var o = asm.CreateInstance(c.FullName); if (c.FullName.IndexOf("EnterGameCatchFishLevelRoomSit_Success") >= 0) { Console.WriteLine(); } var fs = c._GetFieldsConsts(); sb.Append(c._GetDesc()._GetComment_Lua(0) + @" " + cn + @" = { typeName = """ + cn + @""", typeId = " + typeId + @", Create = function() local o = {} o.__proto = " + cn + @" o.__index = o o.__newindex = o "); if (!c._IsList()) { sb.Append(@" "); } foreach (var f in fs) { var ft = f.FieldType; if (o == null) { sb.Append(@" o." + f.Name + " = null"); } else { var v = f.GetValue(f.IsStatic ? null : o); var dv = v._GetDefaultValueDecl_Lua(templateName); sb.Append(f._GetDesc()._GetComment_Lua(8)); if (ft._IsWeak() || ft._IsUserStruct()) { throw new Exception("LUA does not support weak_ptr or struct"); } else if (dv != "") { sb.Append(@" o." + f.Name + @" = " + dv); } else { sb.Append(@" o." + f.Name + " = null"); } } sb.Append(" -- " + ft._GetTypeDecl_Lua(templateName)); } if (c._HasBaseType()) { var bt = c.BaseType._GetTypeDecl_Lua(templateName); sb.Append(@" setmetatable( o, " + bt + @".Create() )"); } sb.Append(@" return o end, FromBBuffer = function( bb, o )"); if (c._HasBaseType()) { var bt = c.BaseType._GetTypeDecl_Lua(templateName); sb.Append(@" local p = getmetatable( o ) p.__proto.FromBBuffer( bb, p )"); } var ftns = new Dictionary <string, int>(); foreach (var f in fs) { var ft = f.FieldType; var ftn = ""; if (ft._IsWeak() || ft._IsUserStruct()) { throw new Exception("LUA does not support weak_ptr or struct"); } if (ft._IsNullable()) { ftn = "Nullable" + ft.GenericTypeArguments[0].Name; } else { ftn = ft.IsEnum ? ft.GetEnumUnderlyingType().Name : ft._IsNumeric() ? ft.Name : "Object"; if (ft._IsData() || ft._IsString()) { ftn = "Object"; } } if (ftns.ContainsKey(ftn)) { ftns[ftn]++; } else { ftns.Add(ftn, 1); } } foreach (var kvp in ftns) { if (kvp.Value > 1) { sb.Append(@" local Read" + kvp.Key + @" = bb.Read" + kvp.Key); } } foreach (var f in fs) { var ft = f.FieldType; var ftn = ""; if (ft._IsWeak() || ft._IsUserStruct()) { throw new Exception("LUA does not support weak_ptr or struct"); } if (ft._IsNullable()) { ftn = "Nullable" + ft.GenericTypeArguments[0].Name; } else { ftn = ft.IsEnum ? ft.GetEnumUnderlyingType().Name : ft._IsNumeric() ? ft.Name : "Object"; if (ft._IsData() || ft._IsString()) { ftn = "Object"; } } if (ftns[ftn] > 1) { sb.Append(@" o." + f.Name + @" = Read" + ftn + @"( bb )"); } else { sb.Append(@" o." + f.Name + @" = bb:Read" + ftn + @"()"); } } if (c._IsList()) { var fn = "ReadObject"; var ct = c.GenericTypeArguments[0]; if (ct._IsWeak() || ct._IsUserStruct()) { throw new Exception("LUA does not support weak_ptr or struct"); } if (!ct._IsUserClass() && !ct._IsData() && !ct._IsString()) { if (ct.IsEnum) { var ctn = ct.GetEnumUnderlyingType().Name; fn = "Read" + ctn; } else { if (ct._IsNullable()) { fn = "ReadNullable" + ct.GenericTypeArguments[0].Name; } else { fn = "Read" + ct.Name; } } } sb.Append(@" local len = bb:ReadUInt32() local f = BBuffer." + fn + @" for i = 1, len do o[ i ] = f( bb ) end" ); } sb.Append(@" end, Serialize = function( bb, o )"); if (c._HasBaseType()) { var bt = c.BaseType._GetTypeDecl_Lua(templateName); sb.Append(@" local p = getmetatable( o ) p.__proto.Serialize( bb, p )"); } foreach (var kvp in ftns) { if (kvp.Value > 1) { sb.Append(@" local Write" + kvp.Key + @" = bb.Write" + kvp.Key); } } foreach (var f in fs) { var ft = f.FieldType; var ftn = ""; if (ft._IsWeak() || ft._IsUserStruct()) { throw new Exception("LUA does not support weak_ptr or struct"); } if (ft._IsNullable()) { ftn = "Nullable" + ft.GenericTypeArguments[0].Name; } else { ftn = ft.IsEnum ? ft.GetEnumUnderlyingType().Name : ft._IsNumeric() ? ft.Name : "Object"; if (ft._IsData() || ft._IsString()) { ftn = "Object"; } } if (ftns[ftn] > 1) { sb.Append(@" Write" + ftn + @"( bb, o." + f.Name + @" )"); } else { sb.Append(@" bb:Write" + ftn + @"( o." + f.Name + @" )"); } } if (c._IsList()) { var fn = "WriteObject"; var ct = c.GenericTypeArguments[0]; if (!ct._IsUserClass() && !ct._IsData() && !ct._IsString()) { if (ct.IsEnum) { var ctn = ct.GetEnumUnderlyingType().Name; fn = "Write" + ctn; } else { var ctn = ct.Name; fn = "Write" + ctn; } } sb.Append(@" local len = #o bb:WriteUInt32( len ) local f = BBuffer." + fn + @" for i = 1, len do f( bb, o[ i ]" + @" ) end" ); } sb.Append(@" end } BBuffer.Register( " + cn + @" )"); } // 临时方案 sb.Replace("`1", ""); sb._WriteToFile(Path.Combine(outDir, templateName + "_class.lua")); }