【调整】调整 proto typescript生成,更灵活处理bright类型来自模块或者内嵌或者puerts注入的情形

main
walon 2021-07-13 12:59:28 +08:00
parent 3549603dcc
commit 6a43f7af6f
7 changed files with 364 additions and 116 deletions

View File

@ -144,17 +144,17 @@ namespace Luban.Job.Common.TypeVisitors
public string Accept(TVector2 type, string bufVarName, string fieldName)
{
return $"{fieldName} = Vector2.from({bufVarName})";
return $"{fieldName} = Vector2.deserializeFrom({bufVarName})";
}
public string Accept(TVector3 type, string bufVarName, string fieldName)
{
return $"{fieldName} = Vector3.from({bufVarName})";
return $"{fieldName} = Vector3.deserializeFrom({bufVarName})";
}
public string Accept(TVector4 type, string bufVarName, string fieldName)
{
return $"{fieldName} = Vector4.from({bufVarName})";
return $"{fieldName} = Vector4.deserializeFrom({bufVarName})";
}
public string Accept(TDateTime type, string bufVarName, string fieldName)

View File

@ -84,17 +84,17 @@ namespace Luban.Job.Common.TypeVisitors
public string Accept(TVector2 type, string bufVarName, string fieldName)
{
return $"{fieldName}.to({bufVarName})";
return $"{fieldName}.serialize({bufVarName})";
}
public string Accept(TVector3 type, string bufVarName, string fieldName)
{
return $"{fieldName}.to({bufVarName})";
return $"{fieldName}.serialize({bufVarName})";
}
public string Accept(TVector4 type, string bufVarName, string fieldName)
{
return $"{fieldName}.to({bufVarName})";
return $"{fieldName}.serialize({bufVarName})";
}
public string Accept(TDateTime type, string bufVarName, string fieldName)

View File

@ -0,0 +1,141 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Luban.Job.Common.Utils
{
public static class TypescriptBrightTypeTemplates
{
public const string PuertsByteBufImports = @"
import {Bright} from 'csharp'
import ByteBuf = Bright.Serialization.ByteBuf";
public const string BrightByteBufImportsFormat = "import ByteBuf from '{0}/serialization/ByteBuf'";
public const string VectorImportsFormat = @"
import Vector2 from '{0}/math/Vector2'
import Vector3 from '{0}/math/Vector3'
import Vector4 from '{0}/math/Vector4'
";
public const string SerializeImportsFormat = @"import BeanBase from '{0}/serialization/BeanBase'";
public const string ProtocolImportsFormat = "import Protocol from '{0}/net/Protocol'";
public const string SerializeTypes = @"
export interface ISerializable {
serialize(buf: ByteBuf): void
deserialize(buf: ByteBuf): void
}
export abstract class BeanBase implements ISerializable {
abstract getTypeId(): number
abstract serialize(buf: Bright.Serialization.ByteBuf): void
abstract deserialize(buf: Bright.Serialization.ByteBuf): void
}
";
public const string ProtoTypes = @"
export abstract class Protocol implements ISerializable {
abstract getTypeId(): number
abstract serialize(buf: ByteBuf): void
abstract deserialize(buf: ByteBuf): void
}
";
public const string VectorTypes = @"
export class Vector2 implements ISerializable {
static deserializeFrom(buf: ByteBuf): Vector2 {
var v = new Vector2()
v.deserialize(buf)
return v
}
x: number
y: number
constructor(x: number = 0, y: number = 0) {
this.x = x
this.y = y
}
serialize(_buf_: ByteBuf) {
_buf_.WriteFloat(this.x)
_buf_.WriteFloat(this.y)
}
deserialize(buf: ByteBuf) {
this.x = buf.ReadFloat()
this.y = buf.ReadFloat()
}
}
export class Vector3 implements ISerializable{
static deserializeFrom(buf: ByteBuf): Vector3 {
var v = new Vector3()
v.deserialize(buf)
return v
}
x: number
y: number
z: number
constructor(x: number = 0, y: number = 0, z: number = 0) {
this.x = x
this.y = y
this.z = z
}
serialize(_buf_: ByteBuf) {
_buf_.WriteFloat(this.x)
_buf_.WriteFloat(this.y)
_buf_.WriteFloat(this.z)
}
deserialize(buf: ByteBuf) {
this.x = buf.ReadFloat()
this.y = buf.ReadFloat()
this.z = buf.ReadFloat()
}
}
export class Vector4 implements ISerializable {
static deserializeFrom(buf: ByteBuf): Vector4 {
var v = new Vector4()
v.deserialize(buf)
return v
}
x: number
y: number
z: number
w: number
constructor(x: number = 0, y: number = 0, z: number = 0, w: number = 0) {
this.x = x
this.y = y
this.z = z
this.w = w
}
serialize(_buf_: ByteBuf) {
_buf_.WriteFloat(this.x)
_buf_.WriteFloat(this.y)
_buf_.WriteFloat(this.z)
_buf_.WriteFloat(this.w)
}
deserialize(buf: ByteBuf) {
this.x = buf.ReadFloat()
this.y = buf.ReadFloat()
this.z = buf.ReadFloat()
this.z = buf.ReadFloat()
}
}
";
}
}

