diff --git a/src/Luban.Cpp/CodeTarget/CppBinCodeTarget.cs b/src/Luban.Cpp/CodeTarget/CppBinRawptrCodeTarget.cs similarity index 61% rename from src/Luban.Cpp/CodeTarget/CppBinCodeTarget.cs rename to src/Luban.Cpp/CodeTarget/CppBinRawptrCodeTarget.cs index 79bfb13c..ea017a74 100644 --- a/src/Luban.Cpp/CodeTarget/CppBinCodeTarget.cs +++ b/src/Luban.Cpp/CodeTarget/CppBinRawptrCodeTarget.cs @@ -4,12 +4,12 @@ namespace Luban.Cpp.CodeTarget; -[CodeTarget("cpp-bin")] -public class CppBinCodeTarget : CppCodeTargetBase +[CodeTarget("cpp-rawptr-bin")] +public class CppBinRawptrCodeTarget : CppCodeTargetBase { protected override void OnCreateTemplateContext(TemplateContext ctx) { base.OnCreateTemplateContext(ctx); - ctx.PushGlobal(new CppBinTemplateExtension()); + ctx.PushGlobal(new CppRawptrBinTemplateExtension()); } } diff --git a/src/Luban.Cpp/CodeTarget/CppBinSharedptrCodeTarget.cs b/src/Luban.Cpp/CodeTarget/CppBinSharedptrCodeTarget.cs new file mode 100644 index 00000000..e05a5866 --- /dev/null +++ b/src/Luban.Cpp/CodeTarget/CppBinSharedptrCodeTarget.cs @@ -0,0 +1,15 @@ +using Luban.CodeTarget; +using Luban.Cpp.TemplateExtensions; +using Scriban; + +namespace Luban.Cpp.CodeTarget; + +[CodeTarget("cpp-sharedptr-bin")] +public class CppBinSharedptrCodeTarget : CppCodeTargetBase +{ + protected override void OnCreateTemplateContext(TemplateContext ctx) + { + base.OnCreateTemplateContext(ctx); + ctx.PushGlobal(new CppSharedptrBinTemplateExtension()); + } +} diff --git a/src/Luban.Cpp/Luban.Cpp.csproj b/src/Luban.Cpp/Luban.Cpp.csproj index be936e18..54aba30b 100644 --- a/src/Luban.Cpp/Luban.Cpp.csproj +++ b/src/Luban.Cpp/Luban.Cpp.csproj @@ -11,6 +11,21 @@ + + Always + + + Always + + + Always + + + Always + + + Always + Always @@ -32,19 +47,19 @@ Always - + Always - + Always - + Always - + Always - + Always @@ -52,8 +67,4 @@ - - - - diff --git a/src/Luban.Cpp/TemplateExtensions/CppBinTemplateExtension.cs b/src/Luban.Cpp/TemplateExtensions/CppBinTemplateExtension.cs deleted file mode 100644 index e363d66e..00000000 --- a/src/Luban.Cpp/TemplateExtensions/CppBinTemplateExtension.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Luban.Cpp.TypeVisitors; -using Luban.Types; -using Scriban.Runtime; - -namespace Luban.Cpp.TemplateExtensions; - -public class CppBinTemplateExtension : ScriptObject -{ - public static string Deserialize(string bufName, string fieldName, TType type) - { - return type.Apply(CppDeserializeVisitor.Ins, bufName, fieldName); - } -} diff --git a/src/Luban.Cpp/TemplateExtensions/CppRawptrBinTemplateExtension.cs b/src/Luban.Cpp/TemplateExtensions/CppRawptrBinTemplateExtension.cs new file mode 100644 index 00000000..d622ebcd --- /dev/null +++ b/src/Luban.Cpp/TemplateExtensions/CppRawptrBinTemplateExtension.cs @@ -0,0 +1,18 @@ +using Luban.Cpp.TypeVisitors; +using Luban.Types; +using Scriban.Runtime; + +namespace Luban.Cpp.TemplateExtensions; + +public class CppRawptrBinTemplateExtension : ScriptObject +{ + public static string Deserialize(string bufName, string fieldName, TType type) + { + return type.Apply(CppRawptrDeserializeVisitor.Ins, bufName, fieldName); + } + + public static string DeclaringTypeName(TType type) + { + return type.Apply(CppRawptrDeclaringTypeNameVisitor.Ins); + } +} diff --git a/src/Luban.Cpp/TemplateExtensions/CppSharedptrBinTemplateExtension.cs b/src/Luban.Cpp/TemplateExtensions/CppSharedptrBinTemplateExtension.cs new file mode 100644 index 00000000..0ce46927 --- /dev/null +++ b/src/Luban.Cpp/TemplateExtensions/CppSharedptrBinTemplateExtension.cs @@ -0,0 +1,18 @@ +using Luban.Cpp.TypeVisitors; +using Luban.Types; +using Scriban.Runtime; + +namespace Luban.Cpp.TemplateExtensions; + +public class CppSharedptrBinTemplateExtension : ScriptObject +{ + public static string Deserialize(string bufName, string fieldName, TType type) + { + return type.Apply(CppSharedptrDeserializeVisitor.Ins, bufName, fieldName); + } + + public static string DeclaringTypeName(TType type) + { + return type.Apply(CppSharedptrDeclaringTypeNameVisitor.Ins); + } +} diff --git a/src/Luban.Cpp/TemplateExtensions/CppTemplateExtension.cs b/src/Luban.Cpp/TemplateExtensions/CppTemplateExtension.cs index 200db45b..449638b8 100644 --- a/src/Luban.Cpp/TemplateExtensions/CppTemplateExtension.cs +++ b/src/Luban.Cpp/TemplateExtensions/CppTemplateExtension.cs @@ -19,11 +19,6 @@ public static string MakeCppName(string typeName) return TypeUtil.MakeCppFullName("", typeName); } - public static string DeclaringTypeName(TType type) - { - return type.Apply(DeclaringTypeNameVisitor.Ins); - } - public static string GetterName(string originName) { var words = originName.Split('_').Where(s => !string.IsNullOrWhiteSpace(s)).ToArray(); diff --git a/src/Luban.Cpp/Templates/cpp-rawptr-bin/bean.sbn b/src/Luban.Cpp/Templates/cpp-rawptr-bin/bean.sbn new file mode 100644 index 00000000..2b856b0a --- /dev/null +++ b/src/Luban.Cpp/Templates/cpp-rawptr-bin/bean.sbn @@ -0,0 +1,32 @@ +{{namespace_with_grace_begin __namespace}} + +{{~if __this.comment != '' ~}} +/** + * {{escape_comment __this.comment}} + */ +{{~end~}} +struct {{__name}} : public{{if __parent_def_type}} {{make_cpp_name __parent_def_type.full_name}} {{else}} luban::CfgBean {{end}} +{ + static bool deserialize{{__name}}(::luban::ByteBuf& _buf, {{__name}}*& _out); + + virtual ~{{__name}}() {} + + bool deserialize(::luban::ByteBuf& _buf); + + {{~ for field in __export_fields ~}} +{{~if field.comment != '' ~}} + /** + * {{escape_comment field.comment}} + */ +{{~end~}} + {{declaring_type_name field.ctype}} {{format_field_name __code_style field.name}}; + {{~end~}} + +{{~if !__this.is_abstract_type~}} + static constexpr int __ID__ = {{__this.id}}; + + int getTypeId() const override { return __ID__; } +{{~end~}} +}; + +{{namespace_with_grace_end __namespace}} diff --git a/src/Luban.Cpp/Templates/cpp-rawptr-bin/schema_cpp.sbn b/src/Luban.Cpp/Templates/cpp-rawptr-bin/schema_cpp.sbn new file mode 100644 index 00000000..72a926de --- /dev/null +++ b/src/Luban.Cpp/Templates/cpp-rawptr-bin/schema_cpp.sbn @@ -0,0 +1,45 @@ +#include "{{__schema_header_file}}" + +{{namespace_with_grace_begin __top_module}} + +{{~for bean in __beans~}} + +bool {{make_cpp_name bean.full_name}}::deserialize(::luban::ByteBuf& _buf) +{ + {{~if bean.parent_def_type~}} + if (!{{make_cpp_name bean.parent_def_type.full_name}}::deserialize(_buf)) + { + return false; + } + {{~end~}} + + {{~ for field in bean.export_fields ~}} + {{deserialize '_buf' (format_field_name __code_style field.name) field.ctype}} + {{~end~}} + + return true; +} + +{{~if bean.is_abstract_type~}} +bool {{make_cpp_name bean.full_name}}::deserialize{{bean.name}}(::luban::ByteBuf& _buf, {{make_cpp_name bean.full_name}}*& _out) +{ + int32_t id; + if (!_buf.readInt(id)) return false; + switch (id) + { + {{~for child in bean.hierarchy_not_abstract_children~}} + case {{make_type_cpp_name child}}::__ID__: { _out = LUBAN_NEW({{make_type_cpp_name child}}){}; if (_out->deserialize(_buf)) { return true; } else { _out = nullptr; return false;} } + {{~end~}} + default: { _out = nullptr; return false;} + } +} +{{~else~}} +bool {{make_cpp_name bean.full_name}}::deserialize{{bean.name}}(::luban::ByteBuf& _buf, {{make_cpp_name bean.full_name}}*& _out) +{ + _out = LUBAN_NEW({{make_type_cpp_name bean}}){}; + return _out->deserialize(_buf); +} +{{~end~}} + +{{~end~}} +{{namespace_with_grace_end __top_module}} diff --git a/src/Luban.Cpp/Templates/cpp-bin/schema_h.sbn b/src/Luban.Cpp/Templates/cpp-rawptr-bin/schema_h.sbn similarity index 100% rename from src/Luban.Cpp/Templates/cpp-bin/schema_h.sbn rename to src/Luban.Cpp/Templates/cpp-rawptr-bin/schema_h.sbn diff --git a/src/Luban.Cpp/Templates/cpp-rawptr-bin/table.sbn b/src/Luban.Cpp/Templates/cpp-rawptr-bin/table.sbn new file mode 100644 index 00000000..511a5463 --- /dev/null +++ b/src/Luban.Cpp/Templates/cpp-rawptr-bin/table.sbn @@ -0,0 +1,134 @@ +{{namespace_with_grace_begin __namespace}} + +{{~if __this.comment != '' ~}} +/** + * {{escape_comment __this.comment}} + */ +{{~end~}} + +class {{__name}} +{ + {{~if __this.is_map_table ~}} + private: + ::luban::HashMap<{{declaring_type_name __key_type}}, {{declaring_type_name __value_type}}> _dataMap; + ::luban::Vector<{{declaring_type_name __value_type}}> _dataList; + + public: + ~{{__name}}() + { + for (auto& _v : _dataList) + { + LUBAN_FREE(_v); + } + } + + bool load(::luban::ByteBuf& _buf) + { + int n; + if (!_buf.readSize(n)) return false; + for(; n > 0 ; --n) + { + {{declaring_type_name __value_type}} _v; + {{deserialize '_buf' '_v' __value_type}} + _dataList.push_back(_v); + _dataMap[_v->{{format_field_name __code_style __this.index_field.name}}] = _v; + } + return true; + } + + const ::luban::HashMap<{{declaring_type_name __key_type}}, {{declaring_type_name __value_type}}>& getDataMap() const { return _dataMap; } + const ::luban::Vector<{{declaring_type_name __value_type}}>& getDataList() const { return _dataList; } + + {{declaring_type_name __value_type}} get({{declaring_type_name __key_type}} key) + { + auto it = _dataMap.find(key); + return it != _dataMap.end() ? it->second : nullptr; + } + + {{~else if __this.is_list_table~}} + private: + ::luban::Vector<{{declaring_type_name __value_type}}> _dataList; + {{~if __this.is_union_index~}} + + {{~else if !__this.index_list.empty?~}} + {{~for idx in __this.index_list~}} + ::luban::HashMap<{{declaring_type_name idx.type}}, {{declaring_type_name __value_type}}> _dataMap_{{idx.index_field.name}}; + {{~end~}} + {{~else~}} + {{~end~}} + + public: + bool load(::luban::ByteBuf& _buf) + { + int n; + if (!_buf.readSize(n)) return false; + for(; n > 0 ; --n) + { + {{declaring_type_name __value_type}} _v; + {{deserialize '_buf' '_v' __value_type}} + _dataList.push_back(_v); + {{~if __this.is_union_index~}} + + {{~else if !__this.index_list.empty?~}} + {{~for idx in __this.index_list~}} + _dataMap_{{idx.index_field.name}}[_v->{{idx.index_field.name}}] = _v; + {{~end~}} + {{~else~}} + {{~end~}} + } + return true; + } + + const ::luban::Vector<{{declaring_type_name __value_type}}>& getDataList() const { return _dataList; } + + {{~if __this.is_union_index~}} + + {{~else if !__this.index_list.empty?~}} + {{~for idx in __this.index_list~}} + ::luban::HashMap<{{declaring_type_name idx.type}}, {{declaring_type_name __value_type}}>& getDataMapBy{{idx.index_field.name}}() + { + return _dataMap_{{idx.index_field.name}}; + } + + {{declaring_type_name __value_type}} getBy{{idx.index_field.name}}({{declaring_type_name idx.type}} key) + { + auto it = _dataMap_{{idx.index_field.name}}.find(key); + return it != _dataMap_{{idx.index_field.name}}.end() ? it->second : nullptr; + } + {{~end~}} + {{~else~}} + + {{declaring_type_name __value_type}} get(size_t index) const + { + return _dataList[index]; + } + {{~end~}} + {{~else~}} + private: + {{declaring_type_name __value_type}} _data; + + public: + {{declaring_type_name __value_type}} data() const { return _data; } + + bool load(::luban::ByteBuf& _buf) + { + int n; + if (!_buf.readSize(n)) return false; + if (n != 1) return false; + {{deserialize '_buf' '_data' __value_type}} + return true; + } + + + {{~ for field in __value_type.def_bean.hierarchy_export_fields ~}} +{{~if field.comment != '' ~}} + /** + * {{escape_comment field.comment}} + */ +{{~end~}} + {{declaring_type_name field.ctype}}& {{getter_name field.name}}() const { return _data->{{format_field_name __code_style field.name}}; } + {{~end~}} + {{~end~}} +}; + +{{namespace_with_grace_end __namespace}} diff --git a/src/Luban.Cpp/Templates/cpp-bin/tables.sbn b/src/Luban.Cpp/Templates/cpp-rawptr-bin/tables.sbn similarity index 100% rename from src/Luban.Cpp/Templates/cpp-bin/tables.sbn rename to src/Luban.Cpp/Templates/cpp-rawptr-bin/tables.sbn diff --git a/src/Luban.Cpp/Templates/cpp-bin/bean.sbn b/src/Luban.Cpp/Templates/cpp-sharedptr-bin/bean.sbn similarity index 100% rename from src/Luban.Cpp/Templates/cpp-bin/bean.sbn rename to src/Luban.Cpp/Templates/cpp-sharedptr-bin/bean.sbn diff --git a/src/Luban.Cpp/Templates/cpp-bin/schema_cpp.sbn b/src/Luban.Cpp/Templates/cpp-sharedptr-bin/schema_cpp.sbn similarity index 95% rename from src/Luban.Cpp/Templates/cpp-bin/schema_cpp.sbn rename to src/Luban.Cpp/Templates/cpp-sharedptr-bin/schema_cpp.sbn index b1cc33b4..4630e54c 100644 --- a/src/Luban.Cpp/Templates/cpp-bin/schema_cpp.sbn +++ b/src/Luban.Cpp/Templates/cpp-sharedptr-bin/schema_cpp.sbn @@ -23,7 +23,7 @@ bool {{make_cpp_name bean.full_name}}::deserialize(::luban::ByteBuf& _buf) bool {{make_cpp_name bean.full_name}}::deserialize{{bean.name}}(::luban::ByteBuf& _buf, ::luban::SharedPtr<{{make_cpp_name bean.full_name}}>& _out) { {{~if bean.is_abstract_type~}} - int id; + int32_t id; if (!_buf.readInt(id)) return false; switch (id) { @@ -47,4 +47,4 @@ bool {{make_cpp_name bean.full_name}}::deserialize{{bean.name}}(::luban::ByteBuf } {{~end~}} -{{namespace_with_grace_end __top_module}} \ No newline at end of file +{{namespace_with_grace_end __top_module}} diff --git a/src/Luban.Cpp/Templates/cpp-sharedptr-bin/schema_h.sbn b/src/Luban.Cpp/Templates/cpp-sharedptr-bin/schema_h.sbn new file mode 100644 index 00000000..90ba84cb --- /dev/null +++ b/src/Luban.Cpp/Templates/cpp-sharedptr-bin/schema_h.sbn @@ -0,0 +1,21 @@ +#pragma once +#include +#include + +#include "CfgBean.h" + +{{namespace_with_grace_begin __top_module}} + +{{__enum_codes~}} + +{{~for b in __beans~}} +{{namespace_with_grace_begin b.namespace}} struct {{b.name}}; {{namespace_with_grace_end b.namespace}} +{{~end~}} + +{{~__bean_codes~}} + +{{~__table_codes~}} + +{{__tables_code}} + +{{namespace_with_grace_end __top_module}} diff --git a/src/Luban.Cpp/Templates/cpp-bin/table.sbn b/src/Luban.Cpp/Templates/cpp-sharedptr-bin/table.sbn similarity index 100% rename from src/Luban.Cpp/Templates/cpp-bin/table.sbn rename to src/Luban.Cpp/Templates/cpp-sharedptr-bin/table.sbn diff --git a/src/Luban.Cpp/Templates/cpp-sharedptr-bin/tables.sbn b/src/Luban.Cpp/Templates/cpp-sharedptr-bin/tables.sbn new file mode 100644 index 00000000..76354d59 --- /dev/null +++ b/src/Luban.Cpp/Templates/cpp-sharedptr-bin/tables.sbn @@ -0,0 +1,23 @@ +class {{__name}} +{ + public: + {{~for table in __tables ~}} +{{~if table.comment != '' ~}} + /** + * {{escape_comment table.comment}} + */ +{{~end~}} + {{make_cpp_name table.full_name}} {{table.name}}; + {{~end~}} + + bool load(::luban::Loader<::luban::ByteBuf> loader) + { + ::luban::ByteBuf buf; + {{~for table in __tables~}} + buf.clear(); + if (!loader(buf, "{{table.output_data_file}}")) return false; + if (!{{table.name}}.load(buf)) return false; + {{~end~}} + return true; + } +}; diff --git a/src/Luban.Cpp/TypeVisitors/CppDeserializeVisitor.cs b/src/Luban.Cpp/TypeVisitors/CppDeserializeVisitor.cs deleted file mode 100644 index 166b5645..00000000 --- a/src/Luban.Cpp/TypeVisitors/CppDeserializeVisitor.cs +++ /dev/null @@ -1,21 +0,0 @@ -using Luban.Types; -using Luban.TypeVisitors; - -namespace Luban.Cpp.TypeVisitors; - -public class CppDeserializeVisitor : DecoratorFuncVisitor -{ - public static CppDeserializeVisitor Ins { get; } = new CppDeserializeVisitor(); - - public override string DoAccept(TType type, string bufName, string fieldName) - { - if (type.IsNullable) - { - return $"{{ bool _has_value_; if(!{bufName}.readBool(_has_value_)){{return false;}} if(_has_value_) {{ {fieldName}.reset({(type.IsBean ? "" : $"new {type.Apply(CppUnderlyingDeclaringTypeNameVisitor.Ins)}()")}); {type.Apply(CppUnderlyingDeserializeVisitor.Ins, bufName, $"{(type.IsBean ? "" : "*")}{fieldName}")} }} else {{ {fieldName}.reset(); }} }}"; - } - else - { - return type.Apply(CppUnderlyingDeserializeVisitor.Ins, bufName, fieldName); - } - } -} diff --git a/src/Luban.Cpp/TypeVisitors/CppRawptrDeclaringTypeNameVisitor.cs b/src/Luban.Cpp/TypeVisitors/CppRawptrDeclaringTypeNameVisitor.cs new file mode 100644 index 00000000..fe81344c --- /dev/null +++ b/src/Luban.Cpp/TypeVisitors/CppRawptrDeclaringTypeNameVisitor.cs @@ -0,0 +1,14 @@ +using Luban.Types; +using Luban.TypeVisitors; + +namespace Luban.Cpp.TypeVisitors; + +public class CppRawptrDeclaringTypeNameVisitor : DecoratorFuncVisitor +{ + public static CppRawptrDeclaringTypeNameVisitor Ins { get; } = new CppRawptrDeclaringTypeNameVisitor(); + + public override string DoAccept(TType type) + { + return type.IsNullable && !type.IsBean ? $"{type.Apply(CppRawptrUnderlyingDeclaringTypeNameVisitor.Ins)}*" : type.Apply(CppRawptrUnderlyingDeclaringTypeNameVisitor.Ins); + } +} diff --git a/src/Luban.Cpp/TypeVisitors/CppRawptrDeserializeVisitor.cs b/src/Luban.Cpp/TypeVisitors/CppRawptrDeserializeVisitor.cs new file mode 100644 index 00000000..0cb6e311 --- /dev/null +++ b/src/Luban.Cpp/TypeVisitors/CppRawptrDeserializeVisitor.cs @@ -0,0 +1,21 @@ +using Luban.Types; +using Luban.TypeVisitors; + +namespace Luban.Cpp.TypeVisitors; + +public class CppRawptrDeserializeVisitor : DecoratorFuncVisitor +{ + public static CppRawptrDeserializeVisitor Ins { get; } = new CppRawptrDeserializeVisitor(); + + public override string DoAccept(TType type, string bufName, string fieldName) + { + if (type.IsNullable) + { + return $"{{ bool _has_value_; if(!{bufName}.readBool(_has_value_)){{return false;}} if(_has_value_) {{ {fieldName} = {(type.IsBean ? "nullptr" : $"new {type.Apply(CppUnderlyingDeclaringTypeNameVisitor.Ins)}{{}}")}; {type.Apply(CppRawptrUnderlyingDeserializeVisitor.Ins, bufName, type.IsBean ? fieldName : $"*{fieldName}", CppRawptrDeclaringTypeNameVisitor.Ins)} }} else {{ {fieldName} = nullptr; }} }}"; + } + else + { + return type.Apply(CppRawptrUnderlyingDeserializeVisitor.Ins, bufName, fieldName, CppRawptrDeclaringTypeNameVisitor.Ins); + } + } +} diff --git a/src/Luban.Cpp/TypeVisitors/CppRawptrUnderlyingDeclaringTypeNameVisitor.cs b/src/Luban.Cpp/TypeVisitors/CppRawptrUnderlyingDeclaringTypeNameVisitor.cs new file mode 100644 index 00000000..0684d9b7 --- /dev/null +++ b/src/Luban.Cpp/TypeVisitors/CppRawptrUnderlyingDeclaringTypeNameVisitor.cs @@ -0,0 +1,15 @@ +using Luban.Cpp.TemplateExtensions; +using Luban.Types; + +namespace Luban.Cpp.TypeVisitors; + +public class CppRawptrUnderlyingDeclaringTypeNameVisitor : CppUnderlyingDeclaringTypeNameVisitor +{ + public new static CppRawptrUnderlyingDeclaringTypeNameVisitor Ins { get; } = new(); + + public override string Accept(TBean type) + { + string typeName = CppTemplateExtension.MakeTypeCppName(type.DefBean); + return $"{typeName}*"; + } +} diff --git a/src/Luban.Cpp/TypeVisitors/CppRawptrUnderlyingDeserializeVisitor.cs b/src/Luban.Cpp/TypeVisitors/CppRawptrUnderlyingDeserializeVisitor.cs new file mode 100644 index 00000000..495f18f9 --- /dev/null +++ b/src/Luban.Cpp/TypeVisitors/CppRawptrUnderlyingDeserializeVisitor.cs @@ -0,0 +1,10 @@ +using Luban.Cpp.TemplateExtensions; +using Luban.Types; +using Luban.TypeVisitors; + +namespace Luban.Cpp.TypeVisitors; + +public class CppRawptrUnderlyingDeserializeVisitor : CppUnderlyingDeserializeVisitorBase +{ + public static CppRawptrUnderlyingDeserializeVisitor Ins { get; } = new(); +} diff --git a/src/Luban.Cpp/TypeVisitors/CppSharedPtrUnderlyingDeclaringTypeNameVisitor.cs b/src/Luban.Cpp/TypeVisitors/CppSharedPtrUnderlyingDeclaringTypeNameVisitor.cs index 5a26e0e1..81ef2684 100644 --- a/src/Luban.Cpp/TypeVisitors/CppSharedPtrUnderlyingDeclaringTypeNameVisitor.cs +++ b/src/Luban.Cpp/TypeVisitors/CppSharedPtrUnderlyingDeclaringTypeNameVisitor.cs @@ -3,9 +3,9 @@ namespace Luban.Cpp.TypeVisitors; -public class CppSharedPtrUnderlyingDeclaringTypeNameVisitor : CppUnderlyingDeclaringTypeNameVisitor +public class CppSharedptrUnderlyingDeclaringTypeNameVisitor : CppUnderlyingDeclaringTypeNameVisitor { - public new static CppSharedPtrUnderlyingDeclaringTypeNameVisitor Ins { get; } = new(); + public new static CppSharedptrUnderlyingDeclaringTypeNameVisitor Ins { get; } = new(); public override string Accept(TBean type) { diff --git a/src/Luban.Cpp/TypeVisitors/CppSharedptrDeclaringTypeNameVisitor.cs b/src/Luban.Cpp/TypeVisitors/CppSharedptrDeclaringTypeNameVisitor.cs new file mode 100644 index 00000000..199a3de9 --- /dev/null +++ b/src/Luban.Cpp/TypeVisitors/CppSharedptrDeclaringTypeNameVisitor.cs @@ -0,0 +1,19 @@ +using Luban.Types; +using Luban.TypeVisitors; + +namespace Luban.Cpp.TypeVisitors; + +public class CppSharedptrDeclaringTypeNameVisitor : DecoratorFuncVisitor +{ + public static CppSharedptrDeclaringTypeNameVisitor Ins { get; } = new CppSharedptrDeclaringTypeNameVisitor(); + + public override string DoAccept(TType type) + { + return type.IsNullable ? $"::luban::SharedPtr<{type.Apply(CppSharedptrUnderlyingDeclaringTypeNameVisitor.Ins)}>" : type.Apply(CppSharedptrUnderlyingDeclaringTypeNameVisitor.Ins); + } + + public override string Accept(TBean type) + { + return type.Apply(CppSharedptrUnderlyingDeclaringTypeNameVisitor.Ins); + } +} diff --git a/src/Luban.Cpp/TypeVisitors/CppSharedptrDeserializeVisitor.cs b/src/Luban.Cpp/TypeVisitors/CppSharedptrDeserializeVisitor.cs new file mode 100644 index 00000000..7fdf2410 --- /dev/null +++ b/src/Luban.Cpp/TypeVisitors/CppSharedptrDeserializeVisitor.cs @@ -0,0 +1,21 @@ +using Luban.Types; +using Luban.TypeVisitors; + +namespace Luban.Cpp.TypeVisitors; + +public class CppSharedptrDeserializeVisitor : DecoratorFuncVisitor +{ + public static CppSharedptrDeserializeVisitor Ins { get; } = new CppSharedptrDeserializeVisitor(); + + public override string DoAccept(TType type, string bufName, string fieldName) + { + if (type.IsNullable) + { + return $"{{ bool _has_value_; if(!{bufName}.readBool(_has_value_)){{return false;}} if(_has_value_) {{ {fieldName}.reset({(type.IsBean ? "" : $"new {type.Apply(CppUnderlyingDeclaringTypeNameVisitor.Ins)}()")}); {type.Apply(CppSharedptrUnderlyingDeserializeVisitor.Ins, bufName, $"{(type.IsBean ? "" : "*")}{fieldName}", CppSharedptrDeclaringTypeNameVisitor.Ins)} }} else {{ {fieldName}.reset(); }} }}"; + } + else + { + return type.Apply(CppSharedptrUnderlyingDeserializeVisitor.Ins, bufName, fieldName, CppSharedptrDeclaringTypeNameVisitor.Ins); + } + } +} diff --git a/src/Luban.Cpp/TypeVisitors/CppSharedptrUnderlyingDeserializeVisitor.cs b/src/Luban.Cpp/TypeVisitors/CppSharedptrUnderlyingDeserializeVisitor.cs new file mode 100644 index 00000000..7fdef170 --- /dev/null +++ b/src/Luban.Cpp/TypeVisitors/CppSharedptrUnderlyingDeserializeVisitor.cs @@ -0,0 +1,31 @@ +using Luban.Cpp.TemplateExtensions; +using Luban.Types; +using Luban.TypeVisitors; + +namespace Luban.Cpp.TypeVisitors; + +public class CppSharedptrUnderlyingDeserializeVisitor : CppUnderlyingDeserializeVisitorBase +{ + public static CppSharedptrUnderlyingDeserializeVisitor Ins { get; } = new CppSharedptrUnderlyingDeserializeVisitor(); + + //public string Accept(TArray type, string bufName, string fieldName) + //{ + // return $"{{::luban::int32 n; if(!{bufName}.readSize(n)) return false; n = std::min(n, ::luban::int32({bufName}.size()));{fieldName}.reserve(n);for(int i = 0 ; i < n ; i++) {{ {type.ElementType.Apply(CppSharedptrDeclaringTypeNameVisitor.Ins)} _e;{type.ElementType.Apply(this, bufName, "_e")} {fieldName}.push_back(_e);}}}}"; + //} + + //public string Accept(TList type, string bufName, string fieldName) + //{ + // return $"{{::luban::int32 n; if(!{bufName}.readSize(n)) return false; n = std::min(n, ::luban::int32({bufName}.size())); {fieldName}.reserve(n);for(int i = 0 ; i < n ; i++) {{ {type.ElementType.Apply(CppSharedptrDeclaringTypeNameVisitor.Ins)} _e; {type.ElementType.Apply(this, bufName, "_e")} {fieldName}.push_back(_e);}}}}"; + //} + + //public string Accept(TSet type, string bufName, string fieldName) + //{ + // return $"{{::luban::int32 n; if(!{bufName}.readSize(n)) return false; n = std::min(n, ::luban::int32({bufName}.size())); {fieldName}.reserve(n * 3 / 2);for(int i = 0 ; i < n ; i++) {{ {type.ElementType.Apply(CppSharedptrDeclaringTypeNameVisitor.Ins)} _e; {type.ElementType.Apply(this, bufName, "_e")} {fieldName}.insert(_e);}}}}"; + //} + + //public string Accept(TMap type, string bufName, string fieldName) + //{ + // return $"{{::luban::int32 n; if(!{bufName}.readSize(n)) return false; n = std::min(n, (::luban::int32){bufName}.size()); {fieldName}.reserve(n * 3 / 2);for(int i = 0 ; i < n ; i++) {{ {type.KeyType.Apply(CppSharedptrDeclaringTypeNameVisitor.Ins)} _k; {type.KeyType.Apply(this, bufName, "_k")} {type.ValueType.Apply(CppSharedptrDeclaringTypeNameVisitor.Ins)} _v; {type.ValueType.Apply(this, bufName, "_v")} {fieldName}[_k] = _v;}}}}"; + + //} +} diff --git a/src/Luban.Cpp/TypeVisitors/CppUnderlyingDeserializeVisitor.cs b/src/Luban.Cpp/TypeVisitors/CppUnderlyingDeserializeVisitorBase.cs similarity index 68% rename from src/Luban.Cpp/TypeVisitors/CppUnderlyingDeserializeVisitor.cs rename to src/Luban.Cpp/TypeVisitors/CppUnderlyingDeserializeVisitorBase.cs index 82f28ad9..a14228ec 100644 --- a/src/Luban.Cpp/TypeVisitors/CppUnderlyingDeserializeVisitor.cs +++ b/src/Luban.Cpp/TypeVisitors/CppUnderlyingDeserializeVisitorBase.cs @@ -4,83 +4,80 @@ namespace Luban.Cpp.TypeVisitors; -public class CppUnderlyingDeserializeVisitor : ITypeFuncVisitor +public abstract class CppUnderlyingDeserializeVisitorBase : ITypeFuncVisitor, string> { - public static CppUnderlyingDeserializeVisitor Ins { get; } = new CppUnderlyingDeserializeVisitor(); - - public string Accept(TBool type, string bufName, string fieldName) + public string Accept(TBool type, string bufName, string fieldName, ITypeFuncVisitor typeVisitor) { return $"if (!{bufName}.readBool({fieldName})) return false;"; } - public string Accept(TByte type, string bufName, string fieldName) + public string Accept(TByte type, string bufName, string fieldName, ITypeFuncVisitor typeVisitor) { return $"if(!{bufName}.readByte({fieldName})) return false;"; } - public string Accept(TShort type, string bufName, string fieldName) + public string Accept(TShort type, string bufName, string fieldName, ITypeFuncVisitor typeVisitor) { return $"if(!{bufName}.readShort({fieldName})) return false;"; } - public string Accept(TInt type, string bufName, string fieldName) + public string Accept(TInt type, string bufName, string fieldName, ITypeFuncVisitor typeVisitor) { return $"if(!{bufName}.readInt({fieldName})) return false;"; } - public string Accept(TLong type, string bufName, string fieldName) + public string Accept(TLong type, string bufName, string fieldName, ITypeFuncVisitor typeVisitor) { return $"if(!{bufName}.readLong({fieldName})) return false;"; } - public string Accept(TFloat type, string bufName, string fieldName) + public string Accept(TFloat type, string bufName, string fieldName, ITypeFuncVisitor typeVisitor) { return $"if(!{bufName}.readFloat({fieldName})) return false;"; } - public string Accept(TDouble type, string bufName, string fieldName) + public string Accept(TDouble type, string bufName, string fieldName, ITypeFuncVisitor typeVisitor) { return $"if(!{bufName}.readDouble({fieldName})) return false;"; } - public string Accept(TEnum type, string bufName, string fieldName) + public string Accept(TEnum type, string bufName, string fieldName, ITypeFuncVisitor typeVisitor) { return $"{{int __enum_temp__; if(!{bufName}.readInt(__enum_temp__)) return false; {fieldName} = {CppTemplateExtension.MakeTypeCppName(type.DefEnum)}(__enum_temp__); }}"; } - public string Accept(TString type, string bufName, string fieldName) + public string Accept(TString type, string bufName, string fieldName, ITypeFuncVisitor typeVisitor) { return $"if(!{bufName}.readString({fieldName})) return false;"; } - public string Accept(TBean type, string bufName, string fieldName) + public string Accept(TBean type, string bufName, string fieldName, ITypeFuncVisitor typeVisitor) { return $"if(!{CppTemplateExtension.MakeTypeCppName(type.DefBean)}::deserialize{type.DefBean.Name}({bufName}, {fieldName})) return false;"; } - public string Accept(TDateTime type, string bufName, string fieldName) + public string Accept(TDateTime type, string bufName, string fieldName, ITypeFuncVisitor typeVisitor) { return $"if(!{bufName}.readLong({fieldName})) return false;"; } - public string Accept(TArray type, string bufName, string fieldName) + public string Accept(TArray type, string bufName, string fieldName, ITypeFuncVisitor typeVisitor) { - return $"{{::luban::int32 n; if(!{bufName}.readSize(n)) return false; n = std::min(n, ::luban::int32({bufName}.size()));{fieldName}.reserve(n);for(int i = 0 ; i < n ; i++) {{ {type.ElementType.Apply(DeclaringTypeNameVisitor.Ins)} _e;{type.ElementType.Apply(this, bufName, "_e")} {fieldName}.push_back(_e);}}}}"; + return $"{{::luban::int32 n; if(!{bufName}.readSize(n)) return false; n = std::min(n, ::luban::int32({bufName}.size()));{fieldName}.reserve(n);for(int i = 0 ; i < n ; i++) {{ {type.ElementType.Apply(typeVisitor)} _e; {type.ElementType.Apply(this, bufName, "_e", typeVisitor)} {fieldName}.push_back(_e);}}}}"; } - public string Accept(TList type, string bufName, string fieldName) + public string Accept(TList type, string bufName, string fieldName, ITypeFuncVisitor typeVisitor) { - return $"{{::luban::int32 n; if(!{bufName}.readSize(n)) return false; n = std::min(n, ::luban::int32({bufName}.size())); {fieldName}.reserve(n);for(int i = 0 ; i < n ; i++) {{ {type.ElementType.Apply(DeclaringTypeNameVisitor.Ins)} _e; {type.ElementType.Apply(this, bufName, "_e")} {fieldName}.push_back(_e);}}}}"; + return $"{{::luban::int32 n; if(!{bufName}.readSize(n)) return false; n = std::min(n, ::luban::int32({bufName}.size())); {fieldName}.reserve(n);for(int i = 0 ; i < n ; i++) {{ {type.ElementType.Apply(typeVisitor)} _e; {type.ElementType.Apply(this, bufName, "_e", typeVisitor)} {fieldName}.push_back(_e);}}}}"; } - public string Accept(TSet type, string bufName, string fieldName) + public string Accept(TSet type, string bufName, string fieldName, ITypeFuncVisitor typeVisitor) { - return $"{{::luban::int32 n; if(!{bufName}.readSize(n)) return false; n = std::min(n, ::luban::int32({bufName}.size())); {fieldName}.reserve(n * 3 / 2);for(int i = 0 ; i < n ; i++) {{ {type.ElementType.Apply(DeclaringTypeNameVisitor.Ins)} _e; {type.ElementType.Apply(this, bufName, "_e")} {fieldName}.insert(_e);}}}}"; + return $"{{::luban::int32 n; if(!{bufName}.readSize(n)) return false; n = std::min(n, ::luban::int32({bufName}.size())); {fieldName}.reserve(n * 3 / 2);for(int i = 0 ; i < n ; i++) {{ {type.ElementType.Apply(typeVisitor)} _e; {type.ElementType.Apply(this, bufName, "_e", typeVisitor)} {fieldName}.insert(_e);}}}}"; } - public string Accept(TMap type, string bufName, string fieldName) + public string Accept(TMap type, string bufName, string fieldName, ITypeFuncVisitor typeVisitor) { - return $"{{::luban::int32 n; if(!{bufName}.readSize(n)) return false; n = std::min(n, (::luban::int32){bufName}.size()); {fieldName}.reserve(n * 3 / 2);for(int i = 0 ; i < n ; i++) {{ {type.KeyType.Apply(DeclaringTypeNameVisitor.Ins)} _k; {type.KeyType.Apply(this, bufName, "_k")} {type.ValueType.Apply(DeclaringTypeNameVisitor.Ins)} _v; {type.ValueType.Apply(this, bufName, "_v")} {fieldName}[_k] = _v;}}}}"; - + return $"{{::luban::int32 n; if(!{bufName}.readSize(n)) return false; n = std::min(n, (::luban::int32){bufName}.size()); {fieldName}.reserve(n * 3 / 2);for(int i = 0 ; i < n ; i++) {{ {type.KeyType.Apply(typeVisitor)} _k; {type.KeyType.Apply(this, bufName, "_k", typeVisitor)} {type.ValueType.Apply(typeVisitor)} _v; {type.ValueType.Apply(this, bufName, "_v", typeVisitor)} {fieldName}[_k] = _v;}}}}"; } } diff --git a/src/Luban.Cpp/TypeVisitors/DeclaringTypeNameVisitor.cs b/src/Luban.Cpp/TypeVisitors/DeclaringTypeNameVisitor.cs deleted file mode 100644 index 7b658f79..00000000 --- a/src/Luban.Cpp/TypeVisitors/DeclaringTypeNameVisitor.cs +++ /dev/null @@ -1,19 +0,0 @@ -using Luban.Types; -using Luban.TypeVisitors; - -namespace Luban.Cpp.TypeVisitors; - -public class DeclaringTypeNameVisitor : DecoratorFuncVisitor -{ - public static DeclaringTypeNameVisitor Ins { get; } = new DeclaringTypeNameVisitor(); - - public override string DoAccept(TType type) - { - return type.IsNullable ? $"::luban::SharedPtr<{type.Apply(CppSharedPtrUnderlyingDeclaringTypeNameVisitor.Ins)}>" : type.Apply(CppSharedPtrUnderlyingDeclaringTypeNameVisitor.Ins); - } - - public override string Accept(TBean type) - { - return type.Apply(CppSharedPtrUnderlyingDeclaringTypeNameVisitor.Ins); - } -}