Compare commits

...

52 Commits
v6.0 ... main

Author SHA1 Message Date
Carson - 宝鱼 720e2eaf49
[fix] 解决7c0579b4bbd7d2c746a8a264d54557ec1e209fd4提交造成的编译错误 (#55)
Co-authored-by: 宝鱼 <kteong1012@outlook.com>
2023-07-06 08:28:08 +08:00
SaNeOr 7c0579b4bb
[fix] 修复 导出python数据, DBool类型 格式问题 (#53) 2023-06-25 18:02:55 +08:00
宝鱼 b791b4276d [new] 新增正则校验器 2023-06-23 12:28:47 +08:00
walon de075ca7d9 [change] DataUtil由GBK编码改为UTF8 2023-06-23 12:21:24 +08:00
SaNeOr 803145e267
[fix] 修复 导出python数据, DMap类型 key的格式问题 (#49)
python的dict类型key不像json只能为string,还可能为其他类型。
2023-06-15 16:46:27 +08:00
walon ea1dc4a462 [fix] 修复data_json_monolithic生成失败的问题 2023-05-12 12:56:33 +08:00
walon 62b60ac581 更新README中文档链接到luban-doc 2023-05-11 17:34:51 +08:00
walon 9bc74b3c73 [fix] 修复ref指向singleton表时,校验错误地使用了ref定义所在的字段而不是ref指向的表的字段的bug 2023-05-06 13:04:44 +08:00
walon 4ef2d70398 [fix] 修复config cpp对多联合索引生成的代码的编译错误 2023-04-12 00:36:41 +08:00
walon 8e68ab0fcd [fix] 修复cfg ts加载bin格式datetime类型时返回bigint的bug 2023-04-03 19:19:42 +08:00
walon bcf81ffe26 [fix] 修复 Proto及DB生成时,对于多级继承在某些遍历顺序下 CollectHierarchyFields 的bug 2023-02-28 21:31:16 +08:00
walon c14437aa59 [fix] 修复Cfg DefBean.PreCompile中CollectHierarchyFields时由于顺序原因有可能发生祖父及更高层级的类的ParentDefType字段未设置导致的未能收集到所有字段的恶劣bug 2023-02-28 20:36:43 +08:00
walon 16e4fe2452 [fix] 修复使用Scriban导出大型文本型数据时发生超出最大迭代次数的问题 2023-02-10 14:37:07 +08:00
walon 7ad942b7cd [fix] 修复生成 java array类型代码的编译bug 2023-02-06 21:33:46 +08:00
walon e8ac256e92 [fix] 修复生成map类型的java resolve代码的有编译错误的问题 2023-02-06 21:12:24 +08:00
walon 46cc7cd26f [change] 删除 ParseExcelBool中对 '是'和'否'的支持 2023-02-03 22:47:45 +08:00
walon e67082a098 [fix] 修复生成db cs代码的编译错误
[change] 生成db cs代码由异步模式换成同步模式
2023-02-03 22:47:45 +08:00
wmltogether ae87bf3f52
[change] 使用int64存储datetime类型,避免读取日期超过2038年出现问题 (#38) 2023-01-29 13:42:46 +08:00
walon ea30f8c202 [fix] 修复db生成代码的bug 2023-01-06 21:49:38 +08:00
Skyhand 874f966a40
[opt] verify param template_search_path (#37) 2022-12-30 18:12:48 +08:00
Carson - 宝鱼 b37f2692e3
[fix] 修复生成java嵌套容器代码有编译错误的bug 2022-12-28 09:50:00 +08:00
Carson - 宝鱼 ba2c5c56e7
[new] 增加java对容器ref的支持 (#34)
[new] 增加java对容器ref的支持
2022-12-14 09:56:04 +08:00
walon d0587324f5 [opt] 优化excel中填写bool类型数据,可以用 true|yes|y|1表示true,用 false|no|n|0表示false 2022-12-07 19:28:46 +08:00
walon 2962b6a1bf
Merge pull request #32 from fgc0109/fix_publish
fix publish single file
2022-12-07 10:58:56 +08:00
Chasel 44b0fc9b36 fix System.Reflection.Assembly.GetCallingAssembly().Location return empty string when publish single file 2022-12-06 17:35:31 +08:00
walon 33b7f25fd4 [fix] 修复excel格式中仅非有效字段列非空的行被判定为非空行,导致解析数据失败的bug 2022-12-05 18:04:24 +08:00
walon 9b97f5d0bd [new] 支持proto java代码生成 2022-11-28 20:17:12 +08:00
宝鱼 88ab94e836 fix: 修复上个commit引发的空引用报错 2022-11-22 18:19:13 +08:00
Carson - 宝鱼 410fdd3618
[fix] 修复了$type-$value的形式没有读取bean在表格添加的sep符号的bug。 (#30)
Co-authored-by: 宝鱼 <kteong1012@outlook.com>
2022-11-18 12:26:13 +08:00
Carson - 宝鱼 bcc7bc8b37
[new]支持$type + 流式$value的填写方式 (#29)
[new]支持$type + 流式$value的填写方式

Co-authored-by: Tianbao Lin <kteong1012@outlook.com>
2022-10-20 09:04:42 +08:00
walon 165ad69a5d
Merge pull request #27 from kteong1012/pr221019
[fix] 修复了beans定义表不能指定单独sheet的bug
2022-10-19 10:39:51 +08:00
Tianbao Lin b1c2507d99 [fix] 修复了beans定义表不能指定单独sheet的bug 2022-10-19 10:33:02 +08:00
walon af492cea8d [fix] 修复 cs_unity_editor_json/bean.tpl 多了一个括号的bug 2022-10-18 22:39:25 +08:00
Carson - 宝鱼 30a4ce12db
[new] 新增表格对##group的支持
[new] 新增表格对##group的支持


Co-authored-by: Tianbao Lin <kteong1012@outlook.com>
2022-10-13 17:48:42 +08:00
walon 14faa26565
Merge pull request #23 from kteong1012/main
[fix] 修复了导出多维数组失败的bug
[fix] 修复CS模板处理嵌套命名空间的bug
2022-09-23 10:05:32 +08:00
Carson Lin 472c912f0f fix: 修复了导出多维数组失败的问题。 2022-09-22 15:22:38 +08:00
Carson Lin e897d6b5c0 fix: 修改CS模板,修复严重bug 2022-09-22 15:18:23 +08:00
walon 70b5a9b061
Merge pull request #21 from kteong1012/pr220910
[new] config c#代码生成支持无命名空间
2022-09-19 17:01:32 +08:00
Carson Lin 15a5a627d5 opt:修改一些细节 2022-09-16 10:55:56 +08:00
walon c707935008 [feature] flags类型的enum支持以枚举项为子列的配置方式 2022-09-14 12:48:20 +08:00
walon 81295cbfe1 [fix] 修复对容器类型的element type为external type时,生成的cs代码错误对external type调用?.Resove的bug 2022-09-14 12:20:20 +08:00
Carson Lin d9013167b8 feat : 支持无命名空间 2022-09-10 11:16:00 +08:00
walon ad4acf337f [opt] 优化生成的emmylua注解中的类型信息 2022-09-07 17:53:54 +08:00
walon f25f91b94d [fix] 修复code_cs_dotnet_json生成的external type代码有编译错误的bug 2022-08-23 10:11:25 +08:00
walon 741d820587
Merge pull request #19 from kteong1012/pr220816
feat:支持tables.xlsx中value_type定义parent,定义格式为TypeChild#parent=TypeParent
2022-08-22 08:42:24 +08:00
Carson Lin c1b4070520 fix:添加一个判空 2022-08-16 19:32:11 +08:00
Carson Lin 4e2891e07b feat:支持tables.xlsx中value_type定义parent,定义格式为TypeChild#parent=TypeParent 2022-08-16 19:01:30 +08:00
walon b1f9105773 [new] excel __beans__.xlsx 支持 alias字段 2022-08-14 16:38:20 +08:00
walon 69a0acf63e [fix] 修复为cs_unity_json生成 反序列化external bean类型的编译错误bug 2022-08-10 20:22:04 +08:00
walon ff6e09ec9d [fix] 修复xml定义table时失误将options属性写成parser_mode的bug 2022-08-10 18:03:10 +08:00
walon c60f91fdd4 [new] 支持纯流式模式的excel解析方式 2022-08-10 15:22:51 +08:00
walon 154d55f372 [fix] 修复为了支持嵌套容器导致未检查容器元素类型不能为可空的bug 2022-08-09 11:51:21 +08:00
112 changed files with 1504 additions and 416 deletions

View File

@ -1,4 +1,4 @@
#Luban
# Luban
[![license](http://img.shields.io/badge/license-MIT-blue.svg)](https://opensource.org/licenses/MIT)
[![Build Status](https://travis-ci.com/focus-creative-games/luban.svg?branch=main)](https://travis-ci.com/focus-creative-games/luban )
@ -21,35 +21,34 @@
luban is your **best game configuration solution**.
Luban efficiently handles data such as excel, json, and xml that are common in game development, checks for data errors, generates code in various languages such as c#, and exports it to various formats such as bytes or json.
Luban efficiently processes data such as excel, json, and xml common in game development, checks data errors, generates codes in various languages such as c#, and exports them into various formats such as bytes or json.
Luban unifies the game configuration development workflow, greatly improving the efficiency of planning and programming.
luban unifies the game configuration development workflow, greatly improving the efficiency of planning and programming.
## Core Features
## Core features
- Powerful data parsing and conversion capabilities {excel(csv,xls,xlsx), json, bson, xml, yaml, lua, unity ScriptableObject} => {binary, json, bson, xml, lua, yaml, erlang, custom format }
- Enhanced excel format that can be easily configured like simple lists, substructures, structured lists, and arbitrarily complex deeply nested structures.
- Complete type system, **support OOP type inheritance**, with data in excel, json, lua, xml and other formats **flexibly and elegantly** to express complex GamePlay data such as behavior trees, skills, plots, and copies
- Support to generate c#, java, go, c++, lua, python, javascript, typescript, erlang, rust code
- Powerful data analysis and conversion capabilities {excel(csv,xls,xlsx), json, bson, xml, yaml, lua, unity ScriptableObject} => {binary, json, bson, xml, lua, yaml, erlang, custom format }
- Enhanced excel format, which can succinctly configure simple lists, substructures, structured lists, and arbitrarily complex deep nested structures.
- Complete type system, **Support OOP type inheritance**, with data in excel, json, lua, xml and other formats **Flexible and elegant** Express complex GamePlay data such as behavior trees, skills, plots, and copies
- Supports generating c#, java, go, c++, lua, python, javascript, typescript, erlang, rust, gdscript code
- Support generating protobuf(schema + binary + json), flatbuffers(schema + json), msgpack(binary)
- Powerful data verification capabilities. ref reference check, path resource path, range range check, etc.
- Powerful data verification capability. ref reference check, path resource path, range range check, etc.
- Perfect localization support. Static text value localization, dynamic text value localization, time localization, main-patch multi-region version
- Powerful and flexible customization capabilities, support for custom code templates and data templates
- **Generic generation and caching tool**. Can also be used to generate code like protocols, databases, or even as an object caching service
- **Good support for mainstream engines, all platforms, mainstream hot update solutions, mainstream front-end and back-end frameworks**. Support mainstream engines such as unity, unreal, cocos2x, and WeChat mini-games. The tool itself is cross-platform and can work well on Win, Linux, and Mac platforms.
- **Universal generation and caching tool**. It can also be used to generate code such as protocols, databases, and even as an object caching service
- **Good support for mainstream engines, all platforms, mainstream hot update solutions, and mainstream front-end and back-end frameworks**. Supports mainstream engines such as Unity, Unreal, Cocos2x, Godot, and WeChat games. The tool itself is cross-platform and can work well on Win, Linux, and Mac platforms.
See [feature](https://focus-creative-games.github.io/luban/feature/) for full features
See [feature](https://focus-creative-games.github.io/luban-doc/#/manual/traits) for complete features
## Documentation
- [Quick Start](https://focus-creative-games.github.io/luban/start_up/)
- [Document](https://focus-creative-games.github.io/luban/), it is relatively complete, if you have any questions, please check this document first.
- [Official Documentation](https://focus-creative-games.github.io/luban-doc/)
- [Quickstart](https://focus-creative-games.github.io/luban-doc/#/beginner/quickstart)
- **Example Project** ([github](https://github.com/focus-creative-games/luban_examples)) ([gitee](https://gitee.com/focus-creative-games/luban_examples) )
- [Version Changelog](https://focus-creative-games.github.io/luban/changelog/)
- Support and Contact
- QQ group: 692890842 (Luban development exchange group). If you have any questions about use, please add the QQ group to ask in time, and someone will help you at any time.
- Email: taojingjian#gmail.com
- [Version Change Log](https://focus-creative-games.github.io/luban-doc/#/changelog)
- Support and contact
- QQ group: 692890842 (Luban development exchange group). If you have any questions about usage, please join the QQ group to ask in time, and someone will help you solve it at any time.
- Email: luban@code-philosophy.com
## Excel format overview

View File

@ -39,22 +39,20 @@ luban统一了游戏配置开发工作流极大提升了策划和程序的工
- **通用型生成和缓存工具**。也可以用于生成协议、数据库之类的代码,甚至可以用作对象缓存服务
- **良好支持主流引擎、全平台、主流热更新方案、主流前后端框架**。支持Unity、Unreal、Cocos2x、Godot、微信小游戏等主流引擎。工具自身跨平台能在Win,Linux,Mac平台良好工作。
完整特性请参见 [feature](https://focus-creative-games.github.io/luban/traits)
完整特性请参见 [feature](https://focus-creative-games.github.io/luban-doc/#/manual/traits)
## 文档
- [快速上手](https://focus-creative-games.github.io/luban/start_up/)
- [Document](https://focus-creative-games.github.io/luban/) ,比较完善,有使用疑问,请先查看此文档。
- [官方文档](https://focus-creative-games.github.io/luban-doc/)
- [快速上手](https://focus-creative-games.github.io/luban-doc/#/beginner/quickstart)
- **示例项目** ([github](https://github.com/focus-creative-games/luban_examples)) ([gitee](https://gitee.com/focus-creative-games/luban_examples))
- [版本变更记录](https://focus-creative-games.github.io/luban/changelog/)
- [版本变更记录](https://focus-creative-games.github.io/luban-doc/#/changelog)
- 支持与联系
- QQ群: 692890842 Luban开发交流群。有使用方面的疑问请及时加QQ群询问随时有人帮助解决。
- 邮箱: luban@focus-creative-games.com
- 邮箱: luban@code-philosophy.com
## excel格式速览
完整示例请详见 [excel格式介绍](https://focus-creative-games.github.io/luban/excel/)
### 普通表
|##var| id | x1 | x5 | x6 | s1 | s2 | v3 | t1 |
@ -392,16 +390,6 @@ Reward为包含 "int item_id; int count; string desc; " 这三个字段的子结
</tr>
</table>
### map 类型的多级子标题
<table border="1">
<tr align="center"><td>##var</td><td>id</td><td colspan="4">lans</td></tr>
<tr align="center"><td>##type</td><td>int</td><td colspan="4">map,string,string</td></tr>
<tr align="center"><td>##var</td><td/><td>ch-zn</td><td>en</td><td>jp</td><td>fr</td></tr>
<tr align="center"><td/><td>1</td><td>苹果</td><td>apple</td><td>aaa</td><td>aaa</td></tr>
<tr align="center"><td/><td>2</td><td>香蕉</td><td>banana</td><td>bbb</td><td>bbb</td></tr>
</table>
### 类型继承适合技能、buff相关配置
<table border="1">
@ -475,7 +463,7 @@ Reward为包含 "int item_id; int count; string desc; " 这三个字段的子结
## json、lua、xml、yaml 格式速览
以行为树为例展示json格式下如何配置行为树配置。xml、lua、yaml等等格式请参见 [详细文档](https://focus-creative-games.github.io/luban/data_source/)。
以行为树为例展示json格式下如何配置行为树配置。xml、lua、yaml等等格式请参见 [详细文档](https://focus-creative-games.github.io/luban-doc/#/manual/datasource)。
```json
{

View File

@ -10,6 +10,7 @@ using Luban.Job.Common.Utils;
using Luban.Server;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
@ -137,7 +138,15 @@ Options:
case "-t":
case "--template_search_path":
{
ops.TemplateSearchPath = args[++i];
var dirName = args[++i];
if (Directory.Exists(dirName))
{
ops.TemplateSearchPath = dirName;
}
else
{
Console.WriteLine("[WARN] 对于Luban.ClientServer参数 {0} {1} 路径不存在,忽略。", arg, dirName);
}
break;
}
case "--":
@ -338,4 +347,4 @@ Options:
return 0;
}
}
}
}

View File

@ -14,7 +14,7 @@ namespace Luban.Common.Utils
public static string GetApplicationDirectory()
{
return Path.GetDirectoryName(System.Reflection.Assembly.GetCallingAssembly().Location);
return AppContext.BaseDirectory;
}
public static string GetPathRelateApplicationDirectory(string relatePath)

View File

@ -29,14 +29,7 @@ namespace Luban.Job.Cfg.DataCreators
return b;
}
var s = x.ToString().ToLower().Trim();
switch (s)
{
case "true":
case "是": return true;
case "false":
case "否": return false;
default: throw new InvalidExcelDataException($"{s} 不是 bool 类型的值 (true 或 false)");
}
return DataUtil.ParseExcelBool(s);
}
public DType Accept(TBool type, ExcelStream x)

View File

@ -15,7 +15,7 @@ using System.Threading.Tasks;
namespace Luban.Job.Cfg.DataCreators
{
class SheetDataCreator : ITypeFuncVisitor<Sheet, TitleRow, DType>
class SheetDataCreator : ITypeFuncVisitor<RowColumnSheet, TitleRow, DType>
{
public static SheetDataCreator Ins { get; } = new();
@ -37,7 +37,7 @@ namespace Luban.Job.Cfg.DataCreators
}
}
public DType Accept(TBool type, Sheet sheet, TitleRow row)
public DType Accept(TBool type, RowColumnSheet sheet, TitleRow row)
{
object x = row.Current;
if (CheckNull(type.IsNullable, x))
@ -53,10 +53,10 @@ namespace Luban.Job.Cfg.DataCreators
{
return DBool.ValueOf(v);
}
return DBool.ValueOf(bool.Parse(x.ToString()));
return DBool.ValueOf(DataUtil.ParseExcelBool(x.ToString()));
}
public DType Accept(TByte type, Sheet sheet, TitleRow row)
public DType Accept(TByte type, RowColumnSheet sheet, TitleRow row)
{
object x = row.Current;
if (CheckNull(type.IsNullable, x))
@ -70,7 +70,7 @@ namespace Luban.Job.Cfg.DataCreators
return DByte.ValueOf(byte.Parse(x.ToString()));
}
public DType Accept(TShort type, Sheet sheet, TitleRow row)
public DType Accept(TShort type, RowColumnSheet sheet, TitleRow row)
{
object x = row.Current;
if (CheckNull(type.IsNullable, x))
@ -85,7 +85,7 @@ namespace Luban.Job.Cfg.DataCreators
return DShort.ValueOf(short.Parse(x.ToString()));
}
public DType Accept(TFshort type, Sheet sheet, TitleRow row)
public DType Accept(TFshort type, RowColumnSheet sheet, TitleRow row)
{
object x = row.Current;
if (CheckNull(type.IsNullable, x))
@ -99,7 +99,7 @@ namespace Luban.Job.Cfg.DataCreators
return DFshort.ValueOf(short.Parse(x.ToString()));
}
public DType Accept(TInt type, Sheet sheet, TitleRow row)
public DType Accept(TInt type, RowColumnSheet sheet, TitleRow row)
{
object x = row.Current;
if (CheckNull(type.IsNullable, x))
@ -114,7 +114,7 @@ namespace Luban.Job.Cfg.DataCreators
return DInt.ValueOf(int.Parse(x.ToString()));
}
public DType Accept(TFint type, Sheet sheet, TitleRow row)
public DType Accept(TFint type, RowColumnSheet sheet, TitleRow row)
{
object x = row.Current;
if (CheckNull(type.IsNullable, x))
@ -129,7 +129,7 @@ namespace Luban.Job.Cfg.DataCreators
return DFint.ValueOf(int.Parse(x.ToString()));
}
public DType Accept(TLong type, Sheet sheet, TitleRow row)
public DType Accept(TLong type, RowColumnSheet sheet, TitleRow row)
{
object x = row.Current;
if (CheckNull(type.IsNullable, x))
@ -144,7 +144,7 @@ namespace Luban.Job.Cfg.DataCreators
return DLong.ValueOf(long.Parse(x.ToString()));
}
public DType Accept(TFlong type, Sheet sheet, TitleRow row)
public DType Accept(TFlong type, RowColumnSheet sheet, TitleRow row)
{
object x = row.Current;
if (CheckNull(type.IsNullable, x))
@ -159,7 +159,7 @@ namespace Luban.Job.Cfg.DataCreators
return DFlong.ValueOf(long.Parse(x.ToString()));
}
public DType Accept(TFloat type, Sheet sheet, TitleRow row)
public DType Accept(TFloat type, RowColumnSheet sheet, TitleRow row)
{
object x = row.Current;
if (CheckNull(type.IsNullable, x))
@ -174,7 +174,7 @@ namespace Luban.Job.Cfg.DataCreators
return DFloat.ValueOf(float.Parse(x.ToString()));
}
public DType Accept(TDouble type, Sheet sheet, TitleRow row)
public DType Accept(TDouble type, RowColumnSheet sheet, TitleRow row)
{
object x = row.Current;
if (CheckNull(type.IsNullable, x))
@ -189,25 +189,82 @@ namespace Luban.Job.Cfg.DataCreators
return DDouble.ValueOf(double.Parse(x.ToString()));
}
public DType Accept(TEnum type, Sheet sheet, TitleRow row)
public DType Accept(TEnum type, RowColumnSheet sheet, TitleRow row)
{
object x = row.Current;
if (CheckNull(type.IsNullable, x))
if (row.Row != null)
{
return null;
object x = row.Current;
if (CheckNull(type.IsNullable, x))
{
return null;
}
if (CheckDefault(x))
{
if (type.DefineEnum.IsFlags || type.DefineEnum.HasZeroValueItem)
{
return new DEnum(type, "0");
}
else
{
throw new InvalidExcelDataException($"枚举类:'{type.DefineEnum.FullName}' 没有value为0的枚举项, 不支持默认值");
}
}
return new DEnum(type, x.ToString());
}
if (CheckDefault(x))
else if (row.Rows != null)
{
if (type.DefineEnum.HasZeroValueItem)
{
return new DEnum(type, "0");
}
else
{
throw new InvalidExcelDataException($"枚举类:'{type.DefineEnum.FullName}' 没有value为0的枚举项, 不支持默认值");
}
throw new Exception($"{type.DefineEnum.FullName} 不支持多行格式");
}
else if (row.Fields != null)
{
//throw new Exception($"array 不支持 子字段. 忘记将字段设为多行模式? {row.SelfTitle.Name} => *{row.SelfTitle.Name}");
var items = new List<string>();
var sortedFields = row.Fields.Values.ToList();
sortedFields.Sort((a, b) => a.SelfTitle.FromIndex - b.SelfTitle.FromIndex);
foreach (var field in sortedFields)
{
string itemName = field.SelfTitle.Name;
if (!type.DefineEnum.TryValueByNameOrAlias(itemName, out _))
{
throw new Exception($"列名:{itemName} 不是枚举类型'{type.DefineEnum.FullName}'的有效枚举项");
}
if (field.IsBlank)
{
continue;
}
string cur = field.Current.ToString().ToLower();
if (cur != "0" && cur != "false")
{
items.Add(itemName);
}
}
if (items.Count == 0)
{
if (type.IsNullable)
{
return null;
}
if (type.DefineEnum.IsFlags || type.DefineEnum.HasZeroValueItem)
{
return new DEnum(type, "0");
}
else
{
throw new InvalidExcelDataException($"枚举类:'{type.DefineEnum.FullName}' 没有value为0的枚举项, 不支持默认值");
}
}
return new DEnum(type, string.Join('|', items));
}
else if (row.Elements != null)
{
throw new Exception($"{type.DefineEnum.FullName} 不支持多行子字段格式");
}
else
{
throw new Exception();
}
return new DEnum(type, x.ToString());
}
@ -227,7 +284,7 @@ namespace Luban.Job.Cfg.DataCreators
}
}
public DType Accept(TString type, Sheet sheet, TitleRow row)
public DType Accept(TString type, RowColumnSheet sheet, TitleRow row)
{
object x = row.Current;
if (CheckDefault(x))
@ -249,12 +306,12 @@ namespace Luban.Job.Cfg.DataCreators
return DString.ValueOf(s);
}
public DType Accept(TBytes type, Sheet sheet, TitleRow row)
public DType Accept(TBytes type, RowColumnSheet sheet, TitleRow row)
{
throw new NotSupportedException();
}
public DType Accept(TText type, Sheet sheet, TitleRow row)
public DType Accept(TText type, RowColumnSheet sheet, TitleRow row)
{
if (string.IsNullOrEmpty(row.SelfTitle.SepOr(type.GetTag("sep"))))
{
@ -279,7 +336,7 @@ namespace Luban.Job.Cfg.DataCreators
}
}
public DType Accept(TDateTime type, Sheet sheet, TitleRow row)
public DType Accept(TDateTime type, RowColumnSheet sheet, TitleRow row)
{
var d = row.Current;
if (CheckNull(type.IsNullable, d))
@ -293,7 +350,7 @@ namespace Luban.Job.Cfg.DataCreators
return DataUtil.CreateDateTime(d.ToString());
}
public DType Accept(TVector2 type, Sheet sheet, TitleRow row)
public DType Accept(TVector2 type, RowColumnSheet sheet, TitleRow row)
{
var d = row.Current;
if (CheckNull(type.IsNullable, d))
@ -308,7 +365,7 @@ namespace Luban.Job.Cfg.DataCreators
return DataUtil.CreateVector(type, d.ToString());
}
public DType Accept(TVector3 type, Sheet sheet, TitleRow row)
public DType Accept(TVector3 type, RowColumnSheet sheet, TitleRow row)
{
var d = row.Current;
if (CheckNull(type.IsNullable, d))
@ -323,7 +380,7 @@ namespace Luban.Job.Cfg.DataCreators
return DataUtil.CreateVector(type, d.ToString());
}
public DType Accept(TVector4 type, Sheet sheet, TitleRow row)
public DType Accept(TVector4 type, RowColumnSheet sheet, TitleRow row)
{
var d = row.Current;
if (CheckNull(type.IsNullable, d))
@ -338,7 +395,7 @@ namespace Luban.Job.Cfg.DataCreators
return DataUtil.CreateVector(type, d.ToString());
}
private List<DType> CreateBeanFields(DefBean bean, Sheet sheet, TitleRow row)
private List<DType> CreateBeanFields(DefBean bean, RowColumnSheet sheet, TitleRow row)
{
var list = new List<DType>();
foreach (DefField f in bean.HierarchyFields)
@ -369,10 +426,9 @@ namespace Luban.Job.Cfg.DataCreators
return list;
}
public DType Accept(TBean type, Sheet sheet, TitleRow row)
public DType Accept(TBean type, RowColumnSheet sheet, TitleRow row)
{
string sep = row.SelfTitle.Sep;// type.GetBeanAs<DefBean>().Sep;
if (row.Row != null)
{
var s = row.AsStream(sep);
@ -393,6 +449,7 @@ namespace Luban.Job.Cfg.DataCreators
}
else if (row.Fields != null)
{
sep += type.GetBeanAs<DefBean>().Sep;
var originBean = (DefBean)type.Bean;
if (originBean.IsAbstractType)
{
@ -401,7 +458,8 @@ namespace Luban.Job.Cfg.DataCreators
{
throw new Exception($"type:'{originBean.FullName}' 是多态类型,需要定义'{DefBean.EXCEL_TYPE_NAME_KEY}'列来指定具体子类型");
}
TitleRow valueTitle = row.GetSubTitleNamedRow(DefBean.EXCEL_VALUE_NAME_KEY);
sep += type.GetTag("sep");
string subType = typeTitle.Current?.ToString()?.Trim();
if (subType == null || subType == DefBean.BEAN_NULL_STR)
{
@ -412,7 +470,36 @@ namespace Luban.Job.Cfg.DataCreators
return null;
}
DefBean implType = DataUtil.GetImplTypeByNameOrAlias(originBean, subType);
return new DBean(type, implType, CreateBeanFields(implType, sheet, row));
if (valueTitle == null)
{
return new DBean(type, implType, CreateBeanFields(implType, sheet, row));
}
else
{
sep += valueTitle.SelfTitle.Sep;
if (valueTitle.Row != null)
{
var s = valueTitle.AsStream(sep);
if (type.IsNullable && s.TryReadEOF())
{
return null;
}
return new DBean(type, implType, CreateBeanFields(implType, s));
}
else if (valueTitle.Rows != null)
{
var s = valueTitle.AsMultiRowConcatStream(sep);
if (type.IsNullable && s.TryReadEOF())
{
return null;
}
return new DBean(type, implType, CreateBeanFields(implType, s));
}
else
{
throw new Exception();
}
}
}
else
{
@ -479,7 +566,7 @@ namespace Luban.Job.Cfg.DataCreators
return datas;
}
private List<DType> ReadCollectionDatas(TType type, TType elementType, Sheet sheet, TitleRow row)
private List<DType> ReadCollectionDatas(TType type, TType elementType, RowColumnSheet sheet, TitleRow row)
{
if (row.Row != null)
{
@ -518,23 +605,23 @@ namespace Luban.Job.Cfg.DataCreators
}
}
public DType Accept(TArray type, Sheet sheet, TitleRow row)
public DType Accept(TArray type, RowColumnSheet sheet, TitleRow row)
{
//string sep = DataUtil.GetSep(type);
return new DArray(type, ReadCollectionDatas(type, type.ElementType, sheet, row));
}
public DType Accept(TList type, Sheet sheet, TitleRow row)
public DType Accept(TList type, RowColumnSheet sheet, TitleRow row)
{
return new DList(type, ReadCollectionDatas(type, type.ElementType, sheet, row));
}
public DType Accept(TSet type, Sheet sheet, TitleRow row)
public DType Accept(TSet type, RowColumnSheet sheet, TitleRow row)
{
return new DSet(type, ReadCollectionDatas(type, type.ElementType, sheet, row));
}
public DType Accept(TMap type, Sheet sheet, TitleRow row)
public DType Accept(TMap type, RowColumnSheet sheet, TitleRow row)
{
string sep = row.SelfTitle.Sep;
@ -563,7 +650,7 @@ namespace Luban.Job.Cfg.DataCreators
foreach (var e in row.Fields)
{
var keyData = type.KeyType.Apply(StringDataCreator.Ins, e.Key);
if (Sheet.IsBlankRow(e.Value.Row, e.Value.SelfTitle.FromIndex, e.Value.SelfTitle.ToIndex))
if (RowColumnSheet.IsBlankRow(e.Value.Row, e.Value.SelfTitle.FromIndex, e.Value.SelfTitle.ToIndex))
{
continue;
}
@ -589,5 +676,29 @@ namespace Luban.Job.Cfg.DataCreators
throw new Exception();
}
}
private List<DType> CreateBeanFields(DefBean bean, ExcelStream stream)
{
var list = new List<DType>();
foreach (DefField f in bean.HierarchyFields)
{
try
{
list.Add(f.CType.Apply(ExcelStreamDataCreator.Ins, stream));
}
catch (DataCreateException dce)
{
dce.Push(bean, f);
throw;
}
catch (Exception e)
{
var dce = new DataCreateException(e, stream.LastReadDataInfo);
dce.Push(bean, f);
throw dce;
}
}
return list;
}
}
}

View File

@ -179,7 +179,7 @@ namespace Luban.Job.Cfg.DataExporters
public void Accept(DDateTime type, ByteBuf x)
{
x.WriteInt(type.UnixTimeOfCurrentAssembly);
x.WriteLong(type.UnixTimeOfCurrentAssembly);
}
}
}

View File

@ -87,7 +87,7 @@ namespace Luban.Job.Cfg.DataExporters
public void Accept(DDateTime type, CodedOutputStream x)
{
x.WriteInt32(type.UnixTimeOfCurrentAssembly);
x.WriteInt64(type.UnixTimeOfCurrentAssembly);
}
public void Accept(DString type, CodedOutputStream x)

View File

@ -1,5 +1,8 @@
using Luban.Job.Cfg.DataCreators;
using Luban.Job.Cfg.DataSources.Excel;
using Luban.Job.Cfg.Defs;
using System;
using System.Collections.Generic;
using System.IO;
namespace Luban.Job.Cfg.DataSources
@ -18,7 +21,35 @@ namespace Luban.Job.Cfg.DataSources
".asset",
};
public static AbstractDataSource Create(string url, string sheetName, Stream stream)
private static string GetSheetParserMode(Dictionary<string, string> options)
{
if (options != null && options.TryGetValue("parser_mode", out var modeStr))
{
return modeStr;
}
//options = DefAssembly.LocalAssebmly.Options;
//if (options != null && options.TryGetValue("sheet.parser_mode", out modeStr))
//{
// return modeStr;
//}
return "";
}
private static bool IsColumnMode(string mode)
{
if (string.IsNullOrEmpty(mode))
{
return true;
}
switch(mode.ToLowerInvariant())
{
case "column": return true;
case "stream": return false;
default: throw new Exception($"unknown parser_mode:{mode}");
}
}
public static AbstractDataSource Create(string url, string sheetName, Dictionary<string, string> options, Stream stream)
{
try
{
@ -29,7 +60,11 @@ namespace Luban.Job.Cfg.DataSources
case "csv":
case "xls":
case "xlsx":
case "xlsm": source = new Excel.ExcelDataSource(); break;
case "xlsm":
{
source = IsColumnMode(GetSheetParserMode(options)) ? new ExcelRowColumnDataSource() : new ExcelStreamDataSource();
break;
}
case "xml": source = new Xml.XmlDataSource(); break;
case "lua": source = new Lua.LuaDataSource(); break;
case "json": source = new Json.JsonDataSource(); break;

View File

@ -10,11 +10,11 @@ using System.IO;
namespace Luban.Job.Cfg.DataSources.Excel
{
class ExcelDataSource : AbstractDataSource
class ExcelRowColumnDataSource : AbstractDataSource
{
private static readonly NLog.Logger s_logger = NLog.LogManager.GetCurrentClassLogger();
private readonly List<Sheet> _sheets = new List<Sheet>();
private readonly List<RowColumnSheet> _sheets = new List<RowColumnSheet>();
public override void Load(string rawUrl, string sheetName, Stream stream)
@ -25,7 +25,7 @@ namespace Luban.Job.Cfg.DataSources.Excel
foreach (RawSheet rawSheet in SheetLoadUtil.LoadRawSheets(rawUrl, sheetName, stream))
{
var sheet = new Sheet(rawUrl, sheetName);
var sheet = new RowColumnSheet(rawUrl, sheetName);
sheet.Load(rawSheet);
_sheets.Add(sheet);
}
@ -40,7 +40,7 @@ namespace Luban.Job.Cfg.DataSources.Excel
{
foreach (RawSheet rawSheet in rawSheets)
{
var sheet = new Sheet("__intern__", rawSheet.TableName);
var sheet = new RowColumnSheet("__intern__", rawSheet.TableName);
sheet.Load(rawSheet);
_sheets.Add(sheet);
}

View File

@ -0,0 +1,76 @@
using ExcelDataReader;
using Luban.Job.Cfg.DataCreators;
using Luban.Job.Cfg.Datas;
using Luban.Job.Cfg.Utils;
using Luban.Job.Common.Types;
using System;
using System.Collections.Generic;
using System.IO;
namespace Luban.Job.Cfg.DataSources.Excel
{
class ExcelStreamDataSource : AbstractDataSource
{
private static readonly NLog.Logger s_logger = NLog.LogManager.GetCurrentClassLogger();
private readonly List<StreamSheet> _sheets = new List<StreamSheet>();
public override void Load(string rawUrl, string sheetName, Stream stream)
{
s_logger.Trace("{filename} {sheet}", rawUrl, sheetName);
RawUrl = rawUrl;
foreach (RawSheet rawSheet in SheetLoadUtil.LoadRawSheets(rawUrl, sheetName, stream))
{
var sheet = new StreamSheet(rawUrl, sheetName);
sheet.Load(rawSheet);
_sheets.Add(sheet);
}
if (_sheets.Count == 0)
{
throw new Exception($"excel:{rawUrl} 不包含有效的单元薄(有效单元薄的A0单元格必须是##).");
}
}
public RawSheetTableDefInfo LoadTableDefInfo(string rawUrl, string sheetName, Stream stream)
{
return SheetLoadUtil.LoadSheetTableDefInfo(rawUrl, sheetName, stream);
}
public override List<Record> ReadMulti(TBean type)
{
var datas = new List<Record>();
foreach (var sheet in _sheets)
{
try
{
var stream = sheet.Stream;
while(!stream.TryReadEOF())
{
var data = (DBean)type.Apply(ExcelStreamDataCreator.Ins, stream);
datas.Add(new Record(data, sheet.RawUrl, null));
}
}
catch (DataCreateException dce)
{
dce.OriginDataLocation = sheet.RawUrl;
throw;
}
catch (Exception e)
{
throw new Exception($"sheet:{sheet.Name}", e);
}
}
return datas;
}
public override Record ReadOne(TBean type)
{
throw new Exception($"excel不支持单例读取模式");
}
}
}

View File

@ -1,4 +1,5 @@
using System;
using DocumentFormat.OpenXml.EMMA;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@ -15,6 +16,7 @@ namespace Luban.Job.Cfg.DataSources.Excel
public string Type { get; set; }
public string Desc { get; set; }
public string Groups { get; set; }
}
class RawSheetTableDefInfo

View File

@ -12,7 +12,7 @@ using System.Linq;
namespace Luban.Job.Cfg.DataSources.Excel
{
class Sheet
class RowColumnSheet
{
private static readonly NLog.Logger s_logger = NLog.LogManager.GetCurrentClassLogger();
@ -22,7 +22,7 @@ namespace Luban.Job.Cfg.DataSources.Excel
public List<(string Tag, TitleRow Row)> Rows { get; } = new();
public Sheet(string rawUrl, string name)
public RowColumnSheet(string rawUrl, string name)
{
this.RawUrl = rawUrl;
this.Name = name;
@ -42,7 +42,7 @@ namespace Luban.Job.Cfg.DataSources.Excel
{
foreach (var row in cells)
{
if (IsBlankRow(row, title.FromIndex, title.ToIndex))
if (IsBlankRow(row, title))
{
continue;
}
@ -188,6 +188,15 @@ namespace Luban.Job.Cfg.DataSources.Excel
return Rows;
}
public static bool IsBlankRow(List<Cell> row, Title title)
{
if (title.SubTitleList.Count == 0)
{
return IsBlankRow(row, title.FromIndex, title.ToIndex);
}
return title.SubTitleList.All(t => IsBlankRow(row, t));
}
public static bool IsBlankRow(List<Cell> row, int fromIndex, int toIndex)
{
for (int i = Math.Max(1, fromIndex), n = Math.Min(toIndex, row.Count - 1); i <= n; i++)

View File

@ -87,6 +87,7 @@ namespace Luban.Job.Cfg.DataSources.Excel
"desc",
"comment",
"column",
"group",
};
private const char s_sep = '#';
@ -450,6 +451,10 @@ namespace Luban.Job.Cfg.DataSources.Excel
{
return IsRowTagEqual(row, "##type");
}
private static bool IsGroupRow(List<Cell> row)
{
return IsRowTagEqual(row, "##group");
}
private static bool IsHeaderRow(List<Cell> row)
{
@ -577,7 +582,7 @@ namespace Luban.Job.Cfg.DataSources.Excel
{
descRow = cells.Count > 1 ? cells.Skip(1).FirstOrDefault(row => IsRowTagEqual(row, "##")) : null;
}
List<Cell> groupRow = cells.Find(row => IsGroupRow(row));
var fields = new Dictionary<string, FieldInfo>();
foreach (var subTitle in title.SubTitleList)
{
@ -617,6 +622,7 @@ namespace Luban.Job.Cfg.DataSources.Excel
Name = subTitle.Name,
Tags = subTitle.Tags,
Type = typeRow[subTitle.FromIndex].Value?.ToString() ?? "",
Groups = groupRow?[subTitle.FromIndex].Value?.ToString() ?? "",
Desc = desc,
});
}

View File

@ -0,0 +1,37 @@
using Bright.Collections;
using ExcelDataReader;
using Luban.Job.Cfg.DataCreators;
using Luban.Job.Cfg.Datas;
using Luban.Job.Cfg.Utils;
using Luban.Job.Common.Types;
using Luban.Job.Common.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Luban.Job.Cfg.DataSources.Excel
{
class StreamSheet
{
private static readonly NLog.Logger s_logger = NLog.LogManager.GetCurrentClassLogger();
public string Name { get; }
public string RawUrl { get; }
public ExcelStream Stream { get; private set; }
public StreamSheet(string rawUrl, string name)
{
this.RawUrl = rawUrl;
this.Name = name;
}
public void Load(RawSheet rawSheet)
{
Title title = rawSheet.Title;
Stream = new ExcelStream(rawSheet.Cells, 1, title.ToIndex, "", "");
}
}
}

View File

@ -75,11 +75,11 @@ namespace Luban.Job.Cfg.DataSources.Excel
{
if (Row != null)
{
return Sheet.IsBlankRow(Row, SelfTitle.FromIndex, SelfTitle.ToIndex);
return RowColumnSheet.IsBlankRow(Row, SelfTitle.FromIndex, SelfTitle.ToIndex);
}
if (Rows != null)
{
return Sheet.IsBlankRow(Rows[0], SelfTitle.FromIndex, SelfTitle.ToIndex);
return RowColumnSheet.IsBlankRow(Rows[0], SelfTitle.FromIndex, SelfTitle.ToIndex);
}
if (Fields != null)
{
@ -105,7 +105,6 @@ namespace Luban.Job.Cfg.DataSources.Excel
}
}
public bool HasSubFields => Fields != null || Elements != null;
public TitleRow(Title selfTitle, List<Cell> row)

View File

@ -7,7 +7,7 @@ namespace Luban.Job.Cfg.DataVisitors
{
abstract class ToLiteralVisitorBase : IDataFuncVisitor<string>
{
public string Accept(DBool type)
public virtual string Accept(DBool type)
{
return type.Value ? "true" : "false";
}

View File

@ -10,6 +10,11 @@ namespace Luban.Job.Cfg.DataVisitors
{
public static ToPythonLiteralVisitor Ins { get; } = new();
public override string Accept(DBool type)
{
return type.Value ? "True" : "False";
}
public override string Accept(DText type)
{
return $"{{\"{DText.KEY_NAME}\":\"{type.Key}\",\"{DText.TEXT_NAME}\":\"{DataUtil.EscapeString(type.TextOfCurrentAssembly)}\"}}";
@ -94,7 +99,7 @@ namespace Luban.Job.Cfg.DataVisitors
x.Append(',');
}
++index;
x.Append('"').Append(e.Key.ToString()).Append('"');
x.Append(e.Key.Apply(this));
x.Append(':');
x.Append(e.Value.Apply(this));
}

View File

@ -11,7 +11,7 @@ namespace Luban.Job.Cfg.Datas
public DateTime Time { get; }
//public int UnixTime { get; }
private readonly int _localTime;
private readonly long _localTime;
public override string TypeName => "datetime";
@ -21,7 +21,7 @@ namespace Luban.Job.Cfg.Datas
this.Time = time;
// time.Kind == DateTimeKind.Unspecified
// DateTimeOffset°ÑËüµ±×÷Local´¦Àí
this._localTime = (int)new DateTimeOffset(TimeZoneInfo.ConvertTime(time, TimeZoneUtil.DefaultTimeZone, TimeZoneInfo.Utc)).ToUnixTimeSeconds();
this._localTime = (long)new DateTimeOffset(TimeZoneInfo.ConvertTime(time, TimeZoneUtil.DefaultTimeZone, TimeZoneInfo.Utc)).ToUnixTimeSeconds();
}
public override bool Equals(object obj)
@ -48,7 +48,7 @@ namespace Luban.Job.Cfg.Datas
return DataUtil.FormatDateTime(Time);
}
public int GetUnixTime(TimeZoneInfo asTimeZone)
public long GetUnixTime(TimeZoneInfo asTimeZone)
{
if (asTimeZone == null || asTimeZone == TimeZoneInfo.Local)
{
@ -57,11 +57,11 @@ namespace Luban.Job.Cfg.Datas
else
{
var destDateTime = TimeZoneInfo.ConvertTime(Time, asTimeZone, TimeZoneInfo.Utc);
return (int)new DateTimeOffset(destDateTime).ToUnixTimeSeconds();
return (long)new DateTimeOffset(destDateTime).ToUnixTimeSeconds();
}
}
public int UnixTimeOfCurrentAssembly => GetUnixTime(DefAssembly.LocalAssebmly.TimeZone);
public long UnixTimeOfCurrentAssembly => GetUnixTime(DefAssembly.LocalAssebmly.TimeZone);
public override void Apply<T>(IDataActionVisitor<T> visitor, T x)
{

View File

@ -236,7 +236,7 @@ namespace Luban.Job.Cfg.Defs
return mode;
}
private readonly List<string> _tableOptionalAttrs = new List<string> { "index", "mode", "group", "patch_input", "comment", "define_from_file", "output" };
private readonly List<string> _tableOptionalAttrs = new List<string> { "index", "mode", "group", "patch_input", "comment", "define_from_file", "output", "options" };
private readonly List<string> _tableRequireAttrs = new List<string> { "name", "value", "input" };
private void AddTable(string defineFile, XElement e)
@ -254,11 +254,12 @@ namespace Luban.Job.Cfg.Defs
string mode = XmlUtil.GetOptionalAttribute(e, "mode");
string tags = XmlUtil.GetOptionalAttribute(e, "tags");
string output = XmlUtil.GetOptionalAttribute(e, "output");
AddTable(defineFile, name, module, valueType, index, mode, group, comment, defineFromFile, input, patchInput, tags, output);
string options = XmlUtil.GetOptionalAttribute(e, "options");
AddTable(defineFile, name, module, valueType, index, mode, group, comment, defineFromFile, input, patchInput, tags, output, options);
}
private void AddTable(string defineFile, string name, string module, string valueType, string index, string mode, string group,
string comment, bool defineFromExcel, string input, string patchInput, string tags, string outputFileName)
string comment, bool defineFromExcel, string input, string patchInput, string tags, string outputFileName, string options)
{
var p = new Table()
{
@ -272,6 +273,7 @@ namespace Luban.Job.Cfg.Defs
Mode = ConvertMode(defineFile, name, mode, index),
Tags = tags,
OutputFile = outputFileName,
Options = options,
};
if (string.IsNullOrWhiteSpace(name))
{
@ -318,20 +320,43 @@ namespace Luban.Job.Cfg.Defs
RawSheetTableDefInfo tableDefInfo;
if (!ExcelTableValueTypeDefInfoCacheManager.Instance.TryGetTableDefInfo(file.MD5, file.SheetName, out tableDefInfo))
{
var source = new ExcelDataSource();
var source = new ExcelRowColumnDataSource();
var stream = new MemoryStream(await this.Agent.GetFromCacheOrReadAllBytesAsync(file.ActualFile, file.MD5));
tableDefInfo = source.LoadTableDefInfo(file.OriginFile, file.SheetName, stream);
ExcelTableValueTypeDefInfoCacheManager.Instance.AddTableDefInfoToCache(file.MD5, file.SheetName, tableDefInfo);
}
var ns = TypeUtil.GetNamespace(table.ValueType);
var (valueType, tags) = DefUtil.ParseType(table.ValueType);
var ns = TypeUtil.GetNamespace(valueType);
string valueTypeNamespace = string.IsNullOrEmpty(ns) ? table.Namespace : ns;
string valueTypeName = TypeUtil.GetName(table.ValueType);
string valueTypeName = TypeUtil.GetName(valueType);
Bean parentBean = null;
if (tags.TryGetValue("parent", out string parentType))
{
var parentNs = TypeUtil.GetNamespace(parentType);
string parentNamespace = string.IsNullOrEmpty(parentNs) ? table.Namespace : parentNs;
string parentName = TypeUtil.GetName(parentType);
parentType = string.Join(".", parentNamespace, parentName);
parentBean = _beans.FirstOrDefault(x => x.FullName == parentType);
}
var cb = new CfgBean() { Namespace = valueTypeNamespace, Name = valueTypeName, Comment = "", Parent = parentType };
if (parentBean != null)
{
foreach (var parentField in parentBean.Fields)
{
if (!tableDefInfo.FieldInfos.Any(x => x.Key == parentField.Name && x.Value.Type == parentField.Type))
{
throw new Exception($"table:'{table.Name}' file:{file.OriginFile} title:缺失父类字段:'{parentField.Type} {parentField.Name}'");
}
}
}
var cb = new CfgBean() { Namespace = valueTypeNamespace, Name = valueTypeName, Comment = "" };
foreach (var (name, f) in tableDefInfo.FieldInfos)
{
if (parentBean != null && parentBean.Fields.Any(x => x.Name == name && x.Type == f.Type))
{
continue;
}
var cf = new CfgField() { Name = name, Id = 0 };
string[] attrs = f.Type.Trim().Split('&').Select(s => s.Trim()).ToArray();
@ -342,9 +367,7 @@ namespace Luban.Job.Cfg.Defs
}
cf.Comment = f.Desc;
cf.Type = attrs[0];
for (int i = 1; i < attrs.Length; i++)
{
var pair = attrs[i].Split('=', 2);
@ -361,6 +384,7 @@ namespace Luban.Job.Cfg.Defs
case "path":
case "range":
case "sep":
case "regex":
{
throw new Exception($"table:'{table.Name}' file:{file.OriginFile} title:'{name}' attr:'{attrName}' 属于type的属性必须用#分割,尝试'{cf.Type}#{attrs[i]}'");
}
@ -386,6 +410,11 @@ namespace Luban.Job.Cfg.Defs
}
}
if (!string.IsNullOrEmpty(f.Groups))
{
cf.Groups = f.Groups.Split(',').Select(s => s.Trim()).Where(s => !string.IsNullOrWhiteSpace(s)).ToList();
}
cb.Fields.Add(cf);
}
return cb;
@ -436,6 +465,7 @@ namespace Luban.Job.Cfg.Defs
new CfgField() { Name = "output", Type = "string" },
new CfgField() { Name = "patch_input", Type = "string" },
new CfgField() { Name = "tags", Type = "string" },
new CfgField() { Name = "options", Type = "string" },
}
})
{
@ -448,10 +478,10 @@ namespace Luban.Job.Cfg.Defs
foreach (var file in inputFileInfos)
{
var source = new ExcelDataSource();
var source = new ExcelRowColumnDataSource();
var bytes = await this.Agent.GetFromCacheOrReadAllBytesAsync(file.ActualFile, file.MD5);
(var actualFile, var sheetName) = FileUtil.SplitFileAndSheetName(FileUtil.Standardize(file.OriginFile));
var records = DataLoaderUtil.LoadCfgRecords(tableRecordType, actualFile, sheetName, bytes, true);
var records = DataLoaderUtil.LoadCfgRecords(tableRecordType, actualFile, sheetName, bytes, true, null);
foreach (var r in records)
{
DBean data = r.Data;
@ -473,7 +503,8 @@ namespace Luban.Job.Cfg.Defs
string patchInput = (data.GetField("patch_input") as DString).Value.Trim();
string tags = (data.GetField("tags") as DString).Value.Trim();
string outputFile = (data.GetField("output") as DString).Value.Trim();
AddTable(file.OriginFile, name, module, valueType, index, mode, group, comment, isDefineFromExcel, inputFile, patchInput, tags, outputFile);
string options = (data.GetField("options") as DString).Value.Trim();
AddTable(file.OriginFile, name, module, valueType, index, mode, group, comment, isDefineFromExcel, inputFile, patchInput, tags, outputFile, options);
};
}
}
@ -547,10 +578,10 @@ namespace Luban.Job.Cfg.Defs
foreach (var file in inputFileInfos)
{
var source = new ExcelDataSource();
var source = new ExcelRowColumnDataSource();
var bytes = await this.Agent.GetFromCacheOrReadAllBytesAsync(file.ActualFile, file.MD5);
(var actualFile, var sheetName) = FileUtil.SplitFileAndSheetName(FileUtil.Standardize(file.OriginFile));
var records = DataLoaderUtil.LoadCfgRecords(tableRecordType, actualFile, sheetName, bytes, true);
var records = DataLoaderUtil.LoadCfgRecords(tableRecordType, actualFile, sheetName, bytes, true, null);
foreach (var r in records)
{
@ -643,6 +674,7 @@ namespace Luban.Job.Cfg.Defs
new CfgField() { Name = "full_name", Type = "string" },
new CfgField() {Name = "parent", Type = "string" },
new CfgField() { Name = "sep", Type = "string" },
new CfgField() { Name = "alias", Type = "string" },
new CfgField() { Name = "comment", Type = "string" },
new CfgField() { Name = "tags", Type = "string" },
new CfgField() { Name = "fields", Type = "list,__FieldInfo__" },
@ -659,9 +691,9 @@ namespace Luban.Job.Cfg.Defs
foreach (var file in inputFileInfos)
{
var source = new ExcelDataSource();
var source = new ExcelRowColumnDataSource();
var bytes = await this.Agent.GetFromCacheOrReadAllBytesAsync(file.ActualFile, file.MD5);
var records = DataLoaderUtil.LoadCfgRecords(tableRecordType, file.OriginFile, null, bytes, true);
var records = DataLoaderUtil.LoadCfgRecords(tableRecordType, file.OriginFile, file.SheetName, bytes, true, null);
foreach (var r in records)
{
@ -677,6 +709,7 @@ namespace Luban.Job.Cfg.Defs
string parent = (data.GetField("parent") as DString).Value.Trim();
string sep = (data.GetField("sep") as DString).Value.Trim();
string alias = (data.GetField("alias") as DString).Value.Trim();
string comment = (data.GetField("comment") as DString).Value.Trim();
string tags = (data.GetField("tags") as DString).Value.Trim();
DList fields = data.GetField("fields") as DList;
@ -685,6 +718,7 @@ namespace Luban.Job.Cfg.Defs
Name = name,
Namespace = module,
Sep = sep,
Alias = alias,
Comment = comment,
Tags = tags,
Parent = parent,

View File

@ -62,7 +62,8 @@ namespace Luban.Job.Cfg.Defs
private readonly ConcurrentDictionary<string, TableDataInfo> _recordsByTables = new();
public Dictionary<string, DefTable> CfgTablesByName = new();
public Dictionary<string, DefTable> CfgTablesByName { get; } = new();
public Dictionary<string, DefTable> CfgTablesByFullName { get; } = new Dictionary<string, DefTable>();
public RawTextTable RawTextTable { get; } = new RawTextTable();
@ -165,12 +166,12 @@ namespace Luban.Job.Cfg.Defs
public List<DefTable> GetAllTables()
{
return Types.Values.Where(t => t is DefTable).Cast<DefTable>().ToList();
return TypeList.Where(t => t is DefTable).Cast<DefTable>().ToList();
}
public List<DefTable> GetExportTables()
{
return Types.Values.Where(t => t is DefTable ct
return TypeList.Where(t => t is DefTable ct
&& !_outputExcludeTables.Contains(t.FullName)
&& (_outputIncludeTables.Contains(t.FullName) || (_overrideOutputTables == null ? ct.NeedExport : _overrideOutputTables.Contains(ct.FullName)))
).Select(t => (DefTable)t).ToList();
@ -312,12 +313,12 @@ namespace Luban.Job.Cfg.Defs
_cfgServices.AddRange(defines.Services);
foreach (var type in Types.Values)
foreach (var type in TypeList)
{
type.AssemblyBase = this;
}
foreach (var type in Types.Values)
foreach (var type in TypeList)
{
try
{
@ -331,7 +332,7 @@ namespace Luban.Job.Cfg.Defs
throw;
}
}
foreach (var type in Types.Values)
foreach (var type in TypeList)
{
try
{
@ -347,7 +348,7 @@ namespace Luban.Job.Cfg.Defs
}
}
foreach (var type in Types.Values)
foreach (var type in TypeList)
{
try
{

View File

@ -23,6 +23,7 @@ namespace Luban.Job.Cfg.Defs
public const string LUA_TYPE_NAME_KEY = "_type_";
public const string EXCEL_TYPE_NAME_KEY = "$type";
public const string EXCEL_VALUE_NAME_KEY = "$value";
public string JsonTypeNameKey => JSON_TYPE_NAME_KEY;
@ -159,21 +160,7 @@ namespace Luban.Job.Cfg.Defs
public override void PreCompile()
{
if (!string.IsNullOrEmpty(Parent))
{
if ((ParentDefType = (DefBean)AssemblyBase.GetDefType(Namespace, Parent)) == null)
{
throw new Exception($"bean:'{FullName}' parent:'{Parent}' not exist");
}
if (ParentDefType.Children == null)
{
ParentDefType.Children = new List<DefBeanBase>();
}
ParentDefType.Children.Add(this);
}
CollectHierarchyFields(HierarchyFields);
base.PreCompile();
this.ExportFields = this.Fields.Select(f => (DefField)f).Where(f => f.NeedExport).ToList();
this.HierarchyExportFields = this.HierarchyFields.Select(f => (DefField)f).Where(f => f.NeedExport).ToList();
}

View File

@ -63,8 +63,9 @@ namespace Luban.Job.Cfg.Defs
{
return Ref.GenRef;
}
// 特殊处理, 目前只有c#支持.而这个属性已经被多种语言模板引用了,故单独处理一下
if (DefAssemblyBase.LocalAssebmly.CurrentLanguage != Common.ELanguage.CS)
// 特殊处理, 目前只有c#和java支持.而这个属性已经被多种语言模板引用了,故单独处理一下
if (DefAssemblyBase.LocalAssebmly.CurrentLanguage != Common.ELanguage.CS
&& DefAssemblyBase.LocalAssebmly.CurrentLanguage != Common.ELanguage.JAVA)
{
return false;
}
@ -73,7 +74,7 @@ namespace Luban.Job.Cfg.Defs
}
public bool HasRecursiveRef => (CType is TBean tb && HostType.AssemblyBase.GetExternalTypeMapper(tb) == null)
|| CType.ElementType?.IsBean == true;
|| (CType.ElementType is TBean eb && HostType.AssemblyBase.GetExternalTypeMapper(eb) == null);
public string CsRefTypeName => RefType.Apply(CsDefineTypeName.Ins);
@ -109,8 +110,18 @@ namespace Luban.Job.Cfg.Defs
{
get
{
var table = Assembly.GetCfgTable(Ref.FirstTable);
return $"{table.ValueTType.Apply(JavaDefineTypeName.Ins)} {RefVarName};";
if (Ref != null)
{
return $"{RefType.Apply(JavaDefineTypeName.Ins)} {RefVarName};";
}
else if (ElementRef != null)
{
return $"{ElementRefType.Apply(JavaDefineTypeName.Ins)} {RefVarName};";
}
else
{
throw new NotSupportedException();
}
}
}

View File

@ -1,4 +1,5 @@
using Bright.Collections;
using Luban.Job.Cfg.DataSources.Excel;
using Luban.Job.Cfg.RawDefs;
using Luban.Job.Cfg.TypeVisitors;
using Luban.Job.Common.Types;
@ -28,8 +29,26 @@ namespace Luban.Job.Cfg.Defs
Comment = b.Comment;
Tags = DefUtil.ParseAttrs(b.Tags);
_outputFile = b.OutputFile;
ParseOptions(b.Options);
}
private void ParseOptions(string optionsStr)
{
foreach(var kvStr in optionsStr.Split('|', ';', ','))
{
if (string.IsNullOrWhiteSpace(kvStr))
{
continue;
}
string[] entry = kvStr.Split('=');
if (entry.Length != 2)
{
throw new Exception($"table:{FullName} options:'{optionsStr}' invalid");
}
Options[entry[0]] = entry[1];
}
}
public string Index { get; private set; }
@ -37,6 +56,8 @@ namespace Luban.Job.Cfg.Defs
public ETableMode Mode { get; }
public Dictionary<string, string> Options { get; } = new Dictionary<string, string>();
public bool IsMapTable => Mode == ETableMode.MAP;
public bool IsOneValueTable => Mode == ETableMode.ONE;
@ -92,7 +113,7 @@ namespace Luban.Job.Cfg.Defs
}
}
if ((ValueTType = (TBean)ass.CreateType(Namespace, ValueType)) == null)
if ((ValueTType = (TBean)ass.CreateType(Namespace, ValueType, false)) == null)
{
throw new Exception($"table:'{FullName}' 的 value类型:'{ValueType}' 不存在");
}

View File

@ -23,7 +23,7 @@ namespace Luban.Job.Cfg.Generate
{
allJsonTask.Add(Task.Run(() =>
{
return (string)DataExporterUtil.ToOutputData(c, ctx.Assembly.GetTableExportDataList(c), "data_json2");
return System.Text.Encoding.UTF8.GetString((byte[])DataExporterUtil.ToOutputData(c, ctx.Assembly.GetTableExportDataList(c), "data_json2"));
}));
}

View File

@ -67,33 +67,33 @@ namespace Luban.Job.Cfg
}
if (genTypes.Contains("data_resources") && string.IsNullOrWhiteSpace(options.OutputDataResourceListFile))
{
errMsg = "--output_data_resource_list_file missing";
errMsg = "--output:data:resource_list_file missing";
return false;
}
if (genTypes.Contains("output_data_json_monolithic_file") && string.IsNullOrWhiteSpace(options.OutputDataJsonMonolithicFile))
if (genTypes.Contains("data_json_monolithic") && string.IsNullOrWhiteSpace(options.OutputDataJsonMonolithicFile))
{
errMsg = "--output_data_json_monolithic_file missing";
errMsg = "--output:data:json_monolithic_file missing";
return false;
}
if (string.IsNullOrWhiteSpace(options.L10nInputTextTableFiles) ^ string.IsNullOrWhiteSpace(options.L10nOutputNotTranslatedTextFile))
{
errMsg = "--input_l10n_text_files must be provided with --output_l10n_not_translated_text_file";
errMsg = "--l10n:input_text_files should be used with --l10n:output_not_translated_text_file";
return false;
}
if (genTypes.Contains("data_template") ^ !string.IsNullOrWhiteSpace(options.TemplateDataFile))
{
errMsg = "gen_types data_template should use with --template:data:file";
errMsg = "gen_types data_template should be used with --template:data:file";
return false;
}
if (genTypes.Contains("convert_template") ^ !string.IsNullOrWhiteSpace(options.TemplateConvertFile))
{
errMsg = "gen_types convert_template should use with --template:convert:file";
errMsg = "gen_types convert_template should be used with --template:convert:file";
return false;
}
if (genTypes.Contains("code_template") ^ !string.IsNullOrWhiteSpace(options.TemplateCodeDir))
{
errMsg = "gen_types code_template should use with --template:code:dir";
errMsg = "gen_types code_template should be used with --template:code:dir";
return false;
}
}

View File

@ -1,3 +1,4 @@
using Luban.Job.Cfg.DataSources.Excel;
using System.Collections.Generic;
namespace Luban.Job.Cfg.RawDefs
@ -34,6 +35,8 @@ namespace Luban.Job.Cfg.RawDefs
public ETableMode Mode { get; set; }
public string Options { get; set; }
public string Comment { get; set; }
public string Tags { get; set; }

View File

@ -1,6 +1,7 @@
using Luban.Job.Cfg.Datas;
using Luban.Job.Cfg.Defs;
using Luban.Job.Cfg.Utils;
using Luban.Job.Common.Utils;
using Scriban;
using System.Collections.Generic;
@ -10,7 +11,7 @@ namespace Luban.Job.Cfg
{
public static string RenderCode(this Template template, object model, Dictionary<string, object> extraModels = null)
{
var ctx = new TemplateContext();
var ctx = TemplateUtil.CreateDefaultTemplateContext();
var env = new TTypeTemplateExtends
{
["x"] = model,
@ -29,8 +30,7 @@ namespace Luban.Job.Cfg
public static string RenderDatas(this Template template, DefTable table, List<DBean> exportDatas, Dictionary<string, object> extraModels = null)
{
var ctx = new TemplateContext();
var ctx = TemplateUtil.CreateDefaultTemplateContext();
var env = new DTypeTemplateExtends
{
["table"] = table,
@ -51,8 +51,7 @@ namespace Luban.Job.Cfg
public static string RenderData(this Template template, DefTable table, DBean data, Dictionary<string, object> extraModels = null)
{
var ctx = new TemplateContext();
var ctx = TemplateUtil.CreateDefaultTemplateContext();
var env = new DTypeTemplateExtends
{
["table"] = table,

View File

@ -120,7 +120,7 @@ namespace Luban.Job.Cfg.TypeVisitors
public string Accept(TDateTime type, string bufName, string fieldName)
{
return $"if(!{bufName}.readInt({fieldName})) return false;";
return $"if(!{bufName}.readLong({fieldName})) return false;";
}
}
}

View File

@ -1,6 +1,7 @@
using Luban.Job.Cfg.Datas;
using Luban.Job.Common.Types;
using Luban.Job.Common.TypeVisitors;
using Luban.Job.Common.Utils;
using System;
namespace Luban.Job.Cfg.TypeVisitors
@ -80,7 +81,8 @@ namespace Luban.Job.Cfg.TypeVisitors
public string Accept(TBean type, string json, string x, int depth)
{
return $"{x} = {type.CsUnderingDefineType()}.Deserialize{type.Bean.Name}({json});";
string src = $"{type.Bean.FullName}.Deserialize{type.Bean.Name}({json})";
return $"{x} = {ExternalTypeUtil.CsCloneToExternal(type.Bean.FullName, src)};";
}
public string Accept(TArray type, string json, string x, int depth)
@ -148,7 +150,7 @@ namespace Luban.Job.Cfg.TypeVisitors
public string Accept(TDateTime type, string json, string x, int depth)
{
return $"{x} = {json}.GetInt32();";
return $"{x} = {json}.GetInt64();";
}
}
}

View File

@ -1,6 +1,7 @@
using Luban.Job.Cfg.Datas;
using Luban.Job.Common.Types;
using Luban.Job.Common.TypeVisitors;
using Luban.Job.Common.Utils;
using System;
namespace Luban.Job.Cfg.TypeVisitors
@ -81,7 +82,8 @@ namespace Luban.Job.Cfg.TypeVisitors
public string Accept(TBean type, string json, string x, int depth)
{
return $"{{ if(!{json}.IsObject) {{ throw new SerializationException(); }} {x} = {type.CsUnderingDefineType()}.Deserialize{type.Bean.Name}({json}); }}";
string src = $"{type.Bean.FullName}.Deserialize{type.Bean.Name}({json})";
return $"{{ if(!{json}.IsObject) {{ throw new SerializationException(); }} {x} = {ExternalTypeUtil.CsCloneToExternal(type.Bean.FullName, src)}; }}";
}
public string Accept(TArray type, string json, string x, int depth)

View File

@ -5,81 +5,81 @@ using System;
namespace Luban.Job.Cfg.TypeVisitors
{
class JavaJsonDeserialize : ITypeFuncVisitor<string, string, string>
class JavaJsonDeserialize : ITypeFuncVisitor<string, string, int, string>
{
public static JavaJsonDeserialize Ins { get; } = new();
public string Accept(TBool type, string json, string x)
public string Accept(TBool type, string json, string x, int depth)
{
return $"{x} = {json}.getAsBoolean();";
}
public string Accept(TByte type, string json, string x)
public string Accept(TByte type, string json, string x, int depth)
{
return $"{x} = {json}.getAsByte();";
}
public string Accept(TShort type, string json, string x)
public string Accept(TShort type, string json, string x, int depth)
{
return $"{x} = {json}.getAsShort();";
}
public string Accept(TFshort type, string json, string x)
public string Accept(TFshort type, string json, string x, int depth)
{
return $"{x} = {json}.getAsShort();";
}
public string Accept(TInt type, string json, string x)
public string Accept(TInt type, string json, string x, int depth)
{
return $"{x} = {json}.getAsInt();";
}
public string Accept(TFint type, string json, string x)
public string Accept(TFint type, string json, string x, int depth)
{
return $"{x} = {json}.getAsInt();";
}
public string Accept(TLong type, string json, string x)
public string Accept(TLong type, string json, string x, int depth)
{
return $"{x} = {json}.getAsLong();";
}
public string Accept(TFlong type, string json, string x)
public string Accept(TFlong type, string json, string x, int depth)
{
return $"{x} = {json}.getAsLong();";
}
public string Accept(TFloat type, string json, string x)
public string Accept(TFloat type, string json, string x, int depth)
{
return $"{x} = {json}.getAsFloat();";
}
public string Accept(TDouble type, string json, string x)
public string Accept(TDouble type, string json, string x, int depth)
{
return $"{x} = {json}.getAsDouble();";
}
public string Accept(TEnum type, string json, string x)
public string Accept(TEnum type, string json, string x, int depth)
{
return $"{x} = {json}.getAsInt();";
}
public string Accept(TString type, string json, string x)
public string Accept(TString type, string json, string x, int depth)
{
return $"{x} = {json}.getAsString();";
}
public string Accept(TBytes type, string json, string x)
public string Accept(TBytes type, string json, string x, int depth)
{
throw new NotSupportedException();
}
public string Accept(TText type, string json, string x)
public string Accept(TText type, string json, string x, int depth)
{
return $"{json}.getAsJsonObject().get(\"{DText.KEY_NAME}\").getAsString(); {x} = {json}.getAsJsonObject().get(\"{DText.TEXT_NAME}\").getAsString();";
}
public string Accept(TBean type, string json, string x)
public string Accept(TBean type, string json, string x, int depth)
{
if (type.IsDynamic)
{
@ -91,44 +91,68 @@ namespace Luban.Job.Cfg.TypeVisitors
}
}
public string Accept(TArray type, string json, string x)
public string Accept(TArray type, string json, string x, int depth)
{
return $"{{ com.google.gson.JsonArray _json0_ = {json}.getAsJsonArray(); int _n = _json0_.size(); {x} = new {type.ElementType.Apply(JavaDefineTypeName.Ins)}[_n]; int _index=0; for(JsonElement __e : _json0_) {{ {type.ElementType.Apply(JavaDefineTypeName.Ins)} __v; {type.ElementType.Apply(this, "__e", "__v")} {x}[_index++] = __v; }} }}";
string __n = $"__n{depth}";
string __e = $"__e{depth}";
string __v = $"__v{depth}";
string __index = $"__index{depth}";
string typeStr = $"{type.ElementType.Apply(JavaDefineTypeName.Ins)}[{__n}]";
if (type.Dimension > 1)
{
if (type.FinalElementType == null)
{
throw new System.Exception("多维数组没有元素类型");
}
typeStr = $"{type.FinalElementType.Apply(JavaDefineTypeName.Ins)}[{__n}]";
for (int i = 0; i < type.Dimension - 1; i++)
{
typeStr += "[]";
}
}
return $"{{ com.google.gson.JsonArray _json{depth}_ = {json}.getAsJsonArray(); int {__n} = _json{depth}_.size(); {x} = new {typeStr}; int {__index}=0; for(JsonElement {__e} : _json{depth}_) {{ {type.ElementType.Apply(JavaDefineTypeName.Ins)} {__v}; {type.ElementType.Apply(this, $"{__e}", $"{__v}", depth + 1)} {x}[{__index}++] = {__v}; }} }}";
}
public string Accept(TList type, string json, string x)
public string Accept(TList type, string json, string x, int depth)
{
return $"{{ com.google.gson.JsonArray _json0_ = {json}.getAsJsonArray(); {x} = new {type.Apply(JavaDefineTypeName.Ins)}(_json0_.size()); for(JsonElement __e : _json0_) {{ {type.ElementType.Apply(JavaDefineTypeName.Ins)} __v; {type.ElementType.Apply(this, "__e", "__v")} {x}.add(__v); }} }}";
string __e = $"_e{depth}";
string __v = $"_v{depth}";
return $"{{ com.google.gson.JsonArray _json{depth}_ = {json}.getAsJsonArray(); {x} = new {type.Apply(JavaDefineTypeName.Ins)}(_json{depth}_.size()); for(JsonElement {__e} : _json{depth}_) {{ {type.ElementType.Apply(JavaDefineTypeName.Ins)} {__v}; {type.ElementType.Apply(this, __e, __v, depth + 1)} {x}.add({__v}); }} }}";
}
public string Accept(TSet type, string json, string x)
public string Accept(TSet type, string json, string x, int depth)
{
return $"{{ com.google.gson.JsonArray _json0_ = {json}.getAsJsonArray(); {x} = new {type.Apply(JavaDefineTypeName.Ins)}(_json0_.size()); for(JsonElement __e : _json0_) {{ {type.ElementType.Apply(JavaDefineTypeName.Ins)} __v; {type.ElementType.Apply(this, "__e", "__v")} {x}.add(__v); }} }}";
string __e = $"_e{depth}";
string __v = $"_v{depth}";
return $"{{ com.google.gson.JsonArray _json{depth}_ = {json}.getAsJsonArray(); {x} = new {type.Apply(JavaDefineTypeName.Ins)}(_json{depth}_.size()); for(JsonElement {__e} : _json{depth}_) {{ {type.ElementType.Apply(JavaDefineTypeName.Ins)} {__v}; {type.ElementType.Apply(this, __e, __v, depth + 1)} {x}.add({__v}); }} }}";
}
public string Accept(TMap type, string json, string x)
public string Accept(TMap type, string json, string x, int depth)
{
return @$"{{ com.google.gson.JsonArray _json0_ = {json}.getAsJsonArray(); {x} = new {type.Apply(JavaDefineTypeName.Ins)}(_json0_.size()); for(JsonElement __e : _json0_) {{ {type.KeyType.Apply(JavaDefineTypeName.Ins)} __k; {type.KeyType.Apply(this, "__e.getAsJsonArray().get(0)", "__k")} {type.ValueType.Apply(JavaDefineTypeName.Ins)} __v; {type.ValueType.Apply(this, "__e.getAsJsonArray().get(1)", "__v")} {x}.put(__k, __v); }} }}";
string __e = $"_e{depth}";
string __k = $"_k{depth}";
string __v = $"_v{depth}";
return @$"{{ com.google.gson.JsonArray _json{depth}_ = {json}.getAsJsonArray(); {x} = new {type.Apply(JavaDefineTypeName.Ins)}(_json{depth}_.size()); for(JsonElement {__e} : _json{depth}_) {{ {type.KeyType.Apply(JavaDefineTypeName.Ins)} {__k}; {type.KeyType.Apply(this, $"{__e}.getAsJsonArray().get(0)", __k, depth + 1)} {type.ValueType.Apply(JavaDefineTypeName.Ins)} {__v}; {type.ValueType.Apply(this, $"{__e}.getAsJsonArray().get(1)", __v, depth + 1)} {x}.put({__k}, {__v}); }} }}";
}
public string Accept(TVector2 type, string json, string x)
public string Accept(TVector2 type, string json, string x, int depth)
{
return $"{{ com.google.gson.JsonObject _json0_ = {json}.getAsJsonObject(); float __x; {TFloat.Ins.Apply(this, "_json0_.get(\"x\")", "__x") } float __y; {TFloat.Ins.Apply(this, "_json0_.get(\"y\")", "__y") } {x} = new {type.Apply(JavaDefineTypeName.Ins)}(__x, __y); }}";
return $"{{ com.google.gson.JsonObject _json{depth}_ = {json}.getAsJsonObject(); float __x; {TFloat.Ins.Apply(this, $"_json{depth}_.get(\"x\")", "__x", depth)} float __y; {TFloat.Ins.Apply(this, $"_json{depth}_.get(\"y\")", "__y", depth)} {x} = new {type.Apply(JavaDefineTypeName.Ins)}(__x, __y); }}";
}
public string Accept(TVector3 type, string json, string x)
public string Accept(TVector3 type, string json, string x, int depth)
{
return $"{{ com.google.gson.JsonObject _json0_ = {json}.getAsJsonObject(); float __x; {TFloat.Ins.Apply(this, "_json0_.get(\"x\")", "__x") } float __y; {TFloat.Ins.Apply(this, "_json0_.get(\"y\")", "__y") } float __z; {TFloat.Ins.Apply(this, "_json0_.get(\"z\")", "__z") } {x} = new {type.Apply(JavaDefineTypeName.Ins)}(__x, __y,__z); }}";
return $"{{ com.google.gson.JsonObject _json{depth}_ = {json}.getAsJsonObject(); float __x; {TFloat.Ins.Apply(this, $"_json{depth}_.get(\"x\")", "__x", depth)} float __y; {TFloat.Ins.Apply(this, $"_json{depth}_.get(\"y\")", "__y", depth)} float __z; {TFloat.Ins.Apply(this, $"_json{depth}_.get(\"z\")", "__z", depth)} {x} = new {type.Apply(JavaDefineTypeName.Ins)}(__x, __y,__z); }}";
}
public string Accept(TVector4 type, string json, string x)
public string Accept(TVector4 type, string json, string x, int depth)
{
return $"{{ com.google.gson.JsonObject _json0_ = {json}.getAsJsonObject(); float __x; {TFloat.Ins.Apply(this, "_json0_.get(\"x\")", "__x") } float __y; {TFloat.Ins.Apply(this, "_json0_.get(\"y\")", "__y") } float __z; {TFloat.Ins.Apply(this, "_json0_.get(\"z\")", "__z") } float __w; {TFloat.Ins.Apply(this, "_json0_.get(\"w\")", "__w") } {x} = new {type.Apply(JavaDefineTypeName.Ins)}(__x, __y, __z, __w); }}";
return $"{{ com.google.gson.JsonObject _json{depth}_ = {json}.getAsJsonObject(); float __x; {TFloat.Ins.Apply(this, $"_json{depth}_.get(\"x\")", "__x", depth)} float __y; {TFloat.Ins.Apply(this, $"_json{depth}_.get(\"y\")", "__y", depth)} float __z; {TFloat.Ins.Apply(this, $"_json{depth}_.get(\"z\")", "__z", depth)} float __w; {TFloat.Ins.Apply(this, $"_json{depth}_.get(\"w\")", "__w", depth)} {x} = new {type.Apply(JavaDefineTypeName.Ins)}(__x, __y, __z, __w); }}";
}
public string Accept(TDateTime type, string json, string x)
public string Accept(TDateTime type, string json, string x, int depth)
{
return $"{x} = {json}.getAsInt();";
return $"{x} = {json}.getAsLong();";
}
}
}

View File

@ -127,7 +127,7 @@ namespace Luban.Job.Cfg.TypeVisitors
public string Accept(TDateTime type, string bufName, string fieldName)
{
return $"{fieldName} = {bufName}.readInt();";
return $"{fieldName} = {bufName}.readLong();";
}
}
}

View File

@ -125,7 +125,7 @@ namespace Luban.Job.Cfg.TypeVisitors
public string Accept(TDateTime type, string jsonVarName)
{
return AsType(jsonVarName, "i32");
return AsType(jsonVarName, "i64");
}
}
}

View File

@ -122,7 +122,7 @@ namespace Luban.Job.Cfg.TypeVisitors
public string Accept(TDateTime type)
{
return "int32";
return "int64";
}
}
}

View File

@ -4,6 +4,7 @@ using Luban.Job.Cfg.Cache;
using Luban.Job.Cfg.DataCreators;
using Luban.Job.Cfg.Datas;
using Luban.Job.Cfg.DataSources;
using Luban.Job.Cfg.DataSources.Excel;
using Luban.Job.Cfg.Defs;
using Luban.Job.Common.Types;
using Luban.Job.Common.Utils;
@ -95,7 +96,7 @@ namespace Luban.Job.Cfg.Utils
file.OriginFile,
file.SheetName,
await agent.GetFromCacheOrReadAllBytesAsync(file.ActualFile, file.MD5),
IsMultiRecordFile(file.ActualFile, file.SheetName));
IsMultiRecordFile(file.ActualFile, file.SheetName), table.Options);
FileRecordCacheManager.Ins.AddCacheLoadedRecords(table, file.MD5, file.SheetName, res);
@ -188,10 +189,10 @@ namespace Luban.Job.Cfg.Utils
await Task.WhenAll(genDataTasks.ToArray());
}
public static List<Record> LoadCfgRecords(TBean recordType, string originFile, string sheetName, byte[] content, bool multiRecord)
public static List<Record> LoadCfgRecords(TBean recordType, string originFile, string sheetName, byte[] content, bool multiRecord, Dictionary<string, string> options)
{
// (md5,sheet,multiRecord,exportTestData) -> (valuetype, List<(datas)>)
var dataSource = DataSourceFactory.Create(originFile, sheetName, new MemoryStream(content));
var dataSource = DataSourceFactory.Create(originFile, sheetName, options, new MemoryStream(content));
try
{
if (multiRecord)

View File

@ -1,4 +1,5 @@
using Luban.Common.Utils;
using Luban.Job.Cfg.DataCreators;
using Luban.Job.Cfg.Datas;
using Luban.Job.Cfg.DataSources;
using Luban.Job.Cfg.Defs;
@ -29,7 +30,7 @@ namespace Luban.Job.Cfg.Utils
var values = SplitVectorString(x);
if (values.Length != 2)
{
throw new Exception($"'{x}' 不是合法vector2类型数据");
throw new Exception($"'{x}' 不是合法vector2类型数据");
}
return new DVector2(new System.Numerics.Vector2(float.Parse(values[0]), float.Parse(values[1])));
@ -40,7 +41,7 @@ namespace Luban.Job.Cfg.Utils
var values = SplitVectorString(x);
if (values.Length != 3)
{
throw new Exception($"'{x}' 不是合法vector3类型数据");
throw new Exception($"'{x}' 不是合法vector3类型数据");
}
return new DVector3(new System.Numerics.Vector3(float.Parse(values[0]), float.Parse(values[1]), float.Parse(values[2])));
@ -51,7 +52,7 @@ namespace Luban.Job.Cfg.Utils
var values = SplitVectorString(x);
if (values.Length != 4)
{
throw new Exception($"'{x}' 不是合法vector4类型数据");
throw new Exception($"'{x}' 不是合法vector4类型数据");
}
return new DVector4(new System.Numerics.Vector4(float.Parse(values[0]), float.Parse(values[1]), float.Parse(values[2]), float.Parse(values[3])));
}
@ -111,6 +112,10 @@ namespace Luban.Job.Cfg.Utils
{
return s.Replace("\\", "\\\\").Replace("\"", "\\\"");
}
public static string UnEscapeString(string s)
{
return s.Replace("\\\"", "\"").Replace("\\\"", "\"");
}
public static string EscapeLuaStringWithQuote(string s)
{
@ -163,11 +168,11 @@ namespace Luban.Job.Cfg.Utils
{
if (key == null || text == null)
{
throw new Exception("text的key或text属性不能为null");
throw new Exception("text的key或text属性不能为null");
}
if (key == "" && text != "")
{
throw new Exception($"text key为空, 但text:'{text}'不为空");
throw new Exception($"text key为空, 但text:'{text}'不为空");
}
}
@ -243,20 +248,37 @@ namespace Luban.Job.Cfg.Utils
{
if (string.IsNullOrEmpty(subType))
{
throw new Exception($"module:'{bean.Namespace}' 多态数据type不能为空");
throw new Exception($"module:'{bean.Namespace}' 多态数据type不能为空");
}
DefBean defType = bean.GetHierarchyChildren().Cast<DefBean>().Where(c => c.Alias == subType || c.Name == subType || c.FullName == subType).FirstOrDefault();
if (defType == null)
{
throw new Exception($"module:'{bean.Namespace}' type:'{subType}' 不是合法类型");
throw new Exception($"module:'{bean.Namespace}' type:'{subType}' 不是合法类型");
}
if (defType.IsAbstractType)
{
throw new Exception($"module:'{bean.Namespace}' type:'{subType}' 是抽象类. 不能创建实例");
throw new Exception($"module:'{bean.Namespace}' type:'{subType}' 是抽象类. 不能创建实例");
}
return defType;
}
public static bool ParseExcelBool(string s)
{
s = s.ToLower().Trim();
switch (s)
{
case "true":
case "1":
case "y":
case "yes": return true;
case "false":
case "0":
case "n":
case "no": return false;
default: throw new InvalidExcelDataException($"{s} 不是 bool 类型的值 (true|1|y|yes 或 false|0|n|no)");
}
}
//public static string Data2String(DType data)
//{
// var s = new StringBuilder();

View File

@ -5,6 +5,7 @@ using Luban.Job.Common.Types;
using Luban.Job.Common.TypeVisitors;
using System;
using System.Linq;
using JavaDeserializeVisitor = Luban.Job.Cfg.TypeVisitors.JavaDeserializeVisitor;
namespace Luban.Job.Cfg.Utils
{
@ -85,16 +86,16 @@ namespace Luban.Job.Cfg.Utils
{
case TArray:
{
return $@"{{ int __n = {name}.Length; {table.FullName} __table = ({table.FullName})_tables[""{ tableName}""]; this.{refVarName} = new {table.ValueTType.Apply(CsDefineTypeName.Ins)}[__n]; for(int i = 0 ; i < __n ; i++) {{ this.{refVarName}[i] = __table.GetOrDefault({name}[i]); }} }}";
return $@"{{ int __n = {name}.Length; {table.FullName} __table = ({table.FullName})_tables[""{tableName}""]; this.{refVarName} = new {table.ValueTType.Apply(CsDefineTypeName.Ins)}[__n]; for(int i = 0 ; i < __n ; i++) {{ this.{refVarName}[i] = __table.GetOrDefault({name}[i]); }} }}";
}
case TList:
case TSet:
{
return $@"{{ {table.FullName} __table = ({table.FullName})_tables[""{ tableName}""]; this.{refVarName} = new {field.ElementRefType.Apply(CsDefineTypeName.Ins)}(); foreach(var __e in {name}) {{ this.{refVarName}.Add(__table.GetOrDefault(__e)); }} }}";
return $@"{{ {table.FullName} __table = ({table.FullName})_tables[""{tableName}""]; this.{refVarName} = new {field.ElementRefType.Apply(CsDefineTypeName.Ins)}(); foreach(var __e in {name}) {{ this.{refVarName}.Add(__table.GetOrDefault(__e)); }} }}";
}
case TMap:
{
return $@"{{ {table.FullName} __table = ({table.FullName})_tables[""{ tableName}""]; this.{refVarName} = new {field.ElementRefType.Apply(CsDefineTypeName.Ins)}(); foreach(var __e in {name}) {{ this.{refVarName}.Add(__e.Key, __table.GetOrDefault(__e.Value)); }} }}";
return $@"{{ {table.FullName} __table = ({table.FullName})_tables[""{tableName}""]; this.{refVarName} = new {field.ElementRefType.Apply(CsDefineTypeName.Ins)}(); foreach(var __e in {name}) {{ this.{refVarName}.Add(__e.Key, __table.GetOrDefault(__e.Value)); }} }}";
}
default: throw new NotSupportedException($"type:'{field.CType.TypeName}' not support ref");
}
@ -110,11 +111,11 @@ namespace Luban.Job.Cfg.Utils
{
if (type.IsNullable)
{
return $"{{ if ({jsonName}.has(\"{jsonFieldName}\") && !{jsonName}.get(\"{jsonFieldName}\").isJsonNull()) {{ {type.Apply(TypeVisitors.JavaJsonDeserialize.Ins, $"{jsonName}.get(\"{jsonFieldName}\")", fieldName)} }} else {{ {fieldName} = null; }} }}";
return $"{{ if ({jsonName}.has(\"{jsonFieldName}\") && !{jsonName}.get(\"{jsonFieldName}\").isJsonNull()) {{ {type.Apply(TypeVisitors.JavaJsonDeserialize.Ins, $"{jsonName}.get(\"{jsonFieldName}\")", fieldName, 0)} }} else {{ {fieldName} = null; }} }}";
}
else
{
return type.Apply(TypeVisitors.JavaJsonDeserialize.Ins, $"{jsonName}.get(\"{jsonFieldName}\")", fieldName);
return type.Apply(TypeVisitors.JavaJsonDeserialize.Ins, $"{jsonName}.get(\"{jsonFieldName}\")", fieldName, 0);
}
}
@ -127,15 +128,41 @@ namespace Luban.Job.Cfg.Utils
{
var refVarName = field.RefVarName;
var name = field.ConventionName;
var tableName = field.Ref.FirstTable;
var table = field.Assembly.GetCfgTable(field.Ref.FirstTable);
if (field.IsNullable)
if (field.Ref != null)
{
return $"this.{refVarName} = this.{name} != null ? (({table.FullNameWithTopModule})_tables.get(\"{tableName}\")).get({name}) : null;";
var tableName = field.Ref.FirstTable;
var table = field.Assembly.GetCfgTable(tableName);
if (field.IsNullable)
{
return $"this.{refVarName} = this.{name} != null ? (({table.FullNameWithTopModule})_tables.get(\"{tableName}\")).get({name}) : null;";
}
else
{
return $"this.{refVarName} = (({table.FullNameWithTopModule})_tables.get(\"{tableName}\")).get({name});";
}
}
else
{
return $"this.{refVarName} = (({table.FullNameWithTopModule})_tables.get(\"{tableName}\")).get({name});";
var tableName = field.ElementRef.FirstTable;
var table = field.Assembly.GetCfgTable(tableName);
switch (field.CType)
{
case TArray:
{
return $@"{{ int __n = {name}.length; {table.FullNameWithTopModule} __table = ({table.FullNameWithTopModule})_tables.get(""{tableName}""); this.{refVarName} = new {table.ValueTType.Apply(JavaDefineTypeName.Ins)}[__n]; for(int i = 0 ; i < __n ; i++) {{ this.{refVarName}[i] = __table.get({name}[i]); }} }}";
}
case TList:
case TSet:
{
return $@"{{ {table.FullNameWithTopModule} __table = ({table.FullNameWithTopModule})_tables.get(""{tableName}""); this.{refVarName} = new {field.ElementRefType.Apply(JavaDefineTypeName.Ins)}(); for({field.CType.ElementType.TypeName} __e : {name}) {{ this.{refVarName}.add(__table.get(__e)); }} }}";
}
case TMap map:
{
return $@"{{ {table.FullNameWithTopModule} __table = ({table.FullNameWithTopModule})_tables.get(""{tableName}""); this.{refVarName} = new {field.ElementRefType.Apply(JavaDefineTypeName.Ins)}(); for(java.util.Map.Entry<{map.KeyType.Apply(JavaBoxDefineTypeName.Ins)}, {map.ValueType.Apply(JavaBoxDefineTypeName.Ins)}> __e : {name}.entrySet()) {{ {map.KeyType.TypeName} __eKey = __e.getKey(); {map.ValueType.TypeName} __eValue = __e.getValue(); this.{refVarName}.put(__eKey, __table.get(__eValue)); }} }}";
}
default: throw new NotSupportedException($"type:'{field.CType.TypeName}' not support ref");
}
}
}

View File

@ -194,23 +194,23 @@ namespace Luban.Job.Cfg.Validators
//}
if (ct.IsOneValueTable)
{
if (string.IsNullOrEmpty(fieldName))
if (string.IsNullOrEmpty(indexName))
{
throw new Exception($"结构:{hostTypeName} 字段:{fieldName} ref:{actualTable} 是singleton表索引字段不能为空");
}
else
{
if (!ct.ValueTType.Bean.TryGetField(fieldName, out var indexField, out _))
if (!ct.ValueTType.Bean.TryGetField(indexName, out var indexField, out _))
{
throw new Exception($"结构:{hostTypeName} 字段:{fieldName} ref:{actualTable} value_type:{ct.ValueTType.Bean.FullName} 未包含索引字段:{fieldName}");
throw new Exception($"结构:{hostTypeName} 字段:{fieldName} ref:{actualTable} value_type:{ct.ValueTType.Bean.FullName} 未包含索引字段:{indexName}");
}
if (!(indexField.CType is TMap tmap))
{
throw new Exception($"结构:{hostTypeName} 字段:{fieldName} ref:{actualTable} value_type:{ct.ValueTType.Bean.FullName} 索引字段:{fieldName} type:{indexField.CType.TypeName} 不是map类型");
throw new Exception($"结构:{hostTypeName} 字段:{fieldName} ref:{actualTable} value_type:{ct.ValueTType.Bean.FullName} 索引字段:{indexName} type:{indexField.CType.TypeName} 不是map类型");
}
if (tmap.KeyType.TypeName != Type.TypeName)
{
throw new Exception($"结构:{hostTypeName} 字段:{fieldName} 类型:'{Type.TypeName}' 与被引用的表:{actualTable} value_type:{ct.ValueTType.Bean.FullName} 索引字段:{fieldName} key_type:{tmap.KeyType.TypeName} 不一致");
throw new Exception($"结构:{hostTypeName} 字段:{fieldName} 类型:'{Type.TypeName}' 与被引用的表:{actualTable} value_type:{ct.ValueTType.Bean.FullName} 索引字段:{indexName} key_type:{tmap.KeyType.TypeName} 不一致");
}
}
}

View File

@ -0,0 +1,121 @@
using Luban.Job.Cfg.Datas;
using Luban.Job.Cfg.Utils;
using Luban.Job.Common.Defs;
using Luban.Job.Common.Types;
using System;
using System.Text.RegularExpressions;
namespace Luban.Job.Cfg.Validators
{
[Validator("regex")]
class RegexValidator : IValidator
{
public TType Type { get; }
private Regex _regex;
public string Source => ValidatorContext.CurrentVisitor.CurrentValidateRecord.Source;
public RegexValidator(TType type, string strRegex)
{
Type = type;
_regex = new Regex(DataUtil.UnEscapeString(strRegex), RegexOptions.Compiled);
}
public void Compile(DefFieldBase def)
{
switch (Type)
{
case TBean:
throw new Exception($"regex检查器不支持检查Bean类型{Type.TypeName}");
}
}
public void Validate(ValidatorContext ctx, TType type, DType data)
{
Validate(ctx, type.IsNullable, data);
}
private void Validate(ValidatorContext ctx, bool nullable, DType data)
{
var assembly = ctx.Assembly;
void Check(string str)
{
var match = _regex.Match(str);
if (!match.Success)
{
assembly.Agent.Error($"记录 {ValidatorContext.CurrentRecordPath}:{data} (来自文件:{Source}) 不符合正则表达式:'{_regex}'");
}
}
if (nullable && data == null)
{
return;
}
switch (data)
{
case DList dList:
{
foreach (var d in dList.Datas)
{
Validate(ctx, nullable, d);
}
break;
}
case DArray dArray:
{
foreach (var d in dArray.Datas)
{
Validate(ctx, nullable, d);
}
break;
}
case DSet dSet:
{
foreach (var d in dSet.Datas)
{
Validate(ctx, nullable, d);
}
break;
}
case DMap dMap:
{
foreach (var d in dMap.Datas.Values)
{
Validate(ctx, nullable, d);
}
break;
}
case DVector2 dVector2:
{
Check(dVector2.Value.X.ToString());
Check(dVector2.Value.Y.ToString());
break;
}
case DVector3 dVector3:
{
Check(dVector3.Value.X.ToString());
Check(dVector3.Value.Y.ToString());
Check(dVector3.Value.Z.ToString());
break;
}
case DVector4 dVector4:
{
Check(dVector4.Value.X.ToString());
Check(dVector4.Value.Y.ToString());
Check(dVector4.Value.Z.ToString());
Check(dVector4.Value.W.ToString());
break;
}
case DText dText:
{
Check(dText.RawValue);
break;
}
default:
Check(data.ToString());
break;
}
}
}
}

View File

@ -1,4 +1,5 @@
using Luban.Job.Cfg.Datas;
using Luban.Job.Cfg.DataSources.Excel;
using Luban.Job.Cfg.Defs;
using Luban.Job.Cfg.RawDefs;
using Luban.Job.Cfg.Utils;
@ -65,7 +66,7 @@ namespace Luban.Job.Cfg.l10n
public void LoadFromFile(string fileName, byte[] bytes)
{
var records = DataLoaderUtil.LoadCfgRecords(_textRowType, fileName, null, bytes, true);
var records = DataLoaderUtil.LoadCfgRecords(_textRowType, fileName, null, bytes, true, null);
foreach (var r in records)
{
//s_logger.Info("== read text:{}", r.Data);

View File

@ -34,6 +34,8 @@ namespace Luban.Job.Common.Defs
public Dictionary<string, DefTypeBase> Types { get; } = new Dictionary<string, DefTypeBase>();
public List<DefTypeBase> TypeList { get; } = new List<DefTypeBase>();
private readonly Dictionary<string, DefTypeBase> _notCaseSenseTypes = new();
private readonly HashSet<string> _namespaces = new();
@ -194,6 +196,7 @@ namespace Luban.Job.Common.Defs
}
Types.Add(fullName, type);
TypeList.Add(type);
}
public DefTypeBase GetDefType(string fullName)
@ -273,7 +276,7 @@ namespace Luban.Job.Common.Defs
return Types.Values.Where(v => typeof(T).IsAssignableFrom(v.GetType())).Select(v => (T)v).ToList();
}
public TType CreateType(string module, string type)
public TType CreateType(string module, string type, bool containerElementType)
{
type = DefUtil.TrimBracePairs(type);
int sepIndex = DefUtil.IndexOfBaseTypeEnd(type);
@ -286,11 +289,11 @@ namespace Luban.Job.Common.Defs
}
else
{
return CreateNotContainerType(module, type);
return CreateNotContainerType(module, type, containerElementType);
}
}
protected TType CreateNotContainerType(string module, string rawType)
protected TType CreateNotContainerType(string module, string rawType, bool containerElementType)
{
bool nullable;
// 去掉 rawType 两侧的匹配的 ()
@ -303,6 +306,10 @@ namespace Luban.Job.Common.Defs
{
throw new Exception($"not support nullable type:'{module}.{type}'");
}
if (containerElementType)
{
throw new Exception($"container element type can't be nullable type:'{module}.{type}'");
}
nullable = true;
type = type.Substring(0, type.Length - 1);
}
@ -363,8 +370,8 @@ namespace Luban.Job.Common.Defs
throw new ArgumentException($"invalid map element type:'{keyValueType}'");
}
return TMap.Create(false, tags,
CreateNotContainerType(module, keyValueType.Substring(0, typeSepIndex).Trim()),
CreateType(module, keyValueType.Substring(typeSepIndex + 1).Trim()), isTreeMap);
CreateNotContainerType(module, keyValueType.Substring(0, typeSepIndex).Trim(), true),
CreateType(module, keyValueType.Substring(typeSepIndex + 1).Trim(), true), isTreeMap);
}
protected TType CreateContainerType(string module, string containerType, Dictionary<string, string> containerTags, string elementType)
@ -373,12 +380,12 @@ namespace Luban.Job.Common.Defs
{
case "array":
{
return TArray.Create(false, containerTags, CreateType(module, elementType));
return TArray.Create(false, containerTags, CreateType(module, elementType, true));
}
case "list": return TList.Create(false, containerTags, CreateType(module, elementType), true);
case "list": return TList.Create(false, containerTags, CreateType(module, elementType, true), true);
case "set":
{
TType type = CreateType(module, elementType);
TType type = CreateType(module, elementType, true);
if (type.IsCollection)
{
throw new Exception("set的元素不支持容器类型");

View File

@ -154,9 +154,9 @@ namespace Luban.Job.Common.Defs
fields.AddRange(Fields);
}
public override void PreCompile()
private void SetUpParentRecursively()
{
if (!string.IsNullOrEmpty(Parent))
if (ParentDefType == null && !string.IsNullOrEmpty(Parent))
{
if ((ParentDefType = (DefBeanBase)AssemblyBase.GetDefType(Namespace, Parent)) == null)
{
@ -167,8 +167,13 @@ namespace Luban.Job.Common.Defs
ParentDefType.Children = new List<DefBeanBase>();
}
ParentDefType.Children.Add(this);
ParentDefType.SetUpParentRecursively();
}
}
public override void PreCompile()
{
SetUpParentRecursively();
CollectHierarchyFields(HierarchyFields);
}

View File

@ -117,7 +117,7 @@ namespace Luban.Job.Common.Defs
try
{
CType = AssemblyBase.CreateType(HostType.Namespace, Type);
CType = AssemblyBase.CreateType(HostType.Namespace, Type, false);
}
catch (Exception e)
{

View File

@ -318,5 +318,28 @@ namespace Luban.Job.Common.Defs
{
return type is TDateTime && !type.IsNullable && ExternalTypeUtil.GetExternalTypeMappfer("datetime") == null;
}
public static string CsStartNameSpaceGrace(string np)
{
if (string.IsNullOrEmpty(np))
{
return string.Empty;
}
else
{
return $"namespace {np}\n{{";
}
}
public static string CsEndNameSpaceGrace(string np)
{
if (string.IsNullOrEmpty(np))
{
return string.Empty;
}
else
{
return "}";
}
}
}
}

View File

@ -152,7 +152,7 @@ namespace Luban.Job.Common.TypeVisitors
{
return mapper.TargetTypeName;
}
return "int";
return "long";
}
}
}

View File

@ -152,7 +152,7 @@ namespace Luban.Job.Common.TypeVisitors
public string Accept(TDateTime type, string bufName, string fieldName, int depth)
{
string src = $"{bufName}.ReadInt()";
string src = $"{bufName}.ReadLong()";
return $"{fieldName} = {ExternalTypeUtil.CsCloneToExternal("datetime", src)};";
}
}

View File

@ -122,7 +122,7 @@ namespace Luban.Job.Common.TypeVisitors
public string Accept(TDateTime type, string bufName, string fieldName)
{
return $"{bufName}.WriteInt({fieldName});";
return $"{bufName}.WriteLong({fieldName});";
}
}
}

View File

@ -98,7 +98,7 @@ namespace Luban.Job.Common.TypeVisitors
public string Accept(TDateTime type)
{
return "int32";
return "int64";
}
public string Accept(TBean type)

View File

@ -94,7 +94,7 @@ namespace Luban.Job.Common.TypeVisitors
public string Accept(TDateTime type, string fieldName, string bufName, string err)
{
return $"{{ if {fieldName}, {err} = {bufName}.ReadInt(); {err} != nil {{ {err} = errors.New(\"{fieldName} error\"); return }} }}";
return $"{{ if {fieldName}, {err} = {bufName}.ReadLong(); {err} != nil {{ {err} = errors.New(\"{fieldName} error\"); return }} }}";
}
public string Accept(TBean type, string fieldName, string bufName, string err)

View File

@ -94,7 +94,7 @@ namespace Luban.Job.Common.TypeVisitors
public string Accept(TDateTime type, string fieldName, string bufName)
{
return $"{bufName}.WriteInt({fieldName})";
return $"{bufName}.WriteLong({fieldName})";
}
public string Accept(TBean type, string fieldName, string bufName)

View File

@ -119,7 +119,7 @@ namespace Luban.Job.Common.TypeVisitors
public string Accept(TDateTime type)
{
return "int32";
return "int64";
}
}
}

View File

@ -58,7 +58,7 @@ namespace Luban.Job.Common.TypeVisitors
public override string Accept(TDateTime type)
{
return "Integer";
return "Long";
}
public override string Accept(TEnum type)

View File

@ -119,7 +119,7 @@ namespace Luban.Job.Common.TypeVisitors
public virtual string Accept(TDateTime type)
{
return type.IsNullable ? "Integer" : "int";
return type.IsNullable ? "Long" : "long";
}
}
}

View File

@ -0,0 +1,22 @@
using Luban.Job.Common.Types;
using Luban.Job.Common.TypeVisitors;
namespace Luban.Job.Common.TypeVisitors
{
public class JavaDeserializeVisitor : DecoratorFuncVisitor<string, string, string>
{
public static JavaDeserializeVisitor Ins { get; } = new JavaDeserializeVisitor();
public override string DoAccept(TType type, string bufName, string fieldName)
{
if (type.IsNullable)
{
return $"if({bufName}.readBool()){{ {type.Apply(JavaUnderingDeserializeVisitor.Ins, bufName, fieldName, 0)} }} else {{ {fieldName} = null; }}";
}
else
{
return type.Apply(JavaUnderingDeserializeVisitor.Ins, bufName, fieldName, 0);
}
}
}
}

View File

@ -0,0 +1,21 @@
using Luban.Job.Common.Types;
namespace Luban.Job.Common.TypeVisitors
{
public class JavaSerializeVisitor : DecoratorFuncVisitor<string, string, string>
{
public static JavaSerializeVisitor Ins { get; } = new JavaSerializeVisitor();
public override string DoAccept(TType type, string bufName, string fieldName)
{
if (type.IsNullable)
{
return $"{{ if ({fieldName} != null){{ {bufName}.writeBool(true); {type.Apply(JavaUnderingSerializeVisitor.Ins, bufName, fieldName)} }} else {{ {bufName}.writeBool(false); }} }}";
}
else
{
return type.Apply(JavaUnderingSerializeVisitor.Ins, bufName, fieldName);
}
}
}
}

View File

@ -0,0 +1,155 @@
using Luban.Job.Common.Types;
using Luban.Job.Common.TypeVisitors;
namespace Luban.Job.Common.TypeVisitors
{
class JavaUnderingDeserializeVisitor : ITypeFuncVisitor<string, string, int, string>
{
public static JavaUnderingDeserializeVisitor Ins { get; } = new JavaUnderingDeserializeVisitor();
public string Accept(TBool type, string bufName, string fieldName, int depth)
{
return $"{fieldName} = {bufName}.readBool();";
}
public string Accept(TByte type, string bufName, string fieldName, int depth)
{
return $"{fieldName} = {bufName}.readByte();";
}
public string Accept(TShort type, string bufName, string fieldName, int depth)
{
return $"{fieldName} = {bufName}.readShort();";
}
public string Accept(TFshort type, string bufName, string fieldName, int depth)
{
return $"{fieldName} = {bufName}.readFshort();";
}
public string Accept(TInt type, string bufName, string fieldName, int depth)
{
return $"{fieldName} = {bufName}.readInt();";
}
public string Accept(TFint type, string bufName, string fieldName, int depth)
{
return $"{fieldName} = {bufName}.readFint();";
}
public string Accept(TLong type, string bufName, string fieldName, int depth)
{
return $"{fieldName} = {bufName}.readLong();";
}
public string Accept(TFlong type, string bufName, string fieldName, int depth)
{
return $"{fieldName} = {bufName}.readFlong();";
}
public string Accept(TFloat type, string bufName, string fieldName, int depth)
{
return $"{fieldName} = {bufName}.readFloat();";
}
public string Accept(TDouble type, string bufName, string fieldName, int depth)
{
return $"{fieldName} = {bufName}.readDouble();";
}
public string Accept(TEnum type, string bufName, string fieldName, int depth)
{
return $"{fieldName} = {bufName}.readInt();";
}
public string Accept(TString type, string bufName, string fieldName, int depth)
{
return $"{fieldName} = {bufName}.readString();";
}
public string Accept(TBytes type, string bufName, string fieldName, int depth)
{
return $"{fieldName} = {bufName}.readBytes();";
}
public string Accept(TText type, string bufName, string fieldName, int depth)
{
return $"{bufName}.readString(); {fieldName} = {bufName}.readString();";
}
public string Accept(TBean type, string bufName, string fieldName, int depth)
{
return $"{fieldName} = {type.Bean.FullNameWithTopModule}.deserialize{type.Bean.Name}({bufName});";
}
public string Accept(TArray type, string bufName, string fieldName, int depth)
{
string __n = $"__n{depth}";
string __e = $"__e{depth}";
string __v = $"__v{depth}";
string __i = $"__i{depth}";
string typeStr = $"{type.ElementType.Apply(CsDefineTypeName.Ins)}[{__n}]";
if (type.Dimension > 1)
{
if (type.FinalElementType == null)
{
throw new System.Exception("多维数组没有元素类型");
}
typeStr = $"{type.FinalElementType.Apply(CsUnderingDefineTypeName.Ins)}[{__n}]";
for (int i = 0; i < type.Dimension - 1; i++)
{
typeStr += "[]";
}
}
return $"{{int {__n} = Math.min({bufName}.readSize(), {bufName}.size());{fieldName} = new {type.ElementType.Apply(JavaDefineTypeName.Ins)}[{__n}];for(int {__i} = 0 ; {__i} < {__n} ; {__i}++) {{ {type.ElementType.Apply(JavaDefineTypeName.Ins)} {__e};{type.ElementType.Apply(this, bufName, __e, depth + 1)} {fieldName}[{__i}] = {__e};}}}}";
}
public string Accept(TList type, string bufName, string fieldName, int depth)
{
string __n = $"__n{depth}";
string __e = $"__e{depth}";
string __v = $"__v{depth}";
string __i = $"__i{depth}";
return $"{{int {__n} = Math.min({bufName}.readSize(), {bufName}.size());{fieldName} = new {type.Apply(JavaDefineTypeName.Ins)}({__n});for(int {__i} = 0 ; {__i} < {__n} ; {__i}++) {{ {type.ElementType.Apply(JavaBoxDefineTypeName.Ins)} {__e}; {type.ElementType.Apply(this, bufName, __e, depth + 1)} {fieldName}.add({__e});}}}}";
}
public string Accept(TSet type, string bufName, string fieldName, int depth)
{
string __n = $"__n{depth}";
string __e = $"__e{depth}";
string __v = $"__v{depth}";
string __i = $"__i{depth}";
return $"{{int {__n} = Math.min({bufName}.readSize(), {bufName}.size());{fieldName} = new {type.Apply(JavaDefineTypeName.Ins)}({__n} * 3 / 2);for(int {__i} = 0 ; {__i} < {__n} ; {__i}++) {{ {type.ElementType.Apply(JavaBoxDefineTypeName.Ins)} {__e}; {type.ElementType.Apply(this, bufName, __e, depth + 1)} {fieldName}.add({__e});}}}}";
}
public string Accept(TMap type, string bufName, string fieldName, int depth)
{
string __n = $"__n{depth}";
string __k = $"__k{depth}";
string __v = $"__v{depth}";
string __i = $"__i{depth}";
return $"{{int {__n} = Math.min({bufName}.readSize(), {bufName}.size());{fieldName} = new {type.Apply(JavaDefineTypeName.Ins)}({__n} * 3 / 2);for(int {__i} = 0 ; {__i} < {__n} ; {__i}++) {{ {type.KeyType.Apply(JavaBoxDefineTypeName.Ins)} {__k}; {type.KeyType.Apply(this, bufName, __k, depth + 1)} {type.ValueType.Apply(JavaBoxDefineTypeName.Ins)} {__v}; {type.ValueType.Apply(this, bufName, __v, depth + 1)} {fieldName}.put({__k}, {__v});}}}}";
}
public string Accept(TVector2 type, string bufName, string fieldName, int depth)
{
return $"{fieldName} = {bufName}.readVector2();";
}
public string Accept(TVector3 type, string bufName, string fieldName, int depth)
{
return $"{fieldName} = {bufName}.readVector3();";
}
public string Accept(TVector4 type, string bufName, string fieldName, int depth)
{
return $"{fieldName} = {bufName}.readVector4();";
}
public string Accept(TDateTime type, string bufName, string fieldName, int depth)
{
return $"{fieldName} = {bufName}.readLong();";
}
}
}

View File

@ -0,0 +1,128 @@
using Luban.Job.Common.Defs;
using Luban.Job.Common.Types;
namespace Luban.Job.Common.TypeVisitors
{
class JavaUnderingSerializeVisitor : ITypeFuncVisitor<string, string, string>
{
public static JavaUnderingSerializeVisitor Ins { get; } = new JavaUnderingSerializeVisitor();
public string Accept(TBool type, string bufName, string fieldName)
{
return $"{bufName}.writeBool({fieldName});";
}
public string Accept(TByte type, string bufName, string fieldName)
{
return $"{bufName}.writeByte({fieldName});";
}
public string Accept(TShort type, string bufName, string fieldName)
{
return $"{bufName}.writeShort({fieldName});";
}
public string Accept(TFshort type, string bufName, string fieldName)
{
return $"{bufName}.writeFshort({fieldName});";
}
public string Accept(TInt type, string bufName, string fieldName)
{
return $"{bufName}.writeInt({fieldName});";
}
public string Accept(TFint type, string bufName, string fieldName)
{
return $"{bufName}.writeFint({fieldName});";
}
public string Accept(TLong type, string bufName, string fieldName)
{
return $"{bufName}.writeLong({fieldName});";
}
public string Accept(TFlong type, string bufName, string fieldName)
{
return $"{bufName}.writeFlong({fieldName});";
}
public string Accept(TFloat type, string bufName, string fieldName)
{
return $"{bufName}.writeFloat({fieldName});";
}
public string Accept(TDouble type, string bufName, string fieldName)
{
return $"{bufName}.writeDouble({fieldName});";
}
public string Accept(TEnum type, string bufName, string fieldName)
{
return $"{bufName}.writeInt((int){fieldName});";
}
public string Accept(TString type, string bufName, string fieldName)
{
return $"{bufName}.writeString({fieldName});";
}
public string Accept(TBytes type, string bufName, string fieldName)
{
return $"{bufName}.writeBytes({fieldName});";
}
public string Accept(TText type, string bufName, string fieldName)
{
return $"{bufName}.writeString({fieldName});";
}
public string Accept(TBean type, string bufName, string fieldName)
{
return $"{type.Bean.FullNameWithTopModule}.serialize{type.Bean.Name}({bufName}, {fieldName});";
}
public string Accept(TArray type, string bufName, string fieldName)
{
return $"{{ {bufName}.writeSize({fieldName}.length); for({type.ElementType.Apply(JavaBoxDefineTypeName.Ins)} _e : {fieldName}) {{ {type.ElementType.Apply(this, bufName, "_e")} }} }}";
}
public string Accept(TList type, string bufName, string fieldName)
{
return $"{{ {bufName}.writeSize({fieldName}.size()); for({type.ElementType.Apply(JavaBoxDefineTypeName.Ins)} _e : {fieldName}) {{ {type.ElementType.Apply(this, bufName, "_e")} }} }}";
}
public string Accept(TSet type, string bufName, string fieldName)
{
return $"{{ {bufName}.writeSize({fieldName}.size()); for({type.ElementType.Apply(JavaBoxDefineTypeName.Ins)} _e : {fieldName}) {{ {type.ElementType.Apply(this, bufName, "_e")} }} }}";
}
public string Accept(TMap type, string bufName, string fieldName)
{
return $"{{ {bufName}.writeSize({fieldName}.size()); for(java.util.Map.Entry<{type.KeyType.Apply(JavaBoxDefineTypeName.Ins)},{type.ValueType.Apply(JavaBoxDefineTypeName.Ins)}> _e : {fieldName}.entrySet()) {{ {type.KeyType.Apply(this, bufName, "_e.getKey()")} {type.ValueType.Apply(this, bufName, "_e.getValue()")} }} }}";
}
public static string VectorName => "Vector";
public string Accept(TVector2 type, string bufName, string fieldName)
{
return $"{bufName}.write{VectorName}2({fieldName});";
}
public string Accept(TVector3 type, string bufName, string fieldName)
{
return $"{bufName}.write{VectorName}3({fieldName});";
}
public string Accept(TVector4 type, string bufName, string fieldName)
{
return $"{bufName}.write{VectorName}4({fieldName});";
}
public string Accept(TDateTime type, string bufName, string fieldName)
{
return $"{bufName}.writeLong({fieldName});";
}
}
}

View File

@ -8,57 +8,57 @@ namespace Luban.Job.Common.TypeVisitors
public string Accept(TBool type)
{
return "bool";
return "boolean";
}
public string Accept(TByte type)
{
return "byte";
return "integer";
}
public string Accept(TShort type)
{
return "short";
return "integer";
}
public string Accept(TFshort type)
{
return "short";
return "integer";
}
public string Accept(TInt type)
{
return "int";
return "integer";
}
public string Accept(TFint type)
{
return "int";
return "integer";
}
public string Accept(TLong type)
{
return "long";
return "integer";
}
public string Accept(TFlong type)
{
return "long";
return "integer";
}
public string Accept(TFloat type)
{
return "float";
return "number";
}
public string Accept(TDouble type)
{
return "double";
return "number";
}
public string Accept(TEnum type)
{
return type.DefineEnum.FullName;
return "integer";
}
public string Accept(TString type)
@ -103,22 +103,22 @@ namespace Luban.Job.Common.TypeVisitors
public string Accept(TVector2 type)
{
return "vector2";
return "{x:number,y:number}";
}
public string Accept(TVector3 type)
{
return "vector3";
return "{x:number,y:number,z:number}";
}
public string Accept(TVector4 type)
{
return "vector4";
return "{x:number,y:number,z:number,w:number}";
}
public string Accept(TDateTime type)
{
return "int";
return "integer";
}
}
}

View File

@ -118,7 +118,7 @@ namespace Luban.Job.Common.TypeVisitors
public string Accept(TDateTime type)
{
return "readInt";
return "readLong";
}
}
}

View File

@ -118,7 +118,7 @@ namespace Luban.Job.Common.TypeVisitors
public string Accept(TDateTime type)
{
return "writeInt";
return "writeLong";
}
}
}

View File

@ -98,7 +98,7 @@ namespace Luban.Job.Common.TypeVisitors
public string Accept(TDateTime type)
{
return "int32";
return "int64";
}
public string Accept(TBean type)

View File

@ -118,7 +118,7 @@ namespace Luban.Job.Common.TypeVisitors
public string Accept(TDateTime type)
{
return "i32";
return "i64";
}
}
}

View File

@ -118,7 +118,7 @@ namespace Luban.Job.Common.TypeVisitors
public string Accept(TDateTime type)
{
return "INT";
return "LONG";
}
}
}

View File

@ -166,7 +166,7 @@ namespace Luban.Job.Common.TypeVisitors
public string Accept(TDateTime type, string bufVarName, string fieldName)
{
return $"{fieldName} = {bufVarName}.ReadInt()";
return $"{fieldName} = {bufVarName}.ReadLongAsNumber()";
}
}
}

View File

@ -93,7 +93,7 @@ namespace Luban.Job.Common.TypeVisitors
public string Accept(TDateTime type, string bufVarName, string fieldName)
{
return $"{bufVarName}.WriteInt({fieldName})";
return $"{bufVarName}.WriteLong({fieldName})";
}
public virtual string Accept(TBean type, string bufVarName, string fieldName)

View File

@ -26,6 +26,10 @@ namespace Luban.Job.Common.Types
Dimension = (ElementType as TArray).Dimension + 1;
FinalElementType = (ElementType as TArray).FinalElementType;
}
else
{
FinalElementType = elementType;
}
}
public override bool TryParseFrom(string s)

View File

@ -0,0 +1,21 @@
using Scriban;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Luban.Job.Common.Utils
{
public static class TemplateUtil
{
public static TemplateContext CreateDefaultTemplateContext()
{
return new TemplateContext()
{
LoopLimit = 0,
NewLine = "\n",
};
}
}
}

View File

@ -48,12 +48,12 @@ namespace Luban.Job.Db.Defs
AddType(new DefTable(p));
}
foreach (var type in Types.Values)
foreach (var type in TypeList)
{
type.AssemblyBase = this;
}
foreach (var type in Types.Values)
foreach (var type in TypeList)
{
try
{
@ -67,7 +67,7 @@ namespace Luban.Job.Db.Defs
throw;
}
}
foreach (var type in Types.Values)
foreach (var type in TypeList)
{
try
{
@ -82,7 +82,7 @@ namespace Luban.Job.Db.Defs
throw;
}
}
foreach (var type in Types.Values)
foreach (var type in TypeList)
{
try
{
@ -101,7 +101,7 @@ namespace Luban.Job.Db.Defs
public List<DefTypeBase> GetExportTypes()
{
return Types.Values.ToList();
return TypeList;
}
}
}

View File

@ -40,7 +40,7 @@ namespace Luban.Job.Db.Defs
ass.AddDbTable(this);
if ((KeyTType = ass.CreateType(Namespace, KeyType)) == null)
if ((KeyTType = ass.CreateType(Namespace, KeyType, false)) == null)
{
throw new Exception($"table:{FullName} key:{KeyType} 类型不合法");
}
@ -50,7 +50,7 @@ namespace Luban.Job.Db.Defs
throw new Exception($"table:{FullName} key:{KeyTType} 不支持。只支持long与string类型");
}
if ((ValueTType = (TBean)ass.CreateType(Namespace, ValueType)) == null)
if ((ValueTType = (TBean)ass.CreateType(Namespace, ValueType, false)) == null)
{
throw new Exception($"table:{FullName} value:{ValueType} 类型不合法");
}

View File

@ -23,7 +23,7 @@ namespace Luban.Job.Db.Generate
public string Render(DefEnum e)
{
var template = StringTemplateManager.Ins.GetTemplate("common/cs/enum");
var result = template.Render(e);
var result = template.RenderCode(e);
return result;
}

View File

@ -23,7 +23,7 @@ namespace Luban.Job.Db.Generate
public string Render(DefEnum e)
{
var template = StringTemplateManager.Ins.GetTemplate("common/cs/enum");
var result = template.Render(e);
var result = template.RenderCode(e);
return result;
}

View File

@ -99,7 +99,7 @@ namespace Luban.Job.Db
case "cs":
{
ass.CurrentLanguage = ELanguage.CS;
var render = new AsyncCsRender();
var render = new SyncCsRender();
foreach (var c in ass.Types.Values)
{
tasks.Add(Task.Run(() =>

View File

@ -1,3 +1,4 @@
using Luban.Job.Common.Utils;
using Luban.Job.Db.Defs;
using Scriban;
using System.Collections.Generic;
@ -8,7 +9,7 @@ namespace Luban.Job.Db
{
public static string RenderCode(this Template template, object model, Dictionary<string, object> extraModels = null)
{
var ctx = new TemplateContext();
var ctx = TemplateUtil.CreateDefaultTemplateContext();
var env = new TTypeTemplateExtends
{
["x"] = model

View File

@ -151,7 +151,7 @@ namespace Luban.Job.Db.TypeVisitors
public string Accept(TDateTime type, string bufName, string fieldName)
{
return $"{fieldName} = {bufName}.ReadInt();";
return $"{fieldName} = {bufName}.ReadLong();";
}
}
}

View File

@ -150,9 +150,9 @@ namespace Luban.Job.Db.TypeVisitors
return $"{bufName}.WriteVector4({fieldName});";
}
public string Accept(TDateTime type, string x, string y)
public string Accept(TDateTime type, string bufName, string fieldName)
{
throw new NotImplementedException();
return $"{bufName}.WriteLong({fieldName});";
}
}
}

View File

@ -25,7 +25,7 @@ namespace Luban.Job.Db.TypeVisitors
public override string Accept(TMap type)
{
return $"BrightDB.Transaction.Collections.{(type.ValueType is TBean ? " PMap2" : "PMap1")}<{type.KeyType.Apply(this)}, {type.ValueType.Apply(this)}>";
return $"BrightDB.Transaction.Collections.{(type.ValueType is TBean ? "PMap2" : "PMap1")}<{type.KeyType.Apply(this)}, {type.ValueType.Apply(this)}>";
}
}
}

View File

@ -128,7 +128,7 @@ namespace Luban.Job.Db.TypeVisitors
public string Accept(TDateTime type)
{
return "Bright.Common.SerializationUtil.DeserializeInt";
return "Bright.Common.SerializationUtil.DeserializeLong";
}
}
}

View File

@ -131,7 +131,7 @@ namespace Luban.Job.Db.TypeVisitors
public string Accept(TDateTime type, string fieldName)
{
throw new NotSupportedException();
return $"{fieldName} = default;";
}
}
}

View File

@ -128,7 +128,7 @@ namespace Luban.Job.Db.TypeVisitors
public string Accept(TDateTime type)
{
return "Bright.Common.SerializationUtil.SerializeInt";
return "Bright.Common.SerializationUtil.SerializeLong";
}
}
}

View File

@ -128,7 +128,7 @@ namespace Luban.Job.Db.TypeVisitors
public string Accept(TDateTime type)
{
return "SerializeFactory.deserializeInt";
return "SerializeFactory.deserializeLong";
}
}
}

View File

@ -130,9 +130,10 @@ namespace Luban.Job.Db.TypeVisitors
return $"{fieldName} = new Vector4()";
}
public string Accept(TDateTime type, string x, string y)
public string Accept(TDateTime type, string fieldName, string logType
)
{
throw new NotSupportedException();
return $"{fieldName} = 0";
}
}
}

View File

@ -128,7 +128,7 @@ namespace Luban.Job.Db.TypeVisitors
public string Accept(TDateTime type)
{
return "SerializeFactory.serializeInt";
return "SerializeFactory.serializeLong";
}
}
}

View File

@ -8,12 +8,6 @@
<EnforceCodeStyleInBuild>True</EnforceCodeStyleInBuild>
</PropertyGroup>
<ItemGroup>
<Compile Remove="Source\TypeVisitors\**" />
<EmbeddedResource Remove="Source\TypeVisitors\**" />
<None Remove="Source\TypeVisitors\**" />
</ItemGroup>
<ItemGroup>
<None Include="..\..\README.md">
<Pack>True</Pack>

View File

@ -50,12 +50,12 @@ namespace Luban.Job.Proto.Defs
AddType(new DefRpc(r));
}
foreach (var type in Types.Values)
foreach (var type in TypeList)
{
type.AssemblyBase = this;
}
foreach (var type in Types.Values)
foreach (var type in TypeList)
{
try
{
@ -69,7 +69,7 @@ namespace Luban.Job.Proto.Defs
throw;
}
}
foreach (var type in Types.Values)
foreach (var type in TypeList)
{
try
{
@ -84,7 +84,7 @@ namespace Luban.Job.Proto.Defs
throw;
}
}
foreach (var type in Types.Values)
foreach (var type in TypeList)
{
try
{
@ -104,7 +104,7 @@ namespace Luban.Job.Proto.Defs
public List<DefTypeBase> GetExportTypes()
{
return Types.Values.ToList();
return TypeList;
}
}
}

View File

@ -36,12 +36,12 @@ namespace Luban.Job.Proto.Defs
}
pass.AddProto(this);
if ((TArgType = Assembly.CreateType(Namespace, ArgType)) == null)
if ((TArgType = Assembly.CreateType(Namespace, ArgType, false)) == null)
{
throw new Exception($"rpc name:'{FullName}' arg:{ArgType} is invalid");
}
if ((TResType = Assembly.CreateType(Namespace, ResType)) == null)
if ((TResType = Assembly.CreateType(Namespace, ResType, false)) == null)
{
throw new Exception($"rpc name:'{FullName}' res:{ResType} is invalid");
}

View File

@ -1,8 +1,20 @@
using Luban.Job.Common.Defs;
using Luban.Job.Common.Types;
using Luban.Job.Common.TypeVisitors;
namespace Luban.Job.Proto.Defs
{
class TTypeTemplateExtends : TTypeTemplateCommonExtends
{
public static string JavaSerialize(string bufName, string fieldName, TType type)
{
return type.Apply(JavaSerializeVisitor.Ins, bufName, fieldName);
}
public static string JavaDeserialize(string bufName, string fieldName, TType type)
{
return type.Apply(JavaDeserializeVisitor.Ins, bufName, fieldName);
}
}
}

View File

@ -5,7 +5,7 @@ namespace Luban.Job.Proto
{
public class GenArgs : GenArgsBase
{
[Option('g', "gen_type", Required = true, HelpText = "cs,lua,java,cpp,typescript")]
[Option('g', "gen_type", Required = true, HelpText = "cs,lua,java,typescript")]
public string GenType { get; set; }
[Option('s', "service", Required = true, HelpText = "service")]

View File

@ -0,0 +1,14 @@
using Luban.Job.Common.Defs;
using Luban.Job.Common.Generate;
using Luban.Job.Common.Utils;
using Luban.Job.Proto.Defs;
using System;
using System.Collections.Generic;
namespace Luban.Job.Proto.Generate
{
[Render("java")]
class JavaRender : TemplateRenderBase
{
}
}

View File

@ -1,3 +1,4 @@
using Luban.Job.Common.Utils;
using Luban.Job.Proto.Defs;
using Scriban;
using System.Collections.Generic;
@ -8,7 +9,7 @@ namespace Luban.Job.Proto
{
public static string RenderCode(this Template template, object model, Dictionary<string, object> extraModels = null)
{
var ctx = new TemplateContext();
var ctx = TemplateUtil.CreateDefaultTemplateContext();
var env = new TTypeTemplateExtends
{
["x"] = model

View File

@ -331,6 +331,18 @@
<None Update="Templates\db\typescript\tables.tpl">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Templates\proto\java\bean.tpl">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Templates\proto\java\proto.tpl">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Templates\proto\java\rpc.tpl">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Templates\proto\java\stub.tpl">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Templates\proto\cs\bean.tpl">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>

View File

@ -5,8 +5,8 @@
items = x.items
~}}
namespace {{namespace_with_top_module}}
{
{{cs_start_name_space_grace x.namespace_with_top_module}}
{{~if comment != '' ~}}
/// <summary>
/// {{comment | html.escape}}
@ -26,4 +26,5 @@ namespace {{namespace_with_top_module}}
{{item.name}} = {{item.value}},
{{~end~}}
}
}
{{cs_end_name_space_grace x.namespace_with_top_module}}

View File

@ -14,38 +14,6 @@
*/
{{~end~}}
{{~if x.is_list_table ~}}
{{~if x.is_union_index~}}
typedef struct t_{{name}}_MultiKey
{
{{~for idx in x.index_list~}}
{{cpp_define_type idx.type}} {{idx.index_field.name}};
{{~end~}}
bool operator==(const t_{{name}}_MultiKey& stOther) const
{
bool bEqual = true;
{{~for idx in x.index_list~}}
bEqual = bEqual && (stOther.{{idx.index_field.name}} == {{idx.index_field.name}});
{{~end~}}
return bEqual;
}
}t_{{name}}_MultiKey;
typedef struct t_{{name}}_MultiKey_HashFunc
{
std::size_t operator()(const t_{{name}}_MultiKey& stMK) const
{
std::size_t sHash = 0;
{{~for idx in x.index_list~}}
sHash ^= std::hash<{{cpp_define_type idx.type}}>()(stMK.{{idx.index_field.name}});
{{~end~}}
return sHash;
}
}t_{{name}}_MultiKey_HashFunc;
{{~end~}}
{{~end~}}
class {{name}}
{
{{~if x.is_map_table ~}}
@ -95,7 +63,7 @@ class {{name}}
private:
::bright::Vector<{{cpp_define_type value_type}}> _dataList;
{{~if x.is_union_index~}}
::bright::HashMapMultiKey<t_{{name}}_MultiKey, {{cpp_define_type value_type}}, t_{{name}}_MultiKey_HashFunc> _dataMap;
{{~else if !x.index_list.empty?~}}
{{~for idx in x.index_list~}}
::bright::HashMap<{{cpp_define_type idx.type}}, {{cpp_define_type value_type}}> _dataMap_{{idx.index_field.name}};
@ -114,11 +82,7 @@ class {{name}}
{{cpp_deserialize '_buf' '_v' value_type}}
_dataList.push_back(_v);
{{~if x.is_union_index~}}
t_{{name}}_MultiKey stKey;
{{~for idx in x.index_list~}}
stKey.{{idx.index_field.name}} = _v->{{idx.index_field.name}};
{{~end~}}
_dataMap[stKey] = _v;
{{~else if !x.index_list.empty?~}}
{{~for idx in x.index_list~}}
_dataMap_{{idx.index_field.name}}[_v->{{idx.index_field.name}}] = _v;
@ -132,20 +96,7 @@ class {{name}}
const ::bright::Vector<{{cpp_define_type value_type}}>& getDataList() const { return _dataList; }
{{~if x.is_union_index~}}
::bright::HashMapMultiKey<t_{{name}}_MultiKey, {{cpp_define_type value_type}}, t_{{name}}_MultiKey_HashFunc>& getDataMap()
{
return _dataMap;
}
{{value_type.bean.cpp_full_name}}* getRaw(t_{{name}}_MultiKey& key)
{
auto it = _dataMap.find(key);
return it != _dataMap.end() ? it->second.get() : nullptr;
}
{{cpp_define_type value_type}} get(t_{{name}}_MultiKey& key)
{
auto it = _dataMap.find(key);
return it != _dataMap.end() ? it->second : nullptr;
}
{{~else if !x.index_list.empty?~}}
{{~for idx in x.index_list~}}
::bright::HashMap<{{cpp_define_type idx.type}}, {{cpp_define_type value_type}}>& getDataMapBy{{idx.index_field.name}}()

View File

@ -1,4 +1,4 @@
using Bright.Serialization;
using Bright.Serialization;
using System.Collections.Generic;
{{
name = x.name
@ -7,10 +7,7 @@ using System.Collections.Generic;
hierarchy_export_fields = x.hierarchy_export_fields
}}
namespace {{x.namespace_with_top_module}}
{
{{cs_start_name_space_grace x.namespace_with_top_module}}
{{~if x.comment != '' ~}}
/// <summary>
/// {{x.escape_comment}}
@ -115,4 +112,4 @@ public {{x.cs_class_modifier}} partial class {{name}} : {{if parent_def_type}} {
partial void PostResolve();
}
}
{{cs_end_name_space_grace x.namespace_with_top_module}}

View File

@ -1,8 +1,8 @@
using Bright.Serialization;
using System.Collections.Generic;
namespace {{x.namespace_with_top_module}}
{
{{cs_start_name_space_grace x.namespace_with_top_module}}
{{
name = x.name
key_type = x.key_ttype
@ -170,4 +170,4 @@ public partial class {{name}}
partial void PostResolve();
}
}
{{cs_end_name_space_grace x.namespace_with_top_module}}

View File

@ -6,9 +6,8 @@ using Bright.Serialization;
tables = x.tables
}}
namespace {{namespace}}
{
{{cs_start_name_space_grace x.namespace}}
public partial class {{name}}
{
{{~for table in tables ~}}
@ -46,4 +45,4 @@ public partial class {{name}}
partial void PostResolve();
}
}
{{cs_end_name_space_grace x.namespace}}

View File

@ -10,8 +10,7 @@ using System.Text.Json;
hierarchy_export_fields = x.hierarchy_export_fields
}}
namespace {{x.namespace_with_top_module}}
{
{{cs_start_name_space_grace x.namespace_with_top_module}}
{{~if x.comment != '' ~}}
/// <summary>
@ -124,4 +123,4 @@ public {{x.cs_class_modifier}} partial class {{name}} : {{if parent_def_type}} {
partial void PostInit();
partial void PostResolve();
}
}
{{cs_end_name_space_grace x.namespace_with_top_module}}

View File

@ -10,8 +10,8 @@ using System.Text.Json;
value_type = x.value_ttype
}}
namespace {{x.namespace_with_top_module}}
{
{{cs_start_name_space_grace x.namespace_with_top_module}}
{{~if x.comment != '' ~}}
/// <summary>
@ -170,4 +170,4 @@ public sealed partial class {{name}}
partial void PostResolve();
}
}
{{cs_end_name_space_grace x.namespace_with_top_module}}

View File

@ -5,8 +5,8 @@ using System.Text.Json;
namespace = x.namespace
tables = x.tables
}}
namespace {{namespace}}
{
{{cs_start_name_space_grace x.namespace}}
public sealed partial class {{name}}
{
@ -45,4 +45,4 @@ public sealed partial class {{name}}
partial void PostResolve();
}
}
{{cs_end_name_space_grace x.namespace}}

View File

@ -10,8 +10,7 @@ using SimpleJSON;
fields = x.fields
}}
namespace {{x.namespace_with_editor_top_module}}
{
{{cs_start_name_space_grace x.namespace_with_editor_top_module}}
{{~if x.comment != '' ~}}
/// <summary>
@ -107,4 +106,5 @@ public {{x.cs_class_modifier}} partial class {{name}} : {{if parent_def_type}} {
{{~end~}}
}
}
{{cs_end_name_space_grace x.namespace_with_editor_top_module}}

Some files were not shown because too many files have changed in this diff Show More