View File

@ -0,0 +1,52 @@
using Luban.Job.Common.Defs;
using Luban.Job.Common.Utils;
using Luban.Job.Db.Defs;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Luban.Job.Db.Generate
{
class TypescriptRender
{
public string RenderAny(object o)
{
switch (o)
{
case DefConst c: return Render(c);
case DefEnum e: return Render(e);
case DefBean b: return Render(b);
case DefTable r: return Render(r);
default: throw new Exception($"unknown render type:{o}");
}
}
private string Render(DefConst c)
{
return RenderUtil.RenderTypescriptConstClass(c);
}
private string Render(DefEnum e)
{
return RenderUtil.RenderTypescriptEnumClass(e);
}
private string Render(DefBean b)
{
return $"// {b.FullName}";
}
public string Render(DefTable c)
{
return $"// {c.FullName}";
}
public string RenderService(string name, string module, List<DefTable> tables)
{
return "// services";
}
}
}

View File

@ -1,6 +1,7 @@
using CommandLine;
using Luban.Common.Protos;
using Luban.Common.Utils;
using Luban.Job.Common;
using Luban.Job.Common.Defs;
using Luban.Job.Common.Utils;
using Luban.Job.Db.Defs;
@ -27,8 +28,11 @@ namespace Luban.Job.Db
[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")]
[Option('g', "gen_type", Required = true, HelpText = "cs,typescript . current only support cs")]
public string GenType { get; set; }
[Option("typescript_bright_require_path", Required = false, HelpText = "bright require path in typescript")]
public string TypescriptBrightRequirePath { get; set; }
}
@ -92,7 +96,7 @@ namespace Luban.Job.Db
var tasks = new List<Task>();
var genCodeFiles = new ConcurrentBag<FileInfo>();
var genScatteredFiles = new ConcurrentBag<FileInfo>();
var genType = args.GenType;
switch (genType)
@ -124,6 +128,110 @@ namespace Luban.Job.Db
}));
break;
}
case "typescript":
{
var render = new TypescriptRender();
var byteBufRequirePath = "";// args.TypescriptByteBufRequirePath ?? "csharp";
tasks.Add(Task.Run(() =>
{
var fileContent = new List<string>
{
@$"
{ (string.IsNullOrEmpty(args.TypescriptBrightRequirePath) ?
@"
import {{Bright}} from 'cshar'
import ByteBuf = Bright.Serialization.ByteBuf
export class Vector2 {
x: number
y: number
constructor(x: number, y: number) {
this.x = x
this.y = y
}
static from(_buf_: Bright.Serialization.ByteBuf): Vector2 {
let x = _buf_.ReadFloat()
let y = _buf_.ReadFloat()
return new Vector2(x, y)
}
}
export class Vector3 {
x: number
y: number
z: number
constructor(x: number, y: number, z: number) {
this.x = x
this.y = y
this.z = z
}
static from(_buf_: Bright.Serialization.ByteBuf): Vector3 {
let x = _buf_.ReadFloat()
let y = _buf_.ReadFloat()
let z = _buf_.ReadFloat()
return new Vector3(x, y, z)
}
}
export class Vector4 {
x: number
y: number
z: number
w: number
constructor(x: number, y: number, z: number, w: number) {
this.x = x
this.y = y
this.z = z
this.w = w
}
static from(_buf_: Bright.Serialization.ByteBuf): Vector4 {
let x = _buf_.ReadFloat()
let y = _buf_.ReadFloat()
let z = _buf_.ReadFloat()
let w = _buf_.ReadFloat()
return new Vector4(x, y, z, w)
}
}
" :
@"
import {{Bright}} from '{byteBufRequirePath}'
") }
export namespace {ass.TopModule} {{
",
@"
"
};
foreach (var type in exportTypes)
{
fileContent.Add(render.RenderAny(type));
}
var tables = ass.Types.Values.Where(t => t is DefTable).Select(t => (DefTable)t).ToList();
fileContent.Add(render.RenderService("Tables", ass.TopModule, tables));
fileContent.Add("}"); // end of topmodule
var content = FileHeaderUtil.ConcatAutoGenerationHeader(string.Join('\n', fileContent), ELanguage.TYPESCRIPT);
var file = "Types.ts";
var md5 = CacheFileUtil.GenMd5AndAddCache(file, content);
genScatteredFiles.Add(new FileInfo() { FilePath = file, MD5 = md5 });
}));
break;
}
default:
{
throw new NotSupportedException($"not support gen type:{genType}");
@ -134,6 +242,10 @@ namespace Luban.Job.Db
await Task.WhenAll(tasks.ToArray());
res.FileGroups.Add(new FileGroup() { Dir = outputCodeDir, Files = genCodeFiles.ToList() });
if (!genScatteredFiles.IsEmpty)
{
res.ScatteredFiles.AddRange(genScatteredFiles);
}
}
catch (Exception e)
{

View File

@ -57,7 +57,7 @@ namespace Luban.Job.Proto.Generate
export {{if x.is_abstract_type}} abstract {{end}} class {{name}} extends {{if parent_def_type}}{{x.parent}}{{else}}BeanBase{{end}} {
{{~if x.is_abstract_type~}}
static serializeTo(_buf_ : Bright.Serialization.ByteBuf, _bean_ : {{name}}) {
static serializeTo(_buf_ : ByteBuf, _bean_ : {{name}}) {
if (_bean_ == null) {
_buf_.WriteInt(0)
return
@ -66,7 +66,7 @@ export {{if x.is_abstract_type}} abstract {{end}} class {{name}} extends {{if pa
_bean_.serialize(_buf_)
}
static deserializeFrom(_buf_ : Bright.Serialization.ByteBuf) : {{name}} {
static deserializeFrom(_buf_ : ByteBuf) : {{name}} {
let _bean_ :{{name}}
switch (_buf_.ReadInt()) {
case 0 : return null
@ -97,7 +97,7 @@ export {{if x.is_abstract_type}} abstract {{end}} class {{name}} extends {{if pa
}
serialize(_buf_ : Bright.Serialization.ByteBuf) {
serialize(_buf_ : ByteBuf) {
{{~if parent_def_type~}}
super.serialize(_buf_)
{{~end~}}
@ -106,7 +106,7 @@ export {{if x.is_abstract_type}} abstract {{end}} class {{name}} extends {{if pa
{{~end~}}
}
deserialize(_buf_ : Bright.Serialization.ByteBuf) {
deserialize(_buf_ : ByteBuf) {
{{~if parent_def_type~}}
super.deserialize(_buf_)
{{~end~}}
@ -159,13 +159,13 @@ export class {{name}} extends Protocol {
{{~end~}}
}
serialize(_buf_ : Bright.Serialization.ByteBuf) {
serialize(_buf_ : ByteBuf) {
{{~ for field in fields ~}}
{{ts_bin_serialize ('this.' + field.ts_style_name) '_buf_' field.ctype}}
{{~end~}}
}
deserialize(_buf_ : Bright.Serialization.ByteBuf) {
deserialize(_buf_ : ByteBuf) {
{{~ for field in fields ~}}
{{ts_bin_deserialize ('this.' + field.ts_style_name) '_buf_' field.ctype}}
{{~end~}}

View File

@ -37,8 +37,14 @@ namespace Luban.Job.Proto
[Option('s', "service", Required = true, HelpText = "service")]
public string Service { get; set; }
[Option("typescript_bytebuf_require_path", Required = false, HelpText = "bytebuf require path in typescript")]
public string TypescriptByteBufRequirePath { get; set; }
[Option("typescript_bright_require_path", Required = false, HelpText = "bright require path in typescript")]
public string TypescriptBrightRequirePath { get; set; }
[Option("use_puerts_bytebuf", Required = false, HelpText = "use puerts bytebuf class. default is false")]
public bool UsePuertsByteBuf { get; set; }
[Option("embed_bright_types", Required = false, HelpText = "use puerts bytebuf class. default is false")]
public bool EmbedBrightTypes { get; set; }
}
@ -59,6 +65,19 @@ namespace Luban.Job.Proto
result = (parseResult as Parsed<GenArgs>).Value;
errMsg = null;
if (!result.UsePuertsByteBuf && string.IsNullOrWhiteSpace(result.TypescriptBrightRequirePath))
{
errMsg = $"while use_puerts_bytebuf is false, should provide option --typescript_bright_require_path";
return false;
}
if (!result.EmbedBrightTypes && string.IsNullOrWhiteSpace(result.TypescriptBrightRequirePath))
{
errMsg = $"while embed_bright_types is false, should provide option --typescript_bright_require_path";
return false;
}
return true;
}
@ -152,111 +171,35 @@ namespace Luban.Job.Proto
case "ts":
{
var render = new TypescriptRender();
var byteBufRequirePath = args.TypescriptByteBufRequirePath ?? "csharp";
var brightRequirePath = args.TypescriptBrightRequirePath;
tasks.Add(Task.Run(() =>
{
var fileContent = new List<string>
var fileContent = new List<string>();
if (args.UsePuertsByteBuf)
{
@$"
import {{Bright}} from '{byteBufRequirePath}'
fileContent.Add(TypescriptBrightTypeTemplates.PuertsByteBufImports);
}
else
{
fileContent.Add(string.Format(TypescriptBrightTypeTemplates.BrightByteBufImportsFormat, brightRequirePath));
}
if (args.EmbedBrightTypes)
{
fileContent.Add(TypescriptBrightTypeTemplates.VectorTypes);
fileContent.Add(TypescriptBrightTypeTemplates.SerializeTypes);
fileContent.Add(TypescriptBrightTypeTemplates.ProtoTypes);
}
else
{
fileContent.Add(string.Format(TypescriptBrightTypeTemplates.SerializeImportsFormat, brightRequirePath));
fileContent.Add(string.Format(TypescriptBrightTypeTemplates.ProtocolImportsFormat, brightRequirePath));
fileContent.Add(string.Format(TypescriptBrightTypeTemplates.VectorImportsFormat, brightRequirePath));
}
fileContent.Add(@$"
export namespace {ass.TopModule} {{
",
@"
export interface ISerializable {
serialize(_buf_: Bright.Serialization.ByteBuf): void
deserialize(_buf_: Bright.Serialization.ByteBuf): void
}
export abstract class BeanBase implements ISerializable {
abstract getTypeId(): number
abstract serialize(_buf_: Bright.Serialization.ByteBuf): void
abstract deserialize(_buf_: Bright.Serialization.ByteBuf): void
}
export abstract class Protocol implements ISerializable {
abstract getTypeId(): number
abstract serialize(_buf_: Bright.Serialization.ByteBuf): void
abstract deserialize(_buf_: Bright.Serialization.ByteBuf): void
}
export class Vector2 {
x: number
y: number
constructor(x: number, y: number) {
this.x = x
this.y = y
}
to(_buf_: Bright.Serialization.ByteBuf) {
_buf_.WriteFloat(this.x)
_buf_.WriteFloat(this.y)
}
static from(_buf_: Bright.Serialization.ByteBuf): Vector2 {
let x = _buf_.ReadFloat()
let y = _buf_.ReadFloat()
return new Vector2(x, y)
}
}
export class Vector3 {
x: number
y: number
z: number
constructor(x: number, y: number, z: number) {
this.x = x
this.y = y
this.z = z
}
to(_buf_: Bright.Serialization.ByteBuf) {
_buf_.WriteFloat(this.x)
_buf_.WriteFloat(this.y)
_buf_.WriteFloat(this.z)
}
static from(_buf_: Bright.Serialization.ByteBuf): Vector3 {
let x = _buf_.ReadFloat()
let y = _buf_.ReadFloat()
let z = _buf_.ReadFloat()
return new Vector3(x, y, z)
}
}
export class Vector4 {
x: number
y: number
z: number
w: number
constructor(x: number, y: number, z: number, w: number) {
this.x = x
this.y = y
this.z = z
this.w = w
}
to(_buf_: Bright.Serialization.ByteBuf) {
_buf_.WriteFloat(this.x)
_buf_.WriteFloat(this.y)
_buf_.WriteFloat(this.z)
_buf_.WriteFloat(this.w)
}
static from(_buf_: Bright.Serialization.ByteBuf): Vector4 {
let x = _buf_.ReadFloat()
let y = _buf_.ReadFloat()
let z = _buf_.ReadFloat()
let w = _buf_.ReadFloat()
return new Vector4(x, y, z, w)
}
}
"
};
");
foreach (var type in exportTypes)
{