Compare commits

...

72 Commits

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
walon 2dd826bafb [change] 修复一些 README.md 错误 2022-08-05 00:44:13 +08:00
walon 412a400471 [fix] 修复ref引用了被过滤的记录却未报告引用错误的bug 2022-07-28 17:02:44 +08:00
walon c738b4dcad
Merge pull request #18 from kteong1012/main
[new] 添加cpp的联合多主键解析
2022-07-26 22:44:10 +08:00
Carson Lin a39339bd51 feat:添加cpp的联合多主键解析
Signed-off-by: Carson Lin <396098651@qq.com>
2022-07-26 21:02:26 +08:00
walon 699b5a167a [new] range和size都支持固定大小或者区间段 xxx=value 或 xxx=[a,b] 的写法 2022-07-19 12:58:02 +08:00
walon 665b9a4cea [new] 新增bidx,即binary格式的索引文件输出。方便优化按需加载 2022-07-19 11:42:49 +08:00
walon abcacebcaa
Merge pull request #14 from kteong1012/main
[new] 支持嵌套容器,支持多维数组和list,array,map的相互嵌套
2022-07-18 19:16:58 +08:00
walon c0706a84f1 [new] 新增Bson导出格式支持 2022-07-18 18:03:53 +08:00
Carson Lin bfc13bc35f fix: 修复TrimBracePairs方法可能会出现的问题 2022-07-13 12:50:13 +08:00
Carson Lin 02f3ebd979 feat: 弃用Type的CollectionLevel,改为在visitor添加depth参数以实现嵌套容器的解析 2022-07-13 11:41:32 +08:00
Carson Lin 79940dcf09 feat: 在TType添加CollectionLevel,用于连续嵌套容器时生成解析代码 2022-07-13 10:28:09 +08:00
carson 6620cca6e1 feat:支持多维数组嵌套 2022-07-13 03:47:23 +08:00
Carson Lin d6ad1e64c4 fea:支持嵌套容器,暂时只支持list 2022-07-12 22:30:14 +08:00
walon c0ddce497c [fix] config enum的java代码生成普通的int,而不是java枚举类。修复flags=1的枚举项反序列化的异常。 2022-06-25 18:29:59 +08:00
walon 4255ae25bf [update] 更新文档,补充godot相关支持的描述,补充c++语言使用示例 2022-06-15 21:01:53 +08:00
Dongua ba1a552d3e [change]gdscript 支持多独立主键 2022-06-11 16:40:15 +08:00
Dongua 60faab741e 【特性】支持gdscript语言 2022-06-09 12:37:45 +08:00
walon f756ab2aa2 [fix] 修复当有两个input文件内容完全相同的情况下,TableDataInfo::BuildIndexs 抛出key重复异常的bug 2022-06-01 17:02:29 +08:00
Dongua 9b086767a1 [change]修改reademe 格式问题,修改链接指向新地址 2022-05-31 15:25:14 +08:00
walon c39b6a623d [new] 添加友情链接 2022-05-29 19:18:39 +08:00
140 changed files with 2839 additions and 762 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. [See details](https://focus-creative-games.github.io/lubandoc/feature.html#%E6%94%AF%E6%8C%81%E4%B8%BB%E6%B5%81% E7%9A%84%E6%B8%B8%E6%88%8F%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80)
- **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/lubandoc/feature.html) 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/lubandoc/start_up.html)
- [Document](https://focus-creative-games.github.io/lubandoc), 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/lubandoc/changelog.html)
- 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
@ -91,7 +90,6 @@ For a complete example, please refer to [Excel Format Introduction](https://focu
<td>desc3</td>
<td colspan="3">desc4</td>
</tr>
<tr align="center">
<td/>
<td>1</td>
@ -100,7 +98,6 @@ For a complete example, please refer to [Excel Format Introduction](https://focu
<td>xx|yy</td>
<td>xxx</td><td>zzz</td><td></td>
</tr>
<tr align="center">
<td/>
<td>2</td>
@ -109,7 +106,6 @@ For a complete example, please refer to [Excel Format Introduction](https://focu
<td>aaaa|bbbb|cccc</td>
<td>aaa</td><td>bbb</td><td>ccc</td>
</tr>
<tr align="center">
<td/>
<td>3</td>
@ -118,7 +114,6 @@ For a complete example, please refer to [Excel Format Introduction](https://focu
<td>aaaa|bbbb|cccc</td>
<td>aaa</td><td>bbb</td><td>ccc</td>
</tr>
</table>
### substructure
@ -126,13 +121,11 @@ For a complete example, please refer to [Excel Format Introduction](https://focu
Reward is a substructure containing the three fields of "int item_id; int count; string desc;".
<table border="1">
<tr align="center"><td>##var</td><td>id</td><td colspan="3">reward</td><td colspan="3">reward2</ td><td>reward3</td></tr>
<tr align="center"><td>##type</td><td>int</td><td colspan="3">Reward</td><td colspan="3">Reward</ td><td>Reward#sep=,</td></tr>
<tr align="center"><td>##var</td><td></td><td>item_id</td><td>count</td><td>desc</td><td></td><td></td><td></td><td/></tr>
<tr align="center"><td/><td>1</td><td>1001</td><td>10</td><td>item 1</td><td>1002< /td><td>11</td><td>item 2</td><td>1002,1,item 3</td></tr>
<tr align="center"><td/><td>2</td><td>2001</td><td>10</td><td>item 2</td><td>2002< /td><td>20</td><td>item 4</td><td>2003,2,item 5</td></tr>
</table>
### Structure List 1
@ -162,7 +155,6 @@ Reward is a substructure containing the three fields of "int item_id; int count;
<td>1001</td><td>1</td><td>desc1</td><td>1002</td><td>2</td><td>desc2</td>
<td>1001,1,desc1</td><td>1002,2,desc2</td><td>1003,3,desc3</td>
</tr>
<tr align="center">
<td/>
<td>2</td>
@ -175,7 +167,6 @@ Reward is a substructure containing the three fields of "int item_id; int count;
### Structure List 2
<table border="1">
<tr align="center">
<td>##var</td>
<td>id</td>
@ -188,7 +179,6 @@ Reward is a substructure containing the three fields of "int item_id; int count;
<td>string</td>
<td colspan="9">list,Reward</td>
</tr>
<tr align="center">
<td>##var</td>
<td></td>
@ -197,7 +187,6 @@ Reward is a substructure containing the three fields of "int item_id; int count;
<td colspan="3">1</td>
<td colspan="3">2</td>
</tr>
<tr align="center"><td/><td>1</td><td>task1</td><td>1001</td><td>10</td><td>desc1</ td><td>1002</td><td>12</td><td>desc2</td><td>1003</td><td>13</td><td>desc3</td> </tr>
<tr align="center"><td/><td>2</td><td>task1</td><td>1003</td><td>30</td><td>desc3</ td><td>1004</td><td>40</td><td>desc4</td><td/><td/><td/></tr>
<tr align="center"><td/><td>3</td><td>task1</td><td>1005</td><td>50</td><td>desc5</ td><td/><td/><td/><td/><td/><td/></tr>
@ -206,7 +195,6 @@ Reward is a substructure containing the three fields of "int item_id; int count;
### Structure List 3
<table border="1">
<tr align="center">
<td>##var</td>
<td>id</td>
@ -219,7 +207,6 @@ Reward is a substructure containing the three fields of "int item_id; int count;
<td>string</td>
<td colspan="9">list,Reward</td>
</tr>
<tr align="center">
<td>##var</td>
<td></td>
@ -236,7 +223,6 @@ Reward is a substructure containing the three fields of "int item_id; int count;
<td>item_id</td><td>num</td><td>desc</td>
<td>item_id</td><td>num</td><td>desc</td>
</tr>
<tr align="center"><td/><td>1</td><td>task1</td><td>1001</td><td>10</td><td>desc1</ td><td>1002</td><td>12</td><td>desc2</td><td>1003</td><td>13</td><td>desc3</td> </tr>
<tr align="center"><td/><td>2</td><td>task1</td><td>1003</td><td>30</td><td>desc3</ td><td>1004</td><td>40</td><td>desc4</td><td/><td/><td/></tr>
<tr align="center"><td/><td>3</td><td>task1</td><td>1005</td><td>50</td><td>desc5</ td><td/><td/><td/><td/><td/><td/></tr>
@ -245,7 +231,6 @@ Reward is a substructure containing the three fields of "int item_id; int count;
### Multi-row table
<table border="1">
<tr align="center">
<td>##var</td>
<td>id</td>
@ -280,7 +265,6 @@ Reward is a substructure containing the three fields of "int item_id; int count;
<td>desc5</td>
<td>desc6</td>
</tr>
<tr align="center">
<td/>
<td>1</td>
@ -301,25 +285,21 @@ Reward is a substructure containing the three fields of "int item_id; int count;
<tr align="center">
<td/><td/><td/><td>2</td><td>stage2</td><td>stage desc2</td><td>1,2,3</td><td>1002</td><td>1</td>
</tr>
</table>
### Multi-level subheadings of type 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>apple</td><td>apple</td><td>aaa</td><td>aaa</td></tr>
<tr align="center"><td/><td>2</td><td>banana</td><td>banana</td><td>bbb</td><td>bbb</td></tr>
</table>
### Type inheritance (suitable for skills, buff related configuration)
<table border="1">
<tr align="center"><td>##var</td><td>id</td><td colspan="4">shape</td><td colspan="4">shape2</ td></tr>
<tr align="center"><td>##type</td><td>int</td><td colspan="4">Shape</td><td colspan="4">Shape</ td></tr>
<tr align="center"><td>##var</td><td></td><td>$type</td><td>radius</td><td>width</td><td>height</td><td></td><td></td><td></td><td></td></tr>
@ -327,7 +307,6 @@ Reward is a substructure containing the three fields of "int item_id; int count;
<tr align="center"><td/><td>2</td><td>Rectangle</td><td></td><td>10</td><td>20</td ><td>Rectangle</td><td>10</td><td>20</td><td></td></tr>
<tr align="center"><td/><td>3</td><td>Circle</td><td>10</td><td/><td/><td>Triangle</td><td>15</td><td>15</td><td>15</td></tr>
<tr align="center"><td/><td>4</td><td>Circle</td><td>10</td><td/><td/><td>Rectangle</td><td>30</td><td>20</td><td></td></tr>
</table>
### Multiple primary key table (joint index)
@ -391,7 +370,7 @@ Some configurations only have one copy globally, such as the opening level of th
## json, lua, xml, yaml format quick overview
Take the behavior tree as an example to show how to configure the behavior tree configuration in json format. For formats such as xml, lua, yaml, etc., please refer to [detailed documentation](https://focus-creative-games.github.io/lubandoc).
Take the behavior tree as an example to show how to configure the behavior tree configuration in json format. For formats such as xml, lua, yaml, etc., please refer to [detailed documentation](https://focus-creative-games.github.io/luban/data_source/).
````json

View File

@ -31,31 +31,28 @@ luban统一了游戏配置开发工作流极大提升了策划和程序的工
- 强大的数据解析和转换能力 {excel(csv,xls,xlsx)、json、bson、xml、yaml、lua、unity ScriptableObject} => {binary、json、bson、xml、lua、yaml、erlang、 custom format}
- 增强的excel格式可以简洁地配置出像简单列表、子结构、结构列表以及任意复杂的深层次的嵌套结构。
- 完备的类型系统,**支持OOP类型继承**搭配excel、json、lua、xml等格式数据**灵活优雅**表达行为树、技能、剧情、副本之类复杂GamePlay数据
- 支持生成c#、java、go、c++、lua、python、javascript、typescript、erlang、rust代码
- 支持生成c#、java、go、c++、lua、python、javascript、typescript、erlang、rust、gdscript 代码
- 支持生成 protobuf(schema + binary + json)、flatbuffers(schema + json)、msgpack(binary)
- 强大的数据校验能力。ref引用检查、path资源路径、range范围检查等等
- 完善的本地化支持。静态文本值本地化、动态文本值本地化、时间本地化、main-patch多地区版本
- 强大灵活的自定义能力,支持自定义代码模板和数据模板
- **通用型生成和缓存工具**。也可以用于生成协议、数据库之类的代码,甚至可以用作对象缓存服务
- **良好支持主流引擎、全平台、主流热更新方案、主流前后端框架**。支持unity、unreal、cocos2x、微信小游戏等主流引擎。工具自身跨平台能在Win,Linux,Mac平台良好工作。[详见](https://focus-creative-games.github.io/lubandoc/feature.html#%E6%94%AF%E6%8C%81%E4%B8%BB%E6%B5%81%E7%9A%84%E6%B8%B8%E6%88%8F%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80)
- **良好支持主流引擎、全平台、主流热更新方案、主流前后端框架**。支持Unity、Unreal、Cocos2x、Godot、微信小游戏等主流引擎。工具自身跨平台能在Win,Linux,Mac平台良好工作。
完整特性请参见 [feature](https://focus-creative-games.github.io/lubandoc/feature.html)
完整特性请参见 [feature](https://focus-creative-games.github.io/luban-doc/#/manual/traits)
## 文档
- [快速上手](https://focus-creative-games.github.io/lubandoc/start_up.html)
- [Document](https://focus-creative-games.github.io/lubandoc) ,比较完善,有使用疑问,请先查看此文档。
- [官方文档](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/lubandoc/changelog.html)
- [版本变更记录](https://focus-creative-games.github.io/luban-doc/#/changelog)
- 支持与联系
- QQ群: 692890842 Luban开发交流群。有使用方面的疑问请及时加QQ群询问随时有人帮助解决。
- 邮箱: taojingjian#gmail.com
- 邮箱: luban@code-philosophy.com
## excel格式速览
完整示例请详见 [excel格式介绍](https://focus-creative-games.github.io/lubandoc/excel.html)
### 普通表
|##var| id | x1 | x5 | x6 | s1 | s2 | v3 | t1 |
@ -93,7 +90,6 @@ luban统一了游戏配置开发工作流极大提升了策划和程序的工
<td>desc3</td>
<td colspan="3">desc4</td>
</tr>
<tr align="center">
<td/>
<td>1</td>
@ -102,7 +98,6 @@ luban统一了游戏配置开发工作流极大提升了策划和程序的工
<td>xx|yy</td>
<td>xxx</td><td>zzz</td><td></td>
</tr>
<tr align="center">
<td/>
<td>2</td>
@ -111,7 +106,6 @@ luban统一了游戏配置开发工作流极大提升了策划和程序的工
<td>aaaa|bbbb|cccc</td>
<td>aaa</td><td>bbb</td><td>ccc</td>
</tr>
<tr align="center">
<td/>
<td>3</td>
@ -120,7 +114,6 @@ luban统一了游戏配置开发工作流极大提升了策划和程序的工
<td>aaaa|bbbb|cccc</td>
<td>aaa</td><td>bbb</td><td>ccc</td>
</tr>
</table>
### 子结构
@ -128,7 +121,6 @@ luban统一了游戏配置开发工作流极大提升了策划和程序的工
Reward为包含 "int item_id; int count; string desc; " 这三个字段的子结构。
<table border="1">
<tr align="center"><td>##var</td><td>id</td><td colspan="3">reward</td><td colspan="3">reward2</td><td>reward3</td></tr>
<tr align="center"><td>##type</td><td>int</td><td colspan="3">Reward</td><td colspan="3">Reward</td><td>Reward#sep=,</td></tr>
<tr align="center"><td>##var</td><td></td><td>item_id</td><td>count</td><td>desc</td><td></td><td></td><td></td><td/></tr>
@ -164,20 +156,17 @@ Reward为包含 "int item_id; int count; string desc; " 这三个字段的子结
<td>1001</td><td>1</td><td>desc1</td><td>1002</td><td>2</td><td>desc2</td>
<td>1001,1,desc1</td><td>1002,2,desc2</td><td>1003,3,desc3</td>
</tr>
<tr align="center">
<td/>
<td>2</td>
<td>1001</td><td>1</td><td>desc1</td><td></td><td></td><td></td>
<td>1001,1,desc1</td><td>1002,2,desc2</td><td></td>
</tr>
</table>
### 结构列表 2
<table border="1">
<tr align="center">
<td>##var</td>
<td>id</td>
@ -190,7 +179,6 @@ Reward为包含 "int item_id; int count; string desc; " 这三个字段的子结
<td>string</td>
<td colspan="9">list,Reward</td>
</tr>
<tr align="center">
<td>##var</td>
<td></td>
@ -199,7 +187,6 @@ Reward为包含 "int item_id; int count; string desc; " 这三个字段的子结
<td colspan="3">1</td>
<td colspan="3">2</td>
</tr>
<tr align="center"><td/><td>1</td><td>task1</td><td>1001</td><td>10</td><td>desc1</td><td>1002</td><td>12</td><td>desc2</td><td>1003</td><td>13</td><td>desc3</td></tr>
<tr align="center"><td/><td>2</td><td>task1</td><td>1003</td><td>30</td><td>desc3</td><td>1004</td><td>40</td><td>desc4</td><td/><td/><td/></tr>
<tr align="center"><td/><td>3</td><td>task1</td><td>1005</td><td>50</td><td>desc5</td><td/><td/><td/><td/><td/><td/></tr>
@ -208,7 +195,6 @@ Reward为包含 "int item_id; int count; string desc; " 这三个字段的子结
### 结构列表 3
<table border="1">
<tr align="center">
<td>##var</td>
<td>id</td>
@ -221,7 +207,6 @@ Reward为包含 "int item_id; int count; string desc; " 这三个字段的子结
<td>string</td>
<td colspan="9">list,Reward</td>
</tr>
<tr align="center">
<td>##var</td>
<td></td>
@ -238,7 +223,6 @@ Reward为包含 "int item_id; int count; string desc; " 这三个字段的子结
<td>item_id</td><td>num</td><td>desc</td>
<td>item_id</td><td>num</td><td>desc</td>
</tr>
<tr align="center"><td/><td>1</td><td>task1</td><td>1001</td><td>10</td><td>desc1</td><td>1002</td><td>12</td><td>desc2</td><td>1003</td><td>13</td><td>desc3</td></tr>
<tr align="center"><td/><td>2</td><td>task1</td><td>1003</td><td>30</td><td>desc3</td><td>1004</td><td>40</td><td>desc4</td><td/><td/><td/></tr>
<tr align="center"><td/><td>3</td><td>task1</td><td>1005</td><td>50</td><td>desc5</td><td/><td/><td/><td/><td/><td/></tr>
@ -247,7 +231,6 @@ Reward为包含 "int item_id; int count; string desc; " 这三个字段的子结
### 多行表
<table border="1">
<tr align="center">
<td>##var</td>
<td>id</td>
@ -282,7 +265,6 @@ Reward为包含 "int item_id; int count; string desc; " 这三个字段的子结
<td>desc5</td>
<td>desc6</td>
</tr>
<tr align="center">
<td/>
<td>1</td>
@ -303,7 +285,6 @@ Reward为包含 "int item_id; int count; string desc; " 这三个字段的子结
<tr align="center">
<td/><td/><td/><td>2</td><td>stage2</td><td>stage desc2</td><td>1,2,3</td><td>1002</td><td>1</td>
</tr>
</table>
### 多级多行表
@ -311,7 +292,6 @@ Reward为包含 "int item_id; int count; string desc; " 这三个字段的子结
多行表的列表字段,每个列表元素还可以是多行。支持任意多级的多行嵌套。另外也允许有多个多行字段,每个字段的行数还可以不同。
<table border="1">
<tr align="center">
<td>##var</td>
<td>id</td>
@ -364,7 +344,6 @@ Reward为包含 "int item_id; int count; string desc; " 这三个字段的子结
<td>item id</td>
<td>count</td>
</tr>
<tr align="center">
<td/>
<td>1</td>
@ -409,25 +388,11 @@ Reward为包含 "int item_id; int count; string desc; " 这三个字段的子结
<tr align="center">
<td/><td/><td/><td></td><td></td><td></td><td>2,2,2</td><td>1002</td><td>2</td><td></td><td></td><td></td><td></td>
</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">
<tr align="center"><td>##var</td><td>id</td><td colspan="4">shape</td><td colspan="4">shape2</td></tr>
<tr align="center"><td>##type</td><td>int</td><td colspan="4">Shape</td><td colspan="4">Shape</td></tr>
<tr align="center"><td>##var</td><td></td><td>$type</td><td>radius</td><td>width</td><td>height</td><td></td><td></td><td></td><td></td></tr>
@ -435,7 +400,6 @@ Reward为包含 "int item_id; int count; string desc; " 这三个字段的子结
<tr align="center"><td/><td>2</td><td>Rectangle</td><td></td><td>10</td><td>20</td><td>矩形</td><td>10</td><td>20</td><td></td></tr>
<tr align="center"><td/><td>3</td><td></td><td>10</td><td/><td/><td>Triangle</td><td>15</td><td>15</td><td>15</td></tr>
<tr align="center"><td/><td>4</td><td>Circle</td><td>10</td><td/><td/><td>Rectangle</td><td>30</td><td>20</td><td></td></tr>
</table>
### 多主键表(联合索引)
@ -499,8 +463,7 @@ Reward为包含 "int item_id; int count; string desc; " 这三个字段的子结
## json、lua、xml、yaml 格式速览
以行为树为例展示json格式下如何配置行为树配置。xml、lua、yaml等等格式请参见 [详细文档](https://focus-creative-games.github.io/lubandoc)。
以行为树为例展示json格式下如何配置行为树配置。xml、lua、yaml等等格式请参见 [详细文档](https://focus-creative-games.github.io/luban-doc/#/manual/datasource)。
```json
{
@ -554,13 +517,13 @@ Reward为包含 "int item_id; int count; string desc; " 这三个字段的子结
## 代码使用预览
这儿只简略展示c#、typescript、go语言在开发中的用法更多语言以及更详细的使用范例和代码见[示例项目](https://github.com/focus-creative-games/luban_examples)。
这儿只简略展示c#、typescript、go、c++ 语言在开发中的用法,更多语言以及更详细的使用范例和代码见[示例项目](https://github.com/focus-creative-games/luban_examples)。
- C# 使用示例
```C#
// 一行代码可以加载所有配置。 cfg.Tables 包含所有表的一个实例字段。
var tables = new cfg.Tables(file => return new ByteBuf(File.ReadAllBytes(gameConfDir + "/" + file + ".bytes")));
var tables = new cfg.Tables(file => return new ByteBuf(File.ReadAllBytes($"{gameConfDir}/{file}.bytes")));
// 访问一个单例表
Console.WriteLine(tables.TbGlobal.Name);
// 访问普通的 key-value 表
@ -592,7 +555,19 @@ if tables , err := cfg.NewTables(loader) ; err != nil {
println(tables.TbGlobal.Name)
// 访问普通的 key-value 表
println(tables.TbItem.Get(12).Name)
```
- c++ 使用示例
```c++
cfg::Tables tables;
if (!tables.load([](ByteBuf& buf, const std::string& s) { buf.clear(); return buf.loadFromFile("../GenerateDatas/bytes/" + s + ".bytes"); }))
{
std::cout << "== load fail == " << std::endl;
return;
}
std::cout << tables.TbGlobal->name << std::endl;
std::cout << tables.TbItem.get(12)->name << std::endl;
```
## 路线图
@ -601,6 +576,11 @@ println(tables.TbItem.Get(12).Name)
- [ ] 新增 unreal 内置编辑器
- [ ] 补充单元测试
## 友情链接
- [Luban Unity插件](https://github.com/LiuOcean/Luban_Unity_GUI) 在Unity里完成生成命令的配置和生成操作
- [LubanTools](https://github.com/MOMOLAXI/LubanTools) Luban的Win GUI命令配置和生成工具
## License
Luban is licensed under the [MIT](LICENSE.TXT) license.

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

@ -121,6 +121,11 @@ namespace Luban.Common.Utils
return module.Replace('.', '_') + name;
}
public static string MakeGDScriptFullName(string module, string name)
{
return UpperCaseFirstChar(module.Replace('.', '_') + name);
}
public static string MakeRustFullName(string module, string name)
{
return MakeGoNamespace(module) + name;

View File

@ -18,6 +18,7 @@
<PackageReference Include="ExcelDataReader" Version="3.6.0" />
<PackageReference Include="MessagePack" Version="2.3.85" />
<PackageReference Include="NeoLua" Version="1.3.14" />
<PackageReference Include="Newtonsoft.Json.Bson" Version="1.0.2" />
<PackageReference Include="Ude.NetStandard" Version="1.2.0" />
<PackageReference Include="YamlDotNet" Version="11.2.1" />
</ItemGroup>

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

@ -0,0 +1,40 @@
using Bright.Serialization;
using Luban.Job.Cfg.Datas;
using Luban.Job.Cfg.DataSources;
using Luban.Job.Cfg.DataVisitors;
using Luban.Job.Cfg.Defs;
using Luban.Job.Cfg.RawDefs;
using System;
using System.Collections.Generic;
namespace Luban.Job.Cfg.DataExporters
{
class BinaryIndexExportor
{
public static BinaryIndexExportor Ins { get; } = new BinaryIndexExportor();
public void WriteList(DefTable table, List<Record> datas, ByteBuf x)
{
x.WriteSize(datas.Count);
var tableDataBuf = new ByteBuf(10 * 1024);
tableDataBuf.WriteSize(datas.Count);
foreach (var d in datas)
{
int offset = tableDataBuf.Size;
d.Data.Apply(BinaryExportor.Ins, tableDataBuf);
string keyStr = "";
foreach (IndexInfo index in table.IndexList)
{
DType key = d.Data.Fields[index.IndexFieldIdIndex];
key.Apply(BinaryExportor.Ins, x);
keyStr += key.ToString() + ",";
}
x.WriteSize(offset);
Console.WriteLine($"table:{table.Name} key:{keyStr} offset:{offset}");
}
}
}
}

View File

@ -0,0 +1,203 @@
using Luban.Job.Cfg.Datas;
using Luban.Job.Cfg.DataSources;
using Luban.Job.Cfg.DataVisitors;
using Luban.Job.Cfg.Defs;
using Luban.Job.Cfg.Utils;
using Newtonsoft.Json.Bson;
using System;
using System.Collections.Generic;
using System.Text.Json;
namespace Luban.Job.Cfg.DataExporters
{
class BsonExportor : IDataActionVisitor<BsonDataWriter>
{
public static BsonExportor Ins { get; } = new BsonExportor();
public void WriteAsArray(List<Record> datas, BsonDataWriter x)
{
x.WriteStartArray();
foreach (var d in datas)
{
d.Data.Apply(this, x);
}
x.WriteEndArray();
}
public void Accept(DBool type, BsonDataWriter x)
{
x.WriteValue(type.Value);
}
public void Accept(DByte type, BsonDataWriter x)
{
x.WriteValue(type.Value);
}
public void Accept(DShort type, BsonDataWriter x)
{
x.WriteValue(type.Value);
}
public void Accept(DFshort type, BsonDataWriter x)
{
x.WriteValue(type.Value);
}
public void Accept(DInt type, BsonDataWriter x)
{
x.WriteValue(type.Value);
}
public void Accept(DFint type, BsonDataWriter x)
{
x.WriteValue(type.Value);
}
public void Accept(DLong type, BsonDataWriter x)
{
x.WriteValue(type.Value);
}
public void Accept(DFlong type, BsonDataWriter x)
{
x.WriteValue(type.Value);
}
public void Accept(DFloat type, BsonDataWriter x)
{
x.WriteValue(type.Value);
}
public void Accept(DDouble type, BsonDataWriter x)
{
x.WriteValue(type.Value);
}
public virtual void Accept(DEnum type, BsonDataWriter x)
{
x.WriteValue(type.Value);
}
public void Accept(DString type, BsonDataWriter x)
{
x.WriteValue(type.Value);
}
public void Accept(DBytes type, BsonDataWriter x)
{
throw new NotImplementedException();
}
public virtual void Accept(DText type, BsonDataWriter x)
{
x.WriteStartObject();
x.WritePropertyName(DText.KEY_NAME);
x.WriteValue(type.Key);
x.WritePropertyName(DText.TEXT_NAME);
x.WriteValue(type.TextOfCurrentAssembly);
x.WriteEndObject();
}
public virtual void Accept(DBean type, BsonDataWriter x)
{
x.WriteStartObject();
if (type.Type.IsAbstractType)
{
x.WritePropertyName(DefBean.JSON_TYPE_NAME_KEY);
x.WriteValue(DataUtil.GetImplTypeName(type));
}
var defFields = type.ImplType.HierarchyFields;
int index = 0;
foreach (var d in type.Fields)
{
var defField = (DefField)defFields[index++];
// 特殊处理 bean 多态类型
// 另外,不生成 xxx:null 这样
if (d == null || !defField.NeedExport)
{
//x.WriteNullValue();
}
else
{
x.WritePropertyName(defField.Name);
d.Apply(this, x);
}
}
x.WriteEndObject();
}
public void WriteList(List<DType> datas, BsonDataWriter x)
{
x.WriteStartArray();
foreach (var d in datas)
{
d.Apply(this, x);
}
x.WriteEndArray();
}
public void Accept(DArray type, BsonDataWriter x)
{
WriteList(type.Datas, x);
}
public void Accept(DList type, BsonDataWriter x)
{
WriteList(type.Datas, x);
}
public void Accept(DSet type, BsonDataWriter x)
{
WriteList(type.Datas, x);
}
public virtual void Accept(DMap type, BsonDataWriter x)
{
x.WriteStartArray();
foreach (var d in type.Datas)
{
x.WriteStartArray();
d.Key.Apply(this, x);
d.Value.Apply(this, x);
x.WriteEndArray();
}
x.WriteEndArray();
}
public void Accept(DVector2 type, BsonDataWriter x)
{
x.WriteStartObject();
x.WritePropertyName("x"); x.WriteValue(type.Value.X);
x.WritePropertyName("y"); x.WriteValue(type.Value.Y);
x.WriteEndObject();
}
public void Accept(DVector3 type, BsonDataWriter x)
{
x.WriteStartObject();
x.WritePropertyName("x"); x.WriteValue(type.Value.X);
x.WritePropertyName("y"); x.WriteValue(type.Value.Y);
x.WritePropertyName("z"); x.WriteValue(type.Value.Z);
x.WriteEndObject();
}
public void Accept(DVector4 type, BsonDataWriter x)
{
x.WriteStartObject();
x.WritePropertyName("x"); x.WriteValue(type.Value.X);
x.WritePropertyName("y"); x.WriteValue(type.Value.Y);
x.WritePropertyName("z"); x.WriteValue(type.Value.Z);
x.WritePropertyName("w"); x.WriteValue(type.Value.W);
x.WriteEndObject();
}
public virtual void Accept(DDateTime type, BsonDataWriter x)
{
x.WriteValue(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

@ -24,6 +24,7 @@ namespace Luban.Job.Cfg.Defs
public Service CfgTargetService { get; private set; }
private readonly string _patchName;
private readonly List<string> _excludeTags;
public Patch TargetPatch { get; private set; }
@ -34,6 +35,8 @@ namespace Luban.Job.Cfg.Defs
public string TableManagerName => CfgTargetService.Manager;
public List<string> ExcludeTags => _excludeTags;
public DefAssembly(string patchName, TimeZoneInfo timezone, List<string> excludeTags, IAgent agent)
{
this._patchName = patchName;
@ -59,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();
@ -162,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();
@ -309,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
{
@ -328,7 +332,7 @@ namespace Luban.Job.Cfg.Defs
throw;
}
}
foreach (var type in Types.Values)
foreach (var type in TypeList)
{
try
{
@ -344,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;
@ -65,6 +86,8 @@ namespace Luban.Job.Cfg.Defs
public bool IsUnionIndex { get; private set; }
public bool MultiKey { get; private set; }
public List<IndexInfo> IndexList { get; } = new();
public bool NeedExport => Assembly.NeedExport(this.Groups);
@ -90,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}' 不存在");
}
@ -141,8 +164,11 @@ namespace Luban.Job.Cfg.Defs
{
if (ValueTType.GetBeanAs<DefBean>().TryGetField(idx, out var f, out var i))
{
IndexField = f;
IndexFieldIdIndex = i;
if (IndexField == null)
{
IndexField = f;
IndexFieldIdIndex = i;
}
this.IndexList.Add(new IndexInfo(f.CType, f, i));
}
else
@ -152,6 +178,7 @@ namespace Luban.Job.Cfg.Defs
}
// 如果不是 union index, 每个key必须唯一否则 (key1,..,key n)唯一
IsUnionIndex = IndexList.Count > 1 && !Index.Contains(',');
MultiKey = IndexList.Count > 1 && Index.Contains(',');
break;
}
default: throw new Exception($"unknown mode:'{Mode}'");

View File

@ -44,13 +44,19 @@ namespace Luban.Job.Cfg.Defs
var overrideRecords = new HashSet<Record>();
foreach (var r in mainRecords)
{
recordIndex.Add(r, index++);
if (recordIndex.TryAdd(r, index))
{
index++;
}
}
if (patchRecords != null)
{
foreach (var r in patchRecords)
{
recordIndex.Add(r, index++);
if (recordIndex.TryAdd(r, index))
{
index++;
}
}
}

View File

@ -8,7 +8,7 @@ namespace Luban.Job.Cfg
[Option('s', "service", Required = true, HelpText = "service")]
public string Service { get; set; }
[Option("gen_types", Required = true, HelpText = "code_cs_bin,code_cs_dotnet_json,code_cs_unity_json,code_cs_unity_editor_json,code_lua_bin,code_java_bin,code_java_json,code_go_bin,code_go_json,code_cpp_bin,code_cpp_ue_editor_json,code_python2_json,code_python3_json,code_typescript_bin,code_typescript_json,code_rust_json,code_protobuf,code_template,code_flatbuffers,data_bin,data_lua,data_json,data_json2,data_json_monolithic,data_yaml,data_xml,data_resources,data_template,data_protobuf_bin,data_protobuf_json,data_flatbuffers_json,convert_json,convert_lua,convert_xlsx . can be multi")]
[Option("gen_types", Required = true, HelpText = "code_cs_bin,code_cs_dotnet_json,code_cs_unity_json,code_cs_unity_editor_json,code_lua_bin,code_java_bin,code_java_json,code_go_bin,code_go_json,code_cpp_bin,code_cpp_ue_editor_json,code_python2_json,code_python3_json,code_typescript_bin,code_typescript_json,code_rust_json,code_protobuf,code_template,code_flatbuffers,code_gdscript_json,data_bin,data_bidx,data_lua,data_json,data_json2,data_json_monolithic,data_bson,data_yaml,data_xml,data_resources,data_template,data_protobuf_bin,data_protobuf_json,data_flatbuffers_json,convert_json,convert_lua,convert_xlsx . can be multi")]
public string GenType { get; set; }
[Option("input_data_dir", Required = true, HelpText = "input data dir")]

View File

@ -8,8 +8,10 @@ using System.Threading.Tasks;
namespace Luban.Job.Cfg.Generate
{
[Render("data_bin")]
[Render("data_bidx")]
[Render("data_json")]
[Render("data_json2")]
[Render("data_bson")]
[Render("data_lua")]
[Render("data_xml")]
[Render("data_yaml")]

View File

@ -45,7 +45,7 @@ namespace Luban.Job.Cfg.Generate
foreach (var subTitle in title.SubTitleList)
{
string titleAndTags = subTitle.Tags.Count == 0 ? subTitle.Name : subTitle.Name + "&" + string.Join('&', subTitle.Tags.Select(e => $"{e.Key}={e.Value}"));
string titleAndTags = subTitle.Tags.Count == 0 ? subTitle.Name : subTitle.Name + "#" + string.Join('#', subTitle.Tags.Select(e => $"{e.Key}={e.Value}"));
titleRow[subTitle.FromIndex] = titleAndTags;
}
dataRangeArray.Add(titleRow);
@ -58,7 +58,7 @@ namespace Luban.Job.Cfg.Generate
foreach (var subTitle in title.SubTitleList)
{
string typeAndTags = valueType.Bean.TryGetField(subTitle.Name, out var f, out _) ?
(f.CType.Tags.Count == 0 ? f.CType.Apply(CsDefineTypeName.Ins) : f.CType.Apply(CsDefineTypeName.Ins) + "&" + string.Join('&', f.CType.Tags.Select(e => $"{e.Key}={e.Value}")))
(f.CType.Tags.Count == 0 ? f.CType.Apply(CsDefineTypeName.Ins) : f.CType.Apply(CsDefineTypeName.Ins) + "#" + string.Join('#', f.CType.Tags.Select(e => $"({e.Key}={e.Value})")))
: "";
typeRow[subTitle.FromIndex] = typeAndTags;
}

View File

@ -0,0 +1,39 @@
using Luban.Job.Cfg.Defs;
using Luban.Job.Common.Generate;
using Luban.Job.Common.Tpl;
using Luban.Job.Common.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Luban.Job.Cfg.Generate
{
[Render("code_gdscript_json")]
internal class GDScriptCodeJsonRender : TemplateCodeRenderBase
{
protected override string RenderTemplateDir => "gdscript_json";
public override void Render(GenContext ctx)
{
ctx.Render = this;
ctx.Lan = Common.ELanguage.GDSCRIPT;
DefAssembly.LocalAssebmly.CurrentLanguage = ctx.Lan;
var lines = new List<string>(10000);
static void PreContent(List<string> fileContent)
{
//fileContent.Add(PythonStringTemplates.ImportTython3Enum);
//fileContent.Add(PythonStringTemplates.PythonVectorTypes);
fileContent.Add(StringTemplateManager.Ins.GetTemplateString("config/gdscript_json/header"));
}
GenerateCodeMonolithic(ctx,
System.IO.Path.Combine(ctx.GenArgs.OutputCodeDir, RenderFileUtil.GetFileOrDefault(ctx.GenArgs.OutputCodeMonolithicFile, "types.gd")),
lines,
PreContent,
null);
}
}
}

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,127 +1,156 @@
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
{
class CsJsonDeserialize : ITypeFuncVisitor<string, string, string>
class CsJsonDeserialize : ITypeFuncVisitor<string, string, int, string>
{
public static CsJsonDeserialize 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}.GetBoolean();";
}
public string Accept(TByte type, string json, string x)
public string Accept(TByte type, string json, string x, int depth)
{
return $"{x} = {json}.GetByte();";
}
public string Accept(TShort type, string json, string x)
public string Accept(TShort type, string json, string x, int depth)
{
return $"{x} = {json}.GetInt16();";
}
public string Accept(TFshort type, string json, string x)
public string Accept(TFshort type, string json, string x, int depth)
{
return $"{x} = {json}.GetInt16();";
}
public string Accept(TInt type, string json, string x)
public string Accept(TInt type, string json, string x, int depth)
{
return $"{x} = {json}.GetInt32();";
}
public string Accept(TFint type, string json, string x)
public string Accept(TFint type, string json, string x, int depth)
{
return $"{x} = {json}.GetInt32();";
}
public string Accept(TLong type, string json, string x)
public string Accept(TLong type, string json, string x, int depth)
{
return $"{x} = {json}.GetInt64();";
}
public string Accept(TFlong type, string json, string x)
public string Accept(TFlong type, string json, string x, int depth)
{
return $"{x} = {json}.GetInt64();";
}
public string Accept(TFloat type, string json, string x)
public string Accept(TFloat type, string json, string x, int depth)
{
return $"{x} = {json}.GetSingle();";
}
public string Accept(TDouble type, string json, string x)
public string Accept(TDouble type, string json, string x, int depth)
{
return $"{x} = {json}.GetDouble();";
}
public string Accept(TEnum type, string json, string x)
public string Accept(TEnum type, string json, string x, int depth)
{
return $"{x} = ({type.CsUnderingDefineType()}){json}.GetInt32();";
}
public string Accept(TString type, string json, string x)
public string Accept(TString type, string json, string x, int depth)
{
return $"{x} = {json}.GetString();";
}
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 $"{x}{TText.L10N_FIELD_SUFFIX} = {json}.GetProperty(\"{DText.KEY_NAME}\").GetString();{x} = {json}.GetProperty(\"{DText.TEXT_NAME}\").GetString();";
}
public string Accept(TBean type, string json, string x)
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)
public string Accept(TArray type, string json, string x, int depth)
{
return $"{{ var _json0 = {json}; int _n = _json0.GetArrayLength(); {x} = new {type.ElementType.CsUnderingDefineType()}[_n]; int _index=0; foreach(JsonElement __e in _json0.EnumerateArray()) {{ {type.ElementType.CsUnderingDefineType()} __v; {type.ElementType.Apply(this, "__e", "__v")} {x}[_index++] = __v; }} }}";
string _n = $"_n{depth}";
string __e = $"__e{depth}";
string __v = $"__v{depth}";
string __json = $"__json{depth}";
string __index = $"__index{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 $"{{ var {__json} = {json}; int {_n} = {__json}.GetArrayLength(); {x} = new {typeStr}; int {__index}=0; foreach(JsonElement {__e} in {__json}.EnumerateArray()) {{ {type.ElementType.CsUnderingDefineType()} {__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 $"{{ var _json0 = {json}; {x} = new {type.CsUnderingDefineType()}(_json0.GetArrayLength()); foreach(JsonElement __e in _json0.EnumerateArray()) {{ {type.ElementType.CsUnderingDefineType()} __v; {type.ElementType.Apply(this, "__e", "__v")} {x}.Add(__v); }} }}";
string __e = $"__e{depth}";
string __v = $"__v{depth}";
string __json = $"__json{depth}";
return $"{{ var {__json} = {json}; {x} = new {type.CsUnderingDefineType()}({__json}.GetArrayLength()); foreach(JsonElement {__e} in {__json}.EnumerateArray()) {{ {type.ElementType.CsUnderingDefineType()} {__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 $"{{ var _json0 = {json}; {x} = new {type.CsUnderingDefineType()}(_json0.GetArrayLength()); foreach(JsonElement __e in _json0.EnumerateArray()) {{ {type.ElementType.CsUnderingDefineType()} __v; {type.ElementType.Apply(this, "__e", "__v")} {x}.Add(__v); }} }}";
string __e = $"__e{depth}";
string __v = $"__v{depth}";
string __json = $"__json{depth}";
return $"{{ var {__json} = {json}; {x} = new {type.CsUnderingDefineType()}({__json}.GetArrayLength()); foreach(JsonElement {__e} in {__json}.EnumerateArray()) {{ {type.ElementType.CsUnderingDefineType()} {__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 @$"{{ var _json0 = {json}; {x} = new {type.CsUnderingDefineType()}(_json0.GetArrayLength()); foreach(JsonElement __e in _json0.EnumerateArray()) {{ {type.KeyType.CsUnderingDefineType()} __k; {type.KeyType.Apply(this, "__e[0]", "__k")} {type.ValueType.CsUnderingDefineType()} __v; {type.ValueType.Apply(this, "__e[1]", "__v")} {x}.Add(__k, __v); }} }}";
string __e = $"__e{depth}";
string __k = $"_k{depth}";
string __v = $"_v{depth}";
string __json = $"__json{depth}";
return @$"{{ var {__json} = {json}; {x} = new {type.CsUnderingDefineType()}({__json}.GetArrayLength()); foreach(JsonElement {__e} in {__json}.EnumerateArray()) {{ {type.KeyType.CsUnderingDefineType()} {__k}; {type.KeyType.Apply(this, $"{__e}[0]", __k,depth + 1)} {type.ValueType.CsUnderingDefineType()} {__v}; {type.ValueType.Apply(this, $"{__e}[1]", __v, depth + 1)} {x}.Add({__k}, {__v}); }} }}";
}
public string Accept(TVector2 type, string json, string x)
public string Accept(TVector2 type, string json, string x, int depth)
{
return $"{{ var _json0 = {json}; float __x; {TFloat.Ins.Apply(this, "_json0.GetProperty(\"x\")", "__x") } float __y; {TFloat.Ins.Apply(this, "_json0.GetProperty(\"y\")", "__y") } {x} = new {type.Apply(CsDefineTypeName.Ins)}(__x, __y); }}";
return $"{{ var _json0 = {json}; float __x; {TFloat.Ins.Apply(this, "_json0.GetProperty(\"x\")", "__x", depth) } float __y; {TFloat.Ins.Apply(this, "_json0.GetProperty(\"y\")", "__y", depth) } {x} = new {type.Apply(CsDefineTypeName.Ins)}(__x, __y); }}";
}
public string Accept(TVector3 type, string json, string x)
public string Accept(TVector3 type, string json, string x, int depth)
{
return $"{{ var _json0 = {json}; float __x; {TFloat.Ins.Apply(this, "_json0.GetProperty(\"x\")", "__x") } float __y; {TFloat.Ins.Apply(this, "_json0.GetProperty(\"y\")", "__y") } float __z; {TFloat.Ins.Apply(this, "_json0.GetProperty(\"z\")", "__z") } {x} = new {type.Apply(CsDefineTypeName.Ins)}(__x, __y,__z); }}";
return $"{{ var _json0 = {json}; float __x; {TFloat.Ins.Apply(this, "_json0.GetProperty(\"x\")", "__x", depth) } float __y; {TFloat.Ins.Apply(this, "_json0.GetProperty(\"y\")", "__y", depth) } float __z; {TFloat.Ins.Apply(this, "_json0.GetProperty(\"z\")", "__z", depth) } {x} = new {type.Apply(CsDefineTypeName.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 $"{{ var _json0 = {json}; float __x; {TFloat.Ins.Apply(this, "_json0.GetProperty(\"x\")", "__x") } float __y; {TFloat.Ins.Apply(this, "_json0.GetProperty(\"y\")", "__y") } float __z; {TFloat.Ins.Apply(this, "_json0.GetProperty(\"z\")", "__z") } float __w; {TFloat.Ins.Apply(this, "_json0.GetProperty(\"w\")", "__w") } {x} = new {type.Apply(CsDefineTypeName.Ins)}(__x, __y, __z, __w); }}";
return $"{{ var _json0 = {json}; float __x; {TFloat.Ins.Apply(this, "_json0.GetProperty(\"x\")", "__x", depth) } float __y; {TFloat.Ins.Apply(this, "_json0.GetProperty(\"y\")", "__y", depth) } float __z; {TFloat.Ins.Apply(this, "_json0.GetProperty(\"z\")", "__z", depth) } float __w; {TFloat.Ins.Apply(this, "_json0.GetProperty(\"w\")", "__w", depth) } {x} = new {type.Apply(CsDefineTypeName.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}.GetInt32();";
return $"{x} = {json}.GetInt64();";
}
}
}

View File

@ -1,132 +1,162 @@
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
{
class CsUnityJsonDeserialize : ITypeFuncVisitor<string, string, string>
class CsUnityJsonDeserialize : ITypeFuncVisitor<string, string, int, string>
{
public static CsUnityJsonDeserialize Ins { get; } = new();
public string Accept(TBool type, string json, string x)
public string Accept(TBool type, string json, string x, int depth)
{
return $"{{ if(!{json}.IsBoolean) {{ throw new SerializationException(); }} {x} = {json}; }}";
}
public string Accept(TByte type, string json, string x)
public string Accept(TByte type, string json, string x, int depth)
{
return $"{{ if(!{json}.IsNumber) {{ throw new SerializationException(); }} {x} = {json}; }}";
}
public string Accept(TShort type, string json, string x)
public string Accept(TShort type, string json, string x, int depth)
{
return $"{{ if(!{json}.IsNumber) {{ throw new SerializationException(); }} {x} = {json}; }}";
}
public string Accept(TFshort type, string json, string x)
public string Accept(TFshort type, string json, string x, int depth)
{
return $"{{ if(!{json}.IsNumber) {{ throw new SerializationException(); }} {x} = {json}; }}";
}
public string Accept(TInt type, string json, string x)
public string Accept(TInt type, string json, string x, int depth)
{
return $"{{ if(!{json}.IsNumber) {{ throw new SerializationException(); }} {x} = {json}; }}";
}
public string Accept(TFint type, string json, string x)
public string Accept(TFint type, string json, string x, int depth)
{
return $"{{ if(!{json}.IsNumber) {{ throw new SerializationException(); }} {x} = {json}; }}";
}
public string Accept(TLong type, string json, string x)
public string Accept(TLong type, string json, string x, int depth)
{
return $"{{ if(!{json}.IsNumber) {{ throw new SerializationException(); }} {x} = {json}; }}";
}
public string Accept(TFlong type, string json, string x)
public string Accept(TFlong type, string json, string x, int depth)
{
return $"{{ if(!{json}.IsNumber) {{ throw new SerializationException(); }} {x} = {json}; }}";
}
public string Accept(TFloat type, string json, string x)
public string Accept(TFloat type, string json, string x, int depth)
{
return $"{{ if(!{json}.IsNumber) {{ throw new SerializationException(); }} {x} = {json}; }}";
}
public string Accept(TDouble type, string json, string x)
public string Accept(TDouble type, string json, string x, int depth)
{
return $"{{ if(!{json}.IsNumber) {{ throw new SerializationException(); }} {x} = {json}; }}";
}
public string Accept(TEnum type, string json, string x)
public string Accept(TEnum type, string json, string x, int depth)
{
return $"{{ if(!{json}.IsNumber) {{ throw new SerializationException(); }} {x} = ({type.CsUnderingDefineType()}){json}.AsInt; }}";
}
public string Accept(TString type, string json, string x)
public string Accept(TString type, string json, string x, int depth)
{
return $"{{ if(!{json}.IsString) {{ throw new SerializationException(); }} {x} = {json}; }}";
}
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 $"{{ if(!{json}[\"{DText.KEY_NAME}\"].IsString) {{ throw new SerializationException(); }} {x}{TText.L10N_FIELD_SUFFIX} = {json}[\"{DText.KEY_NAME}\"]; if(!{json}[\"{DText.TEXT_NAME}\"].IsString) {{ throw new SerializationException(); }} {x} = {json}[\"{DText.TEXT_NAME}\"]; }}";
}
public string Accept(TBean type, string json, string x)
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)
public string Accept(TArray type, string json, string x, int depth)
{
string tempJsonName = $"_json1";
return $"{{ var {tempJsonName} = {json}; if(!{tempJsonName}.IsArray) {{ throw new SerializationException(); }} int _n = {tempJsonName}.Count; {x} = new {type.ElementType.CsUnderingDefineType()}[_n]; int _index=0; foreach(JSONNode __e in {tempJsonName}.Children) {{ {type.ElementType.CsUnderingDefineType()} __v; {type.ElementType.Apply(this, "__e", "__v")} {x}[_index++] = __v; }} }}";
string _n = $"_n{depth}";
string __e = $"__e{depth}";
string __v = $"__v{depth}";
string __json = $"__json{depth}";
string __index = $"__index{depth}";
string tempJsonName = __json;
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 $"{{ var {tempJsonName} = {json}; if(!{tempJsonName}.IsArray) {{ throw new SerializationException(); }} int {_n} = {tempJsonName}.Count; {x} = new {typeStr}; int {__index}=0; foreach(JSONNode {__e} in {tempJsonName}.Children) {{ {type.ElementType.CsUnderingDefineType()} {__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)
{
string tempJsonName = $"_json1";
return $"{{ var {tempJsonName} = {json}; if(!{tempJsonName}.IsArray) {{ throw new SerializationException(); }} {x} = new {type.CsUnderingDefineType()}({tempJsonName}.Count); foreach(JSONNode __e in {tempJsonName}.Children) {{ {type.ElementType.CsUnderingDefineType()} __v; {type.ElementType.Apply(this, "__e", "__v")} {x}.Add(__v); }} }}";
string __e = $"__e{depth}";
string __v = $"__v{depth}";
string __json = $"__json{depth}";
string tempJsonName = __json;
return $"{{ var {tempJsonName} = {json}; if(!{tempJsonName}.IsArray) {{ throw new SerializationException(); }} {x} = new {type.CsUnderingDefineType()}({tempJsonName}.Count); foreach(JSONNode {__e} in {tempJsonName}.Children) {{ {type.ElementType.CsUnderingDefineType()} {__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)
{
string tempJsonName = $"_json1";
return $"{{ var {tempJsonName} = {json}; if(!{tempJsonName}.IsArray) {{ throw new SerializationException(); }} {x} = new {type.CsUnderingDefineType()}(/*{tempJsonName}.Count*/); foreach(JSONNode __e in {tempJsonName}.Children) {{ {type.ElementType.CsUnderingDefineType()} __v; {type.ElementType.Apply(this, "__e", "__v")} {x}.Add(__v); }} }}";
string __e = $"__e{depth}";
string __v = $"__v{depth}";
string __json = $"__json{depth}";
string tempJsonName = __json;
return $"{{ var {tempJsonName} = {json}; if(!{tempJsonName}.IsArray) {{ throw new SerializationException(); }} {x} = new {type.CsUnderingDefineType()}(/*{tempJsonName}.Count*/); foreach(JSONNode {__e} in {tempJsonName}.Children) {{ {type.ElementType.CsUnderingDefineType()} {__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)
{
string tempJsonName = $"_json1";
return @$"{{ var {tempJsonName} = {json}; if(!{tempJsonName}.IsArray) {{ throw new SerializationException(); }} {x} = new {type.CsUnderingDefineType()}({tempJsonName}.Count); foreach(JSONNode __e in {tempJsonName}.Children) {{ {type.KeyType.CsUnderingDefineType()} __k; {type.KeyType.Apply(this, "__e[0]", "__k")} {type.ValueType.CsUnderingDefineType()} __v; {type.ValueType.Apply(this, "__e[1]", "__v")} {x}.Add(__k, __v); }} }}";
string __e = $"__e{depth}";
string __k = $"_k{depth}";
string __v = $"_v{depth}";
string __json = $"__json{depth}";
string tempJsonName = __json;
return @$"{{ var {tempJsonName} = {json}; if(!{tempJsonName}.IsArray) {{ throw new SerializationException(); }} {x} = new {type.CsUnderingDefineType()}({tempJsonName}.Count); foreach(JSONNode {__e} in {tempJsonName}.Children) {{ {type.KeyType.CsUnderingDefineType()} {__k}; {type.KeyType.Apply(this, $"{__e}[0]", __k, depth + 1)} {type.ValueType.CsUnderingDefineType()} { __v}; {type.ValueType.Apply(this, $"{__e}[1]", __v, depth + 1)} {x}.Add({__k}, { __v}); }} }}";
}
public string Accept(TVector2 type, string json, string x)
public string Accept(TVector2 type, string json, string x, int depth)
{
string tempJsonName = $"_json2";
return $"{{ var {tempJsonName} = {json}; if(!{tempJsonName}.IsObject) {{ throw new SerializationException(); }} float __x; {TFloat.Ins.Apply(this, $"{tempJsonName}[\"x\"]", "__x") } float __y; {TFloat.Ins.Apply(this, $"{tempJsonName}[\"y\"]", "__y") } {x} = new {type.Apply(CsDefineTypeName.Ins)}(__x, __y); }}";
return $"{{ var {tempJsonName} = {json}; if(!{tempJsonName}.IsObject) {{ throw new SerializationException(); }} float __x; {TFloat.Ins.Apply(this, $"{tempJsonName}[\"x\"]", "__x", depth) } float __y; {TFloat.Ins.Apply(this, $"{tempJsonName}[\"y\"]", "__y", depth) } {x} = new {type.Apply(CsDefineTypeName.Ins)}(__x, __y); }}";
}
public string Accept(TVector3 type, string json, string x)
public string Accept(TVector3 type, string json, string x, int depth)
{
string tempJsonName = $"_json2";
return $"{{ var {tempJsonName} = {json}; if(!{tempJsonName}.IsObject) {{ throw new SerializationException(); }} float __x; {TFloat.Ins.Apply(this, $"{tempJsonName}[\"x\"]", "__x") } float __y; {TFloat.Ins.Apply(this, $"{tempJsonName}[\"y\"]", "__y") } float __z; {TFloat.Ins.Apply(this, $"{tempJsonName}[\"z\"]", "__z") } {x} = new {type.Apply(CsDefineTypeName.Ins)}(__x, __y,__z); }}";
return $"{{ var {tempJsonName} = {json}; if(!{tempJsonName}.IsObject) {{ throw new SerializationException(); }} float __x; {TFloat.Ins.Apply(this, $"{tempJsonName}[\"x\"]", "__x", depth) } float __y; {TFloat.Ins.Apply(this, $"{tempJsonName}[\"y\"]", "__y", depth) } float __z; {TFloat.Ins.Apply(this, $"{tempJsonName}[\"z\"]", "__z", depth) } {x} = new {type.Apply(CsDefineTypeName.Ins)}(__x, __y,__z); }}";
}
public string Accept(TVector4 type, string json, string x)
public string Accept(TVector4 type, string json, string x, int depth)
{
string tempJsonName = $"_json2";
return $"{{ var {tempJsonName} = {json}; if(!{tempJsonName}.IsObject) {{ throw new SerializationException(); }} float __x; {TFloat.Ins.Apply(this, $"{tempJsonName}[\"x\"]", "__x") } float __y; {TFloat.Ins.Apply(this, $"{tempJsonName}[\"y\"]", "__y") } float __z; {TFloat.Ins.Apply(this, $"{tempJsonName}[\"z\"]", "__z") } float __w; {TFloat.Ins.Apply(this, $"{tempJsonName}[\"w\"]", "__w") } {x} = new {type.Apply(CsDefineTypeName.Ins)}(__x, __y, __z, __w); }}";
return $"{{ var {tempJsonName} = {json}; if(!{tempJsonName}.IsObject) {{ throw new SerializationException(); }} float __x; {TFloat.Ins.Apply(this, $"{tempJsonName}[\"x\"]", "__x", depth) } float __y; {TFloat.Ins.Apply(this, $"{tempJsonName}[\"y\"]", "__y", depth) } float __z; {TFloat.Ins.Apply(this, $"{tempJsonName}[\"z\"]", "__z", depth) } float __w; {TFloat.Ins.Apply(this, $"{tempJsonName}[\"w\"]", "__w", depth) } {x} = new {type.Apply(CsDefineTypeName.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 $"{{ if(!{json}.IsNumber) {{ throw new SerializationException(); }} {x} = {json}; }}";
}

View File

@ -0,0 +1,159 @@
using Luban.Job.Cfg.Datas;
using Luban.Job.Common.Types;
using Luban.Job.Common.TypeVisitors;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Luban.Job.Cfg.TypeVisitors
{
class GDScriptUnderingDeserializeVisitor : ITypeFuncVisitor<string, string, string>
{
public static GDScriptUnderingDeserializeVisitor Ins { get; } = new();
public string Accept(TBool type, string jsonVarName, string fieldName)
{
return $"{fieldName} = {jsonVarName}";
}
public string Accept(TByte type, string jsonVarName, string fieldName)
{
return $"{fieldName} = {jsonVarName}";
}
public string Accept(TShort type, string jsonVarName, string fieldName)
{
return $"{fieldName} = {jsonVarName}";
}
public string Accept(TFshort type, string jsonVarName, string fieldName)
{
return $"{fieldName} = {jsonVarName}";
}
public string Accept(TInt type, string jsonVarName, string fieldName)
{
return $"{fieldName} = {jsonVarName}";
}
public string Accept(TFint type, string jsonVarName, string fieldName)
{
return $"{fieldName} = {jsonVarName}";
}
public string Accept(TLong type, string jsonVarName, string fieldName)
{
return $"{fieldName} = {jsonVarName}";
}
public string Accept(TFlong type, string jsonVarName, string fieldName)
{
return $"{fieldName} = {jsonVarName}";
}
public string Accept(TFloat type, string jsonVarName, string fieldName)
{
return $"{fieldName} = {jsonVarName}";
}
public string Accept(TDouble type, string jsonVarName, string fieldName)
{
return $"{fieldName} = {jsonVarName}";
}
public string Accept(TEnum type, string jsonVarName, string fieldName)
{
return $"{fieldName} = {jsonVarName}";
}
public string Accept(TString type, string jsonVarName, string fieldName)
{
return $"{fieldName} = {jsonVarName}";
}
public string Accept(TBytes type, string jsonVarName, string fieldName)
{
return $"{fieldName} = {jsonVarName}";
}
public string Accept(TText type, string jsonVarName, string fieldName)
{
return $"{fieldName} = {jsonVarName}['{DText.TEXT_NAME}']";
}
public string Accept(TBean type, string jsonVarName, string fieldName)
{
if (type.Bean.IsAbstractType)
{
return $"{fieldName} = {type.Bean.GDScriptFullName}.from_json({jsonVarName})";
}
else
{
return $"{fieldName} = {type.Bean.GDScriptFullName}.new({jsonVarName})";
}
}
public string Accept(TArray type, string jsonVarName, string fieldName)
{
if (type.Apply(SimpleJsonTypeVisitor.Ins))
{
return $"{fieldName} = {jsonVarName}";
}
else
{
return $"{fieldName} = []\n for _ele in {jsonVarName}:\n var {type.ElementType.Apply(this, "_ele", "_e")};\n {fieldName}.append(_e)";
}
}
public string Accept(TList type, string jsonVarName, string fieldName)
{
if (type.Apply(SimpleJsonTypeVisitor.Ins))
{
return $"{fieldName} = {jsonVarName}";
}
else
{
return $"{fieldName} = []\n for _ele in {jsonVarName}:\n var {type.ElementType.Apply(this, "_ele", "_e")};\n {fieldName}.append(_e)";
}
}
public string Accept(TSet type, string jsonVarName, string fieldName)
{
if (type.Apply(SimpleJsonTypeVisitor.Ins))
{
return $"{fieldName} = {jsonVarName}";
}
else
{
return $"{fieldName} = set()\n for _ele in {jsonVarName}:\n var {type.ElementType.Apply(this, "_ele", "_e")};\n {fieldName}.add(_e)";
}
}
public string Accept(TMap type, string jsonVarName, string fieldName)
{
return $"{fieldName} = {{}}\n for _v in {jsonVarName}:\n {fieldName}[_v[0]] =_v[1]";
}
public string Accept(TVector2 type, string jsonVarName, string fieldName)
{
return $"{fieldName} = Vector2({jsonVarName}['x'], {jsonVarName}['y'])";
}
public string Accept(TVector3 type, string jsonVarName, string fieldName)
{
return $"{fieldName} = Vector3({jsonVarName}['x'], {jsonVarName}['y'], {jsonVarName}['z'])";
}
public string Accept(TVector4 type, string jsonVarName, string fieldName)
{
return $"{fieldName} = Vector3({jsonVarName}['x'], {jsonVarName}['y'], {jsonVarName}['z'])";
}
public string Accept(TDateTime type, string jsonVarName, string fieldName)
{
return $"{fieldName} = {jsonVarName}";
}
}
}

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} = {type.DefineEnum.FullNameWithTopModule}.valueOf({json}.getAsInt());";
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

@ -59,7 +59,7 @@ namespace Luban.Job.Cfg.TypeVisitors
public string Accept(TEnum type, string bufName, string fieldName)
{
return $"{fieldName} = {type.DefineEnum.FullNameWithTopModule}.valueOf({bufName}.readInt());";
return $"{fieldName} = {bufName}.readInt();";
}
public string Accept(TString type, string bufName, string fieldName)
@ -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

@ -11,6 +11,7 @@ using Luban.Job.Common.Tpl;
using Luban.Job.Common.Types;
using Luban.Job.Common.Utils;
using MessagePack;
using Newtonsoft.Json.Bson;
using Scriban;
using System;
using System.Collections.Generic;
@ -43,6 +44,14 @@ namespace Luban.Job.Cfg.Utils
ThreadLocalTemporalByteBufPool.Free(buf);
return bytes;
}
case "data_bidx":
{
var buf = ThreadLocalTemporalByteBufPool.Alloc(1024 * 1024);
BinaryIndexExportor.Ins.WriteList(table, records, buf);
var bytes = buf.CopyData();
ThreadLocalTemporalByteBufPool.Free(buf);
return bytes;
}
case "data_json":
case "data_json2":
{
@ -79,6 +88,14 @@ namespace Luban.Job.Cfg.Utils
tw.Flush();
return DataUtil.StreamToBytes(ms);
}
case "data_bson":
{
var ss = new MemoryStream();
var bsonWriter = new BsonDataWriter(ss);
BsonExportor.Ins.WriteAsArray(records, bsonWriter);
bsonWriter.Flush();
return DataUtil.StreamToBytes(ss);
}
case "data_xml":
{
var xwSetting = new XmlWriterSettings() { Indent = true };

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
{
@ -29,11 +30,11 @@ namespace Luban.Job.Cfg.Utils
{
if (type.IsNullable)
{
return $"{{ if ({bufName}.TryGetProperty(\"{jsonFieldName}\", out var _j) && _j.ValueKind != JsonValueKind.Null) {{ {type.Apply(TypeVisitors.CsJsonDeserialize.Ins, "_j", fieldName)} }} else {{ {fieldName} = null; }} }}";
return $"{{ if ({bufName}.TryGetProperty(\"{jsonFieldName}\", out var _j) && _j.ValueKind != JsonValueKind.Null) {{ {type.Apply(TypeVisitors.CsJsonDeserialize.Ins, "_j", fieldName, 0)} }} else {{ {fieldName} = null; }} }}";
}
else
{
return type.Apply(TypeVisitors.CsJsonDeserialize.Ins, $"{bufName}.GetProperty(\"{jsonFieldName}\")", fieldName);
return type.Apply(TypeVisitors.CsJsonDeserialize.Ins, $"{bufName}.GetProperty(\"{jsonFieldName}\")", fieldName, 0);
}
}
@ -46,11 +47,11 @@ namespace Luban.Job.Cfg.Utils
{
if (type.IsNullable)
{
return $"{{ var _j = {bufName}[\"{jsonFieldName}\"]; if (_j.Tag != JSONNodeType.None && _j.Tag != JSONNodeType.NullValue) {{ {type.Apply(TypeVisitors.CsUnityJsonDeserialize.Ins, "_j", fieldName)} }} else {{ {fieldName} = null; }} }}";
return $"{{ var _j = {bufName}[\"{jsonFieldName}\"]; if (_j.Tag != JSONNodeType.None && _j.Tag != JSONNodeType.NullValue) {{ {type.Apply(TypeVisitors.CsUnityJsonDeserialize.Ins, "_j", fieldName, 0)} }} else {{ {fieldName} = null; }} }}";
}
else
{
return type.Apply(TypeVisitors.CsUnityJsonDeserialize.Ins, $"{bufName}[\"{jsonFieldName}\"]", fieldName);
return type.Apply(TypeVisitors.CsUnityJsonDeserialize.Ins, $"{bufName}[\"{jsonFieldName}\"]", fieldName, 0);
}
}
@ -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");
}
}
}
@ -225,6 +252,30 @@ namespace Luban.Job.Cfg.Utils
}
}
public static string GdscriptDeserializeValue(string fieldName, string jsonVarName, TType type)
{
if (type.IsNullable)
{
return $"if {jsonVarName} != None: {type.Apply(GDScriptUnderingDeserializeVisitor.Ins, jsonVarName, fieldName)}";
}
else
{
return type.Apply(GDScriptUnderingDeserializeVisitor.Ins, jsonVarName, fieldName);
}
}
public static string GdscriptDeserializeField(string fieldName, string jsonVarName, string jsonFieldName, TType type)
{
if (type.IsNullable)
{
return $"if {jsonVarName}.get('{jsonFieldName}') != null: {type.Apply(GDScriptUnderingDeserializeVisitor.Ins, $"{jsonVarName}['{jsonFieldName}']", fieldName)}";
}
else
{
return type.Apply(GDScriptUnderingDeserializeVisitor.Ins, $"{jsonVarName}['{jsonFieldName}']", fieldName);
}
}
public static string DefineTextKeyField(DefField field, string lan)
{
switch (lan)
@ -266,7 +317,7 @@ namespace Luban.Job.Cfg.Utils
public static string CsUnityEditorJsonLoad(string jsonName, string fieldName, TType type)
{
return $"{type.Apply(CsEditorJsonLoad.Ins, jsonName, fieldName)}";
return $"{type.Apply(CsEditorJsonLoad.Ins, jsonName, fieldName)}";
}
public static string CsUnityEditorJsonSave(string jsonName, string jsonFieldName, string fieldName, TType type)

View File

@ -0,0 +1,145 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Luban.Job.Cfg.Validators
{
internal class Range
{
private readonly string _str;
private long? _min;
private long? _max;
private double? _mind;
private double? _maxd;
private bool _includeMinBound;
private bool _includeMaxBound;
public Range(string strRange)
{
_str = strRange.Trim();
}
public string RawStr => _str;
private bool TryParse(string s, ref long? x)
{
s = s.Trim();
if (string.IsNullOrEmpty(s))
{
x = null;
return true;
}
else if (long.TryParse(s, out var v))
{
x = v;
return true;
}
else
{
return false;
}
}
private bool TryParse(string s, ref double? x)
{
s = s.Trim();
if (string.IsNullOrEmpty(s))
{
x = null;
return true;
}
else if (double.TryParse(s, out var v))
{
x = v;
return true;
}
else
{
return false;
}
}
public void Compile()
{
void ThrowError()
{
throw new Exception($"range定义不合法");
}
if (long.TryParse(_str, out long value))
{
// size=xxxx
_min = _max = value;
_mind = _maxd = value;
_includeMinBound = _includeMaxBound = true;
return;
}
if (_str.Length <= 2)
{
ThrowError();
}
switch (_str[0])
{
case '[': _includeMinBound = true; break;
case '(': _includeMinBound = false; break;
default: ThrowError(); break;
}
switch (_str[^1])
{
case ']': _includeMaxBound = true; break;
case ')': _includeMaxBound = false; break;
default: ThrowError(); break;
}
var pars = _str[1..^1].Split(',');
if (pars.Length != 2)
{
ThrowError();
}
bool p1 = TryParse(pars[0], ref _min);
bool p2 = TryParse(pars[0], ref _mind);
bool p3 = TryParse(pars[1], ref _max);
bool p4 = TryParse(pars[1], ref _maxd);
if ((!p1 && !p2) || (!p3 && !p4))
{
ThrowError();
}
}
public bool CheckInLongRange(long x)
{
if (_min is long m && (_includeMinBound ? m > x : m >= x))
{
return false;
}
if (_max is long n && (_includeMaxBound ? n < x : n <= x))
{
return false;
}
return true;
}
public bool CheckInDoubleRange(double x)
{
if (_mind is double m && (_includeMinBound ? m > x : m >= x))
{
return false;
}
if (_maxd is double n && (_includeMaxBound ? n < x : n <= x))
{
return false;
}
return true;
}
}
}

View File

@ -11,128 +11,17 @@ namespace Luban.Job.Cfg.Validators
{
public TType Type { get; }
private readonly string _str;
private long? _min;
private long? _max;
private double? _mind;
private double? _maxd;
private bool _includeMinBound;
private bool _includeMaxBound;
private Range _range;
public RangeValidator(TType type, string strRange)
{
Type = type;
_str = strRange.Trim();
}
private bool TryParse(string s, ref long? x)
{
s = s.Trim();
if (string.IsNullOrEmpty(s))
{
x = null;
return true;
}
else if (long.TryParse(s, out var v))
{
x = v;
return true;
}
else
{
return false;
}
}
private bool TryParse(string s, ref double? x)
{
s = s.Trim();
if (string.IsNullOrEmpty(s))
{
x = null;
return true;
}
else if (double.TryParse(s, out var v))
{
x = v;
return true;
}
else
{
return false;
}
_range = new Range(strRange);
}
public void Compile(DefFieldBase def)
{
void ThrowError()
{
throw new Exception($"结构:{ def.HostType.FullName } 字段: { def.Name} range 定义:{_str} 不合法");
}
if (_str.Length <= 2)
{
ThrowError();
}
switch (_str[0])
{
case '[': _includeMinBound = true; break;
case '(': _includeMinBound = false; break;
default: ThrowError(); break;
}
switch (_str[^1])
{
case ']': _includeMaxBound = true; break;
case ')': _includeMaxBound = false; break;
default: ThrowError(); break;
}
var pars = _str[1..^1].Split(',');
if (pars.Length != 2)
{
ThrowError();
}
bool p1 = TryParse(pars[0], ref _min);
bool p2 = TryParse(pars[0], ref _mind);
bool p3 = TryParse(pars[1], ref _max);
bool p4 = TryParse(pars[1], ref _maxd);
if ((!p1 && !p2) || (!p3 && !p4))
{
ThrowError();
}
}
private bool CheckInLongRange(long x)
{
if (_min is long m && (_includeMinBound ? m > x : m >= x))
{
return false;
}
if (_max is long n && (_includeMaxBound ? n < x : n <= x))
{
return false;
}
return true;
}
private bool CheckInDoubleRange(double x)
{
if (_mind is double m && (_includeMinBound ? m > x : m >= x))
{
return false;
}
if (_maxd is double n && (_includeMaxBound ? n < x : n <= x))
{
return false;
}
return true;
_range.Compile();
}
public string Source => ValidatorContext.CurrentVisitor.CurrentValidateRecord.Source;
@ -142,7 +31,7 @@ namespace Luban.Job.Cfg.Validators
var assembly = ctx.Assembly;
void LogError()
{
assembly.Agent.Error("记录 {0}:{1} (来自文件:{2}) 不在范围:{3}内", ValidatorContext.CurrentRecordPath, data, Source, _str);
assembly.Agent.Error("记录 {0}:{1} (来自文件:{2}) 不在范围:{3}内", ValidatorContext.CurrentRecordPath, data, Source, _range.RawStr);
}
if (type.IsNullable && data == null)
@ -154,7 +43,7 @@ namespace Luban.Job.Cfg.Validators
{
case DByte b:
{
if (!CheckInLongRange(b.Value))
if (!_range.CheckInLongRange(b.Value))
{
LogError();
return;
@ -163,7 +52,7 @@ namespace Luban.Job.Cfg.Validators
}
case DFshort s:
{
if (!CheckInLongRange(s.Value))
if (!_range.CheckInLongRange(s.Value))
{
LogError();
return;
@ -172,7 +61,7 @@ namespace Luban.Job.Cfg.Validators
}
case DShort s:
{
if (!CheckInLongRange(s.Value))
if (!_range.CheckInLongRange(s.Value))
{
LogError();
return;
@ -181,7 +70,7 @@ namespace Luban.Job.Cfg.Validators
}
case DInt i:
{
if (!CheckInLongRange(i.Value))
if (!_range.CheckInLongRange(i.Value))
{
LogError();
return;
@ -190,7 +79,7 @@ namespace Luban.Job.Cfg.Validators
}
case DFint i:
{
if (!CheckInLongRange(i.Value))
if (!_range.CheckInLongRange(i.Value))
{
LogError();
return;
@ -199,7 +88,7 @@ namespace Luban.Job.Cfg.Validators
}
case DLong l:
{
if (!CheckInLongRange(l.Value))
if (!_range.CheckInLongRange(l.Value))
{
LogError();
return;
@ -208,7 +97,7 @@ namespace Luban.Job.Cfg.Validators
}
case DFlong fl:
{
if (!CheckInLongRange(fl.Value))
if (!_range.CheckInLongRange(fl.Value))
{
LogError();
return;
@ -217,7 +106,7 @@ namespace Luban.Job.Cfg.Validators
}
case DFloat ff:
{
if (!CheckInDoubleRange(ff.Value))
if (!_range.CheckInDoubleRange(ff.Value))
{
LogError();
return;
@ -226,7 +115,7 @@ namespace Luban.Job.Cfg.Validators
}
case DDouble dd:
{
if (!CheckInDoubleRange(dd.Value))
if (!_range.CheckInDoubleRange(dd.Value))
{
LogError();
return;

View File

@ -1,4 +1,5 @@
using Luban.Job.Cfg.Datas;
using Luban.Job.Cfg.DataSources;
using Luban.Job.Cfg.DataVisitors;
using Luban.Job.Cfg.Defs;
using Luban.Job.Cfg.RawDefs;
@ -58,8 +59,14 @@ namespace Luban.Job.Cfg.Validators
case ETableMode.MAP:
{
var recordMap = assembly.GetTableDataInfo(defTable).FinalRecordMap;
if (recordMap.ContainsKey(key))
if (recordMap.TryGetValue(key, out Record rec))
{
if (!rec.IsNotFiltered(assembly.ExcludeTags))
{
string locationFile = ValidatorContext.CurrentVisitor.CurrentValidateRecord.Source;
assembly.Agent.Error("记录 {0} = {1} (来自文件:{2}) 在引用表:{3} 中存在,但导出时被过滤了",
ValidatorContext.CurrentRecordPath, key, locationFile, defTable.FullName);
}
return;
}
break;
@ -67,8 +74,14 @@ namespace Luban.Job.Cfg.Validators
case ETableMode.LIST:
{
var recordMap = assembly.GetTableDataInfo(defTable).FinalRecordMapByIndexs[field];
if (recordMap.ContainsKey(key))
if (recordMap.TryGetValue(key, out Record rec))
{
if (!rec.IsNotFiltered(assembly.ExcludeTags))
{
string locationFile = ValidatorContext.CurrentVisitor.CurrentValidateRecord.Source;
assembly.Agent.Error("记录 {0} = {1} (来自文件:{2}) 在引用表:{3} 中存在,但导出时被过滤了",
ValidatorContext.CurrentRecordPath, key, locationFile, defTable.FullName);
}
return;
}
break;
@ -181,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

@ -12,16 +12,16 @@ namespace Luban.Job.Cfg.Validators
[Validator("size")]
internal class SizeValidator : IValidator
{
private readonly int _size;
private Range _range;
public SizeValidator(TType type, string rule)
{
this._size = int.Parse(rule);
_range = new Range(rule);
}
public void Compile(DefFieldBase def)
{
_range.Compile();
}
private static string Source => ValidatorContext.CurrentVisitor.CurrentValidateRecord.Source;
@ -31,7 +31,7 @@ namespace Luban.Job.Cfg.Validators
var assembly = ctx.Assembly;
void LogError(int size)
{
assembly.Agent.Error("记录 {0}:{1} (来自文件:{2}) size:{3},但要求为 {4} ", ValidatorContext.CurrentRecordPath, data, Source, size, _size);
assembly.Agent.Error("记录 {0}:{1} (来自文件:{2}) size:{3},但要求为 {4} ", ValidatorContext.CurrentRecordPath, data, Source, size, _range.RawStr);
}
if (type.IsNullable && data == null)
@ -43,7 +43,7 @@ namespace Luban.Job.Cfg.Validators
{
case DArray b:
{
if (b.Datas.Count != _size)
if (!_range.CheckInLongRange(b.Datas.Count))
{
LogError(b.Datas.Count);
return;
@ -52,7 +52,7 @@ namespace Luban.Job.Cfg.Validators
}
case DList b:
{
if (b.Datas.Count != _size)
if (!_range.CheckInLongRange(b.Datas.Count))
{
LogError(b.Datas.Count);
return;
@ -61,7 +61,7 @@ namespace Luban.Job.Cfg.Validators
}
case DSet b:
{
if (b.Datas.Count != _size)
if (!_range.CheckInLongRange(b.Datas.Count))
{
LogError(b.Datas.Count);
return;
@ -70,7 +70,7 @@ namespace Luban.Job.Cfg.Validators
}
case DMap b:
{
if (b.Datas.Count != _size)
if (!_range.CheckInLongRange(b.Datas.Count))
{
LogError(b.Datas.Count);
return;

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,7 +34,9 @@ namespace Luban.Job.Common.Defs
public Dictionary<string, DefTypeBase> Types { get; } = new Dictionary<string, DefTypeBase>();
private readonly Dictionary<string, DefTypeBase> _notCaseSenseTypes = new ();
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,8 +276,9 @@ 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);
if (sepIndex > 0)
{
@ -285,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 两侧的匹配的 ()
@ -302,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);
}
@ -340,17 +348,17 @@ namespace Luban.Job.Common.Defs
case "time":
case "datetime": return SupportDatetimeType ? TDateTime.Create(nullable, tags) : throw new NotSupportedException($"只有配置支持datetime数据类型");
default:
{
var dtype = GetDefTType(module, type, nullable, tags);
if (dtype != null)
{
return dtype;
var dtype = GetDefTType(module, type, nullable, tags);
if (dtype != null)
{
return dtype;
}
else
{
throw new ArgumentException($"invalid type. module:'{module}' type:'{type}'");
}
}
else
{
throw new ArgumentException($"invalid type. module:'{module}' type:'{type}'");
}
}
}
}
@ -362,22 +370,33 @@ 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()),
CreateNotContainerType(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)
{
switch (containerType)
{
case "array": return TArray.Create(false, containerTags, CreateNotContainerType(module, elementType));
case "list": return TList.Create(false, containerTags, CreateNotContainerType(module, elementType), true);
case "set": return TSet.Create(false, containerTags, CreateNotContainerType(module, elementType), false);
case "array":
{
return TArray.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, true);
if (type.IsCollection)
{
throw new Exception("set的元素不支持容器类型");
}
return TSet.Create(false, containerTags, type, false);
}
case "map": return CreateMapType(module, containerTags, elementType, false);
default:
{
throw new ArgumentException($"invalid container type. module:'{module}' container:'{containerType}' element:'{elementType}'");
}
{
throw new ArgumentException($"invalid container type. module:'{module}' container:'{containerType}' element:'{elementType}'");
}
}
}
}

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

@ -33,24 +33,25 @@ namespace Luban.Job.Common.Defs
case NamingConvention.UnderScores: cn = TypeUtil.ToUnderScores(Name); break;
case NamingConvention.Invalid: throw new Exception($"invalid NamingConvention");
case NamingConvention.LanguangeRecommend:
{
switch (curLan)
{
case ELanguage.INVALID: throw new Exception($"not set current language. can't get recommend naming convention name");
case ELanguage.CS: cn = TypeUtil.ToPascalCase(Name); break;
case ELanguage.JAVA: cn = TypeUtil.ToCamelCase(Name); break;
case ELanguage.GO: cn = TypeUtil.ToPascalCase(Name); break;
case ELanguage.CPP: cn = TypeUtil.ToCamelCase(Name); break;
case ELanguage.LUA: cn = TypeUtil.ToUnderScores(Name); break;
case ELanguage.JAVASCRIPT: cn = TypeUtil.ToCamelCase(Name); break;
case ELanguage.TYPESCRIPT: cn = TypeUtil.ToCamelCase(Name); break;
case ELanguage.PYTHON: cn = TypeUtil.ToUnderScores(Name); break;
case ELanguage.RUST: cn = TypeUtil.ToUnderScores(Name); break;
case ELanguage.PROTOBUF: cn = Name; break;
default: throw new Exception($"unknown language:{curLan}");
switch (curLan)
{
case ELanguage.INVALID: throw new Exception($"not set current language. can't get recommend naming convention name");
case ELanguage.CS: cn = TypeUtil.ToPascalCase(Name); break;
case ELanguage.JAVA: cn = TypeUtil.ToCamelCase(Name); break;
case ELanguage.GO: cn = TypeUtil.ToPascalCase(Name); break;
case ELanguage.CPP: cn = TypeUtil.ToCamelCase(Name); break;
case ELanguage.LUA: cn = TypeUtil.ToUnderScores(Name); break;
case ELanguage.JAVASCRIPT: cn = TypeUtil.ToCamelCase(Name); break;
case ELanguage.TYPESCRIPT: cn = TypeUtil.ToCamelCase(Name); break;
case ELanguage.PYTHON: cn = TypeUtil.ToUnderScores(Name); break;
case ELanguage.GDSCRIPT: cn = TypeUtil.ToUnderScores(Name); break;
case ELanguage.RUST: cn = TypeUtil.ToUnderScores(Name); break;
case ELanguage.PROTOBUF: cn = Name; break;
default: throw new Exception($"unknown language:{curLan}");
}
break;
}
break;
}
default: throw new Exception($"unknown NamingConvention:{AssemblyBase.NamingConventionBeanMember}");
}
if (curLan == ELanguage.RUST)
@ -116,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)
{
@ -131,21 +132,21 @@ namespace Luban.Job.Common.Defs
switch (CType)
{
case TArray t:
{
if (t.ElementType is TBean e && !e.IsDynamic && e.Bean.HierarchyFields.Count == 0)
{
throw new Exception($"container element type:'{e.Bean.FullName}' can't be empty bean");
if (t.ElementType is TBean e && !e.IsDynamic && e.Bean.HierarchyFields.Count == 0)
{
throw new Exception($"container element type:'{e.Bean.FullName}' can't be empty bean");
}
break;
}
break;
}
case TList t:
{
if (t.ElementType is TBean e && !e.IsDynamic && e.Bean.HierarchyFields.Count == 0)
{
throw new Exception($"container element type:'{e.Bean.FullName}' can't be empty bean");
if (t.ElementType is TBean e && !e.IsDynamic && e.Bean.HierarchyFields.Count == 0)
{
throw new Exception($"container element type:'{e.Bean.FullName}' can't be empty bean");
}
break;
}
break;
}
}
}

View File

@ -53,6 +53,8 @@ namespace Luban.Job.Common.Defs
public string PyFullName => TypeUtil.MakePyFullName(Namespace, Name);
public string GDScriptFullName => TypeUtil.MakeGDScriptFullName(Namespace, Name);
public string RustFullName => TypeUtil.MakeRustFullName(Namespace, Name);
public string PbFullName => TypeUtil.MakePbFullName(Namespace, Name);

View File

@ -87,6 +87,11 @@ namespace Luban.Job.Common.Defs
return type.Apply(CppDefineTypeName.Ins);
}
public static string GdscriptDefineType(TType type)
{
return type.Apply(GDScriptDefineTypeName.Ins);
}
public static string CppConstValue(TType type, string value)
{
return type.Apply(CsConstValueVisitor.Ins, value);
@ -101,7 +106,7 @@ namespace Luban.Job.Common.Defs
{
return type.Apply(LuaCommentTypeVisitor.Ins);
}
public static string EmmyLuaCommentType(TType type)
{
return type.Apply(EmmyLuaCommentTypeVisitor.Ins);
@ -190,7 +195,6 @@ namespace Luban.Job.Common.Defs
return type.Apply(ErlangDefineTypeNameVisitor.Ins);
}
public static string GoDefineType(TType type)
{
return type.Apply(GoTypeNameVisitor.Ins);
@ -314,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

@ -15,5 +15,6 @@ namespace Luban.Job.Common
RUST,
PROTOBUF,
FLATBUFFERS,
GDSCRIPT,
}
}

View File

@ -5,16 +5,15 @@ namespace Luban.Job.Common.TypeVisitors
public class CsDeserializeVisitor : DecoratorFuncVisitor<string, string, string>
{
public static CsDeserializeVisitor Ins { get; } = new CsDeserializeVisitor();
public override string DoAccept(TType type, string bufName, string fieldName)
{
if (type.IsNullable)
{
return $"if({bufName}.ReadBool()){{ {type.Apply(CsUnderingDeserializeVisitor.Ins, bufName, fieldName)} }} else {{ {fieldName} = null; }}";
return $"if({bufName}.ReadBool()){{ {type.Apply(CsUnderingDeserializeVisitor.Ins, bufName, fieldName, 0)} }} else {{ {fieldName} = null; }}";
}
else
{
return type.Apply(CsUnderingDeserializeVisitor.Ins, bufName, fieldName);
return type.Apply(CsUnderingDeserializeVisitor.Ins, bufName, fieldName, 0);
}
}

View File

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

View File

@ -4,130 +4,155 @@ using Luban.Job.Common.Utils;
namespace Luban.Job.Common.TypeVisitors
{
class CsUnderingDeserializeVisitor : ITypeFuncVisitor<string, string, string>
class CsUnderingDeserializeVisitor : ITypeFuncVisitor<string, string, int, string>
{
public static CsUnderingDeserializeVisitor Ins { get; } = new CsUnderingDeserializeVisitor();
public string Accept(TBool type, string bufName, string fieldName)
public string Accept(TBool type, string bufName, string fieldName, int depth)
{
return $"{fieldName} = {bufName}.ReadBool();";
}
public string Accept(TByte type, string bufName, string fieldName)
public string Accept(TByte type, string bufName, string fieldName, int depth)
{
return $"{fieldName} = {bufName}.ReadByte();";
}
public string Accept(TShort type, string bufName, string fieldName)
public string Accept(TShort type, string bufName, string fieldName, int depth)
{
return $"{fieldName} = {bufName}.ReadShort();";
}
public string Accept(TFshort type, string bufName, string fieldName)
public string Accept(TFshort type, string bufName, string fieldName, int depth)
{
return $"{fieldName} = {bufName}.ReadFshort();";
}
public string Accept(TInt type, string bufName, string fieldName)
public string Accept(TInt type, string bufName, string fieldName, int depth)
{
return $"{fieldName} = {bufName}.ReadInt();";
}
public string Accept(TFint type, string bufName, string fieldName)
public string Accept(TFint type, string bufName, string fieldName, int depth)
{
return $"{fieldName} = {bufName}.ReadFint();";
}
public string Accept(TLong type, string bufName, string fieldName)
public string Accept(TLong type, string bufName, string fieldName, int depth)
{
return $"{fieldName} = {bufName}.ReadLong();";
}
public string Accept(TFlong type, string bufName, string fieldName)
public string Accept(TFlong type, string bufName, string fieldName, int depth)
{
return $"{fieldName} = {bufName}.ReadFlong();";
}
public string Accept(TFloat type, string bufName, string fieldName)
public string Accept(TFloat type, string bufName, string fieldName, int depth)
{
return $"{fieldName} = {bufName}.ReadFloat();";
}
public string Accept(TDouble type, string bufName, string fieldName)
public string Accept(TDouble type, string bufName, string fieldName, int depth)
{
return $"{fieldName} = {bufName}.ReadDouble();";
}
public string Accept(TEnum type, string bufName, string fieldName)
public string Accept(TEnum type, string bufName, string fieldName, int depth)
{
return $"{fieldName} = ({ type.Apply(CsUnderingDefineTypeName.Ins)}){bufName}.ReadInt();";
}
public string Accept(TString type, string bufName, string fieldName)
public string Accept(TString type, string bufName, string fieldName, int depth)
{
return $"{fieldName} = {bufName}.ReadString();";
}
public string Accept(TBytes type, string bufName, string fieldName)
public string Accept(TBytes type, string bufName, string fieldName, int depth)
{
return $"{fieldName} = {bufName}.ReadBytes();";
}
public string Accept(TText type, string bufName, string fieldName)
public string Accept(TText type, string bufName, string fieldName, int depth)
{
return $"{fieldName}{TText.L10N_FIELD_SUFFIX} = {bufName}.ReadString(); {fieldName} = {bufName}.ReadString();";
}
public string Accept(TBean type, string bufName, string fieldName)
public string Accept(TBean type, string bufName, string fieldName, int depth)
{
string src = $"{type.Bean.FullName}.Deserialize{type.Bean.Name}({bufName})";
return $"{fieldName} = {ExternalTypeUtil.CsCloneToExternal(type.Bean.FullName, src)};";
}
public string Accept(TArray type, string bufName, string fieldName)
public string Accept(TArray type, string bufName, string fieldName, int depth)
{
return $"{{int n = System.Math.Min({bufName}.ReadSize(), {bufName}.Size);{fieldName} = new {type.ElementType.Apply(CsDefineTypeName.Ins)}[n];for(var i = 0 ; i < n ; i++) {{ {type.ElementType.Apply(CsDefineTypeName.Ins)} _e;{type.ElementType.Apply(this, bufName, "_e")} {fieldName}[i] = _e;}}}}";
string __n = $"__n{depth}";
string __e = $"__e{depth}";
string __index = $"__index{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} = System.Math.Min({bufName}.ReadSize(), {bufName}.Size);{fieldName} = new {typeStr};for(var {__index} = 0 ; {__index} < {__n} ; {__index}++) {{ {type.ElementType.Apply(CsDefineTypeName.Ins)} {__e};{type.ElementType.Apply(this, bufName, $"{__e}", depth + 1)} {fieldName}[{__index}] = {__e};}}}}";
}
public string Accept(TList type, string bufName, string fieldName)
public string Accept(TList type, string bufName, string fieldName, int depth)
{
return $"{{int n = System.Math.Min({bufName}.ReadSize(), {bufName}.Size);{fieldName} = new {type.Apply(CsDefineTypeName.Ins)}(n);for(var i = 0 ; i < n ; i++) {{ {type.ElementType.Apply(CsDefineTypeName.Ins)} _e; {type.ElementType.Apply(this, bufName, "_e")} {fieldName}.Add(_e);}}}}";
string n = $"n{depth}";
string _e = $"_e{depth}";
string i = $"i{depth}";
return $"{{int {n} = System.Math.Min({bufName}.ReadSize(), {bufName}.Size);{fieldName} = new {type.Apply(CsDefineTypeName.Ins)}({n});for(var {i} = 0 ; {i} < {n} ; {i}++) {{ {type.ElementType.Apply(CsDefineTypeName.Ins)} {_e}; {type.ElementType.Apply(this, bufName, $"{_e}", depth + 1)} {fieldName}.Add({_e});}}}}";
}
public string Accept(TSet type, string bufName, string fieldName)
public string Accept(TSet type, string bufName, string fieldName, int depth)
{
return $"{{int n = System.Math.Min({bufName}.ReadSize(), {bufName}.Size);{fieldName} = new {type.Apply(CsDefineTypeName.Ins)}(/*n * 3 / 2*/);for(var i = 0 ; i < n ; i++) {{ {type.ElementType.Apply(CsDefineTypeName.Ins)} _e; {type.ElementType.Apply(this, bufName, "_e")} {fieldName}.Add(_e);}}}}";
string n = $"n{depth}";
string _e = $"_e{depth}";
string i = $"i{depth}";
return $"{{int {n} = System.Math.Min({bufName}.ReadSize(), {bufName}.Size);{fieldName} = new {type.Apply(CsDefineTypeName.Ins)}(/*{n} * 3 / 2*/);for(var {i} = 0 ; {i} < {n} ; {i}++) {{ {type.ElementType.Apply(CsDefineTypeName.Ins)} {_e}; {type.ElementType.Apply(this, bufName, $"{_e}", +1)} {fieldName}.Add({_e});}}}}";
}
public string Accept(TMap type, string bufName, string fieldName)
public string Accept(TMap type, string bufName, string fieldName, int depth)
{
return $"{{int n = System.Math.Min({bufName}.ReadSize(), {bufName}.Size);{fieldName} = new {type.Apply(CsDefineTypeName.Ins)}(n * 3 / 2);for(var i = 0 ; i < n ; i++) {{ {type.KeyType.Apply(CsDefineTypeName.Ins)} _k; {type.KeyType.Apply(this, bufName, "_k")} {type.ValueType.Apply(CsDefineTypeName.Ins)} _v; {type.ValueType.Apply(this, bufName, "_v")} {fieldName}.Add(_k, _v);}}}}";
string n = $"n{depth}";
string _k = $"_k{depth}";
string _v = $"_v{depth}";
string i = $"i{depth}";
return $"{{int {n} = System.Math.Min({bufName}.ReadSize(), {bufName}.Size);{fieldName} = new {type.Apply(CsDefineTypeName.Ins)}({n} * 3 / 2);for(var {i} = 0 ; {i} < {n} ; {i}++) {{ {type.KeyType.Apply(CsDefineTypeName.Ins)} {_k}; {type.KeyType.Apply(this, bufName, _k, depth + 1)} {type.ValueType.Apply(CsDefineTypeName.Ins)} {_v}; {type.ValueType.Apply(this, bufName, _v, depth + 1)} {fieldName}.Add({_k}, {_v});}}}}";
}
public static string VectorName => (DefAssemblyBase.IsUseUnityVectors ? "UnityVector" : "Vector");
public string Accept(TVector2 type, string bufName, string fieldName)
public string Accept(TVector2 type, string bufName, string fieldName, int depth)
{
string src = $"{bufName}.Read{VectorName}2()";
return $"{fieldName} = {ExternalTypeUtil.CsCloneToExternal("vector2", src)};";
}
public string Accept(TVector3 type, string bufName, string fieldName)
public string Accept(TVector3 type, string bufName, string fieldName, int depth)
{
string src = $"{bufName}.Read{VectorName}3()";
return $"{fieldName} = {ExternalTypeUtil.CsCloneToExternal("vector3", src)};";
}
public string Accept(TVector4 type, string bufName, string fieldName)
public string Accept(TVector4 type, string bufName, string fieldName, int depth)
{
string src = $"{bufName}.Read{VectorName}4()";
return $"{fieldName} = {ExternalTypeUtil.CsCloneToExternal("vector4", src)};";
}
public string Accept(TDateTime type, string bufName, string fieldName)
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

@ -0,0 +1,43 @@
using Luban.Job.Common.Types;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Luban.Job.Common.TypeVisitors
{
public class GDScriptDefineTypeName : DecoratorFuncVisitor<string>
{
public static PyDefineTypeName Ins { get; } = new PyDefineTypeName();
public override string DoAccept(TType type)
{
throw new System.NotSupportedException();
}
public override string Accept(TEnum type)
{
return type.DefineEnum.GDScriptFullName;
}
public override string Accept(TBean type)
{
return type.Bean.GDScriptFullName;
}
public override string Accept(TVector2 type)
{
return "Vector2";
}
public override string Accept(TVector3 type)
{
return "Vector3";
}
public override string Accept(TVector4 type)
{
return "Vector4";
}
}
}

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,6 +58,12 @@ namespace Luban.Job.Common.TypeVisitors
public override string Accept(TDateTime type)
{
return "Long";
}
public override string Accept(TEnum type)
{
//return type.DefineEnum.FullNameWithTopModule;
return "Integer";
}
}

View File

@ -56,9 +56,10 @@ namespace Luban.Job.Common.TypeVisitors
return type.IsNullable ? "Double" : "double";
}
public string Accept(TEnum type)
public virtual string Accept(TEnum type)
{
return type.DefineEnum.FullNameWithTopModule;
//return type.DefineEnum.FullNameWithTopModule;
return type.IsNullable ? "Integer" : "int";
}
public string Accept(TString type)
@ -118,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

@ -15,10 +15,21 @@ namespace Luban.Job.Common.Types
public override TType ElementType { get; }
public override string TypeName => "array";
public int Dimension { get; } = 1;
public TType FinalElementType { get; protected set; }
private TArray(bool isNullable, Dictionary<string, string> tags, TType elementType) : base(isNullable, tags)
{
ElementType = elementType;
if (ElementType.TypeName == "array")
{
Dimension = (ElementType as TArray).Dimension + 1;
FinalElementType = (ElementType as TArray).FinalElementType;
}
else
{
FinalElementType = elementType;
}
}
public override bool TryParseFrom(string s)

View File

@ -20,6 +20,8 @@ namespace Luban.Job.Common.Types
public abstract string TypeName { get; }
public int CollectionLevel { get; set; }
public bool HasTag(string attrName)
{
return Tags != null && Tags.ContainsKey(attrName);

View File

@ -81,7 +81,7 @@ namespace Luban.Job.Common.Utils
{
++braceDepth;
}
else if (c == ')' || c == ')' || c == '}')
else if (c == ')' || c == ']' || c == '}')
{
--braceDepth;
}
@ -119,7 +119,7 @@ namespace Luban.Job.Common.Utils
{
++braceDepth;
}
else if (c == ')' || c == ')' || c == '}')
else if (c == ')' || c == ']' || c == '}')
{
--braceDepth;
}
@ -137,6 +137,44 @@ namespace Luban.Job.Common.Utils
}
public static string TrimBracePairs(string rawType)
{
while (rawType.Length > 0 && rawType[0] == '(')
{
int braceDepth = 0;
int level1Left = -1;
int level1Right = -1;
for (int i = 0; i < rawType.Length; i++)
{
if (rawType[i] == '(')
{
braceDepth++;
if (level1Left < 0)
{
level1Left = i;
}
}
if (rawType[i] == ')')
{
braceDepth--;
if (level1Right < 0 && braceDepth == 0)
{
level1Right = i;
break;
}
}
}
if (level1Left >= 0 && level1Right == rawType.Length - 1)
{
rawType = rawType.Substring(1, rawType.Length - 2);
}
else
{
break;
}
}
return rawType;
}
public static string TrimBracePairs2(string rawType, bool soft = false)
{
while (rawType.Length > 0 && rawType[0] == '(')
{
@ -146,7 +184,14 @@ namespace Luban.Job.Common.Utils
}
else
{
throw new Exception($"type:{rawType} brace not match");
if (soft)
{
return rawType;
}
else
{
throw new Exception($"type:{rawType} brace not match");
}
}
}
return rawType;
@ -200,7 +245,7 @@ namespace Luban.Job.Common.Utils
return (typeStr, attrs);
}
public static bool ParseOrientation(string value)
public static bool ParseOrientation(string value)
{
switch (value.Trim())
{
@ -210,9 +255,9 @@ namespace Luban.Job.Common.Utils
case "c":
case "column": return false;
default:
{
throw new Exception($"orientation 属性值只能为row|r|column|c");
}
{
throw new Exception($"orientation 属性值只能为row|r|column|c");
}
}
}
@ -265,7 +310,8 @@ namespace Luban.Job.Common.Utils
case ELanguage.PYTHON:
case ELanguage.RUST:
case ELanguage.PROTOBUF:
return System.Web.HttpUtility.HtmlEncode(comment).Replace("\n", "<br/>");
case ELanguage.GDSCRIPT:
return System.Web.HttpUtility.HtmlEncode(comment).Replace("\n", "<br/>");
default: throw new Exception($"unknown language:{curLan}");
}
}
@ -291,6 +337,7 @@ namespace Luban.Job.Common.Utils
case "rust": return ELanguage.RUST;
case "pb":
case "protobuf": return ELanguage.PROTOBUF;
case "gdscript": return ELanguage.GDSCRIPT;
default: throw new ArgumentException($"parse lan:'{lan}' fail");
}
}

View File

@ -29,6 +29,13 @@ namespace Luban.Job.Common.Utils
the code is regenerated.
</auto-generated>
'''
";
const string AUTO_GENERATE_GDScript= @"# <auto-generated>
# This code was generated by a tool.
# Changes to this file may cause incorrect behavior and will be lost if
# the code is regenerated.
# </auto-generated>
";
public static string ConcatAutoGenerationHeader(string txt, ELanguage lan)
@ -37,6 +44,7 @@ namespace Luban.Job.Common.Utils
{
case ELanguage.LUA: return AUTO_GENERATE_LUA + txt;
case ELanguage.PYTHON: return AUTO_GENERATE_PYTHON + txt;
case ELanguage.GDSCRIPT: return AUTO_GENERATE_GDScript + txt;
default: return AUTO_GENERATE_C_LIKE + txt;
}
}
@ -47,6 +55,7 @@ namespace Luban.Job.Common.Utils
{
case ELanguage.LUA: return AUTO_GENERATE_LUA;
case ELanguage.PYTHON: return AUTO_GENERATE_PYTHON;
case ELanguage.GDSCRIPT: return AUTO_GENERATE_GDScript;
default: return AUTO_GENERATE_C_LIKE;
}
}

View File

@ -19,9 +19,9 @@ namespace Luban.Job.Common.Utils
case ELanguage.TYPESCRIPT: return fullName.Replace('.', '/') + ".ts";
case ELanguage.RUST: return fullName.Replace('.', '_') + ".rs";
case ELanguage.PROTOBUF: return fullName.Replace('.', '_') + ".pb";
case ELanguage.GDSCRIPT: return fullName.Replace('.', '_') + ".gd";
default: throw new NotSupportedException();
}
}
public static string GetCsDefTypePath(string fullName)
@ -44,7 +44,6 @@ namespace Luban.Job.Common.Utils
return fullName.Replace('.', '_');
}
public static string GetCppDefTypeCppFilePath(string fullName)
{
return fullName + ".cpp";
@ -73,6 +72,7 @@ namespace Luban.Job.Common.Utils
{ "erlang", ELanguage.ERLANG },
{ "rust", ELanguage.RUST },
{ "protobuf", ELanguage.PROTOBUF },
{ "gdscript", ELanguage.GDSCRIPT },
};
public static ELanguage GetLanguage(string genType)
@ -103,6 +103,7 @@ namespace Luban.Job.Common.Utils
ELanguage.RUST => "rust",
ELanguage.PROTOBUF => "protobuf",
ELanguage.FLATBUFFERS => "flatbuffers",
ELanguage.GDSCRIPT => "gdscript",
_ => throw new Exception($"not support common template dir for lan:{lan}"),
};
}
@ -110,8 +111,10 @@ namespace Luban.Job.Common.Utils
private static readonly Dictionary<string, string> s_name2Suxxifx = new()
{
{ "json", "json" },
{ "bson", "bson" },
{ "lua", "lua" },
{ "bin", "bytes" },
{ "bidx", "bytes" },
{ "xml", "xml" },
{ "yaml", "yml" },
{ "yml", "yml" },

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";
}
}
}

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