Skip to content

Commit

Permalink
v1.0 支持使用js脚本扩展字段类型
Browse files Browse the repository at this point in the history
  • Loading branch information
821869798 committed Jan 23, 2024
1 parent 1fa5203 commit 42ad228
Show file tree
Hide file tree
Showing 30 changed files with 493 additions and 83 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v3
with:
go-version: '1.20'
go-version: '1.21'

- run: go build -o bin/${{ github.event.repository.name }}_linux_x64 .
- run: CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -o bin/${{ github.event.repository.name }}_win_x64.exe
Expand Down
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,11 +121,15 @@ table_export -g csv_test,csv_test.csv

# TODO

在1.0版本中会加入数据检测,自定义复合类型,自定义枚举,特殊后处理等功能。

目前1.0版本中已经支持,后续会更新使用文档
- 数据检测
- 自定义复合类型(使用go或者js脚本扩展)
- 自定义枚举

TODO :添加特殊后处理等功能。

## Credits

- [LuaTableOptimizer](https://github.com/lujian101/LuaTableOptimizer) 使用了lua表优化工具,在此基础上做了更进一步的优化
- [luban](https://github.com/focus-creative-games/luban) 使用了二进制序列化的代码和一些思路
- [luban](https://github.com/focus-creative-games/luban) 使用了二进制序列化的代码和一些思路
- [goja](https://github.com/dop251/goja) js的脚本引擎,使用js来扩展自定义类型和表后处理
90 changes: 90 additions & 0 deletions component/goja/table_engine/module.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package table_engine

import (
"github.com/821869798/table-export/config"
"github.com/821869798/table-export/field_type"
"github.com/dop251/goja"
"github.com/dop251/goja_nodejs/require"
_ "github.com/dop251/goja_nodejs/util"
)

type TableEngine struct {
runtime *goja.Runtime
//util *goja.Object
}

func (c *TableEngine) NewTableFieldClass(name string) *field_type.TableFieldClass {
return field_type.NewTableFieldClass(name)
}

func (c *TableEngine) NewTableFieldType(fieldType int) *field_type.TableFieldType {
return field_type.NewTableFieldType(field_type.EFieldType(fieldType))
}

func (c *TableEngine) NewTableFieldEnumType(name string) *field_type.TableFieldType {
return field_type.NewTableFieldEnumType(name)
}

func (c *TableEngine) NewTableFieldArrayType(value *field_type.TableFieldType) *field_type.TableFieldType {
return field_type.NewTableFieldArrayType(value)
}

func (c *TableEngine) NewTableFieldMapType(key *field_type.TableFieldType, value *field_type.TableFieldType) *field_type.TableFieldType {
return field_type.NewTableFieldMapType(key, value)
}

func (c *TableEngine) NewTableFieldClassType(class *field_type.TableFieldClass) *field_type.TableFieldType {
return field_type.NewTableFieldClassType(class)
}

//func (c *TableEngine) log(p func(string)) func(goja.FunctionCall) goja.Value {
// return func(call goja.FunctionCall) goja.Value {
// if format, ok := goja.AssertFunction(c.util.Get("format")); ok {
// ret, err := format(c.util, call.Arguments...)
// if err != nil {
// panic(err)
// }
//
// p(ret.String())
// } else {
// panic(c.runtime.NewTypeError("util.format is not a function"))
// }
//
// return nil
// }
//}

func Require(runtime *goja.Runtime, module *goja.Object) {
requireWithPrinter()(runtime, module)
}

func RequireWithPrinter() require.ModuleLoader {
return requireWithPrinter()
}

func requireWithPrinter() require.ModuleLoader {
return func(runtime *goja.Runtime, module *goja.Object) {
c := &TableEngine{
runtime: runtime,
}

//c.util = require.Require(runtime, "util").(*goja.Object)

o := module.Get("exports").(*goja.Object)
o.Set("NewTableFieldClass", c.NewTableFieldClass)
o.Set("NewTableFieldType", c.NewTableFieldType)
o.Set("NewTableFieldEnumType", c.NewTableFieldEnumType)
o.Set("NewTableFieldArrayType", c.NewTableFieldArrayType)
o.Set("NewTableFieldMapType", c.NewTableFieldMapType)
o.Set("NewTableFieldClassType", c.NewTableFieldClassType)
o.Set("TableConfig", config.GlobalConfig.Table)
}
}

func Enable(runtime *goja.Runtime) {
runtime.Set("tableEngine", require.Require(runtime, "tableEngine"))
}

func init() {
require.RegisterNativeModule("tableEngine", Require)
}
39 changes: 0 additions & 39 deletions config/config_rule.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,42 +42,3 @@ type RawMetaRuleUnitLua struct {
func (r *RawMetaRuleUnitLua) RuleExportType() ExportType {
return ExportType_Lua
}

type RawMetaRuleUnitCSBin struct {
CodeTempDir string `toml:"code_temp_dir"`
DataTempDir string `toml:"data_temp_dir"`
GenCodeDir string `toml:"gen_code_dir"`
DataBinDir string `toml:"data_bin_dir"`
GenCodeNamespace string `toml:"code_namespace"`
GenCodeHead string `toml:"gen_code_head"`
CodeNotFoundKey string `toml:"code_not_found_key"`
GenOptimizeData bool `toml:"gen_optimize"`
EnumFiles []string `toml:"enum_files"`
EnumDefinePrefix string `toml:"enum_define_prefix"`
ClassDefinePrefix string `toml:"class_define_prefix"`
BuiltinFieldTypes []string `toml:"builtin_field_types"`
}

func (r *RawMetaRuleUnitCSBin) RuleExportType() ExportType {
return ExportType_CS_Bin
}

func (r *RawMetaRuleUnitCSBin) ActiveOptimizeData() bool {
return r.GenOptimizeData
}

func (r *RawMetaRuleUnitCSBin) GetEnumFiles() []string {
return r.EnumFiles
}

func (r *RawMetaRuleUnitCSBin) GetEnumDefinePrefix() string {
return r.EnumDefinePrefix
}

func (r *RawMetaRuleUnitCSBin) GetClassDefinePrefix() string {
return r.ClassDefinePrefix
}

func (r *RawMetaRuleUnitCSBin) GetBuiltinFieldTypes() []string {
return r.BuiltinFieldTypes
}
45 changes: 45 additions & 0 deletions config/config_rule_csbin.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package config

type RawMetaRuleUnitCSBin struct {
CodeTempDir string `toml:"code_temp_dir"`
DataTempDir string `toml:"data_temp_dir"`
GenCodeDir string `toml:"gen_code_dir"`
DataBinDir string `toml:"data_bin_dir"`
GenCodeNamespace string `toml:"code_namespace"`
GenCodeHead string `toml:"gen_code_head"`
CodeNotFoundKey string `toml:"code_not_found_key"`
GenOptimizeData bool `toml:"gen_optimize"`
EnumFiles []string `toml:"enum_files"`
EnumDefinePrefix string `toml:"enum_define_prefix"`
ClassDefinePrefix string `toml:"class_define_prefix"`
BuiltinFieldTypes []string `toml:"builtin_field_types"`
ScriptFieldTypes []string `toml:"script_field_types"`
}

func (r *RawMetaRuleUnitCSBin) RuleExportType() ExportType {
return ExportType_CS_Bin
}

func (r *RawMetaRuleUnitCSBin) ActiveOptimizeData() bool {
return r.GenOptimizeData
}

func (r *RawMetaRuleUnitCSBin) GetEnumFiles() []string {
return r.EnumFiles
}

func (r *RawMetaRuleUnitCSBin) GetEnumDefinePrefix() string {
return r.EnumDefinePrefix
}

func (r *RawMetaRuleUnitCSBin) GetClassDefinePrefix() string {
return r.ClassDefinePrefix
}

func (r *RawMetaRuleUnitCSBin) GetBuiltinFieldTypes() []string {
return r.BuiltinFieldTypes
}

func (r *RawMetaRuleUnitCSBin) GetExtFieldTypeScriptPath() []string {
return r.ScriptFieldTypes
}
1 change: 1 addition & 0 deletions config/define.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,5 @@ type MetaRuleUnitPlus interface {
GetEnumDefinePrefix() string
GetClassDefinePrefix() string
GetBuiltinFieldTypes() []string
GetExtFieldTypeScriptPath() []string
}
1 change: 1 addition & 0 deletions convert/apiconvert/idatavisitor.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,5 @@ type IDataVisitor interface {
AcceptCommonMap(r map[interface{}]interface{}, KeyType *field_type.TableFieldType, ValueType *field_type.TableFieldType)
AcceptClass(r map[string]interface{}, class *field_type.TableFieldClass)
AcceptClassString(r map[string]string, class *field_type.TableFieldClass)
AcceptClassNull(class *field_type.TableFieldClass)
}
10 changes: 10 additions & 0 deletions convert/visitor/binary.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,3 +202,13 @@ func (b *BinaryVisitor) AcceptClassString(r map[string]string, class *field_type
}
}
}

func (b *BinaryVisitor) AcceptClassNull(class *field_type.TableFieldClass) {
for _, field := range class.AllFields() {
// 使用默认值解析
err := wrap.RunDataVisitorString(b, field.Type, "")
if err != nil {
slog.Fatalf("export binary AcceptClass failed: %v", err)
}
}
}
6 changes: 5 additions & 1 deletion convert/wrap/wrap_class.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ func (c *classWrap) DataVisitorString(visitor apiconvert.IDataVisitor, fieldType
}

func (c *classWrap) DataVisitorValue(visitor apiconvert.IDataVisitor, fieldType *field_type.TableFieldType, origin interface{}) error {
if origin == nil {
visitor.AcceptClassNull(fieldType.Class)
return nil
}
switch value := origin.(type) {
case map[string]interface{}:
visitor.AcceptClass(value, fieldType.Class)
Expand All @@ -44,7 +48,7 @@ func (c *classWrap) DataVisitorValue(visitor apiconvert.IDataVisitor, fieldType
case string:
return RunDataVisitorString(visitor, fieldType, value)
default:
return errors.New(fmt.Sprintf("[DataVisitorValue|map] no support type[%T]", origin))
return errors.New(fmt.Sprintf("[DataVisitorValue|class] no support type[%T]", origin))
}
}

Expand Down
19 changes: 12 additions & 7 deletions convert/wrap/wrap_double.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,16 +59,21 @@ func (b *doubleWrap) DataVisitorString(visitor apiconvert.IDataVisitor, fieldTyp
}

func (b *doubleWrap) DataVisitorValue(visitor apiconvert.IDataVisitor, fieldType *field_type.TableFieldType, origin interface{}) error {
value, ok := origin.(float64)
if ok {
switch value := origin.(type) {
case float64:
visitor.AcceptDouble(value)
return nil
case float32:
visitor.AcceptDouble(float64(value))
return nil
case int64:
visitor.AcceptDouble(float64(value))
return nil
case string:
return b.DataVisitorString(visitor, fieldType, value)
default:
return errors.New(fmt.Sprintf("[DataVisitorValue|double] no support type[%T]", origin))
}
stringValue, ok := origin.(string)
if ok {
return b.DataVisitorString(visitor, fieldType, stringValue)
}
return errors.New(fmt.Sprintf("[DataVisitorValue|double] no support type[%T]", origin))
}

func (b *doubleWrap) CodePrintValue(print apiconvert.ICodePrinter, fieldType *field_type.TableFieldType, fieldName string, reader string, depth int32) string {
Expand Down
3 changes: 3 additions & 0 deletions convert/wrap/wrap_enum.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ func (e *enumWrap) DataVisitorValue(visitor apiconvert.IDataVisitor, fieldType *
case int:
visitor.AcceptInt(int32(value))
return nil
case float64:
visitor.AcceptInt(int32(value))
return nil
case string:
return e.DataVisitorString(visitor, fieldType, value)
default:
Expand Down
3 changes: 3 additions & 0 deletions convert/wrap/wrap_float.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ func (b *floatWrap) DataVisitorValue(visitor apiconvert.IDataVisitor, fieldType
case float64:
visitor.AcceptFloat(float32(value))
return nil
case int64:
visitor.AcceptFloat(float32(value))
return nil
case string:
return b.DataVisitorString(visitor, fieldType, value)
default:
Expand Down
3 changes: 3 additions & 0 deletions convert/wrap/wrap_int.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ func (b *intWrap) DataVisitorValue(visitor apiconvert.IDataVisitor, fieldType *f
case int:
visitor.AcceptInt(int32(value))
return nil
case float64:
visitor.AcceptInt(int32(value))
return nil
case string:
return b.DataVisitorString(visitor, fieldType, value)
default:
Expand Down
22 changes: 15 additions & 7 deletions convert/wrap/wrap_long.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,16 +59,24 @@ func (b *longWrap) DataVisitorString(visitor apiconvert.IDataVisitor, fieldType
}

func (b *longWrap) DataVisitorValue(visitor apiconvert.IDataVisitor, fieldType *field_type.TableFieldType, origin interface{}) error {
value, ok := origin.(int64)
if ok {
switch value := origin.(type) {
case int64:
visitor.AcceptLong(value)
return nil
case int32:
visitor.AcceptLong(int64(value))
return nil
case int:
visitor.AcceptLong(int64(value))
return nil
case float64:
visitor.AcceptLong(int64(value))
return nil
case string:
return b.DataVisitorString(visitor, fieldType, value)
default:
return errors.New(fmt.Sprintf("[DataVisitorValue|long] no support type[%T]", origin))
}
stringValue, ok := origin.(string)
if ok {
return b.DataVisitorString(visitor, fieldType, stringValue)
}
return errors.New(fmt.Sprintf("[DataVisitorValue|long] no support type[%T]", origin))
}

func (b *longWrap) CodePrintValue(print apiconvert.ICodePrinter, fieldType *field_type.TableFieldType, fieldName string, reader string, depth int32) string {
Expand Down
12 changes: 12 additions & 0 deletions convert/wrap/wrap_uint.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,18 @@ func (b *uintWrap) DataVisitorValue(visitor apiconvert.IDataVisitor, fieldType *
case uint64:
visitor.AcceptUInt(uint32(value))
return nil
case int:
visitor.AcceptUInt(uint32(value))
return nil
case float64:
visitor.AcceptUInt(uint32(value))
return nil
case int64:
visitor.AcceptUInt(uint32(value))
return nil
case int32:
visitor.AcceptUInt(uint32(value))
return nil
case string:
return b.DataVisitorString(visitor, fieldType, value)
default:
Expand Down
Loading

0 comments on commit 42ad228

Please sign in to comment.