From a0fd8af74b6adbbb81be6572d2e3c620cf5885df Mon Sep 17 00:00:00 2001 From: Pavel Shevaev Date: Thu, 8 Dec 2022 17:45:28 +0300 Subject: [PATCH] Adding RPC support --- src/codegen.inc.php | 15 ++++++++ tpl/macro.twig | 89 ++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 102 insertions(+), 2 deletions(-) diff --git a/src/codegen.inc.php b/src/codegen.inc.php index 36f4d54..058cb30 100644 --- a/src/codegen.inc.php +++ b/src/codegen.inc.php @@ -115,6 +115,12 @@ function _add_twig_support(\Twig\Environment $twig) return var2buf($name, $fname, $type, $buf, $tokens, $is_ptr); } )); + $twig->addFilter(new \Twig\TwigFilter('rpc_invert', + function($name) + { + return rpc_invert($name); + } + )); $twig->addFilter(new \Twig\TwigFilter('go_type', function($type, $tokens) { @@ -364,3 +370,12 @@ function _read_op(array $tokens, $op) { return "if err := $op; err != nil { return " . (array_key_exists("optional", $tokens) ? "/*optional*/nil" : "err"). " }"; } + +function rpc_invert($name) +{ + if(strpos($name, '_RSP_') !== false) + return str_replace('_RSP_', '_REQ_', $name); + else + return str_replace('_REQ_', '_RSP_', $name); +} + diff --git a/tpl/macro.twig b/tpl/macro.twig index 908c3f6..bd5d5a4 100644 --- a/tpl/macro.twig +++ b/tpl/macro.twig @@ -5,7 +5,7 @@ {%- elseif u.object is instanceof('\\mtgMetaEnum') ~%} {{ _self.decl_enum(u.object) }} {%- elseif u.object is instanceof('\\mtgMetaRPC') ~%} - {{ _self.decl_rpc(u.object) }} + {{ _self.decl_rpc(meta, u.object) }} {%- endif ~%} {%- endfor ~%} {% endmacro %} @@ -34,25 +34,32 @@ var _{{o.name}}_fields_props meta.ClassFieldsProps = {{_self.struct_fields_props func {{o.name}}_CLASS_ID() uint32 { return {{o.classid}} } + type I{{o.name}} interface { meta.IMetaStruct Ptr{{o.name}}() *{{o.name}} } + func (*{{o.name}}) CLASS_ID() uint32 { return {{o.classid}} } + func (*{{o.name}}) CLASS_NAME() string { return "{{o.name}}" } + func (*{{o.name}}) CLASS_PROPS() *map[string]string { return &_{{o.name}}_class_props } + func (*{{o.name}}) CLASS_FIELDS() []string { return _{{o.name}}_class_fields } + func (*{{o.name}}) CLASS_FIELDS_PROPS() *meta.ClassFieldsProps { return &_{{o.name}}_fields_props } + //convenience getter func Ptr{{o.name}}(m meta.IMetaStruct) *{{o.name}} { p, ok := m.(I{{o.name}}) @@ -61,20 +68,25 @@ func Ptr{{o.name}}(m meta.IMetaStruct) *{{o.name}} { } return p.Ptr{{o.name}}() } + func (self *{{o.name}}) Ptr{{o.name}}() *{{o.name}} { return self } + func New{{o.name}}() *{{o.name}} { item := new ({{o.name}}) item.Reset() return item } + func (self *{{o.name}}) Reset() { {{_self.struct_reset_fields(o)}} } + func (self *{{o.name}}) Read(reader meta.Reader) error { return meta.ReadStruct(reader, self, "") } + func (self *{{o.name}}) ReadFields(reader meta.Reader) error { self.Reset() @@ -82,9 +94,11 @@ func (self *{{o.name}}) ReadFields(reader meta.Reader) error { return nil } + func (self *{{o.name}}) Write(writer meta.Writer) error { return meta.WriteStruct(writer, self, "") } + func (self *{{o.name}}) WriteFields(writer meta.Writer) error { {{_self.struct_write_fields(o)}} @@ -370,6 +384,77 @@ func New{{o.name}}ByName(name string) ({{o.name}}, error) { {%- endfor ~%} {% endmacro %} -{% macro decl_rpc(o) %} +{% macro decl_rpc(meta, o) %} + +{{_self._decl_rpc_part(meta, o.req, o.code)}} +{{_self._decl_rpc_part(meta, o.rsp, o.code)}} + +func New{{o.name}}() *{{o.name}} { + rpc := {{o.name}}{} + rpc.Req = New{{o.req.name}}() + rpc.Rsp = New{{o.rsp.name}}() + return &rpc +} + +type {{o.name}} struct { + ErrCode int32 + ErrMsg string + Req *{{o.req.name}} + Rsp *{{o.rsp.name}} +} + +func (rpc *{{o.name}}) SetError(code int32, msg string) { + rpc.ErrCode = code + rpc.ErrMsg = msg +} + +func (rpc *{{o.name}}) GetError() (int32, string) { + return rpc.ErrCode, rpc.ErrMsg +} + +func (rpc *{{o.name}}) GetRequest() meta.IMetaStruct { + return rpc.Req +} + +func (rpc *{{o.name}}) GetResponse() meta.IMetaStruct { + return rpc.Rsp +} + +func (rpc *{{o.name}}) GetName() string { + return "{{o.name}}" +} + +func (rpc *{{o.name}}) GetCode() int32 { + return {{o.code}} +} + +type IRPCHandler_{{o.name}} interface { + {{o.name}}(*{{o.name}}) error +} + +func (rpc *{{o.name}}) Execute(h interface{}) error{ + mh, ok := h.(IRPCHandler_{{o.name}}) + if !ok { + return errors.New("RPC '{{o.name}}(*{{o.name}}) error' is not implemented") + } + return mh.{{o.name}}(rpc) +} + +{% endmacro %} + +{% macro _decl_rpc_part(meta, o, code) %} + +{{_self.decl_struct(meta, o)}} + +var {{o.name}}_ func(interface{}, *{{o.name}}, *{{o.name|rpc_invert}}) error + +func (self *{{o.name}}) I{{o.name}}() *{{o.name}} { + return self +} + +func (*{{o.name}}) GetCode() int32 { + return {{code}} +} + {% endmacro %}