Example #1
0
        public async Task GenAsync(RemoteAgent agent, GenJob rpc)
        {
            var res = new GenJobRes()
            {
                ErrCode    = Luban.Common.EErrorCode.OK,
                ErrMsg     = "succ",
                FileGroups = new List <FileGroup>(),
            };

            if (!TryParseArg(rpc.Arg.JobArguments, out GenArgs args, out string errMsg))
            {
                res.ErrCode = Luban.Common.EErrorCode.JOB_ARGUMENT_ERROR;
                res.ErrMsg  = errMsg;
                agent.Session.ReplyRpc <GenJob, GenJobArg, GenJobRes>(rpc, res);
                return;
            }

            var timer = new ProfileTimer();

            timer.StartPhase("= gen_all =");
            try
            {
                string inputDataDir  = args.InputDataDir;
                string outputCodeDir = args.OutputCodeDir;
                string outputDataDir = args.OutputDataDir;

                var genTypes = args.GenType.Split(',').Select(s => s.Trim()).ToList();

                timer.StartPhase("build defines");
                var loader = new CfgDefLoader(agent);
                await loader.LoadAsync(args.DefineFile);

                timer.EndPhaseAndLog();

                var rawDefines = loader.BuildDefines();

                TimeZoneInfo timeZoneInfo = string.IsNullOrEmpty(args.TimeZone) ? TimeZoneInfo.Local : TimeZoneInfo.FindSystemTimeZoneById(args.TimeZone);

                var ass = new DefAssembly(timeZoneInfo);

                ass.Load(args.Service, rawDefines, agent);

                var targetService = ass.CfgTargetService;


                List <DefTable>    exportTables = ass.GetExportTables();
                List <DefTypeBase> exportTypes  = ass.GetExportTypes();

                bool hasLoadCfgData = false;


                async Task CheckLoadCfgDataAsync()
                {
                    if (!hasLoadCfgData)
                    {
                        hasLoadCfgData = true;
                        var timer = new ProfileTimer();
                        timer.StartPhase("load config data");
                        await LoadCfgDataAsync(agent, ass, args.InputDataDir, args.ExportTestData);

                        timer.EndPhaseAndLog();

                        timer.StartPhase("validate");
                        var validateCtx = new ValidatorContext(ass, args.ValidateRootDir);
                        await validateCtx.ValidateTables(exportTables);

                        timer.EndPhaseAndLog();
                    }
                }

                var tasks = new List <Task>();

                var genCodeFiles = new ConcurrentBag <FileInfo>();
                var genDataFiles = new ConcurrentBag <FileInfo>();

                foreach (var genType in genTypes)
                {
                    switch (genType)
                    {
                    case "code_cs_bin":
                    case "code_cs_json":

                    case "code_java_bin":
                    {
                        ICodeRender render = CreateCodeRender(genType);
                        ELanguage   lan    = GetLanguage(genType);

                        foreach (var c in exportTypes)
                        {
                            tasks.Add(Task.Run(() =>
                                {
                                    var content = FileHeaderUtil.ConcatAutoGenerationHeader(render.RenderAny(c), lan);
                                    var file    = RenderFileUtil.GetDefTypePath(c.FullName, lan);
                                    var md5     = CacheFileUtil.GenMd5AndAddCache(file, content);
                                    genCodeFiles.Add(new FileInfo()
                                    {
                                        FilePath = file, MD5 = md5
                                    });
                                }));
                        }

                        tasks.Add(Task.Run(() =>
                            {
                                var module  = ass.TopModule;
                                var name    = targetService.Manager;
                                var content = FileHeaderUtil.ConcatAutoGenerationHeader(render.RenderService(name, module, exportTables), lan);
                                var file    = RenderFileUtil.GetDefTypePath(name, lan);
                                var md5     = CacheFileUtil.GenMd5AndAddCache(file, content);
                                genCodeFiles.Add(new FileInfo()
                                {
                                    FilePath = file, MD5 = md5
                                });
                            }));

                        break;
                    }

                    case "code_lua_bin":
                    {
                        tasks.Add(Task.Run(() =>
                            {
                                var render  = new LuaRender();
                                var content = FileHeaderUtil.ConcatAutoGenerationHeader(render.RenderAll(ass.Types.Values.ToList()), ELanguage.LUA);
                                var file    = "Types.lua";
                                var md5     = CacheFileUtil.GenMd5AndAddCache(file, content);
                                genCodeFiles.Add(new FileInfo()
                                {
                                    FilePath = file, MD5 = md5
                                });
                            }));
                        break;
                    }

                    case "code_go_bin":
                    {
                        var render = new GoCodeRender();
                        foreach (var c in exportTypes)
                        {
                            tasks.Add(Task.Run(() =>
                                {
                                    var content = FileHeaderUtil.ConcatAutoGenerationHeader(render.RenderAny(c), ELanguage.GO);
                                    var file    = RenderFileUtil.GetDefTypePath(c.FullName, ELanguage.GO);
                                    var md5     = CacheFileUtil.GenMd5AndAddCache(file, content);
                                    genCodeFiles.Add(new FileInfo()
                                    {
                                        FilePath = file, MD5 = md5
                                    });
                                }));
                        }

                        tasks.Add(Task.Run(() =>
                            {
                                var module  = ass.TopModule;
                                var name    = targetService.Manager;
                                var content = FileHeaderUtil.ConcatAutoGenerationHeader(render.RenderService(name, module, exportTables), ELanguage.GO);
                                var file    = RenderFileUtil.GetDefTypePath(name, ELanguage.GO);
                                var md5     = CacheFileUtil.GenMd5AndAddCache(file, content);
                                genCodeFiles.Add(new FileInfo()
                                {
                                    FilePath = file, MD5 = md5
                                });
                            }));
                        break;
                    }

                    case "code_cpp_bin":
                    {
                        var render = new CppBinCodeRender();


                        // 将所有 头文件定义 生成到一个文件
                        // 按照 const,enum,bean,table, service 的顺序生成

                        tasks.Add(Task.Run(() =>
                            {
                                var headerFileContent = new List <string>
                                {
                                    @$ "
#pragma once
#include <functional>

#include " "bright/serialization/ByteBuf.h" "
#include " "bright/CfgBean.hpp" "

using ByteBuf = bright::serialization::ByteBuf;

namespace {ass.TopModule}
{{

"
                                };

                                foreach (var type in exportTypes)
                                {
                                    if (type is DefEnum e)
                                    {
                                        headerFileContent.Add(render.Render(e));
                                    }
                                }

                                foreach (var type in exportTypes)
                                {
                                    if (type is DefConst c)
                                    {
                                        headerFileContent.Add(render.Render(c));
                                    }
                                }

                                foreach (var type in exportTypes)
                                {
                                    if (type is DefBean e)
                                    {
                                        headerFileContent.Add(render.RenderForwardDefine(e));
                                    }
                                }

                                foreach (var type in exportTypes)
                                {
                                    if (type is DefBean e)
                                    {
                                        headerFileContent.Add(render.Render(e));
                                    }
                                }

                                foreach (var type in exportTables)
                                {
                                    headerFileContent.Add(render.Render(type));
                                }

                                headerFileContent.Add(render.RenderService("Tables", ass.TopModule, exportTables));

                                headerFileContent.Add("}"); // end of topmodule

                                var content = FileHeaderUtil.ConcatAutoGenerationHeader(string.Join('\n', headerFileContent), ELanguage.CPP);
                                var file    = "gen_types.h";
                                var md5     = CacheFileUtil.GenMd5AndAddCache(file, content);
                                genCodeFiles.Add(new FileInfo()
                                {
                                    FilePath = file, MD5 = md5
                                });
                            }));

                        var beanTypes = exportTypes.Where(c => c is DefBean).ToList();

                        int TYPE_PER_STUB_FILE = 100;

                        for (int i = 0, n = (beanTypes.Count + TYPE_PER_STUB_FILE - 1) / TYPE_PER_STUB_FILE; i < n; i++)
                        {
                            int index = i;
                            tasks.Add(Task.Run(() =>
                                {
                                    int startIndex = index * TYPE_PER_STUB_FILE;
                                    var content    = FileHeaderUtil.ConcatAutoGenerationHeader(
                                        render.RenderStub(ass.TopModule, beanTypes.GetRange(startIndex, Math.Min(TYPE_PER_STUB_FILE, beanTypes.Count - startIndex))),
                                        ELanguage.CPP);
                                    var file = $"gen_stub_{index}.cpp";
                                    var md5  = CacheFileUtil.GenMd5AndAddCache(file, content);
                                    genCodeFiles.Add(new FileInfo()
                                    {
                                        FilePath = file, MD5 = md5
                                    });
                                }));
                        }
                        break;
                    }

                    case "code_typescript_json":
                    {
                        var render = new TypeScriptJsonCodeRender();
                        tasks.Add(Task.Run(() =>
                            {
                                var fileContent = new List <string>
                                {
                                    @$ "
export namespace {ass.TopModule} {{
",

                                    @"
export class Vector2 {
        x: number;
        y: number;
        constructor(x: number, y: number) {
            this.x = x;
            this.y = y;
        }

        static fromJson(_json_: any): Vector2 {
            let x = _json_['x'];
            let y = _json_['y'];
            if (x == null || y == null) {
                throw new Error();
            }
            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 fromJson(_json_: any): Vector3 {
            let x = _json_['x'];
            let y = _json_['y'];
            let z = _json_['z'];
            if (x == null || y == null || z == null) {
                throw new Error();
            }
            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 fromJson(_json_: any): Vector4 {
            let x = _json_['x'];
            let y = _json_['y'];
            let z = _json_['z'];
            let w = _json_['w'];
            if (x == null || y == null || z == null || w == null) {
                throw new Error();
            }
            return new Vector4(x, y, z, w);
        }
    }

"
                                };

                                foreach (var type in exportTypes)
                                {
                                    if (type is DefEnum e)
                                    {
                                        fileContent.Add(render.Render(e));
                                    }
                                }

                                foreach (var type in exportTypes)
                                {
                                    if (type is DefConst c)
                                    {
                                        fileContent.Add(render.Render(c));
                                    }
                                }

                                foreach (var type in exportTypes)
                                {
                                    if (type is DefBean e)
                                    {
                                        fileContent.Add(render.Render(e));
                                    }
                                }

                                foreach (var type in exportTables)
                                {
                                    fileContent.Add(render.Render(type));
                                }

                                fileContent.Add(render.RenderService("Tables", ass.TopModule, exportTables));

                                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);
                                genCodeFiles.Add(new FileInfo()
                                {
                                    FilePath = file, MD5 = md5
                                });
                            }));
Example #2
0
        public async Task GenAsync(RemoteAgent agent, GenJob rpc)
        {
            var res = new GenJobRes()
            {
                ErrCode    = Luban.Common.EErrorCode.OK,
                ErrMsg     = "succ",
                FileGroups = new List <FileGroup>(),
            };

            if (!TryParseArg(rpc.Arg.JobArguments, out GenArgs args, out string errMsg))
            {
                res.ErrCode = Luban.Common.EErrorCode.JOB_ARGUMENT_ERROR;
                res.ErrMsg  = errMsg;
                agent.Session.ReplyRpc <GenJob, GenJobArg, GenJobRes>(rpc, res);
                return;
            }

            var timer = new ProfileTimer();

            timer.StartPhase("= gen_all =");
            try
            {
                string outputCodeDir = args.OutputCodeDir;


                timer.StartPhase("build defines");
                var loader = new ProtoDefLoader(agent);
                await loader.LoadAsync(args.DefineFile);

                timer.EndPhaseAndLog();

                var rawDefines = loader.BuildDefines();

                var ass = new DefAssembly();

                ass.Load(rawDefines, agent);

                var targetService = args.Service;


                List <DefTypeBase> exportTypes = ass.GetExportTypes();

                var tasks        = new List <Task>();
                var genCodeFiles = new ConcurrentBag <FileInfo>();


                var genType = args.GenType;
                switch (genType)
                {
                case "cs":
                {
                    var render = new CsRender();
                    foreach (var c in ass.Types.Values)
                    {
                        tasks.Add(Task.Run(() =>
                            {
                                var content = FileHeaderUtil.ConcatAutoGenerationHeader(render.RenderAny(c), Common.ELanguage.CS);
                                var file    = RenderFileUtil.GetDefTypePath(c.FullName, Common.ELanguage.CS);
                                var md5     = CacheFileUtil.GenMd5AndAddCache(file, content);
                                genCodeFiles.Add(new FileInfo()
                                {
                                    FilePath = file, MD5 = md5
                                });
                            }));
                    }
                    tasks.Add(Task.Run(() =>
                        {
                            var module  = ass.TopModule;
                            var name    = "ProtocolStub";
                            var content = FileHeaderUtil.ConcatAutoGenerationHeader(
                                render.RenderStubs(name, module,
                                                   ass.Types.Values.Where(t => t is DefProto).ToList(),
                                                   ass.Types.Values.Where(t => t is DefRpc).ToList()),
                                Common.ELanguage.CS);
                            var file = RenderFileUtil.GetDefTypePath(name, Common.ELanguage.CS);
                            var md5  = CacheFileUtil.GenMd5AndAddCache(file, content);
                            genCodeFiles.Add(new FileInfo()
                            {
                                FilePath = file, MD5 = md5
                            });
                        }));
                    break;
                }

                case "lua":
                {
                    tasks.Add(Task.Run(() =>
                        {
                            var render  = new LuaRender();
                            var content = FileHeaderUtil.ConcatAutoGenerationHeader(render.RenderTypes(ass.Types.Values.ToList()), Common.ELanguage.LUA);
                            var file    = "Types.lua";
                            var md5     = CacheFileUtil.GenMd5AndAddCache(file, content);
                            genCodeFiles.Add(new FileInfo()
                            {
                                FilePath = file, MD5 = md5
                            });
                        }));
                    break;
                }

                default:
                {
                    throw new NotSupportedException($"not support gen type:{genType}");
                }
                }

                await Task.WhenAll(tasks.ToArray());

                res.FileGroups.Add(new FileGroup()
                {
                    Dir = outputCodeDir, Files = genCodeFiles.ToList()
                });
            }
            catch (Exception e)
            {
                res.ErrCode = Luban.Common.EErrorCode.JOB_EXCEPTION;
                res.ErrMsg  = $"{e.Message} \n {e.StackTrace}";
            }
            timer.EndPhaseAndLog();

            agent.Session.ReplyRpc <GenJob, GenJobArg, GenJobRes>(rpc, res);
        }