From f4d8ed0fa0b01f7d2c4a54289ec1fdc7c5ebe535 Mon Sep 17 00:00:00 2001 From: davyxu Date: Sat, 24 Dec 2022 23:21:26 +0800 Subject: [PATCH] =?UTF-8?q?UE4=20C++=E6=B3=A8=E5=86=8C=E5=85=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/protoplus/main.go | 4 +- gen/pbscheme/gen_dir.go | 83 +++++------------------------------------ gen/ppcpp/func.go | 33 ++++++++++++++++ gen/ppcpp/gen_cpp.go | 22 +++++++++++ gen/ppcpp/text.go | 23 ++++++++++++ model/pbdescset.go | 77 ++++++++++++++++++++++++++++++++++++++ 6 files changed, 168 insertions(+), 74 deletions(-) create mode 100644 gen/ppcpp/func.go create mode 100644 gen/ppcpp/gen_cpp.go create mode 100644 gen/ppcpp/text.go create mode 100644 model/pbdescset.go diff --git a/cmd/protoplus/main.go b/cmd/protoplus/main.go index 9b8cfce..2383bf5 100644 --- a/cmd/protoplus/main.go +++ b/cmd/protoplus/main.go @@ -7,6 +7,7 @@ import ( _ "github.com/davyxu/protoplus/codegen" "github.com/davyxu/protoplus/gen" "github.com/davyxu/protoplus/gen/pbscheme" + "github.com/davyxu/protoplus/gen/ppcpp" "github.com/davyxu/protoplus/gen/ppcs" "github.com/davyxu/protoplus/gen/ppgo" "github.com/davyxu/protoplus/gen/ppscheme" @@ -42,7 +43,8 @@ var ( //{name: "ppcs_out", usage: "output protoplus message serialize csharp source file", outfile: ppcs.GenCS}, {name: "ppgoreg_out", usage: "output protoplus message register entry in golang", outfile: ppgo.GenGoReg}, - {name: "ppcsreg_out", usage: "output protoplus message register entry in csharp", outfile: ppcs.GenCSReg}, + {name: "ppcppreg_out", usage: "output protoplus message register entry in c++", outfile: ppcpp.GenCppReg}, + {name: "ppcsreg_out", usage: "output protoplus message register entry in c#", outfile: ppcs.GenCSReg}, {name: "pbscheme_out", usage: "output google protobuf schema file as single file", outfile: pbscheme.GenProto}, // 文件夹输出 使用例子: protoc $(cat filelist.txt) diff --git a/gen/pbscheme/gen_dir.go b/gen/pbscheme/gen_dir.go index 39c0303..a4f4fbc 100644 --- a/gen/pbscheme/gen_dir.go +++ b/gen/pbscheme/gen_dir.go @@ -5,8 +5,10 @@ import ( "github.com/davyxu/protoplus/codegen" "github.com/davyxu/protoplus/gen" "github.com/davyxu/protoplus/model" + "io/ioutil" "path/filepath" "sort" + "strings" ) const protoDirCodeTemplate = `// Generated by github.com/davyxu/protoplus @@ -33,76 +35,11 @@ message {{.Name}} { {{range .Fields}} {{end}} ` -type PBDescriptorSet struct { - model.DescriptorSet - - // pb生成文件依赖时, 使用以下字段 - DependentSource []string // 按文件管理的描述符取出时, 这个字段有效. 本文件依赖的其他source的symbiol - SourceName string // 按文件管理的描述符取出时, 这个字段有效. 表示本DescriptorSet的文件名 - dsBySource map[string]*PBDescriptorSet // 按文件名管理的描述符集合 -} - -func (self *PBDescriptorSet) addDependentSource(name string) { - - if self.SourceName == name { - return - } - - for _, n := range self.DependentSource { - if n == name { - return - } - } - - self.DependentSource = append(self.DependentSource, name) -} - -func (self *PBDescriptorSet) DescriptorSetBySource() map[string]*PBDescriptorSet { - if self.dsBySource != nil { - return self.dsBySource - } - - self.dsBySource = map[string]*PBDescriptorSet{} - - for _, obj := range self.Objects { - ds := self.dsBySource[obj.SrcName] - if ds == nil { - ds = &PBDescriptorSet{} - - ds.PackageName = self.PackageName - ds.Codec = self.Codec - ds.SourceName = obj.SrcName - - self.dsBySource[obj.SrcName] = ds - } - - ds.AddObject(obj) - } - - for _, file := range self.dsBySource { - for _, st := range file.Structs() { - - for _, fd := range st.Fields { - - switch fd.Kind { - case model.Kind_Struct, model.Kind_Enum: - refTarget := self.ObjectByName(fd.Type) - if refTarget != nil { - file.addDependentSource(refTarget.SrcName) - } - } - } - } - } - - return self.dsBySource -} - func GenProtoDir(ctx *gen.Context) error { - rootDS := &PBDescriptorSet{DescriptorSet: *ctx.DescriptorSet} + rootDS := &model.PBDescriptorSet{DescriptorSet: *ctx.DescriptorSet} - //var sb strings.Builder + var sb strings.Builder var srcNameList []string for srcName, ds := range rootDS.DescriptorSetBySource() { @@ -129,11 +66,11 @@ func GenProtoDir(ctx *gen.Context) error { sort.Strings(srcNameList) - //for _, d := range srcNameList { - // fmt.Fprintf(&sb, "%s ", d) - //} - // - //err := ioutil.WriteFile(filepath.Join(ctx.OutputFileName, "filelist.txt"), []byte(sb.String()), 0666) + for _, d := range srcNameList { + fmt.Fprintf(&sb, "%s ", d) + } + + err := ioutil.WriteFile(filepath.Join(ctx.OutputFileName, "filelist.txt"), []byte(sb.String()), 0666) - return nil + return err } diff --git a/gen/ppcpp/func.go b/gen/ppcpp/func.go new file mode 100644 index 0000000..c54ea13 --- /dev/null +++ b/gen/ppcpp/func.go @@ -0,0 +1,33 @@ +package ppcpp + +import ( + "github.com/davyxu/protoplus/gen" + "github.com/davyxu/protoplus/model" + "path" + "path/filepath" + "strings" + "text/template" +) + +var UsefulFunc = template.FuncMap{} + +func ChangeExtension(filename, newExt string) string { + + file := filepath.Base(filename) + + return strings.TrimSuffix(file, path.Ext(file)) + newExt +} + +func SourceList(ctx *gen.Context) (ret []string) { + + rootDS := &model.PBDescriptorSet{DescriptorSet: *ctx.DescriptorSet} + for _, protoFile := range rootDS.SourceList() { + ret = append(ret, ChangeExtension(protoFile, ".pb.h")) + } + + return +} + +func init() { + UsefulFunc["SourceList"] = SourceList +} diff --git a/gen/ppcpp/gen_cpp.go b/gen/ppcpp/gen_cpp.go new file mode 100644 index 0000000..a392ba7 --- /dev/null +++ b/gen/ppcpp/gen_cpp.go @@ -0,0 +1,22 @@ +package ppcpp + +import ( + "fmt" + "github.com/davyxu/protoplus/codegen" + "github.com/davyxu/protoplus/gen" +) + +func GenCppReg(ctx *gen.Context) error { + + codeGen := codegen.NewCodeGen("cppreg"). + RegisterTemplateFunc(codegen.UsefulFunc). + RegisterTemplateFunc(UsefulFunc). + ParseTemplate(RegTemplateText, ctx) + + if codeGen.Error() != nil { + fmt.Println(codeGen.Code()) + return codeGen.Error() + } + + return codeGen.WriteOutputFile(ctx.OutputFileName).Error() +} diff --git a/gen/ppcpp/text.go b/gen/ppcpp/text.go new file mode 100644 index 0000000..92e0e02 --- /dev/null +++ b/gen/ppcpp/text.go @@ -0,0 +1,23 @@ +package ppcpp + +const RegTemplateText = `// Generated by github.com/davyxu/protoplus +#pragma once +#include "MessageRegistry.h" +{{range SourceList $}} +#include "{{.}}"{{end}} + +{{range .Structs}} +class {{.Name}}Meta : public MessageMeta +{ +public: + virtual const char* GetMessageName( ) const override{ return "{{$.PackageName}}.{{.Name}}"; } + virtual int32 GetMessageId( ) const override{ return {{StructMsgID .}}; } + virtual void* NewMessage() override { return {{$.PackageName}}::{{.Name}}::default_instance().New(); } +}; {{end}} + +void StaticRegisterMeta( ) +{ {{range .Structs}} + MessageRegistry::Register(new {{.Name}}Meta); {{end}} +} + +` diff --git a/model/pbdescset.go b/model/pbdescset.go new file mode 100644 index 0000000..f12cbee --- /dev/null +++ b/model/pbdescset.go @@ -0,0 +1,77 @@ +package model + +import "sort" + +type PBDescriptorSet struct { + DescriptorSet + + // pb生成文件依赖时, 使用以下字段 + DependentSource []string // 按文件管理的描述符取出时, 这个字段有效. 本文件依赖的其他source的symbiol + SourceName string // 按文件管理的描述符取出时, 这个字段有效. 表示本DescriptorSet的文件名 + dsBySource map[string]*PBDescriptorSet // 按文件名管理的描述符集合 +} + +func (self *PBDescriptorSet) addDependentSource(name string) { + + if self.SourceName == name { + return + } + + for _, n := range self.DependentSource { + if n == name { + return + } + } + + self.DependentSource = append(self.DependentSource, name) +} + +func (self *PBDescriptorSet) SourceList() (ret []string) { + for sourceName := range self.DescriptorSetBySource() { + ret = append(ret, sourceName) + } + + sort.Strings(ret) + return +} + +func (self *PBDescriptorSet) DescriptorSetBySource() map[string]*PBDescriptorSet { + if self.dsBySource != nil { + return self.dsBySource + } + + self.dsBySource = map[string]*PBDescriptorSet{} + + for _, obj := range self.Objects { + ds := self.dsBySource[obj.SrcName] + if ds == nil { + ds = &PBDescriptorSet{} + + ds.PackageName = self.PackageName + ds.Codec = self.Codec + ds.SourceName = obj.SrcName + + self.dsBySource[obj.SrcName] = ds + } + + ds.AddObject(obj) + } + + for _, file := range self.dsBySource { + for _, st := range file.Structs() { + + for _, fd := range st.Fields { + + switch fd.Kind { + case Kind_Struct, Kind_Enum: + refTarget := self.ObjectByName(fd.Type) + if refTarget != nil { + file.addDependentSource(refTarget.SrcName) + } + } + } + } + } + + return self.dsBySource +}