vRp.CD2g_test/planner/pce/tmpls/golang.go

232 lines
5.2 KiB
Go

package tmpls
import (
"fmt"
"github.com/kercylan98/minotaur/planner/pce"
"strings"
)
// NewGolang 创建一个 Golang 配置导出模板
func NewGolang(packageName string) *Golang {
return &Golang{
Package: packageName,
}
}
// Golang 配置导出模板
type Golang struct {
Package string
Templates []*pce.TmplStruct
}
func (slf *Golang) Render(templates ...*pce.TmplStruct) (string, error) {
slf.Templates = templates
return render(`// Code generated by minotaur. DO NOT EDIT.
package {{.Package}}
import (
jsonIter "github.com/json-iterator/go"
"github.com/kercylan98/minotaur/utils/log"
"github.com/kercylan98/minotaur/utils/hash"
"sync"
)
type Sign string
const (
{{- range .Templates}}
{{.Name}}Sign Sign = "{{.Name}}" // {{.Desc}}
{{- end}}
)
var (
json = jsonIter.ConfigCompatibleWithStandardLibrary
configs map[Sign]any
signs = []Sign{
{{- range .Templates}}
{{.Name}}Sign,
{{- end}}
}
mutex sync.Mutex
)
var (
{{- range .Templates}}
{{- if $.HasIndex .}}
{{.Name}} {{$.GetVariable .}} // {{.Desc}}
{{- end}}
{{- end}}
)
var (
{{- range .Templates}}
{{- if $.HasIndex .}}{{- else}}
{{.Name}} *{{$.GetConfigName .}} // {{.Desc}}
{{- end}}
{{- end}}
)
var (
{{- range .Templates}}
{{- if $.HasIndex .}}
_{{.Name}} {{$.GetVariable .}} // {{.Desc}}
{{- end}}
{{- end}}
)
var (
{{- range .Templates}}
{{- if $.HasIndex .}}{{- else}}
_{{.Name}} *{{$.GetConfigName .}} // {{.Desc}}
{{- end}}
{{- end}}
)
{{- range .Templates}}
// {{$.GetConfigName .}} {{.Desc}}
type {{$.GetConfigName .}} struct {
{{- range .Fields}}
{{- if .IsSlice}}
{{- if .IsStruct}}
{{.Name}} []*{{.Struct.Name}} // {{.Desc}}
{{- else}}
{{.Name}} []{{.Type}} // {{.Desc}}
{{- end}}
{{- else}}
{{- if .IsStruct}}
{{.Name}} *{{.Struct.Name}} // {{.Desc}}
{{- else}}
{{.Name}} {{.Type}} // {{.Desc}}
{{- end}}
{{- end}}
{{- end}}
}
func (slf *{{$.GetConfigName .}}) String() string {
if data, err := json.Marshal(slf); err == nil {
return string(data)
}
return "{}"
}
{{- end}}
{{- range .Templates}}
{{- range .AllChildren}}
// {{.Name}} {{.Desc}}
type {{.Name}} struct {
{{- range .Fields}}
{{- if .IsSlice}}
{{- if .IsStruct}}
{{.Name}} []*{{.Struct.Name}} // {{.Desc}}
{{- else}}
{{.Name}} []{{.Type}} // {{.Desc}}
{{- end}}
{{- else}}
{{- if .IsStruct}}
{{.Name}} *{{.Struct.Name}} // {{.Desc}}
{{- else}}
{{.Name}} {{.Type}} // {{.Desc}}
{{- end}}
{{- end}}
{{- end}}
}
{{- end}}
{{- end}}
// Load 通过自定义的方式加载配置
// - 通常建议使用该方法加载配置,因为仅执行一次加解锁
func LoadWithHandle(handle func(sign Sign, config any, json jsonIter.API) error) {
mutex.Lock()
defer mutex.Unlock()
for _, sign := range signs {
switch sign {
{{- range .Templates}}
case {{.Name}}Sign:
{{- if $.HasIndex .}}
temp := make({{$.GetVariable .}})
{{- else}}
temp := new({{$.GetConfigName .}})
{{- end}}
if err := handle(sign, &temp, json);err != nil {
log.Error("Config", log.String("Name", "{{.Name}}"), log.Bool("Invalid", true), log.Err(err))
}else {
_{{.Name}} = temp
}
{{- end}}
}
}
}
// LoadIndexConfig 通过 JSON 加载配置
func LoadWithJSON(sign Sign, data []byte) {
switch sign {
{{- range .Templates}}
case {{.Name}}Sign:
{{- if $.HasIndex .}}
temp := make({{$.GetVariable .}})
{{- else}}
temp := new({{$.GetConfigName .}})
{{- end}}
if err := json.Unmarshal(data, &{{.Name}}); err != nil {
log.Error("Config", log.String("Name", "{{.Name}}"), log.Bool("Invalid", true), log.Err(err))
return
}
_{{.Name}} = temp
{{- end}}
}
}
// Refresh 将加载后的配置刷新到线上
func Refresh() {
mutex.Lock()
defer mutex.Unlock()
cs := make(map[Sign]any)
{{- range .Templates}}
{{.Name}} = _{{.Name}}
cs[{{.Name}}Sign] = {{.Name}}
{{- end}}
configs = cs
}
// GetConfigs 获取所有配置
func GetConfigs() map[Sign]any {
mutex.Lock()
defer mutex.Unlock()
return hash.Copy(configs)
}
// GetConfigSigns 获取所有配置的标识
func GetConfigSigns() []Sign {
return signs
}
// Sync 同步操作配置
func Sync(handle func(configs map[Sign]any)) {
mutex.Lock()
defer mutex.Unlock()
handle(hash.Copy(configs))
}
`, slf)
}
func (slf *Golang) GetVariable(config *pce.TmplStruct) string {
var prefix string
for _, field := range config.Fields {
if field.IsIndex() {
prefix += fmt.Sprintf("map[%s]", field.Type)
}
}
return fmt.Sprintf("%s*%s", prefix, slf.GetConfigName(config))
}
func (slf *Golang) GetConfigName(config *pce.TmplStruct) string {
return strings.ReplaceAll(config.Name, "Config", "Configuration")
}
func (slf *Golang) HasIndex(config *pce.TmplStruct) bool {
return config.IndexCount > 0
}