【特性】完善 db cs 生成

main
walon 2020-11-17 17:11:35 +08:00
parent 3c34affab2
commit 5deb0427ca
27 changed files with 960 additions and 1170 deletions

View File

@ -59,7 +59,15 @@ namespace Luban.Common.Utils
public static string MakeFullName(string module, string name)
{
return module != null && module.Length > 0 ? module + "." + name : name;
if (string.IsNullOrEmpty(module))
{
return name;
}
if (string.IsNullOrEmpty(name))
{
return module;
}
return module + "." + name;
}
public static string MakeGoPkgName(string module)

View File

@ -161,11 +161,11 @@ namespace Luban.Job.Common.Defs
private void AddModule(XElement me)
{
var name = XmlUtil.GetRequiredAttribute(me, "name");
if (string.IsNullOrEmpty(name))
{
throw new LoadDefException($"xml:{CurImportFile} contains module which's name is empty");
}
var name = XmlUtil.GetOptionalAttribute(me, "name");
//if (string.IsNullOrEmpty(name))
//{
// throw new LoadDefException($"xml:{CurImportFile} contains module which's name is empty");
//}
_namespaceStack.Push(_namespaceStack.Count > 0 ? TypeUtil.MakeFullName(_namespaceStack.Peek(), name) : name);

View File

@ -6,6 +6,11 @@ namespace Luban.Job.Common.Defs
{
public class TTypeTemplateCommonExtends : ScriptObject
{
public static string TagName(TType type)
{
return type.Apply(TagNameVisitor.Ins);
}
public static bool CsNeedInit(TType type)
{
return type.Apply(CsNeedInitVisitor.Ins);

View File

@ -0,0 +1,129 @@
using Luban.Job.Common.Types;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Luban.Job.Common.TypeVisitors
{
public class TagNameVisitor : ITypeFuncVisitor<string>
{
public static TagNameVisitor Ins { get; } = new TagNameVisitor();
public string Accept(TBool type)
{
return "BOOL";
}
public string Accept(TByte type)
{
return "BYTE";
}
public string Accept(TShort type)
{
return "SHORT";
}
public string Accept(TFshort type)
{
return "FSHORT";
}
public string Accept(TInt type)
{
return "INT";
}
public string Accept(TFint type)
{
return "FINT";
}
public string Accept(TLong type)
{
return "LONG";
}
public string Accept(TFlong type)
{
return "FLONG";
}
public string Accept(TFloat type)
{
return "FLOAT";
}
public string Accept(TDouble type)
{
return "DOUBLE";
}
public string Accept(TEnum type)
{
return "INT";
}
public string Accept(TString type)
{
return "STRING";
}
public string Accept(TBytes type)
{
return "BYTES";
}
public string Accept(TText type)
{
return "STRING";
}
public string Accept(TBean type)
{
return "BEAN";
}
public string Accept(TArray type)
{
return "ARRAY";
}
public string Accept(TList type)
{
return "LIST";
}
public string Accept(TSet type)
{
return "SET";
}
public string Accept(TMap type)
{
return "MAP";
}
public string Accept(TVector2 type)
{
return "VECTOR2";
}
public string Accept(TVector3 type)
{
return "VECTOR3";
}
public string Accept(TVector4 type)
{
return "VECTOR4";
}
public string Accept(TDateTime type)
{
return "INT";
}
}
}

View File

@ -21,7 +21,14 @@ namespace Luban.Job.Db.Defs
public Defines BuildDefines()
{
return new Defines();
return new Defines()
{
TopModule = TopModule,
Consts = _consts,
Enums = _enums,
Beans = _beans,
DbTables = _tables,
};
}

View File

@ -3,6 +3,7 @@ using Luban.Job.Db.RawDefs;
using Luban.Server.Common;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Luban.Job.Db.Defs
{
@ -104,6 +105,9 @@ namespace Luban.Job.Db.Defs
}
}
public List<DefTypeBase> GetExportTypes()
{
return Types.Values.ToList();
}
}
}

View File

@ -1,142 +1,27 @@
using Luban.Job.Common.Defs;
using Luban.Job.Common.RawDefs;
using Luban.Job.Db.TypeVisitors;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Luban.Job.Db.Defs
{
class DefBean : DbDefTypeBase
class DefBean : DefBeanBase
{
public const string TYPE_NAME_KEY = "__type__";
public bool IsBean => true;
public string Parent { get; }
public bool IsValueType { get; }
public bool IsMultiRow { get; set; }
public DefBean ParentDefType { get; protected set; }
public DefBean RootDefType => this.ParentDefType == null ? this : this.ParentDefType.RootDefType;
public bool IsSerializeCompatible { get; }
public List<DefBean> Children { get; private set; }
public List<DefBean> HierarchyNotAbstractChildren { get; private set; }
public bool IsNotAbstractType => Children == null;
public bool IsAbstractType => Children != null;
public List<DefField> HierarchyFields { get; private set; } = new List<DefField>();
public List<DefField> Fields { get; } = new List<DefField>();
public string CsClassModifier => IsAbstractType ? "abstract" : "sealed";
public string CsMethodModifier => ParentDefType != null ? "override" : (IsAbstractType ? "virtual" : "");
public DefBean(Bean b)
public DefBean(Bean b) : base(b)
{
Name = b.Name;
Namespace = b.Namespace;
Parent = b.Parent;
Id = b.TypeId;
IsValueType = b.IsValueType;
foreach (var field in b.Fields)
{
Fields.Add(new DefField(this, field, 0));
}
}
private void CollectHierarchyNotAbstractChildren(List<DefBean> children)
protected override DefFieldBase CreateField(Field f, int idOffset)
{
if (IsAbstractType)
{
foreach (var c in Children)
{
c.CollectHierarchyNotAbstractChildren(children);
}
}
else
{
children.Add(this);
}
}
internal DefBean GetNotAbstractChildType(string typeNameOrAliasName)
{
if (string.IsNullOrWhiteSpace(typeNameOrAliasName))
{
return null;
}
foreach (var c in HierarchyNotAbstractChildren)
{
if (c.Name == typeNameOrAliasName)
{
return c;
}
}
return null;
}
internal DefField GetField(string index)
{
return HierarchyFields.Where(f => f.Name == index).FirstOrDefault();
}
internal bool TryGetField(string index, out DefField field, out int fieldIndexId)
{
for (int i = 0; i < HierarchyFields.Count; i++)
{
if (HierarchyFields[i].Name == index)
{
field = HierarchyFields[i];
fieldIndexId = i;
return true;
}
}
field = null;
fieldIndexId = 0;
return false;
}
private void CollectHierarchyFields(List<DefField> fields)
{
if (ParentDefType != null)
{
ParentDefType.CollectHierarchyFields(fields);
}
fields.AddRange(Fields);
}
public override void PreCompile()
{
var agent = AssemblyBase.Agent;
agent.Trace("compile bean module:{0} name:{1} begin", Namespace, Name);
if (!string.IsNullOrEmpty(Parent))
{
if ((ParentDefType = (DefBean)Assembly.GetDefType(Namespace, Parent)) == null)
{
throw new Exception($"bean:{FullName} parent:{Parent} not exist");
}
if (ParentDefType.Children == null)
{
ParentDefType.Children = new List<DefBean>();
}
ParentDefType.Children.Add(this);
}
CollectHierarchyFields(HierarchyFields);
return new DefField(this, f, idOffset);
}
public override void Compile()
{
var agent = AssemblyBase.Agent;
var cs = new List<DefBean>();
var cs = new List<DefBeanBase>();
if (Children != null)
{
CollectHierarchyNotAbstractChildren(cs);
@ -158,25 +43,17 @@ namespace Luban.Job.Db.Defs
}
DefField.CompileFields(this, HierarchyFields, true);
if (IsValueType && HierarchyFields.Any(f => f.CType.NeedSetChildrenRoot()))
{
foreach (var f in Fields)
{
if (f.CType.NeedSetChildrenRoot())
{
throw new Exception($"bean:{FullName} value type field:{f.Name} must be primitive type");
}
}
//if (IsValueType && HierarchyFields.Any(f => f.CType.Apply(NeedSetChildrenRootVisitor.Ins)))
//{
// foreach (var f in Fields)
// {
// if (f.CType.Apply(NeedSetChildrenRootVisitor.Ins))
// {
// throw new Exception($"bean:{FullName} value type field:{f.Name} must be primitive type");
// }
// }
}
}
public override void PostCompile()
{
foreach (var field in HierarchyFields)
{
field.PostCompile();
}
//}
}
}
}

View File

@ -7,7 +7,11 @@ namespace Luban.Job.Db.Defs
{
public DefAssembly Assembly => (DefAssembly)HostType.AssemblyBase;
public DefField(DbDefTypeBase host, Field f, int idOffset) : base(host, f, idOffset)
public string LogType => $"Log_{Name}";
public string InternalName => "__" + Name;
public DefField(DefTypeBase host, Field f, int idOffset) : base(host, f, idOffset)
{
}

View File

@ -1,5 +1,6 @@
using Luban.Job.Common.Types;
using Luban.Job.Db.RawDefs;
using Luban.Job.Db.TypeVisitors;
using System;
namespace Luban.Job.Db.Defs
@ -30,7 +31,7 @@ namespace Luban.Job.Db.Defs
public string InternalTableType => "_" + Name;
//public string BaseTableType => KeyTType.GetDbCsBaseTableType(KeyTType, ValueTType);
public string BaseTableType => $"Bright.Transaction.TxnTable<{KeyTType.Apply(DbCsDefineTypeVisitor.Ins)},{ValueTType.Apply(DbCsDefineTypeVisitor.Ins)}>";
public override void Compile()
{

View File

@ -0,0 +1,76 @@
using Luban.Job.Common.Defs;
using Luban.Job.Common.Types;
using Luban.Job.Db.TypeVisitors;
using System.Text;
namespace Luban.Job.Db.Defs
{
class TTypeTemplateExtends : TTypeTemplateCommonExtends
{
public static string DbCsDefineType(TType type)
{
return type.Apply(DbCsDefineTypeVisitor.Ins);
}
public static string CsImmutableType(TType type)
{
return type.Apply(ImmutableTypeName.Ins);
}
public static string DbCsInitField(string fieldName, string logType, TType type)
{
return type.Apply(DbCsInitFieldVisitor.Ins, fieldName, logType);
}
public static bool HasSetter(TType type)
{
return type.Apply(BeanFieldHasSetterVisitor.Ins);
}
public static bool NeedSetChildrenRoot(TType type)
{
return type.Apply(NeedSetChildrenRootVisitor.Ins);
}
public static string DbCsCompatibleSerialize(string bufName, string fieldName, TType type)
{
if (type.Apply(CompatibleSerializeNeedEmbedVisitor.Ins))
{
var sb = new StringBuilder($"{bufName}.BeginWriteSegment(out var _state_);");
sb.Append(type.Apply(DbCsCompatibleSerializeVisitor.Ins, bufName, fieldName));
sb.Append("_buf.EndWriteSegment(_state_);");
return sb.ToString();
}
else
{
return type.Apply(DbCsCompatibleSerializeVisitor.Ins, bufName, fieldName);
}
}
public static string DbCsCompatibleDeserialize(string bufName, string fieldName, TType type)
{
if (type.Apply(CompatibleSerializeNeedEmbedVisitor.Ins))
{
var sb = new StringBuilder($"{bufName}.EnterSegment(out var _state_);");
sb.Append(type.Apply(DbCsCompatibleDeserializeVisitor.Ins, bufName, fieldName));
sb.Append("_buf.LeaveSegment(_state_);");
return sb.ToString();
}
else
{
return type.Apply(DbCsCompatibleDeserializeVisitor.Ins, bufName, fieldName);
}
}
public static string CsInitFieldCtorValue(DefField field)
{
return $"{field.CsStyleName} = default;";
}
public static string CsWriteBlob(string bufName, string valueName, TType type)
{
return type.Apply(DbWriteBlob.Ins, bufName, valueName);
}
}
}

View File

@ -36,89 +36,95 @@ namespace Luban.Job.Db.Generate
public string Render(DefBean b)
{
var template = t_beanRender ??= Template.Parse(@"
{{
name = x.name
parent_def_type = x.parent_def_type
fields = x.fields
hierarchy_fields = x.hierarchy_fields
is_abstract_type = x.is_abstract_type
}}
using Bright.Serialization;
namespace {{namespace_with_top_module}}
namespace {{x.namespace_with_top_module}}
{
{{if !is_value_type}}
public {{cs_class_modifier}} class {{name}} : {{if parent_def_type}} {{parent}} {{else}} Bright.Transaction.BeanBase {{end}}
public {{x.cs_class_modifier}} class {{name}} : {{if parent_def_type}} {{x.parent}} {{else}} Bright.Transaction.TxnBeanBase {{end}}
{
{{- for field in fields }}
{{if is_abstract_type}}protected{{else}}private{{end}} {{field.ctype.db_cs_define_type}} {{field.internal_name}};
{{-end}}
{{~ for field in fields~}}
{{if is_abstract_type}}protected{{else}}private{{end}} {{db_cs_define_type field.ctype}} {{field.internal_name}};
{{~end}}
public {{name}}()
{
{{- for field in fields }}
{{if field.ctype.need_init}}{{field.db_cs_init_field}} {{end}}
{{end}}
{{~ for field in fields~}}
{{if cs_need_init field.ctype}}{{db_cs_init_field field.internal_name field.log_type field.ctype }} {{end}}
{{~end~}}
}
{{- for field in fields }}
{{if field.ctype.has_setter}}
{{~ for field in fields~}}
{{~if has_setter field.ctype~}}
private sealed class {{field.log_type}} : Bright.Transaction.FieldLogger<{{name}}, {{field.ctype.db_cs_define_type}}>
private sealed class {{field.log_type}} : Bright.Transaction.FieldLogger<{{name}}, {{db_cs_define_type field.ctype}}>
{
public {{field.log_type}}({{name}} self, {{db_cs_define_type field.ctype}} value) : base(self, value) { }
public override long FieldId => host._objectId_ + {{field.id}};
public override void Commit() { this.host.{{field.internal_name}} = this.Value; }
public override void WriteBlob(ByteBuf _buf)
{
public {{field.log_type}}({{name}} self, {{field.ctype.db_cs_define_type}} value) : base(self, value) { }
_buf.WriteInt(FieldTag.{{tag_name field.ctype}});
{{cs_write_blob '_buf' 'this.Value' field.ctype}}
}
}
public override long FieldId => host._objectId_ + {{field.id}};
public override void Commit() { this.host.{{field.internal_name}} = this.Value; }
public override void WriteBlob(ByteBuf _buf)
public {{db_cs_define_type field.ctype}} {{field.cs_style_name}}
{
get
{
if (this.InitedObjectId)
{
_buf.WriteInt(FieldTag.{{field.ctype.tag_name}});
{{field.db_write_blob}}
var txn = Bright.Transaction.TransactionContext.ThreadStaticTxn;
if (txn == null) return {{field.internal_name}};
var log = ({{field.log_type}})txn.GetField(_objectId_ + {{field.id}});
return log != null ? log.Value : {{field.internal_name}};
}
else
{
return {{field.internal_name}};
}
}
public {{field.ctype.db_cs_define_type}} {{field.public_name}}
{
get
set
{
{{~if db_field_cannot_null~}}
if (value == null) throw new ArgumentNullException();
{{~end~}}
if (this.InitedObjectId)
{
if (this.InitedObjectId)
{
var txn = Bright.Transaction.TransactionContext.ThreadStaticTxn;
if (txn == null) return {{field.internal_name}};
var log = ({{field.log_type}})txn.GetField(_objectId_ + {{field.id}});
return log != null ? log.Value : {{field.internal_name}};
}
else
{
return {{field.internal_name}};
}
var txn = Bright.Transaction.TransactionContext.ThreadStaticTxn;
txn.PutField(_objectId_ + {{field.id}}, new {{field.log_type}}(this, value));
{{~if field.ctype.need_set_children_root}}
value?.InitRoot(GetRoot());
{{end}}
}
set
else
{
{{if db_field_cannot_null}}if (value == null) throw new ArgumentNullException();{{end}}
if (this.InitedObjectId)
{
var txn = Bright.Transaction.TransactionContext.ThreadStaticTxn;
txn.PutField(_objectId_ + {{field.id}}, new {{field.log_type}}(this, value));
{{-if field.ctype.need_set_children_root}}
value?.InitRoot(GetRoot());
{{end}}
}
else
{
{{field.internal_name}} = value;
}
}
{{field.internal_name}} = value;
}
}
{{else}}
{{if field.ctype.is_collection}}
private class {{field.log_type}} : {{field.ctype.db_cs_define_type}}.Log
}
{{~else~}}
{{~if field.ctype.is_collection~}}
private class {{field.log_type}} : {{db_cs_define_type field.ctype}}.Log
{
private readonly {{name}} host;
public {{field.log_type}}({{name}} host, {{field.ctype.immutable_type}} value) : base(value) { this.host = host; }
public {{field.log_type}}({{name}} host, {{cs_immutable_type field.ctype}} value) : base(value) { this.host = host; }
public override long FieldId => host._objectId_ + {{field.id}};
public override Bright.Transaction.BeanBase Host => host;
public override Bright.Transaction.TxnBeanBase Host => host;
public override void Commit()
{
@ -127,17 +133,17 @@ public {{cs_class_modifier}} class {{name}} : {{if parent_def_type}} {{parent}}
public override void WriteBlob(ByteBuf _buf)
{
_buf.WriteInt(FieldTag.{{field.ctype.tag_name}});
{{field.db_write_blob}}
_buf.WriteInt(FieldTag.{{tag_name field.ctype}});
{{cs_write_blob '_buf' 'this.Value' field.ctype}}
}
}
{{end}}
{{~end~}}
public {{field.ctype.db_cs_define_type}} {{field.public_name}} => {{field.internal_name}};
{{end}}
{{-end}}
public {{db_cs_define_type field.ctype}} {{field.cs_style_name}} => {{field.internal_name}};
{{~end~}}
{{~end~}}
{{if is_abstract_type}}
{{~if is_abstract_type~}}
public static void Serialize{{name}}(ByteBuf _buf, {{name}} x)
{
if (x == null) { _buf.WriteInt(0); return; }
@ -151,21 +157,21 @@ public {{cs_class_modifier}} class {{name}} : {{if parent_def_type}} {{parent}}
switch (_buf.ReadInt())
{
case 0 : return null;
{{- for child in hierarchy_not_abstract_children}}
{{~ for child in x.hierarchy_not_abstract_children~}}
case {{child.full_name}}.ID: x = new {{child.full_name}}(); break;
{{-end}}
{{~end~}}
default: throw new SerializationException();
}
x.Deserialize(_buf);
return x;
}
{{else}}
{{~else~}}
public override void Serialize(ByteBuf _buf)
{
_buf.WriteLong(_objectId_);
{{- for field in hierarchy_fields }}
{ _buf.WriteInt(FieldTag.{{field.ctype.tag_name}} | ({{field.id}} << FieldTag.TAG_SHIFT)); {{field.db_serialize_compatible}} }
{{-end}}
{{~ for field in hierarchy_fields~}}
{ _buf.WriteInt(FieldTag.{{tag_name field.ctype}} | ({{field.id}} << FieldTag.TAG_SHIFT)); {{db_cs_compatible_serialize '_buf' field.internal_name field.ctype}} }
{{~end}}
}
public override void Deserialize(ByteBuf _buf)
@ -176,87 +182,38 @@ public {{cs_class_modifier}} class {{name}} : {{if parent_def_type}} {{parent}}
int _tag_ = _buf.ReadInt();
switch (_tag_)
{
{{- for field in hierarchy_fields }}
case FieldTag.{{field.ctype.tag_name}} | ({{field.id}} << FieldTag.TAG_SHIFT) : { {{field.db_deserialize_compatible}} break; }
{{-end}}
{{~ for field in hierarchy_fields~}}
case FieldTag.{{tag_name field.ctype}} | ({{field.id}} << FieldTag.TAG_SHIFT) : { {{db_cs_compatible_deserialize '_buf' field.internal_name field.ctype}} break; }
{{~end~}}
default: { _buf.SkipUnknownField(_tag_); break; }
}
}
}
public const int ID = {{id}};
public const int ID = {{x.id}};
public override int GetTypeId() => ID;
{{end}}
{{~end~}}
protected override void InitChildrenRoot(Bright.Transaction.TKey root)
{
{{- for field in hierarchy_fields }}
{{if field.ctype.need_set_children_root}}this.{{field.internal_name}}?.InitRoot(root);{{end}}
{{-end}}
{{~ for field in hierarchy_fields~}}
{{if need_set_children_root field.ctype}}{{field.internal_name}}?.InitRoot(root);{{end}}
{{~end}}
}
public override string ToString()
{
return ""{{full_name}}{ ""
{{- for field in hierarchy_fields }}
+ ""{{field.public_name}}:"" + {{field.db_cs_to_string}} + "",""
{{-end}}
{{~ for field in hierarchy_fields~}}
+ ""{{field.cs_style_name}}:"" + {{cs_to_string field.cs_style_name field.ctype}} + "",""
{{~end~}}
+ ""}"";
}
}
{{else}}
public struct {{name}} : ISerializable
{
{{- for field in fields }}
private {{field.ctype.db_cs_define_type}} {{field.internal_name}};
{{-end}}
{{- for field in fields }}
public {{field.ctype.db_cs_define_type}} {{field.public_name}} {get => {{field.internal_name}}; set => {{field.internal_name}} = value;}
{{-end}}
public void Serialize(ByteBuf _buf)
{
_buf.WriteSize({{hierarchy_fields.size}});
{{- for field in hierarchy_fields }}
{ _buf.WriteInt(FieldTag.{{field.ctype.tag_name}} | ({{field.id}} << FieldTag.TAG_SHIFT)); {{field.db_serialize_compatible}} }
{{-end}}
}
public void Deserialize(ByteBuf _buf)
{
for (int _var_num_ = _buf.ReadSize(); -- _var_num_ >= 0;)
{
int _tag_ = _buf.ReadInt();
switch (_tag_)
{
{{- for field in hierarchy_fields }}
case FieldTag.{{field.ctype.tag_name}} | ({{field.id}} << FieldTag.TAG_SHIFT) : { {{field.db_deserialize_compatible}} break; }
{{-end}}
default: { _buf.SkipUnknownField(_tag_); break; }
}
}
}
public int GetTypeId() => 0;
public override string ToString()
{
return ""{{full_name}}{ ""
{{- for field in hierarchy_fields }}
+ ""{{field.public_name}}:"" + {{field.db_cs_to_string}} + "",""
{{-end}}
+ ""}"";
}
}
{{end}}
}
");
var result = template.Render(b);
var result = template.RenderCode(b);
return result;
}
@ -265,15 +222,22 @@ public {{cs_class_modifier}} class {{name}} : {{if parent_def_type}} {{parent}}
public string Render(DefTable p)
{
var template = t_tableRender ??= Template.Parse(@"
{{
name = x.name
key_ttype = x.key_ttype
value_ttype = x.value_ttype
base_table_type = x.base_table_type
internal_table_type = x.internal_table_type
}}
using System;
using System.Threading.Tasks;
namespace {{namespace_with_top_module}}
namespace {{x.namespace_with_top_module}}
{
public sealed class {{name}}
{
public static {{base_table_type}} Table { get; } = new {{internal_table_type}}({{table_uid}});
public static {{base_table_type}} Table { get; } = new {{internal_table_type}}({{x.table_uid}});
private class {{internal_table_type}} : {{base_table_type}}
{
@ -283,32 +247,32 @@ public sealed class {{name}}
}
};
public static {{value_ttype.cs_define_type}} Get({{key_ttype.cs_define_type}} key)
public static {{db_cs_define_type value_ttype}} Get({{db_cs_define_type key_ttype}} key)
{
return Table.Get(key);
}
public static {{value_ttype.cs_define_type}} CreateIfNotExist({{key_ttype.cs_define_type}} key)
public static {{db_cs_define_type value_ttype}} CreateIfNotExist({{db_cs_define_type key_ttype}} key)
{
return Table.CreateIfNotExist(key);
}
public static void Insert({{key_ttype.cs_define_type}} key, {{value_ttype.cs_define_type}} value)
public static void Insert({{db_cs_define_type key_ttype}} key, {{db_cs_define_type value_ttype}} value)
{
Table.Insert(key, value);
}
public static void Remove({{key_ttype.cs_define_type}} key)
public static void Remove({{db_cs_define_type key_ttype}} key)
{
Table.Remove(key);
}
public static void Put({{key_ttype.cs_define_type}} key, {{value_ttype.cs_define_type}} value)
public static void Put({{db_cs_define_type key_ttype}} key, {{db_cs_define_type value_ttype}} value)
{
Table.Put(key, value);
}
public static {{value_ttype.cs_define_type}} Select({{key_ttype.cs_define_type}} key)
public static {{db_cs_define_type value_ttype}} Select({{db_cs_define_type key_ttype}} key)
{
return Table.Select(key);
}
@ -316,14 +280,14 @@ public sealed class {{name}}
}
");
var result = template.Render(p);
var result = template.RenderCode(p);
return result;
}
[ThreadStatic]
private static Template t_stubRender;
public string RenderTables(string name, string module, List<DbDefTypeBase> tables)
public string RenderTables(string name, string module, List<DefTable> tables)
{
var template = t_stubRender ??= Template.Parse(@"
using Bright.Serialization;
@ -335,9 +299,9 @@ public static class {{name}}
{
public static System.Collections.Generic.List<Bright.Transaction.TxnTable> TableList { get; } = new System.Collections.Generic.List<Bright.Transaction.TxnTable>
{
{{- for table in tables }}
{{~ for table in tables~}}
{{table.full_name}}.Table,
{{-end}}
{{~end}}
};
}

View File

@ -1,18 +1,148 @@
using Luban.Common.Protos;
using CommandLine;
using Luban.Common.Protos;
using Luban.Common.Utils;
using Luban.Job.Common.Defs;
using Luban.Job.Common.Utils;
using Luban.Job.Db.Defs;
using Luban.Job.Db.Generate;
using Luban.Server.Common;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FileInfo = Luban.Common.Protos.FileInfo;
namespace Luban.Job.Db
{
public class JobController : IJobController
{
public Task GenAsync(RemoteAgent agent, GenJob rpc)
class GenArgs
{
throw new NotImplementedException();
[Option('d', "define_file", Required = true, HelpText = "define file")]
public string DefineFile { get; set; }
[Option('c', "output_code_dir", Required = true, HelpText = "output code directory")]
public string OutputCodeDir { get; set; }
[Option('g', "gen_type", Required = true, HelpText = "cs . current only support cs")]
public string GenType { get; set; }
}
private bool TryParseArg(List<string> args, out GenArgs result, out string errMsg)
{
var helpWriter = new StringWriter();
var parser = new Parser(ps =>
{
ps.HelpWriter = helpWriter;
}); ;
var parseResult = parser.ParseArguments<GenArgs>(args);
if (parseResult.Tag == ParserResultType.NotParsed)
{
errMsg = helpWriter.ToString();
result = null;
return false;
}
result = (parseResult as Parsed<GenArgs>).Value;
errMsg = null;
return true;
}
public async Task GenAsync(RemoteAgent agent, GenJob rpc)
{
var res = new GenJobRes()
{
ErrCode = Luban.Common.EErrorCode.OK,
ErrMsg = "succ",
FileGroups = new List<FileGroup>(),
};
if (!TryParseArg(rpc.Arg.JobArguments, out GenArgs args, out string errMsg))
{
res.ErrCode = Luban.Common.EErrorCode.JOB_ARGUMENT_ERROR;
res.ErrMsg = errMsg;
agent.Session.ReplyRpc<GenJob, GenJobArg, GenJobRes>(rpc, res);
return;
}
var timer = new ProfileTimer();
timer.StartPhase("= gen_all =");
try
{
string outputCodeDir = args.OutputCodeDir;
timer.StartPhase("build defines");
var loader = new DbDefLoader(agent);
await loader.LoadAsync(args.DefineFile);
timer.EndPhaseAndLog();
var rawDefines = loader.BuildDefines();
var ass = new DefAssembly();
ass.Load(rawDefines, agent);
List<DefTypeBase> exportTypes = ass.GetExportTypes();
var tasks = new List<Task>();
var genCodeFiles = new ConcurrentBag<FileInfo>();
var genType = args.GenType;
switch (genType)
{
case "cs":
{
var render = new CsRender();
foreach (var c in ass.Types.Values)
{
tasks.Add(Task.Run(() =>
{
var content = FileHeaderUtil.ConcatAutoGenerationHeader(render.RenderAny(c), Common.ELanguage.CS);
var file = RenderFileUtil.GetDefTypePath(c.FullName, Common.ELanguage.CS);
var md5 = CacheFileUtil.GenMd5AndAddCache(file, content);
genCodeFiles.Add(new FileInfo() { FilePath = file, MD5 = md5 });
}));
}
tasks.Add(Task.Run(() =>
{
var module = ass.TopModule;
var name = "Tables";
var content = FileHeaderUtil.ConcatAutoGenerationHeader(
render.RenderTables(name, module,
ass.Types.Values.Where(t => t is DefTable).Select(t => (DefTable)t).ToList()),
Common.ELanguage.CS);
var file = RenderFileUtil.GetDefTypePath(name, Common.ELanguage.CS);
var md5 = CacheFileUtil.GenMd5AndAddCache(file, content);
genCodeFiles.Add(new FileInfo() { FilePath = file, MD5 = md5 });
}));
break;
}
default:
{
throw new NotSupportedException($"not support gen type:{genType}");
}
}
await Task.WhenAll(tasks.ToArray());
res.FileGroups.Add(new FileGroup() { Dir = outputCodeDir, Files = genCodeFiles.ToList() });
}
catch (Exception e)
{
res.ErrCode = Luban.Common.EErrorCode.JOB_EXCEPTION;
res.ErrMsg = $"{e.Message} \n {e.StackTrace}";
}
timer.EndPhaseAndLog();
agent.Session.ReplyRpc<GenJob, GenJobArg, GenJobRes>(rpc, res);
}
}
}

View File

@ -1,119 +0,0 @@
//using Bright.Common;
//using CommandLine;
//using CommandLine.Text;
//using Gen.Client.Common.Net;
//using Gen.Client.Common.Utils;
//using Gen.Db.Common.RawDefs;
//using Luban.Job.Common.Net;
//using Luban.Job.Common.Utils;
//using System;
//namespace Luban.Job.Db.Client
//{
// public class CommandLineOptions
// {
// [Option('h', "host", Required = true, HelpText = "gen server host")]
// public string Host { get; set; }
// [Option('p', "port", Required = false, HelpText = "gen server port")]
// public int Port { get; set; } = 8899;
// [Option('d', "define", Required = true, HelpText = "define file")]
// public string DefineFile { get; set; }
// [Option('c', "outputcodedir", Required = true, HelpText = "output code directory")]
// public string OutputCodeDir { get; set; }
// [Option('l', "language", Required = true, HelpText = "code language. only support cs currently")]
// public string Languange { get; set; } = "cs";
// [Option('v', "verbose", Required = false, HelpText = "verbose output")]
// public bool Verbose { get; set; }
// [Option("cachemetainfofile", Required = false, HelpText = "cache meta info file")]
// public string CacheMetaInfoFile { get; set; } = ".cache.meta";
// }
// class Program
// {
// private static NLog.Logger s_logger;
// private static CommandLineOptions _options;
// static void Main(string[] args)
// {
// var parseResult = Parser.Default.ParseArguments<CommandLineOptions>(args);
// parseResult.WithNotParsed(errs =>
// {
// Environment.Exit(1);
// });
// parseResult.WithParsed(opts =>
// {
// _options = opts;
// });
// LogUtil.InitSimpleNLogConfigure(NLog.LogLevel.Info);
// s_logger = NLog.LogManager.GetCurrentClassLogger();
// int exitCode = 0;
// try
// {
// var timer = new ProfileTimer();
// timer.StartPhase("total");
// long beginTime = Bright.Time.TimeUtil.NowMillis;
// timer.StartPhase("load cache meta file");
// CacheMetaManager.Ins.Load(_options.CacheMetaInfoFile);
// timer.EndPhaseAndLog();
// RpcManager.Ins.Start();
// var conn = GenClient.Ins.Start(_options.Host, _options.Port, ProtocolStub.Factories, _options.Verbose);
// conn.Wait();
// timer.StartPhase("load defines");
// var loader = new DbDefLoader();
// loader.Load(_options.DefineFile);
// timer.EndPhaseAndLog();
// timer.StartPhase("call GenDb");
// string outputDir = _options.OutputCodeDir;
// var rpc = new GenDb();
// var res = rpc.Call(GenClient.Ins.Session, new GenDbArg()
// {
// Define = loader.BuildDefines(),
// OutputCodeRelatePath = outputDir,
// }).Result;
// timer.EndPhaseAndLog();
// if (res.OK)
// {
// timer.StartPhase("fetch generated files");
// DownloadFileUtil.DownloadGeneratedFiles(outputDir, res.NewCodeFiles).Wait();
// timer.EndPhaseAndLog();
// CacheMetaManager.Ins.Save();
// timer.EndPhaseAndLog();
// s_logger.Info("==== run succ ====");
// }
// else
// {
// timer.EndPhaseAndLog();
// s_logger.Error("==== run fail ====");
// exitCode = 1;
// }
// }
// catch (Exception e)
// {
// s_logger.Error(e, "==== run fail ====");
// exitCode = 1;
// }
// Environment.Exit(exitCode);
// }
// }
//}

View File

@ -5,8 +5,6 @@ namespace Luban.Job.Db.RawDefs
{
public class Defines
{
public string Language { get; set; } = "cs";
public string TopModule { get; set; } = "";
public List<Bean> Beans { get; set; } = new List<Bean>();

View File

@ -0,0 +1,27 @@
using Luban.Job.Db.Defs;
using Scriban;
using System.Collections.Generic;
namespace Luban.Job.Db
{
public static class RenderExtension
{
public static string RenderCode(this Template template, object model, Dictionary<string, object> extraModels = null)
{
var ctx = new TemplateContext();
var env = new TTypeTemplateExtends
{
["x"] = model
};
if (extraModels != null)
{
foreach ((var k, var v) in extraModels)
{
env[k] = v;
}
}
ctx.PushGlobal(env);
return template.Render(ctx);
}
}
}

View File

@ -1,623 +0,0 @@
namespace Luban.Job.Db
{
class RpcController
{
//private void LogException(IContext ctx, Exception e)
//{
// if (e is AggregateException ae)
// {
// foreach (var ie in ae.InnerExceptions)
// {
// LogException(ctx, ie);
// }
// }
// else
// {
// s_logger.Error(e, "发生异常");
// ctx.Error(e, " {0} \n ", e.StackTrace);
// }
//}
//private bool ValidateDataType(string outputDataType)
//{
// switch (outputDataType)
// {
// case "bin":
// case "cbin":
// case "json": return true;
// default: return false;
// }
//}
//private void OnGenDb(Session session, GenDb proto)
//{
// var timer = new ProfileTimer();
// timer.StartPhase("生成代码");
// var res = new GenDbRes();
// string relatePath = proto.Arg.OutputCodeRelatePath;
// var ass = new DefAssembly();
// var ctx = new SessionContext(session, proto.Arg.Verbose);
// try
// {
// var genCodeTasks = new List<Task>();
// var outputFiles = new ConcurrentBag<FileInfo>();
// ass.Load(EJobType.DB, proto.Arg.Define, ctx);
// var render = new Generate.Db.CsRender();
// foreach (var c in ass.Types.Values)
// {
// genCodeTasks.Add(Task.Run(() =>
// {
// var content = RenderUtils.ConcatAutoGenerationHeader(render.RenderAny(c), "cs");
// var file = FileUtil.GetCsDefTypePath(c.FullName);
// var md5 = GenMd5AndAddCache(file, content);
// outputFiles.Add(new FileInfo() { FilePath = file, MD5 = md5 });
// }));
// }
// genCodeTasks.Add(Task.Run(() =>
// {
// var module = ass.TopModule;
// var name = "Tables";
// var content = RenderUtils.ConcatAutoGenerationHeader(render.RenderTables(name, module, ass.Types.Values.Where(t => t is BTable).ToList()), "cs");
// var file = FileUtil.GetCsDefTypePath(name);
// var md5 = GenMd5AndAddCache(file, content);
// outputFiles.Add(new FileInfo() { FilePath = file, MD5 = md5 });
// }));
// Task.WhenAll(genCodeTasks).Wait();
// ctx.Info(timer.EndPhaseAndLogToString());
// res.NewCodeFiles = outputFiles.ToList();
// res.OK = true;
// }
// catch (Exception e)
// {
// res.OK = false;
// LogException(ctx, e);
// }
// proto.ReturnResult(session, res);
//}
//private ICsCodeRender CreateCsCodeRender(string outputDataType)
//{
// switch (outputDataType)
// {
// case "bin": return new AppCsBinCodeRender();
// case "cbin": return new AppCsCompatibleBinCodeRender();
// case "json": return new AppCsJsonCodeRender();
// default: throw new ArgumentException($"not support output data type:{outputDataType}");
// }
//}
//private void OnGenCfg(Session session, GenCfg proto)
//{
// var res = new GenCfgRes();
// string lan = proto.Arg.Define.Language;
// DefAssembly ass = new DefAssembly();
// var ctx = new SessionContext(session, proto.Arg.Verbose);
// var allJobs = new List<Task>();
// try
// {
// string outputDataType = proto.Arg.OutputDataType;
// if (!ValidateDataType(outputDataType))
// {
// throw new ArgumentException($"unknown outputdatatype:{outputDataType}");
// }
// bool exportTestData = proto.Arg.ExportTestData;
// long genStartTime = TimeUtil.NowMillis;
// var genCodeTasks = new List<Task>();
// var outputCodeFiles = new ConcurrentBag<FileInfo>();
// ass.Load(EJobType.CONFIG, proto.Arg.Define, ctx);
// EGenTypes genTypes = proto.Arg.GenTypes;
// var targetService = ass.CfgTargetService;
// List<CTable> exportTables = ass.Types.Values.Where(t => t is CTable ct && ct.NeedExport).Select(t => (CTable)t).ToList();
// if (genTypes.HasFlag(EGenTypes.APP_CODE))
// {
// var refTypes = new Dictionary<string, IDefType>();
// long genCodeStartTime = TimeUtil.NowMillis;
// foreach (var refType in targetService.Refs)
// {
// if (!ass.Types.ContainsKey(refType))
// {
// throw new Exception($"service:{targetService.Name} ref:{refType} 类型不存在");
// }
// if (!refTypes.TryAdd(refType, ass.Types[refType]))
// {
// throw new Exception($"service:{targetService.Name} ref:{refType} 重复引用");
// }
// }
// foreach (var table in exportTables)
// {
// refTypes[table.FullName] = table;
// table.ValueTType.Apply(RefTypeVisitor.Ins, refTypes);
// }
// foreach (var type in ass.Types)
// {
// if (type.Value is DefConst || type.Value is DefEnum)
// {
// refTypes[type.Key] = type.Value;
// }
// }
// List<IDefType> exportTypes = refTypes.Values.ToList();
// switch (lan)
// {
// case "cs":
// {
// ICsCodeRender render = CreateCsCodeRender(outputDataType);
// foreach (var c in exportTypes)
// {
// genCodeTasks.Add(Task.Run(() =>
// {
// var content = RenderUtils.ConcatAutoGenerationHeader(render.RenderAny(c), "cs");
// var file = FileUtil.GetCsDefTypePath(c.FullName);
// var md5 = GenMd5AndAddCache(file, content);
// outputCodeFiles.Add(new FileInfo() { FilePath = file, MD5 = md5 });
// }));
// }
// genCodeTasks.Add(Task.Run(() =>
// {
// var module = ass.TopModule;
// var name = targetService.Manager;
// var content = RenderUtils.ConcatAutoGenerationHeader(render.RenderService(name, module, exportTables), "cs");
// var file = FileUtil.GetCsDefTypePath(name);
// var md5 = GenMd5AndAddCache(file, content);
// outputCodeFiles.Add(new FileInfo() { FilePath = file, MD5 = md5 });
// }));
// break;
// }
// case "go":
// {
// //
// // TODO?
// // 由于 go 语言不支持类型继承
// // go 不支持 table.value_type 为多态的表
// //
// //
// var render = new AppGoCodeRender();
// foreach (var c in exportTypes)
// {
// genCodeTasks.Add(Task.Run(() =>
// {
// var content = RenderUtils.ConcatAutoGenerationHeader(render.RenderAny(c), "go");
// var file = FileUtil.GetGoDefTypePath(c.FullName);
// var md5 = GenMd5AndAddCache(file, content);
// outputCodeFiles.Add(new FileInfo() { FilePath = file, MD5 = md5 });
// }));
// }
// genCodeTasks.Add(Task.Run(() =>
// {
// var module = ass.TopModule;
// var name = targetService.Manager;
// var content = RenderUtils.ConcatAutoGenerationHeader(render.RenderService(name, module, exportTables), "go");
// var file = FileUtil.GetGoDefTypePath(name);
// var md5 = GenMd5AndAddCache(file, content);
// outputCodeFiles.Add(new FileInfo() { FilePath = file, MD5 = md5 });
// }));
// break;
// }
// case "lua":
// {
// genCodeTasks.Add(Task.Run(() =>
// {
// var render = new Generate.Cfg.LuaRender();
// var content = RenderUtils.ConcatAutoGenerationHeader(render.RenderAll(exportTypes.ToList()), "lua");
// var file = "CfgTypes.lua";
// var md5 = GenMd5AndAddCache(file, content);
// outputCodeFiles.Add(new FileInfo() { FilePath = file, MD5 = md5 });
// }));
// break;
// }
// case "editor_cs":
// {
// var render = new EditorCsRender();
// foreach (var c in ass.Types.Values)
// {
// genCodeTasks.Add(Task.Run(() =>
// {
// var content = RenderUtils.ConcatAutoGenerationHeader(render.RenderAny(c), "cpp");
// var file = FileUtil.GetCsDefTypePath(c.FullName);
// var md5 = GenMd5AndAddCache(file, content);
// outputCodeFiles.Add(new FileInfo() { FilePath = file, MD5 = md5 });
// }));
// }
// break;
// }
// case "editor_cpp":
// {
// var render = new EditorCppRender();
// foreach (var c in ass.Types.Values)
// {
// genCodeTasks.Add(Task.Run(() =>
// {
// var content = RenderUtils.ConcatAutoGenerationHeader(render.RenderAny(c), "cpp");
// var file = FileUtil.GetCsDefTypePath(c.FullName);
// var md5 = GenMd5AndAddCache(file, content);
// outputCodeFiles.Add(new FileInfo() { FilePath = file, MD5 = md5 });
// }));
// }
// break;
// }
// case "editor_ue_cpp":
// {
// var render = new UE4EditorCppRender();
// var renderTypes = ass.Types.Values.Where(c => c is DefEnum || c is DefBean).ToList();
// foreach (var c in renderTypes)
// {
// genCodeTasks.Add(Task.Run(() =>
// {
// var content = RenderUtils.ConcatAutoGenerationHeader(render.RenderAny(c), "cpp");
// var file = c.UeEditorHeaderFileName;
// var md5 = GenMd5AndAddCache(file, content);
// outputCodeFiles.Add(new FileInfo() { FilePath = file, MD5 = md5 });
// }));
// }
// int TYPE_PER_STUB_FILE = 200;
// for (int i = 0, n = (renderTypes.Count + TYPE_PER_STUB_FILE - 1) / TYPE_PER_STUB_FILE; i < n; i++)
// {
// int index = i;
// genCodeTasks.Add(Task.Run(() =>
// {
// int startIndex = index * TYPE_PER_STUB_FILE;
// var content = RenderUtils.ConcatAutoGenerationHeader(
// render.RenderStub(renderTypes.GetRange(startIndex, Math.Min(TYPE_PER_STUB_FILE, renderTypes.Count - startIndex))),
// "cpp");
// var file = $"Stub_{index}.cpp";
// var md5 = GenMd5AndAddCache(file, content);
// outputCodeFiles.Add(new FileInfo() { FilePath = file, MD5 = md5 });
// }));
// }
// break;
// }
// case "ue_bp_cpp":
// {
// var render = new UE4BpCppRender();
// foreach (var c in exportTypes)
// {
// if (c is DefConst || c is CTable)
// {
// continue;
// }
// genCodeTasks.Add(Task.Run(() =>
// {
// var content = RenderUtils.ConcatAutoGenerationHeader(render.RenderAny(c), "cpp");
// var file = c.UeBpHeaderFileName;
// var md5 = GenMd5AndAddCache(file, content);
// outputCodeFiles.Add(new FileInfo() { FilePath = file, MD5 = md5 });
// }));
// }
// //{
// // var module = ass.TopModule;
// // var name = targetService.Manager;
// // var content = render.RenderService(name, module, exportTables);
// // var file = FileUtil.GetCppDefTypeCppFilePath(name);
// // var md5 = GenMd5AndAddCache(file, content);
// // outputFiles.Add(new FileInfo() { FilePath = file, MD5 = md5 });
// //}
// break;
// }
// default:
// {
// throw new Exception($"unknown language:{lan}");
// }
// }
// allJobs.Add(Task.Run(async () =>
// {
// await Task.WhenAll(genCodeTasks);
// res.NewAppCodeFiles = outputCodeFiles.ToList();
// long genCodeEndTime = TimeUtil.NowMillis;
// ctx.Info("====== 生成代码 总共耗时 {0} ms ======", (genCodeEndTime - genCodeStartTime));
// }));
// }
// if ((genTypes & (EGenTypes.APP_DATA | EGenTypes.APP_RESOURCE_LIST)) != 0)
// {
// var genDataTasks = new List<Task>();
// var outputDataFiles = new ConcurrentBag<FileInfo>();
// var render = new AppBinaryDataRender();
// long genDataStartTime = TimeUtil.NowMillis;
// foreach (CTable c in exportTables)
// {
// genDataTasks.Add(Task.Run(async () =>
// {
// long beginTime = TimeUtil.NowMillis;
// await c.Load(session, exportTestData);
// long endTime = TimeUtil.NowMillis;
// if (endTime - beginTime > 100)
// {
// ctx.Info("====== 配置表 {0} 加载耗时 {1} ms ======", c.FullName, (endTime - beginTime));
// }
// }));
// }
// Task.WaitAll(genDataTasks.ToArray());
// }
// if (genTypes.HasFlag(EGenTypes.APP_DATA))
// {
// var genDataTasks = new List<Task>();
// var outputDataFiles = new ConcurrentBag<FileInfo>();
// var render = new AppBinaryDataRender();
// long genDataStartTime = TimeUtil.NowMillis;
// foreach (CTable c in exportTables)
// {
// genDataTasks.Add(Task.Run(() =>
// {
// var content = c.ToOutputData(outputDataType);
// var file = c.OutputDataFile;
// var md5 = GenMd5AndAddCache(file, content);
// outputDataFiles.Add(new FileInfo() { FilePath = file, MD5 = md5 });
// }));
// }
// allJobs.Add(Task.Run(async () =>
// {
// await Task.WhenAll(genDataTasks);
// long genDataEndTime = TimeUtil.NowMillis;
// ctx.Info("====== 生成配置数据 总共耗时 {0} ms ======", (genDataEndTime - genDataStartTime));
// res.NewAppDataFiles = outputDataFiles.ToList();
// long verifyStartTime = TimeUtil.NowMillis;
// render.VerifyTables(exportTables);
// res.PathQueries = ass.GetPathQueries();
// long verifyEndTime = TimeUtil.NowMillis;
// ctx.Info("====== 校验配置 总共耗时 {0} ms ======", (verifyEndTime - verifyStartTime));
// }));
// }
// if (genTypes.HasFlag(EGenTypes.APP_RESOURCE_LIST))
// {
// var genDataTasks = new List<Task<List<CfgResourceInfo>>>();
// var render = new AppBinaryDataRender();
// long genDataStartTime = TimeUtil.NowMillis;
// foreach (CTable c in exportTables)
// {
// genDataTasks.Add(Task.Run(() =>
// {
// return c.ExportResourceList();
// }));
// }
// allJobs.Add(Task.Run(async () =>
// {
// var ress = new HashSet<(string, string)>(10000);
// foreach (var task in genDataTasks)
// {
// foreach (var ri in await task)
// {
// if (ress.Add((ri.Resource, ri.Tag)))
// {
// res.ResourceList.Add(ri);
// }
// }
// }
// long genDataEndTime = TimeUtil.NowMillis;
// ctx.Info("====== 生成导出资源列表 总共耗时 {0} ms ======", (genDataEndTime - genDataStartTime));
// }));
// }
// Task.WhenAll(allJobs).Wait();
// long genEndTime = TimeUtil.NowMillis;
// ctx.Info("======== 服务器端 总共耗时 {0} ms =======", (genEndTime - genStartTime));
// res.OK = true;
// }
// catch (Exception e)
// {
// res.OK = false;
// LogException(ctx, e);
// }
// proto.ReturnResult(session, res);
//}
//private void OnGenProto(Session session, GenProto proto)
//{
// var timer = new ProfileTimer();
// timer.StartPhase("服务器生成代码");
// var res = new GenProtoRes();
// string relatePath = proto.Arg.OutputCodeRelatePath;
// DefAssembly ass = new DefAssembly();
// var ctx = new SessionContext(session, proto.Arg.Verbose);
// try
// {
// var genCodeTasks = new List<Task>();
// var outputFiles = new ConcurrentBag<FileInfo>();
// ass.Load(EJobType.PROTO, proto.Arg.Define, ctx);
// var outputSyncFiles = new ConcurrentBag<FileInfo>();
// switch (proto.Arg.Define.Language)
// {
// case "cs":
// {
// var render = new CsRender();
// foreach (var c in ass.Types.Values)
// {
// genCodeTasks.Add(Task.Run(() =>
// {
// var content = RenderUtils.ConcatAutoGenerationHeader(render.RenderAny(c), "cs");
// var file = FileUtil.GetCsDefTypePath(c.FullName);
// var md5 = GenMd5AndAddCache(file, content);
// outputFiles.Add(new FileInfo() { FilePath = file, MD5 = md5 });
// }));
// }
// genCodeTasks.Add(Task.Run(() =>
// {
// var module = ass.TopModule;
// var name = "ProtocolStub";
// var content = RenderUtils.ConcatAutoGenerationHeader(
// render.RenderStubs(name, module,
// ass.Types.Values.Where(t => t is PProto).ToList(),
// ass.Types.Values.Where(t => t is PRpc).ToList()),
// "cs");
// var file = FileUtil.GetCsDefTypePath(name);
// var md5 = GenMd5AndAddCache(file, content);
// outputFiles.Add(new FileInfo() { FilePath = file, MD5 = md5 });
// }));
// break;
// }
// case "lua":
// {
// genCodeTasks.Add(Task.Run(() =>
// {
// var render = new Generate.Proto.LuaRender();
// var content = RenderUtils.ConcatAutoGenerationHeader(render.RenderTypes(ass.Types.Values.ToList()), "lua");
// var file = "ProtoTypes.lua";
// var md5 = GenMd5AndAddCache(file, content);
// outputFiles.Add(new FileInfo() { FilePath = file, MD5 = md5 });
// }));
// break;
// }
// default:
// {
// throw new Exception($"unknown lan:{proto.Arg.Define.Language}");
// }
// }
// Task.WhenAll(genCodeTasks).Wait();
// res.NewCodeFiles = outputFiles.ToList();
// ctx.Info(timer.EndPhaseAndLogToString());
// res.OK = true;
// }
// catch (Exception e)
// {
// res.OK = false;
// LogException(ctx, e);
// }
// proto.ReturnResult(session, res);
//}
//private void OnGenRep(Session session, GenRep proto)
//{
// var timer = new ProfileTimer();
// timer.StartPhase("服务器生成代码");
// var res = new GenRepRes();
// string relatePath = proto.Arg.OutputCodeRelatePath;
// DefAssembly ass = new DefAssembly();
// var ctx = new SessionContext(session, proto.Arg.Verbose);
// try
// {
// var genCodeTasks = new List<Task>();
// var outputFiles = new ConcurrentBag<FileInfo>();
// ass.Load(EJobType.REP, proto.Arg.Define, ctx);
// var outputSyncFiles = new ConcurrentBag<FileInfo>();
// switch (proto.Arg.Define.Language)
// {
// case "cs":
// {
// var render = new Generate.Rep.CsRender();
// foreach (var c in ass.Types.Values)
// {
// genCodeTasks.Add(Task.Run(() =>
// {
// var content = RenderUtils.ConcatAutoGenerationHeader(render.RenderAny(c), "cs");
// var file = FileUtil.GetCsDefTypePath(c.FullName);
// var md5 = GenMd5AndAddCache(file, content);
// outputFiles.Add(new FileInfo() { FilePath = file, MD5 = md5 });
// }));
// }
// genCodeTasks.Add(Task.Run(() =>
// {
// var module = ass.TopModule;
// var name = "RepStub";
// var content = RenderUtils.ConcatAutoGenerationHeader(
// render.RenderStubs(name, module, ass.Types.Values.Where(t => (t is DefActor) || (t is DefComponent)).ToList()),
// "cs");
// var file = FileUtil.GetCsDefTypePath(name);
// var md5 = GenMd5AndAddCache(file, content);
// outputFiles.Add(new FileInfo() { FilePath = file, MD5 = md5 });
// }));
// break;
// }
// case "lua":
// {
// genCodeTasks.Add(Task.Run(() =>
// {
// var render = new Generate.Rep.LuaRender();
// var content = RenderUtils.ConcatAutoGenerationHeader(render.RenderTypes(ass.Types.Values.ToList()), "lua");
// var file = "RepTypes.lua";
// var md5 = GenMd5AndAddCache(file, content);
// outputFiles.Add(new FileInfo() { FilePath = file, MD5 = md5 });
// }));
// break;
// }
// default:
// {
// throw new Exception($"unknown lan:{proto.Arg.Define.Language}");
// }
// }
// Task.WhenAll(genCodeTasks).Wait();
// res.NewCodeFiles = outputFiles.ToList();
// ctx.Info(timer.EndPhaseAndLogToString());
// res.OK = true;
// }
// catch (Exception e)
// {
// res.OK = false;
// LogException(ctx, e);
// }
// proto.ReturnResult(session, res);
//}
}
}

View File

@ -1,18 +0,0 @@
using Luban.Job.Common.Types;
using System;
namespace Luban.Job.Db
{
static class TTypeExtensions
{
public static string DbCsDefineType(this TType type)
{
throw new NotImplementedException();
}
public static bool NeedSetChildrenRoot(this TType type)
{
throw new NotImplementedException();
}
}
}

View File

@ -0,0 +1,46 @@
using Luban.Job.Common.Types;
using Luban.Job.Common.TypeVisitors;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Luban.Job.Db.TypeVisitors
{
class BeanFieldHasSetterVisitor : AllTrueVisitor
{
public static BeanFieldHasSetterVisitor Ins { get; } = new BeanFieldHasSetterVisitor();
public override bool Accept(TBean type)
{
return type.IsDynamic;
}
public override bool Accept(TBytes type)
{
return false;
}
public override bool Accept(TArray type)
{
throw new NotSupportedException();
}
public override bool Accept(TList type)
{
return false;
}
public override bool Accept(TSet type)
{
return false;
}
public override bool Accept(TMap type)
{
return false;
}
}
}

View File

@ -0,0 +1,35 @@
using Luban.Job.Common.Types;
using Luban.Job.Common.TypeVisitors;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Luban.Job.Db.TypeVisitors
{
class CompatibleSerializeNeedEmbedVisitor : AllFalseVisitor
{
public static CompatibleSerializeNeedEmbedVisitor Ins { get; } = new CompatibleSerializeNeedEmbedVisitor();
public override bool Accept(TArray type)
{
return true;
}
public override bool Accept(TList type)
{
return true;
}
public override bool Accept(TSet type)
{
return true;
}
public override bool Accept(TMap type)
{
return true;
}
}
}

View File

@ -0,0 +1,133 @@
using Luban.Job.Common.Types;
using Luban.Job.Common.TypeVisitors;
namespace Luban.Job.Db.TypeVisitors
{
class DbCsCompatibleDeserializeVisitor : ITypeFuncVisitor<string, string, string>
{
public static DbCsCompatibleDeserializeVisitor Ins { get; } = new DbCsCompatibleDeserializeVisitor();
public string Accept(TBool type, string bufName, string fieldName)
{
return $"{fieldName} = {bufName}.ReadBool();";
}
public string Accept(TByte type, string bufName, string fieldName)
{
return $"{fieldName} = {bufName}.ReadByte();";
}
public string Accept(TShort type, string bufName, string fieldName)
{
return $"{fieldName} = {bufName}.ReadShort();";
}
public string Accept(TFshort type, string bufName, string fieldName)
{
return $"{fieldName} = {bufName}.ReadFshort();";
}
public string Accept(TInt type, string bufName, string fieldName)
{
return $"{fieldName} = {bufName}.ReadInt();";
}
public string Accept(TFint type, string bufName, string fieldName)
{
return $"{fieldName} = {bufName}.ReadFint();";
}
public string Accept(TLong type, string bufName, string fieldName)
{
return $"{fieldName} = {bufName}.ReadLong();";
}
public string Accept(TFlong type, string bufName, string fieldName)
{
return $"{fieldName} = {bufName}.ReadFlong();";
}
public string Accept(TFloat type, string bufName, string fieldName)
{
return $"{fieldName} = {bufName}.ReadFloat();";
}
public string Accept(TDouble type, string bufName, string fieldName)
{
return $"{fieldName} = {bufName}.ReadDouble();";
}
public string Accept(TEnum type, string bufName, string fieldName)
{
return $"{fieldName} = ({type.DefineEnum.FullName}){bufName}.ReadInt();";
}
public string Accept(TString type, string bufName, string fieldName)
{
return $"{fieldName} = {bufName}.ReadString();";
}
public string Accept(TBytes type, string bufName, string fieldName)
{
return $"{fieldName} = {bufName}.ReadBytes();";
}
public string Accept(TText type, string bufName, string fieldName)
{
return $"{fieldName} = {bufName}.ReadString();";
}
public string Accept(TBean type, string bufName, string fieldName)
{
var bean = type.Bean;
if (bean.IsNotAbstractType)
{
return $"{bufName}.EnterSegment(out var _state2_); {fieldName} = new {type.Apply(DbCsDefineTypeVisitor.Ins)}(); {fieldName}.Deserialize({bufName}); {bufName}.LeaveSegment(_state2_);";
}
else
{
return $"{bufName}.EnterSegment(out var _state2_); {fieldName} = {bean.FullName}.Deserialize{bean.Name}({bufName}); {bufName}.LeaveSegment(_state2_);";
}
}
public string Accept(TArray type, string bufName, string fieldName)
{
throw new System.NotSupportedException();
}
public string Accept(TList type, string bufName, string fieldName)
{
return $"int _tagType = {bufName}.ReadInt(); System.Diagnostics.Debug.Assert(_tagType == FieldTag.{type.ElementType.Apply(TagNameVisitor.Ins)}); while({bufName}.Size > 0) {{ {type.ElementType.Apply(DbCsDefineTypeVisitor.Ins)} _e; {type.ElementType.Apply(this, bufName, "_e")} {fieldName}.Add(_e);}}";
}
public string Accept(TSet type, string bufName, string fieldName)
{
return $"int _tagType = {bufName}.ReadInt(); System.Diagnostics.Debug.Assert(_tagType == FieldTag.{type.ElementType.Apply(TagNameVisitor.Ins)}); while({bufName}.Size > 0) {{ {type.ElementType.Apply(DbCsDefineTypeVisitor.Ins)} _e; {type.ElementType.Apply(this, bufName, "_e")} {fieldName}.Add(_e);}}";
}
public string Accept(TMap type, string bufName, string fieldName)
{
return $"int _keyTagType = {bufName}.ReadInt(); System.Diagnostics.Debug.Assert(_keyTagType == FieldTag.{type.KeyType.Apply(TagNameVisitor.Ins)}); int _valueTagType = {bufName}.ReadInt(); System.Diagnostics.Debug.Assert(_valueTagType == FieldTag.{type.ValueType.Apply(TagNameVisitor.Ins)}); while({bufName}.Size > 0) {{ {type.KeyType.Apply(DbCsDefineTypeVisitor.Ins)} _k; {type.KeyType.Apply(this, bufName, "_k")} {type.ValueType.Apply(DbCsDefineTypeVisitor.Ins)} _v; {type.ValueType.Apply(this, bufName, "_v")} {fieldName}.Add(_k, _v);}}";
}
public string Accept(TVector2 type, string bufName, string fieldName)
{
return $"{fieldName} = {bufName}.ReadVector2();";
}
public string Accept(TVector3 type, string bufName, string fieldName)
{
return $"{fieldName} = {bufName}.ReadVector3();";
}
public string Accept(TVector4 type, string bufName, string fieldName)
{
return $"{fieldName} = {bufName}.ReadVector4();";
}
public string Accept(TDateTime type, string bufName, string fieldName)
{
return $"{fieldName} = {bufName}.ReadInt();";
}
}
}

View File

@ -0,0 +1,139 @@
using Luban.Job.Common.Types;
using Luban.Job.Common.TypeVisitors;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Luban.Job.Db.TypeVisitors
{
class DbCsCompatibleSerializeVisitor : ITypeFuncVisitor<string, string, string>
{
public static DbCsCompatibleSerializeVisitor Ins { get; } = new DbCsCompatibleSerializeVisitor();
public string Accept(TBool type, string byteBufName, string fieldName)
{
return $"{byteBufName}.WriteBool({fieldName});";
}
public string Accept(TByte type, string byteBufName, string fieldName)
{
return $"{byteBufName}.WriteByte({fieldName});";
}
public string Accept(TShort type, string byteBufName, string fieldName)
{
return $"{byteBufName}.WriteShort({fieldName});";
}
public string Accept(TFshort type, string byteBufName, string fieldName)
{
return $"{byteBufName}.WriteFshort({fieldName});";
}
public string Accept(TInt type, string byteBufName, string fieldName)
{
return $"{byteBufName}.WriteInt({fieldName});";
}
public string Accept(TFint type, string byteBufName, string fieldName)
{
return $"{byteBufName}.WriteFint({fieldName});";
}
public string Accept(TLong type, string byteBufName, string fieldName)
{
return $"{byteBufName}.WriteLong({fieldName});";
}
public string Accept(TFlong type, string byteBufName, string fieldName)
{
return $"{byteBufName}.WriteFlong({fieldName});";
}
public string Accept(TFloat type, string byteBufName, string fieldName)
{
return $"{byteBufName}.WriteFloat({fieldName});";
}
public string Accept(TDouble type, string byteBufName, string fieldName)
{
return $"{byteBufName}.WriteDouble({fieldName});";
}
public string Accept(TEnum type, string byteBufName, string fieldName)
{
return $"{byteBufName}.WriteInt((int){fieldName});";
}
public string Accept(TString type, string byteBufName, string fieldName)
{
return $"{byteBufName}.WriteString({fieldName});";
}
public string Accept(TBytes type, string byteBufName, string fieldName)
{
return $"{byteBufName}.WriteBytes({fieldName});";
}
public string Accept(TText type, string byteBufName, string fieldName)
{
return $"{byteBufName}.WriteString({fieldName});";
}
public string Accept(TBean type, string byteBufName, string fieldName)
{
var bean = type.Bean;
if (bean.IsNotAbstractType)
{
return $"{byteBufName}.BeginWriteSegment(out var _state2_); {fieldName}.Serialize({byteBufName}); {byteBufName}.EndWriteSegment(_state2_);";
}
else
{
return $"{byteBufName}.BeginWriteSegment(out var _state2_); {bean.FullName}.Serialize{bean.Name}({byteBufName}, {fieldName});{byteBufName}.EndWriteSegment(_state2_);";
}
}
public string Accept(TArray type, string byteBufName, string fieldName)
{
throw new NotSupportedException();
}
public string Accept(TList type, string byteBufName, string fieldName)
{
return $"{byteBufName}.WriteInt(FieldTag.{type.ElementType.Apply(TagNameVisitor.Ins)}); foreach(var _e in {fieldName}) {{ {type.ElementType.Apply(this, byteBufName, "_e")} }}";
}
public string Accept(TSet type, string byteBufName, string fieldName)
{
return $"{byteBufName}.WriteInt(FieldTag.{type.ElementType.Apply(TagNameVisitor.Ins)}); foreach(var _e in {fieldName}) {{ {type.ElementType.Apply(this, byteBufName, "_e")} }}";
}
public string Accept(TMap type, string byteBufName, string fieldName)
{
return $"{byteBufName}.WriteInt(FieldTag.{type.KeyType.Apply(TagNameVisitor.Ins)}); {byteBufName}.WriteInt(FieldTag.{type.ValueType.Apply(TagNameVisitor.Ins)}); foreach((var _k, var _v) in {fieldName}) {{ {type.KeyType.Apply(this, byteBufName, "_k")} {type.ValueType.Apply(this, byteBufName, "_v")}}}";
}
public string Accept(TVector2 type, string byteBufName, string fieldName)
{
return $"{byteBufName}.WriteVector2({fieldName});";
}
public string Accept(TVector3 type, string byteBufName, string fieldName)
{
return $"{byteBufName}.WriteVector3({fieldName});";
}
public string Accept(TVector4 type, string byteBufName, string fieldName)
{
return $"{byteBufName}.WriteVector4({fieldName});";
}
public string Accept(TDateTime type, string x, string y)
{
throw new NotImplementedException();
}
}
}

View File

@ -0,0 +1,31 @@
using Luban.Job.Common.Types;
using Luban.Job.Common.TypeVisitors;
namespace Luban.Job.Db.TypeVisitors
{
class DbCsDefineTypeVisitor : DecoratorFuncVisitor<string>
{
public static DbCsDefineTypeVisitor Ins { get; } = new DbCsDefineTypeVisitor();
public override string DoAccept(TType type)
{
return type.Apply(CsDefineTypeName.Ins);
}
public override string Accept(TList type)
{
return $"Bright.Transaction.Collections.{(type.ElementType is TBean ? " PList2" : "PList1")}<{type.ElementType.Apply(this)}>";
}
public override string Accept(TSet type)
{
return $"Bright.Transaction.Collections.PSet1<{type.ElementType.Apply(this)}>";
}
public override string Accept(TMap type)
{
return $"Bright.Transaction.Collections.{(type.ValueType is TBean ? " PMap2" : "PMap1")}<{type.KeyType.Apply(this)}, {type.ValueType.Apply(this)}>";
}
}
}

View File

@ -86,7 +86,7 @@ namespace Luban.Job.Db.TypeVisitors
}
else
{
return $"{fieldName} = new {type.DbCsDefineType()}();";
return $"{fieldName} = new {type.Apply(DbCsDefineTypeVisitor.Ins)}();";
}
}
@ -97,17 +97,17 @@ namespace Luban.Job.Db.TypeVisitors
public string Accept(TList type, string fieldName, string logType)
{
return $"{fieldName} = new {type.DbCsDefineType()}(_v => new {logType}(this, _v));";
return $"{fieldName} = new {type.Apply(DbCsDefineTypeVisitor.Ins)}(_v => new {logType}(this, _v));";
}
public string Accept(TSet type, string fieldName, string logType)
{
return $"{fieldName} = new {type.DbCsDefineType()}(_v => new {logType}(this, _v));";
return $"{fieldName} = new {type.Apply(DbCsDefineTypeVisitor.Ins)}(_v => new {logType}(this, _v));";
}
public string Accept(TMap type, string fieldName, string logType)
{
return $"{fieldName} = new {type.DbCsDefineType()}(_v => new {logType}(this, _v));";
return $"{fieldName} = new {type.Apply(DbCsDefineTypeVisitor.Ins)}(_v => new {logType}(this, _v));";
}
public string Accept(TVector2 type, string fieldName, string logType)

View File

@ -109,7 +109,7 @@ namespace Luban.Job.Db.TypeVisitors
public string Accept(TMap type, string byteBufName, string fieldName)
{
return $"{byteBufName}.WriteSize({fieldName}.Count); foreach(var _e in {fieldName}) {{ {type.KeyType.Apply(this, byteBufName, "_e.Key")} {type.ValueType.Apply(this, byteBufName, "_e.Value")}}}";
return $"{byteBufName}.WriteSize({fieldName}.Count); foreach((var _k, var _v) in {fieldName}) {{ {type.KeyType.Apply(this, byteBufName, "_k")} {type.ValueType.Apply(this, byteBufName, "_v")}}}";
}

View File

@ -3,123 +3,29 @@ using Luban.Job.Common.TypeVisitors;
namespace Luban.Job.Db.TypeVisitors
{
class ImmutableTypeName : ITypeFuncVisitor<string>
class ImmutableTypeName : DecoratorFuncVisitor<string>
{
public static ImmutableTypeName Ins { get; } = new ImmutableTypeName();
public string Accept(TBool type)
public override string DoAccept(TType type)
{
return "";
}
public string Accept(TByte type)
public override string Accept(TList type)
{
return "";
return $"System.Collections.Immutable.ImmutableList<{type.ElementType.Apply(DbCsDefineTypeVisitor.Ins)}>";
}
public string Accept(TShort type)
public override string Accept(TSet type)
{
return "";
return $"System.Collections.Immutable.ImmutableHashSet<{type.ElementType.Apply(DbCsDefineTypeVisitor.Ins)}>";
}
public string Accept(TFshort type)
public override string Accept(TMap type)
{
return "";
}
public string Accept(TInt type)
{
return "";
}
public string Accept(TFint type)
{
return "";
}
public string Accept(TLong type)
{
return "";
}
public string Accept(TFlong type)
{
return "";
}
public string Accept(TFloat type)
{
return "";
}
public string Accept(TDouble type)
{
return "";
}
public string Accept(TEnum type)
{
return "";
}
public string Accept(TString type)
{
return "";
}
public string Accept(TBytes type)
{
return "";
}
public string Accept(TText type)
{
return "";
}
public string Accept(TBean type)
{
return "";
}
public string Accept(TArray type)
{
return "";
}
public string Accept(TList type)
{
return $"System.Collections.Immutable.ImmutableList<{type.ElementType.DbCsDefineType()}>";
}
public string Accept(TSet type)
{
return $"System.Collections.Immutable.ImmutableHashSet<{type.ElementType.DbCsDefineType()}>";
}
public string Accept(TMap type)
{
return $"System.Collections.Immutable.ImmutableDictionary<{type.KeyType.DbCsDefineType()}, {type.ValueType.DbCsDefineType()}>";
}
public string Accept(TVector2 type)
{
return "";
}
public string Accept(TVector3 type)
{
return "";
}
public string Accept(TVector4 type)
{
return "";
}
public string Accept(TDateTime type)
{
return "";
return $"System.Collections.Immutable.ImmutableDictionary<{type.KeyType.Apply(DbCsDefineTypeVisitor.Ins)}, {type.ValueType.Apply(DbCsDefineTypeVisitor.Ins)}>";
}
}
}

View File

@ -0,0 +1,30 @@
using Luban.Job.Common.Types;
using Luban.Job.Common.TypeVisitors;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Luban.Job.Db.TypeVisitors
{
class NeedSetChildrenRootVisitor : AllFalseVisitor
{
public static NeedSetChildrenRootVisitor Ins { get; } = new NeedSetChildrenRootVisitor();
public override bool Accept(TBean type)
{
return true;
}
public override bool Accept(TList type)
{
return type.ElementType is TBean;
}
public override bool Accept(TMap type)
{
return type.ValueType is TBean;
}
}
}

View File

@ -96,9 +96,9 @@ namespace {{x.namespace_with_top_module}}
switch (_buf.ReadInt())
{
case 0 : return null;
{{- for child in x.hierarchy_not_abstract_children}}
{{~ for child in x.hierarchy_not_abstract_children~}}
case {{child.full_name}}.ID: x = new {{child.full_name}}(); break;
{{-end}}
{{~end~}}
default: throw new SerializationException();
}
x.Deserialize(_buf);