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(@" }"); }
public static void Gen(Assembly asm, string outDir, string templateName, TemplateLibrary.Filter <TemplateLibrary.CppFilter> filter = null) { var ts = asm._GetTypes(); var typeIds = new TemplateLibrary.TypeIds(asm); var sb = new StringBuilder(); var cs = ts._GetClasssStructs(); cs._SortByInheritRelation(); // 生成 .h sb.GenH_Include(templateName); sb.GenH_RootNamespace(templateName); sb.GenH_PkgGenMd5(templateName); sb.GenH_Enums(ts, filter); sb.GenH_Predeclare(cs, filter); sb.GenH_ClassAndStruct(cs, templateName, filter, asm); sb.GenH_RootNamespaceEnd(); sb.GenH_StructTemplates(cs, typeIds, filter, templateName); sb.GenH_IncludeEnd(cs, templateName, filter); sb._WriteToFile(Path.Combine(outDir, templateName + "_class" + (filter != null ? "_filter" : "") + ".h")); // 生成 .cpp sb.Clear(); sb.GenCPP_Include(templateName, filter, cs); sb.GenCPP_StructTemplate(templateName, cs, filter); sb.GenCPP_FuncImpls(templateName, cs, filter, typeIds); sb.GenCpp_Registers(templateName, filter, typeIds); sb._WriteToFile(Path.Combine(outDir, templateName + "_class" + (filter != null ? "_filter" : "") + ".cpp")); // 生成 .inc, hpp sb.Clear(); sb.GenInc(); sb._WriteToFile(Path.Combine(outDir, templateName + "_class" + (filter != null ? "_filter" : "") + ".inc")); sb.Clear(); sb.GenIncEnd(); sb._WriteToFile(Path.Combine(outDir, templateName + "_class_end" + (filter != null ? "_filter" : "") + ".inc")); sb.Clear(); sb._WriteToFile(Path.Combine(outDir, templateName + "_class" + (filter != null ? "_filter" : "") + ".hpp")); // 生成 里面的类.inc .hpp sb.Clear(); foreach (var c in cs) { if (c._Has <TemplateLibrary.Include>()) { sb._WriteToFile(Path.Combine(outDir, c._GetTypeDecl_Lua(templateName) + ".inc")); sb._WriteToFile(Path.Combine(outDir, c._GetTypeDecl_Lua(templateName) + ".hpp")); } } }
public static bool Gen(Assembly asm, string outDir, string templateName) { var typeIds = new TemplateLibrary.TypeIds(asm); if (typeIds.typeIdMappingsExists && !typeIds.hasNewMappings) { return(true); } var sb = new StringBuilder(); sb.Append(@"#pragma warning disable 0169, 0414 using TemplateLibrary; [TypeIdMappings] interface ITypeIdMappings {"); int count = 0; foreach (var kv in typeIds.types) { if (kv.Key == typeof(string) || kv.Key == typeof(TemplateLibrary.BBuffer) ) { continue; } var typeId = (ushort)kv.Value; var c = kv.Key; var cn = c._GetTypeDecl_GenTypeIdTemplate(); sb.Append(@" " + cn + @" _" + typeId + @" { get; } "); ++count; } sb.Append(@" } "); if (count == 0) { return(true); } sb._WriteToFile(Path.Combine(outDir, templateName + "_TypeIdMappings.cs")); return(false); }
public static void Gen(Assembly asm, string outDir, string templateName, string md5) { var sb = new StringBuilder(); // usings sb.Append(@"using System;"); // template namespace sb.Append(@" namespace " + templateName + @" { public static class PkgGenMd5 { public const string value = """ + md5 + @"""; } "); var ts = asm._GetTypes(); // 找出所有成员含 Column 标记的类 var sqlcs = ts._GetClasss().Where(a => a._GetFields().Any(b => b._Has <TemplateLibrary.Column>())).ToList(); var es = ts._GetEnums(); for (int i = 0; i < es.Count; ++i) { var e = es[i]; // namespace e_ns { if (e.Namespace != null && (i == 0 || (i > 0 && es[i - 1].Namespace != e.Namespace))) // namespace 去重 { sb.Append(@" namespace " + e.Namespace + @" {"); } // desc // public enum xxxxxxxxx : underlyingType sb.Append(e._GetDesc()._GetComment_CSharp(4) + @" public enum " + e.Name + @" : " + e._GetEnumUnderlyingTypeName_Csharp() + @" {"); // desc // xxxxxx = val var fs = e._GetEnumFields(); foreach (var f in fs) { sb.Append(f._GetDesc()._GetComment_CSharp(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 cs = ts._GetClasssStructs(); for (int i = 0; i < cs.Count; ++i) { var c = cs[i]; 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 + @" {"); } // desc // public T xxxxxxxxx = defaultValue // public const T xxxxxxxxx = defaultValue if (c.IsValueType) { sb.Append(c._GetDesc()._GetComment_CSharp(4) + @" public partial struct " + c.Name + @" : xx.IObject {"); } else { sb.Append(c._GetDesc()._GetComment_CSharp(4) + @" public partial class " + c.Name + @" : " + c.BaseType._GetTypeDecl_Csharp() + @" {"); } // consts( static ) / fields var fs = c._GetFieldsConsts(); foreach (var f in fs) { var ft = f.FieldType; var ftn = ft._GetTypeDecl_Csharp(); sb.Append(f._GetDesc()._GetComment_CSharp(8) + @" public " + (f.IsStatic ? "const " : "") + ftn + " " + f.Name); var v = f.GetValue(f.IsStatic ? null : o); var dv = v._GetDefaultValueDecl_Csharp(); if (dv != "") { sb.Append(" = " + dv + ";"); } //else if (f._Has<TemplateLibrary.CreateInstance>()) //{ // sb.Append(" = new " + ftn + "();"); //} else { sb.Append(";"); } } sb.Append(@" public" + (c.IsValueType ? "" : " override") + @" ushort GetPackageId() { return xx.TypeId<" + c.Name + @">.value; } public" + (c.IsValueType ? "" : " override") + @" void ToBBuffer(xx.BBuffer bb) {"); if (!c.IsValueType && c._HasBaseType()) { sb.Append(@" base.ToBBuffer(bb);"); } fs = c._GetFields(); foreach (var f in fs) { if (f.FieldType._IsExternal() && !f.FieldType._GetExternalSerializable()) { continue; } var ft = f.FieldType; if (f._Has <TemplateLibrary.NotSerialize>()) { sb.Append(@" bb.Write(default(" + f.FieldType._GetTypeDecl_Csharp() + "));"); } else if (f._Has <TemplateLibrary.CustomSerialize>()) { sb.Append(@" bb.CustomWrite(bb, this, """ + f.Name + @""");"); } else if (ft.IsEnum) { sb.Append(@" bb.Write((" + ft._GetEnumUnderlyingTypeName_Csharp() + ")this." + f.Name + ");"); } else if (!ft._IsNullable() && ft.IsValueType && !ft.IsPrimitive) { sb.Append(@" ((xx.IObject)this." + f.Name + ").ToBBuffer(bb);"); } else { sb.Append(@" bb.Write(this." + f.Name + ");"); } } sb.Append(@" } public" + (c.IsValueType ? "" : " override") + @" void FromBBuffer(xx.BBuffer bb) {"); if (!c.IsValueType && c._HasBaseType()) { sb.Append(@" base.FromBBuffer(bb);"); } fs = c._GetFields(); foreach (var f in fs) { if (f.FieldType._IsExternal() && !f.FieldType._GetExternalSerializable()) { continue; } var ft = f.FieldType; if (ft.IsEnum) { var ftn = ft._GetTypeDecl_Csharp(); var etn = ft._GetEnumUnderlyingTypeName_Csharp(); sb.Append(@" { " + etn + @" tmp = 0; bb.Read(ref tmp); this." + f.Name + @" = (" + ftn + @")tmp; }"); } else if (!ft._IsNullable() && ft.IsValueType && !ft.IsPrimitive) { sb.Append(@" ((xx.IObject)this." + f.Name + ").FromBBuffer(bb);"); } else { if (ft._IsContainer()) { sb.Append(@" bb.readLengthLimit = " + f._GetLimit() + ";"); } sb.Append(@" bb.Read(ref this." + f.Name + ");"); } } sb.Append(@" } public" + (c.IsValueType ? "" : " override") + @" void ToString(System.Text.StringBuilder s) {"); if (!c.IsValueType) { sb.Append(@" if (__toStringing) { s.Append(""[ \""***** recursived *****\"" ]""); return; } else __toStringing = true; "); } sb.Append(@" s.Append(""{ \""pkgTypeName\"":\""" + (string.IsNullOrEmpty(c.Namespace) ? c.Name : c.Namespace + "." + c.Name) + @"\"", \""pkgTypeId\"":"" + GetPackageId()); ToStringCore(s); s.Append("" }"");"); if (!c.IsValueType) { sb.Append(@" __toStringing = false;"); } sb.Append(@" } public" + (c.IsValueType ? "" : " override") + @" void ToStringCore(System.Text.StringBuilder s) {" + (c._HasBaseType() ? @" base.ToStringCore(s);" : "")); foreach (var f in fs) { var ft = f.FieldType; if (ft._IsExternal() && !ft._GetExternalSerializable()) { continue; } if (ft._IsString()) { sb.Append(@" if (" + f.Name + @" != null) s.Append("", \""" + f.Name + @"\"":\"""" + " + f.Name + @".ToString() + ""\""""); else s.Append("", \""" + f.Name + @"\"":nil"");"); } else if (ft._IsNullable()) { sb.Append(@" s.Append("", \""" + f.Name + @"\"":"" + (" + f.Name + @".HasValue ? " + f.Name + @".Value.ToString() : ""nil""));"); } else if (ft._IsUserClass() || ft._IsString() || ft._IsList()) // todo: 进一步判断所有可能为空的 { sb.Append(@" s.Append("", \""" + f.Name + @"\"":"" + (" + f.Name + @" == null ? ""nil"" : " + f.Name + @".ToString()));"); } else { sb.Append(@" s.Append("", \""" + f.Name + @"\"":"" + " + f.Name + @".ToString());"); } } sb.Append(@" } public override string ToString() { var sb = new System.Text.StringBuilder(); ToString(sb); return sb.ToString(); }"); if (!c.IsValueType) { sb.Append(@" public override void MySqlAppend(System.Text.StringBuilder sb, bool ignoreReadOnly) {"); if (sqlcs.Contains(c)) { sb.Append(@" sb.Append(""("");"); foreach (var m in fs) { if (!m._Has <TemplateLibrary.Column>()) { continue; } if (m._IsReadOnly()) { sb.Append(@" if (!ignoreReadOnly) {"); } var mt = m.FieldType; var mtn = mt._GetTypeDecl_Csharp(); if (mt._IsUserClass()) { throw new Exception("column is Object, unsupported now."); } else if (mt._IsString()) { sb.Append(@" sb.Append(this." + m.Name + @" == null ? ""null"" : (""'"" + this." + m.Name + @".Replace(""'"", ""''"") + ""'""));"); } else if (mt.IsEnum) { sb.Append(@" sb.Append(" + "(" + mt._GetEnumUnderlyingTypeName_Csharp() + ")this." + m.Name + @");"); } else if (mt._IsNullable()) { sb.Append(@" sb.Append(this." + m.Name + @".HasValue ? this." + m.Name + @".Value.ToString() : ""null"");"); } else { sb.Append(@" sb.Append(this." + m.Name + @");"); } sb.Append(@" sb.Append("", "");"); if (m._IsReadOnly()) { sb.Append(@" }"); } } sb.Append(@" sb.Length -= 2; sb.Append("")""); "); } else { if (c._HasBaseType()) { sb.Append(@" base.MySqlAppend(sb, ignoreReadOnly);"); } } sb.Append(@" }"); } // todo: ToString support // class / sb.Append(@" }"); // namespace } if (c.Namespace != null && ((i < cs.Count - 1 && cs[i + 1].Namespace != c.Namespace) || i == cs.Count - 1)) { sb.Append(@" }"); } } // 遍历所有 type 及成员数据类型 生成 BBuffer.Register< T >( typeId ) 函数组. 0 不能占. string 占掉 1. BBuffer 占掉 2. // 在基础命名空间中造一个静态类 AllTypes 静态方法 Register var typeIds = new TemplateLibrary.TypeIds(asm); sb.Append(@" public static class AllTypes { public static void Register() { xx.Object.RegisterInternals();"); foreach (var kv in typeIds.types) { var ct = kv.Key; if (ct._IsString() || ct._IsBBuffer() || ct._IsExternal() && !ct._GetExternalSerializable()) { continue; } var ctn = ct._GetTypeDecl_Cpp(templateName); var typeId = kv.Value; sb.Append(@" xx.Object.Register<" + ct._GetTypeDecl_Csharp() + @">(" + typeId++ + ");"); } sb.Append(@" } }"); // template namespace / sb.Append(@" } "); sb._WriteToFile(Path.Combine(outDir, templateName + "_class.cs"), 1); }
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 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 }
public static void Gen(Assembly asm, string outDir, string templateName, string md5) { var sb = new StringBuilder(); // template namespace sb.Append(@"#pragma once #include ""xx_list.h"" namespace " + templateName + @" { struct PkgGenMd5 { inline static const std::string value = """ + md5 + @"""; }; "); var ts = asm._GetTypes(); // predefines var cs = ts._GetClasssStructs(); for (int i = 0; i < cs.Count; ++i) { var c = cs[i]; // 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(@" }"); } } var es = ts._GetEnums(); for (int i = 0; i < es.Count; ++i) { var e = es[i]; // 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()._SortByInheritRelation(); for (int i = 0; i < ss.Count; ++i) { var c = ss[i]; 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._IsRef()) // 当前还无法正确处理 String 数据类型的默认值 { sb.Append(" = " + dv + ";"); } else { sb.Append(";"); } } // 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()._SortByInheritRelation(); // 预声明 for (int i = 0; i < cs.Count; ++i) { var c = cs[i]; 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._IsRef()) // 当前还无法正确处理 String 数据类型的默认值 { sb.Append(" = " + dv + ";"); } else { sb.Append(";"); } } } 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; virtual uint16_t GetTypeId() const noexcept; void ToBBuffer(xx::BBuffer& bb) const noexcept override; int FromBBuffer(xx::BBuffer& bb) noexcept override; int FromBBufferCore(xx::BBuffer& bb) noexcept; static std::shared_ptr<" + c.Name + @"> MakeShared() noexcept; inline static std::shared_ptr<ThisType> defaultInstance; };"); // 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) { 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); } } 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 var typeIds = new TemplateLibrary.TypeIds(asm); foreach (var kv in typeIds.types) { 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(@" } namespace " + templateName + @" {"); cs = ts._GetClasss(); //._SortByInheritRelation(); // 实现 for (int i = 0; i < cs.Count; ++i) { var c = cs[i]; 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"; var fs = c._GetFields(); sb.Append(@" inline uint16_t " + c.Name + @"::GetTypeId() const noexcept { return " + typeIds.types[c] + @"; } inline void " + c.Name + @"::ToBBuffer(xx::BBuffer& bb) const noexcept {"); if (c._HasBaseType()) { sb.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>()) { // sb.Append(@" //bb.WriteDefaultValue<" + ft._GetTypeDecl_Cpp(templateName, "_s") + ">();"); } else if (f._Has <TemplateLibrary.CustomSerialize>()) { // sb.Append(@" //bb.CustomWrite(bb, (void*)this, _offsetof(ThisType, " + f.Name + "));"); throw new NotImplementedException(); } else { sb.Append(@" bb.Write(this->" + f.Name + ");"); } } sb.Append(@" } inline int " + c.Name + @"::FromBBuffer(xx::BBuffer& bb) noexcept {"); if (c._HasBaseType()) { sb.Append(@" if (int r = this->BaseType::FromBBuffer(bb)) return r;"); } sb.Append(@" return this->FromBBufferCore(bb); } inline int " + c.Name + @"::FromBBufferCore(xx::BBuffer& bb) noexcept {"); fs = c._GetFields(); foreach (var f in fs) { if (f.FieldType._IsExternal() && !f.FieldType._GetExternalSerializable()) { continue; } if (f.FieldType._IsContainer()) { sb.Append(@" bb.readLengthLimit = " + f._GetLimit() + ";"); } sb.Append(@" if (int r = bb.Read(this->" + f.Name + @")) return r;"); } sb.Append(@" return 0; } inline 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); } inline 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()) { sb.Append(@" if (this->" + f.Name + @") xx::Append(s, "", \""" + f.Name + @"\"":\"""", this->" + f.Name + @", ""\""""); else xx::Append(s, "", \""" + f.Name + @"\"":nil"");"); } else { sb.Append(@" xx::Append(s, "", \""" + f.Name + @"\"":"", this->" + f.Name + @");"); } } sb.Append(@" } inline std::shared_ptr<" + c.Name + @"> " + c.Name + @"::MakeShared() noexcept { return std::make_shared<" + c.Name + @">(); }"); // namespace } if (c.Namespace != null && ((i < cs.Count - 1 && cs[i + 1].Namespace != c.Namespace) || i == cs.Count - 1)) { sb.Append(@" }"); } } sb.Append(@" }"); sb.Append(@" namespace " + templateName + @" { inline void AllTypesRegister() noexcept {" ); foreach (var kv in typeIds.types) { var ct = kv.Key; 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"; sb.Append(@" xx::BBuffer::Register<" + ctn + @">(" + kv.Value + @");"); } sb.Append(@" } } "); var outFN = Path.Combine(outDir, templateName + "_class.h"); sb._WriteToFile(outFN); System.Console.WriteLine("已生成 " + outFN); }
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")); }