package f5 import ( "reflect" ) type MetaTable interface { IsNoLoad() bool Load() PreInit1() ElementsInit(int) PostInit1() } type LoadFromJson interface { LoadFromJsonStr(string) } type RawMetaTable[T any] struct { FileName string PrimKey string NoLoad bool rawList []*T } type IdMetaTable[T any] struct { RawMetaTable[T] idHash map[int64]*T } type NameMetaTable[T any] struct { RawMetaTable[T] nameHash map[string]*T } func (this *RawMetaTable[T]) Traverse(cb func (*T) bool) { for _, val := range this.rawList { if !cb(val) { break } } } func (this *RawMetaTable[T]) IsNoLoad() bool { return this.NoLoad } func (this *RawMetaTable[T]) PreInit1() { } func (this *RawMetaTable[T]) ElementInit(round int) { type RoundInit1 interface { Init1() } type RoundInit2 interface { Init2() } type RoundInit3 interface { Init3() } this.Traverse(func (obj *T) bool { var x interface{} = obj switch round { case 0: if init, ok := x.(RoundInit1); ok { init.Init1() } case 1: if init, ok := x.(RoundInit2); ok { init.Init2() } case 2: if init, ok := x.(RoundInit3); ok { init.Init3() } } return true }) } func (this *IdMetaTable[T]) GetById(id int64) *T { if v, ok := this.idHash[id]; ok { return v } else { return nil } } func (this *IdMetaTable[T]) Load() { if this.NoLoad { return } } func (this *NameMetaTable[T]) GetByName(name string) *T { if v, ok := this.nameHash[name]; ok { return v } else { return nil } } func (this *NameMetaTable[T]) Load() { if this.NoLoad { return } } func LoadMetaTable(table interface{}) { ele := reflect.ValueOf(table).Elem() for i := 0; i < ele.NumField(); i++ { var tbl MetaTable = ele.Field(i).Interface().(MetaTable) if !tbl.IsNoLoad() { tbl.PreInit1() } } for i := 0; i < ele.NumField(); i++ { var tbl MetaTable = ele.Field(i).Interface().(MetaTable) if !tbl.IsNoLoad() { tbl.Load() } } for i := 0; i < 3; i++ { for ii := 0; ii < ele.NumField(); ii++ { var tbl MetaTable = ele.Field(ii).Interface().(MetaTable) if !tbl.IsNoLoad() { tbl.Load() } tbl.ElementsInit(i) } } for i := 0; i < ele.NumField(); i++ { var tbl MetaTable = ele.Field(i).Interface().(MetaTable) if !tbl.IsNoLoad() { tbl.PostInit1() } } }