【修复】修复cpp抽象bean不包含字段时,生成的bean代码包含两个空构造函数的bug

【特性】go支持多态普通表
【修复】修复java多态表 getAs 泛型函数的bug
【修复】修复python抽象bean不包含字段时, __init__ 为空,导致编译出错的bug.通过 新增 pass 行解决
【修复】修复java可空变量相关生成的bug
【修复】FileCleaner清理目录时,不再删除meta文件
【优化】优化python的Vector2类缩进过多的问题
【更新】更新 README.md
main
walon 2020-12-18 20:24:24 +08:00
parent 6e127e3b7a
commit 147ce91166
11 changed files with 71 additions and 32 deletions

View File

@ -12,7 +12,7 @@
## 介绍
luban是一个相当完备成熟的游戏配置解决方案,同时也可以用作通用型对象生成与缓存工具。
luban是一个比较完备的游戏配置解决方案,同时也可以用作通用型对象生成与缓存工具。
luban创新性提出 **定义 + 数据源** 的设计实现了完备的类型系统增强了excel格式同时提供json、xml、lua等多种数据源支持统一了数据定义、加载、检验、数据导出及代码生成的游戏配置Pipeline彻底解决了中大型项目中难以在excel中配置复杂数据以及一个项目中excel、json等多种的配置方案并存的问题。
@ -30,12 +30,13 @@ Luban另一优点是生成过程极快。对于普通的导表工具一个典
- [Excel 配置数据简介](docs/data_excel.md)
- [使用说明](docs/catalog.md)
- [常见问题](docs/faq.md)
- [示例项目](https://github.com/focus-creative-games/luban_examples)
## 特性
- 支持增强的excel格式可以在excel里比较简洁填写出任意复杂的数据。
- 支持excel族、json、xml、lua 多种数据格式
- 强大完备的类型系统。支持所有常见原生类型、容器类型list,set,map、枚举和结构、**多态结构**以及**可空类型**
- 灵活的数据源定义。一个表可以来自多个文件,或者一个文件内定义多个表或者一个表对应一个目录下所有文件。以及以上的组合
- 支持excel族、json、xml、lua 多种数据格式,基本统一了游戏内的配置数据
- 灵活的数据源定义。一个表可以来自多个文件或者一个文件内定义多个表或者一个表对应一个目录下所有文件,以及以上的组合。
- 强大完备的类型系统。支持所有常见原生类型、容器类型list,set,map、枚举和结构、**多态结构**以及**可空类型**。
- 支持表与字段级别分组。可以选择性地导出客户端或者服务器所用的表及字段。
- 多种导出数据格式支持。支持binary、json、lua 等导出数据格式。
- 支持数据标签。 可以选择导出符合要求的数据,发布正式数据时策划不必手动注释掉那些测试或者非正式数据了。
@ -71,9 +72,9 @@ Luban另一优点是生成过程极快。对于普通的导表工具一个典
- 其他所有支持lua的引擎和平台
- 其他所有支持js的引擎和平台
## 结构定义与配置表填写
## 使用预览
与常见的专注于excel的导表工具中定义和数据放在同一个excel文件的做法不同luban的定义与数据分离使用单独的xml定义 **表和结构**,数据文件只包含数据。
与常见的专注于excel的导表工具不同luban的定义与数据分离使用单独的xml定义 **表和结构**,数据文件只包含数据。
### 常规的原生数据
```
@ -414,7 +415,7 @@ luban支持横表与纵表默认为横表。对于单例表纵表填写更
</k15>
</data>
```
### json 数据源
### lua 数据源
定义
@ -496,7 +497,7 @@ luban支持横表与纵表默认为横表。对于单例表纵表填写更
```Lua
-- 直接 require 表
local data = require("<--output_data_dir lua>.TbFullTypes")
local data = require("<lua>.TbFullTypes")
-- 获取 key为1001的道具数据
local cfg = data[1]
print(cfg.X4)
@ -506,7 +507,7 @@ luban支持横表与纵表默认为横表。对于单例表纵表填写更
```C#
// 一行代码可以加载所有配置。 cfg.Tables 包含所有表的一个实例字段。
var tables = new cfg.Tables(file => return new ByteBuf(File.ReadAllBytes("<--output_data_dir>/" + file)));
var tables = new cfg.Tables(file => return new ByteBuf(File.ReadAllBytes("<数据路径>/" + file)));
// 访问一个单例表
Console.WriteLine(tables.TbGlobal.Name);
// 访问普通的 key-value 表

View File

@ -1,5 +1,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using Luban.Common.Utils;
namespace Luban.Client.Common.Utils
{
@ -67,7 +69,7 @@ namespace Luban.Client.Common.Utils
{
s_logger.Trace("remain file:{file}", file);
}
else
else if(!_ignoreFileExtensions.Contains(FileUtil.GetFileExtension(file)))
{
s_logger.Info("[remove] file: {file}", file);
File.Delete(file);
@ -76,7 +78,7 @@ namespace Luban.Client.Common.Utils
// 清除空目录
var subDirs = new List<string>(Directory.GetDirectories(dir, "*", SearchOption.AllDirectories));
subDirs.Sort((a, b) => -a.CompareTo(b));
subDirs.Sort((a, b) => -String.Compare(a, b, StringComparison.Ordinal));
foreach (var subDir in subDirs)
{
string fullSubDirPath = Path.GetFullPath(subDir);

View File

@ -22,6 +22,18 @@ namespace Luban.Common.Utils
return index >= 0 ? path[..index] : path;
}
public static string GetFileNameWithoutExt(string file)
{
int index = file.LastIndexOf('.');
return index >= 0 ? file.Substring(0, index) : file;
}
public static string GetFileExtension(string file)
{
int index = file.LastIndexOf('.');
return index >= 0 ? file.Substring(index + 1) : "";
}
public static string GetPathRelateRootFile(string rootFile, string file)
{
return Combine(GetParent(rootFile), file);

View File

@ -125,9 +125,14 @@ namespace Luban.Job.Cfg.DataVisitors
line.Append(type.Value);
}
private string EscapeString(string s)
{
return s.Replace("\\", "\\\\").Replace("'", "\\'");
}
public void Accept(DString type, StringBuilder line)
{
line.Append('\'').Append(type.Value).Append('\'');
line.Append('\'').Append(EscapeString(type.Value)).Append('\'');
}
public void Accept(DBytes type, StringBuilder line)
@ -137,7 +142,7 @@ namespace Luban.Job.Cfg.DataVisitors
public void Accept(DText type, StringBuilder line)
{
line.Append('\'').Append(type.Value).Append('\'');
line.Append('\'').Append(EscapeString(type.Value)).Append('\'');
}
public void Accept(DBean type, StringBuilder line)

View File

@ -59,7 +59,7 @@ namespace Luban.Job.Cfg.Defs
var table = field.Assembly.GetCfgTable(field.Ref.FirstTable);
if (field.IsNullable)
{
return $"this.{refVarName} = this.{name} != null ? (({table.FullNameWithTopModule})_tables.get(\"{tableName}\")).get({name}.Value) : null;";
return $"this.{refVarName} = this.{name} != null ? (({table.FullNameWithTopModule})_tables.get(\"{tableName}\")).get({name}) : null;";
}
else
{

View File

@ -51,6 +51,7 @@ class {{name}} : public {{if parent_def_type}} {{parent_def_type.cpp_full_name}}
}
{{~if !hierarchy_export_fields.empty?~}}
{{name}}({{- for field in hierarchy_export_fields }}{{cpp_define_type field.ctype}} {{field.name}}{{if !for.last}},{{end}} {{end}})
{{-if parent_def_type-}}
: {{parent_def_type.cpp_full_name}}({{ for field in parent_def_type.hierarchy_export_fields }}{{field.name}}{{if !for.last}}, {{end}}{{end}})
@ -61,7 +62,7 @@ class {{name}} : public {{if parent_def_type}} {{parent_def_type.cpp_full_name}}
this->{{field.cpp_style_name}} = {{field.name}};
{{~end~}}
}
{{~end~}}
virtual ~{{name}}() {}
bool deserialize(ByteBuf& _buf);

View File

@ -136,6 +136,7 @@ func NewChild{{go_full_name}}(_buf *serialization.ByteBuf) (_v interface{}, err
private static Template t_tableRender;
public string Render(DefTable p)
{
// TODO 目前只有普通表支持多态. 单例表和双key表都不支持
string package = "cfg";
var template = t_tableRender ??= Template.Parse(@"
{{-
@ -233,7 +234,16 @@ func New{{go_full_name}}(_buf *serialization.ByteBuf) (*{{go_full_name}}, error)
return nil, err2
} else {
_dataList = append(_dataList, _v)
{{~if value_type.is_dynamic ~}}
{{- for child in value_type.bean.hierarchy_not_abstract_children}}
if __v, __is := _v.(*{{child.go_full_name}}) ; __is {
dataMap[__v.{{index_field.cs_style_name}}] = _v
continue
}
{{-end}}
{{~else~}}
dataMap[_v.{{index_field.cs_style_name}}] = _v
{{~end~}}
}
}
return &{{go_full_name}}{_dataList:_dataList, _dataMap:dataMap}, nil

View File

@ -192,7 +192,8 @@ public final class {{name}}
public java.util.ArrayList<{{java_box_define_type value_type}}> getDataList() { return _dataList; }
{{if value_type.is_dynamic}}
public T getAs<T extends {{java_box_define_type value_type}}>({{java_define_type key_type1}} key1, {{java_define_type key_type2}} key2) { return (T)_dataMapMap.get(key1).get(key2); }
@SuppressWarnings(""unchecked"")
public <T extends {{java_box_define_type value_type}}> T getAs({{java_define_type key_type1}} key1, {{java_define_type key_type2}} key2) { return (T)_dataMapMap.get(key1).get(key2); }
{{end}}
public {{java_box_define_type value_type}} get({{java_define_type key_type1}} key1, {{java_define_type key_type2}} key2) { return _dataMapMap.get(key1).get(key2);}
@ -225,7 +226,8 @@ public final class {{name}}
public java.util.ArrayList<{{java_box_define_type value_type}}> getDataList() { return _dataList; }
{{~if value_type.is_dynamic~}}
public T getAs<T extends {{java_box_define_type value_type}}>({{java_box_define_type key_type}} key) { return (T)_dataMap.get(key); }
@SuppressWarnings(""unchecked"")
public <T extends {{java_box_define_type value_type}}> T getAs({{java_define_type key_type}} key) { return (T)_dataMap.get(key); }
{{~end~}}
public {{java_box_define_type value_type}} get({{java_define_type key_type}} key) { return _dataMap.get(key); }

View File

@ -102,6 +102,9 @@ class {{name}} {{if parent_def_type}}({{parent_def_type.py_full_name}}){{end}}:
{{~end~}}
{{py27_deserialize ('self.' + field.py_style_name) ('_json_[""' + field.name + '""]') field.ctype}}
{{~end~}}
{{~if export_fields.empty?}}
pass
{{~end~}}
");
var result = template.RenderCode(b);

View File

@ -102,6 +102,9 @@ class {{name}} {{if parent_def_type}}({{parent_def_type.py_full_name}}){{else if
{{~end~}}
{{py3_deserialize ('self.' + field.py_style_name) ('_json_[""' + field.name + '""]') field.ctype}}
{{~end~}}
{{~if export_fields.empty?}}
pass
{{~end~}}
");
var result = template.RenderCode(b);