diff --git a/src/Luban.Job.Cfg/Source/Defs/DefField.cs b/src/Luban.Job.Cfg/Source/Defs/DefField.cs index a78cfae..21d28c6 100644 --- a/src/Luban.Job.Cfg/Source/Defs/DefField.cs +++ b/src/Luban.Job.Cfg/Source/Defs/DefField.cs @@ -89,6 +89,15 @@ namespace Luban.Job.Cfg.Defs } } + public string CppRefValidatorDefine + { + get + { + var table = Assembly.GetCfgTable(Ref.FirstTable); + return $"{table.ValueTType.Apply(CppDefineTypeName.Ins)} {CppRefVarName};"; + } + } + public string TsRefValidatorDefine { get @@ -119,6 +128,8 @@ namespace Luban.Job.Cfg.Defs public string JavaRefVarName => $"{JavaStyleName}_Ref"; + public string CppRefVarName => $"{CsStyleName}_Ref"; + public string TsRefVarName => $"{TsStyleName}_Ref"; public string JavaGetterName => TypeUtil.ToJavaGetterName(Name); diff --git a/src/Luban.Job.Cfg/Source/Defs/TTypeTemplateExtends.cs b/src/Luban.Job.Cfg/Source/Defs/TTypeTemplateExtends.cs index 74975f4..800f6cc 100644 --- a/src/Luban.Job.Cfg/Source/Defs/TTypeTemplateExtends.cs +++ b/src/Luban.Job.Cfg/Source/Defs/TTypeTemplateExtends.cs @@ -71,11 +71,11 @@ namespace Luban.Job.Cfg.Defs var table = field.Assembly.GetCfgTable(field.Ref.FirstTable); if (field.IsNullable) { - return $"this.{refVarName} = this.{name} != null ? (({table.FullNameWithTopModule})_tables.get(\"{tableName}\")).get({name}) : null;"; + return $"this.{refVarName} = this.{name} != null ? (({table.CppFullName})_tables.get(\"{tableName}\")).get({name}) : null;"; } else { - return $"this.{refVarName} = (({table.FullNameWithTopModule})_tables.get(\"{tableName}\")).get({name});"; + return $"this.{refVarName} = (({table.CppFullName})_tables.get(\"{tableName}\")).get({name});"; } } @@ -84,6 +84,26 @@ namespace Luban.Job.Cfg.Defs return type.Apply(CppDeserializeVisitor.Ins, bufName, fieldName); } + public static string CppRecursiveResolve(DefField field, string tables) + { + return field.CType.Apply(CppRecursiveResolveVisitor.Ins, field.CsStyleName, tables); + } + + public static string CppRefValidatorResolve(DefField field) + { + var refVarName = field.CppRefVarName; + var name = field.CsStyleName; + var tableName = field.Ref.FirstTable; + var table = field.Assembly.GetCfgTable(field.Ref.FirstTable); + if (field.IsNullable) + { + return $"this->{refVarName} = this->{name} != nullptr ? (({table.CppFullName}*)(_tables[\"{tableName}\"]))->get(*(this->{name})) : nullptr;"; + } + else + { + return $"this->{refVarName} = (({table.CppFullName}*)(_tables[\"{tableName}\"]))->get({name});"; + } + } public static string GoDefineType(TType type) { diff --git a/src/Luban.Job.Cfg/Source/Generate/CppCodeBinRender.cs b/src/Luban.Job.Cfg/Source/Generate/CppCodeBinRender.cs index 6709ba4..20157f9 100644 --- a/src/Luban.Job.Cfg/Source/Generate/CppCodeBinRender.cs +++ b/src/Luban.Job.Cfg/Source/Generate/CppCodeBinRender.cs @@ -75,6 +75,12 @@ class {{name}} : public {{if parent_def_type}} {{parent_def_type.cpp_full_name}} {{field.comment}} */ {{cpp_define_type field.ctype}} {{field.cpp_style_name}}; + {{~if field.index_field~}} + std::unordered_map<{{cpp_define_type field.index_field.ctype}}, {{cpp_define_type field.ctype.element_type}}> {{field.cpp_style_name}}_Index; + {{~end~}} + {{~if field.gen_ref~}} + {{field.cpp_ref_validator_define}} + {{~end~}} {{~end~}} {{~if !x.is_abstract_type~}} @@ -83,6 +89,7 @@ class {{name}} : public {{if parent_def_type}} {{parent_def_type.cpp_full_name}} int getTypeId() const { return ID; } {{~end~}} + virtual void resolve(std::unordered_map& _tables); }; {{x.cpp_namespace_end}} @@ -136,18 +143,26 @@ class {{name}} const std::unordered_map<{{cpp_define_type key_type}}, {{cpp_define_type value_type}}>& getDataMap() const { return _dataMap; } const std::vector<{{cpp_define_type value_type}}>& getDataList() const { return _dataList; } - const {{cpp_define_type value_type}} get({{cpp_define_type key_type}} key) + {{cpp_define_type value_type}} get({{cpp_define_type key_type}} key) { auto it = _dataMap.find(key); return it != _dataMap.end() ? it->second : nullptr; } + void resolve(std::unordered_map& _tables) + { + for(auto v : _dataList) + { + v->resolve(_tables); + } + } + {{~else~}} private: {{cpp_define_type value_type}} _data; public: - const {{cpp_define_type value_type}} data() const { return _data; } + {{cpp_define_type value_type}} data() const { return _data; } bool load(ByteBuf& _buf) { @@ -158,14 +173,17 @@ class {{name}} return true; } + void resolve(std::unordered_map& _tables) + { + _data->resolve(_tables); + } {{~ for field in value_type.bean.hierarchy_export_fields ~}} /** {{field.comment}} */ - const {{cpp_define_type field.ctype}}& {{field.cpp_getter_name}}() const { return _data->{{field.cpp_style_name}}; } + {{cpp_define_type field.ctype}}& {{field.cpp_getter_name}}() const { return _data->{{field.cpp_style_name}}; } {{~end~}} - {{~end~}} }; {{x.cpp_namespace_end}} @@ -190,12 +208,19 @@ class {{name}} {{table.cpp_full_name}} {{table.name}}; {{~end~}} - bool load(std::function loader) + bool load(std::function loader) { + std::unordered_map __tables__; + ByteBuf buf; {{~for table in tables~}} if (!loader(buf, ""{{table.output_data_file}}"")) return false; if (!{{table.name}}.load(buf)) return false; + __tables__[""{{table.full_name}}""] = &{{table.name}}; + {{~end~}} + + {{~for table in tables ~}} + {{table.name}}.resolve(__tables__); {{~end~}} return true; } @@ -225,6 +250,7 @@ using ByteBuf = bright::serialization::ByteBuf; namespace {{x.top_module}} { {{~for type in x.types~}} + bool {{type.cpp_full_name}}::deserialize(ByteBuf& _buf) { {{~if type.parent_def_type~}} @@ -267,6 +293,20 @@ namespace {{x.top_module}} } {{~end~}} } + + void {{type.cpp_full_name}}::resolve(std::unordered_map& _tables) + { + {{~if type.parent_def_type~}} + {{type.parent_def_type.name}}::resolve(_tables); + {{~end~}} + {{~ for field in type.export_fields ~}} + {{~if field.gen_ref~}} + {{cpp_ref_validator_resolve field}} + {{~else if field.has_recursive_ref~}} + {{cpp_recursive_resolve field '_tables'}} + {{~end~}} + {{~end~}} + } {{~end~}} } "); diff --git a/src/Luban.Job.Cfg/Source/TypeVisitors/CppDeserializeVisitor.cs b/src/Luban.Job.Cfg/Source/TypeVisitors/CppDeserializeVisitor.cs index 866f68d..d1d8850 100644 --- a/src/Luban.Job.Cfg/Source/TypeVisitors/CppDeserializeVisitor.cs +++ b/src/Luban.Job.Cfg/Source/TypeVisitors/CppDeserializeVisitor.cs @@ -11,17 +11,12 @@ namespace Luban.Job.Cfg.TypeVisitors { if (type.IsNullable) { - return $"{{ bool _read_succ_; if(!{bufName}.readBool(_read_succ_)){{return false;}} if(_read_succ_) {{ {type.Apply(CppUnderingDeserializeVisitor.Ins, bufName, fieldName)} }} else {{ {fieldName} = {{}}; }} }}"; + return $"{{ bool _has_value_; if(!{bufName}.readBool(_has_value_)){{return false;}} if(_has_value_) {{{type.Apply(CppUnderingDefineTypeName.Ins)} _temp_; {type.Apply(CppUnderingDeserializeVisitor.Ins, bufName, "_temp_")} {(type.IsBean ? $"{fieldName} = _temp_;" : $"{fieldName} = new {type.Apply(CppUnderingDefineTypeName.Ins)}; *{fieldName} = _temp_;")} }} else {{ {fieldName} = nullptr; }} }}"; } else { return type.Apply(CppUnderingDeserializeVisitor.Ins, bufName, fieldName); } } - - public override string Accept(TBean type, string bufName, string fieldName) - { - return type.Apply(CppUnderingDeserializeVisitor.Ins, bufName, fieldName); - } } } diff --git a/src/Luban.Job.Cfg/Source/TypeVisitors/CppRecursiveResolveVisitor.cs b/src/Luban.Job.Cfg/Source/TypeVisitors/CppRecursiveResolveVisitor.cs new file mode 100644 index 0000000..c7b9c19 --- /dev/null +++ b/src/Luban.Job.Cfg/Source/TypeVisitors/CppRecursiveResolveVisitor.cs @@ -0,0 +1,161 @@ +using Luban.Job.Common.Types; +using Luban.Job.Common.TypeVisitors; +using System; + +namespace Luban.Job.Cfg.TypeVisitors +{ + class CppRecursiveResolveVisitor : ITypeFuncVisitor + { + public static CppRecursiveResolveVisitor Ins { get; } = new(); + + public string Accept(TBool type, string fieldName, string tablesName) + { + throw new NotImplementedException(); + } + + public string Accept(TByte type, string fieldName, string tablesName) + { + throw new NotImplementedException(); + } + + public string Accept(TShort type, string fieldName, string tablesName) + { + throw new NotImplementedException(); + } + + public string Accept(TFshort type, string fieldName, string tablesName) + { + throw new NotImplementedException(); + } + + public string Accept(TInt type, string fieldName, string tablesName) + { + throw new NotImplementedException(); + } + + public string Accept(TFint type, string fieldName, string tablesName) + { + throw new NotImplementedException(); + } + + public string Accept(TLong type, string fieldName, string tablesName) + { + throw new NotImplementedException(); + } + + public string Accept(TFlong type, string fieldName, string tablesName) + { + throw new NotImplementedException(); + } + + public string Accept(TFloat type, string fieldName, string tablesName) + { + throw new NotImplementedException(); + } + + public string Accept(TDouble type, string fieldName, string tablesName) + { + throw new NotImplementedException(); + } + + public string Accept(TEnum type, string fieldName, string tablesName) + { + throw new NotImplementedException(); + } + + public string Accept(TString type, string fieldName, string tablesName) + { + throw new NotImplementedException(); + } + + public string Accept(TBytes type, string fieldName, string tablesName) + { + throw new NotImplementedException(); + } + + public string Accept(TText type, string fieldName, string tablesName) + { + throw new NotImplementedException(); + } + + public string Accept(TBean type, string fieldName, string tablesName) + { + if (type.IsNullable) + { + return $"if ({fieldName} != nullptr) {fieldName}->resolve({tablesName});"; + } + else + { + return $"{fieldName}->resolve({tablesName});"; + } + } + + public string Accept(TArray type, string fieldName, string tablesName) + { + if (type.ElementType.IsNullable) + { + return $@"for(auto _e : {fieldName}) {{ if (_e != nullptr) {{ _e->resolve({tablesName}); }} }}"; + } + else + { + return $@"for(auto _e : {fieldName}) {{ _e->resolve({tablesName}); }}"; + } + } + + public string Accept(TList type, string fieldName, string tablesName) + { + if (type.ElementType.IsNullable) + { + return $@"for(auto _e : {fieldName}) {{ if (_e != nullptr) {{ _e->resolve({tablesName}); }} }}"; + } + else + { + return $@"for(auto _e : {fieldName}) {{ _e->resolve({tablesName}); }}"; + } + } + + public string Accept(TSet type, string fieldName, string tablesName) + { + if (type.ElementType.IsNullable) + { + return $@"for(auto _e : {fieldName}) {{ if (_e != nullptr) {{ _e->resolve({tablesName}); }} }}"; + } + else + { + return $@"for(auto _e : {fieldName}) {{ _e->resolve({tablesName}); }}"; + } + } + + public string Accept(TMap type, string fieldName, string tablesName) + { + if (type.ValueType.IsNullable) + { + return $@"for(auto _e : {fieldName}) {{ if (_e.second != nullptr) {{ _e.second->resolve({tablesName}); }} }}"; + } + else + { + return $@"for(auto _e : {fieldName}) {{ _e.second->resolve({tablesName}); }}"; + } + } + + public string Accept(TVector2 type, string fieldName, string tablesName) + { + throw new NotImplementedException(); + } + + public string Accept(TVector3 type, string fieldName, string tablesName) + { + throw new NotImplementedException(); + } + + public string Accept(TVector4 type, string fieldName, string tablesName) + { + throw new NotImplementedException(); + } + + public string Accept(TDateTime type, string fieldName, string tablesName) + { + throw new NotImplementedException(); + } + } +} diff --git a/src/Luban.Job.Cfg/Source/TypeVisitors/CppUnderingDeserializeVisitor.cs b/src/Luban.Job.Cfg/Source/TypeVisitors/CppUnderingDeserializeVisitor.cs index 8d7dd93..ed4d841 100644 --- a/src/Luban.Job.Cfg/Source/TypeVisitors/CppUnderingDeserializeVisitor.cs +++ b/src/Luban.Job.Cfg/Source/TypeVisitors/CppUnderingDeserializeVisitor.cs @@ -59,7 +59,7 @@ namespace Luban.Job.Cfg.TypeVisitors public string Accept(TEnum type, string bufName, string fieldName) { - return $"{{int _temp_; if(!{bufName}.readInt(_temp_)) return false; {fieldName} = {type.DefineEnum.CppFullName}(_temp_); }}"; + return $"{{int __enum_temp__; if(!{bufName}.readInt(__enum_temp__)) return false; {fieldName} = {type.DefineEnum.CppFullName}(__enum_temp__); }}"; } public string Accept(TString type, string bufName, string fieldName) diff --git a/src/Luban.Job.Common/Source/TypeVisitors/CppDefineTypeName.cs b/src/Luban.Job.Common/Source/TypeVisitors/CppDefineTypeName.cs index dcfd9a3..cd8063d 100644 --- a/src/Luban.Job.Common/Source/TypeVisitors/CppDefineTypeName.cs +++ b/src/Luban.Job.Common/Source/TypeVisitors/CppDefineTypeName.cs @@ -9,7 +9,7 @@ namespace Luban.Job.Common.TypeVisitors public override string DoAccept(TType type) { //return type.IsNullable ? $"std::optional<{type.Apply(CppUnderingDefineTypeName.Ins)}>" : type.Apply(CppUnderingDefineTypeName.Ins); - return type.Apply(CppUnderingDefineTypeName.Ins); + return type.Apply(CppUnderingDefineTypeName.Ins) + (type.IsNullable ? "*" : ""); } public override string Accept(TBean type)