From fb63898043ced6b32f43e8cc38879920ee0f5ce4 Mon Sep 17 00:00:00 2001 From: zijiren233 Date: Wed, 16 Oct 2024 18:04:24 +0800 Subject: [PATCH] fix: init settings --- internal/bootstrap/setting.go | 59 +++---------------------- internal/settings/bool.go | 13 +++--- internal/settings/floate64.go | 13 +++--- internal/settings/int64.go | 13 +++--- internal/settings/setting.go | 81 +++++++++++++++++++++++++++++++++++ internal/settings/string.go | 13 +++--- 6 files changed, 120 insertions(+), 72 deletions(-) diff --git a/internal/bootstrap/setting.go b/internal/bootstrap/setting.go index e206db62..d097fd2c 100644 --- a/internal/bootstrap/setting.go +++ b/internal/bootstrap/setting.go @@ -6,71 +6,28 @@ import ( "github.com/synctv-org/synctv/internal/db" "github.com/synctv-org/synctv/internal/model" "github.com/synctv-org/synctv/internal/settings" - "github.com/zijiren233/gencontainer/heap" ) -var _ heap.Interface[maxHeapItem] = (*maxHeap)(nil) - -type maxHeapItem struct { - priority int - settings.Setting -} - -type maxHeap struct { - items []maxHeapItem -} - -func (h *maxHeap) Len() int { - return len(h.items) -} - -func (h *maxHeap) Less(i, j int) bool { - return h.items[i].priority > h.items[j].priority -} - -func (h *maxHeap) Swap(i, j int) { - h.items[i], h.items[j] = h.items[j], h.items[i] -} - -func (h *maxHeap) Push(x maxHeapItem) { - h.items = append(h.items, x) -} - -func (h *maxHeap) Pop() maxHeapItem { - n := len(h.items) - x := h.items[n-1] - h.items = h.items[:n-1] - return x -} - func InitSetting(ctx context.Context) error { - ss := []settings.Setting{} - for _, s := range settings.Settings { - ss = append(ss, s) - } - return initAndFixSettings(ss) + return initAndFixSettings() } func settingEqual(s *model.Setting, b settings.Setting) bool { return s.Type == b.Type() && s.Group == b.Group() && s.Name == b.Name() } -func initAndFixSettings(ss []settings.Setting) error { +func initAndFixSettings() error { settingsCache, err := db.GetSettingItemsToMap() if err != nil { return err } var setting *model.Setting - list := new(maxHeap) - for _, s := range ss { - heap.Push(list, maxHeapItem{ - priority: s.InitPriority(), - Setting: s, - }) - } - for list.Len() > 0 { - b := heap.Pop(list) + for { + b, ok := settings.PopNeedInit() + if !ok { + return nil + } if sc, ok := settingsCache[b.Name()]; ok && settingEqual(sc, b) { setting = sc @@ -95,6 +52,4 @@ func initAndFixSettings(ss []settings.Setting) error { } } } - - return nil } diff --git a/internal/settings/bool.go b/internal/settings/bool.go index e799a265..cc35c3f6 100644 --- a/internal/settings/bool.go +++ b/internal/settings/bool.go @@ -78,10 +78,6 @@ func newBool(name string, value bool, group model.SettingGroup, options ...BoolS return b } -func (b *Bool) SetInitPriority(priority int) { - b.initPriority = priority -} - func (b *Bool) SetBeforeInit(beforeInit func(BoolSetting, bool) (bool, error)) { b.beforeInit = beforeInit } @@ -111,6 +107,10 @@ func (b *Bool) Get() bool { } func (b *Bool) Init(value string) error { + if b.Inited() { + return ErrSettingAlreadyInited + } + v, err := b.Parse(value) if err != nil { return err @@ -129,6 +129,8 @@ func (b *Bool) Init(value string) error { b.afterInit(b, v) } + b.inited = true + return nil } @@ -221,9 +223,10 @@ func CoverBoolSetting(k string, v bool, g model.SettingGroup, options ...BoolSet b := newBool(k, v, g, options...) Settings[k] = b if GroupSettings[g] == nil { - GroupSettings[g] = make(map[string]Setting) + GroupSettings[g] = make(map[model.SettingGroup]Setting) } GroupSettings[g][k] = b + pushNeedInit(b) return b } diff --git a/internal/settings/floate64.go b/internal/settings/floate64.go index 75a66e91..b6389f34 100644 --- a/internal/settings/floate64.go +++ b/internal/settings/floate64.go @@ -86,10 +86,6 @@ func newFloat64(name string, value float64, group model.SettingGroup, options .. return f } -func (f *Float64) SetInitPriority(priority int) { - f.initPriority = priority -} - func (f *Float64) SetBeforeInit(beforeInit func(Float64Setting, float64) (float64, error)) { f.beforeInit = beforeInit } @@ -122,6 +118,10 @@ func (f *Float64) Stringify(value float64) string { } func (f *Float64) Init(value string) error { + if f.Inited() { + return ErrSettingAlreadyInited + } + v, err := f.Parse(value) if err != nil { return err @@ -140,6 +140,8 @@ func (f *Float64) Init(value string) error { f.afterInit(f, v) } + f.inited = true + return nil } @@ -239,9 +241,10 @@ func CoverFloat64Setting(k string, v float64, g model.SettingGroup, options ...F f := newFloat64(k, v, g, options...) Settings[k] = f if GroupSettings[g] == nil { - GroupSettings[g] = make(map[string]Setting) + GroupSettings[g] = make(map[model.SettingGroup]Setting) } GroupSettings[g][k] = f + pushNeedInit(f) return f } diff --git a/internal/settings/int64.go b/internal/settings/int64.go index fe6c9a8f..c6b5f49f 100644 --- a/internal/settings/int64.go +++ b/internal/settings/int64.go @@ -85,10 +85,6 @@ func newInt64(name string, value int64, group model.SettingGroup, options ...Int return i } -func (i *Int64) SetInitPriority(priority int) { - i.initPriority = priority -} - func (i *Int64) SetBeforeInit(beforeInit func(Int64Setting, int64) (int64, error)) { i.beforeInit = beforeInit } @@ -121,6 +117,10 @@ func (i *Int64) Stringify(value int64) string { } func (i *Int64) Init(value string) error { + if i.Inited() { + return ErrSettingAlreadyInited + } + v, err := i.Parse(value) if err != nil { return err @@ -139,6 +139,8 @@ func (i *Int64) Init(value string) error { i.afterInit(i, v) } + i.inited = true + return nil } @@ -238,9 +240,10 @@ func CoverInt64Setting(k string, v int64, g model.SettingGroup, options ...Int64 i := newInt64(k, v, g, options...) Settings[k] = i if GroupSettings[g] == nil { - GroupSettings[g] = make(map[string]Setting) + GroupSettings[g] = make(map[model.SettingGroup]Setting) } GroupSettings[g][k] = i + pushNeedInit(i) return i } diff --git a/internal/settings/setting.go b/internal/settings/setting.go index ed90a6ed..b338b70a 100644 --- a/internal/settings/setting.go +++ b/internal/settings/setting.go @@ -1,22 +1,94 @@ package settings import ( + "errors" "fmt" json "github.com/json-iterator/go" "github.com/synctv-org/synctv/internal/model" + "github.com/zijiren233/gencontainer/heap" ) +var ErrSettingAlreadyInited = errors.New("setting already inited") + +var _ heap.Interface[maxHeapItem] = (*maxHeap)(nil) + +type maxHeapItem struct { + priority int + Setting +} + +type maxHeap struct { + items []maxHeapItem +} + +func (h *maxHeap) Len() int { + return len(h.items) +} + +func (h *maxHeap) Less(i, j int) bool { + return h.items[i].priority > h.items[j].priority +} + +func (h *maxHeap) Swap(i, j int) { + h.items[i], h.items[j] = h.items[j], h.items[i] +} + +func (h *maxHeap) Push(x maxHeapItem) { + h.items = append(h.items, x) +} + +func (h *maxHeap) Pop() maxHeapItem { + n := len(h.items) + x := h.items[n-1] + h.items = h.items[:n-1] + return x +} + var ( Settings = make(map[string]Setting) GroupSettings = make(map[model.SettingGroup]map[string]Setting) + needInit = new(maxHeap) ) +func pushNeedInit(s Setting) { + if s == nil { + panic("push need init failed, setting is nil") + } + for i, item := range needInit.items { + if item.Setting.Name() == s.Name() { + heap.Remove(needInit, i) + break + } + } + heap.Push(needInit, maxHeapItem{ + priority: s.InitPriority(), + Setting: s, + }) +} + +func hasNeedInit() bool { + return needInit.Len() > 0 +} + +func PopNeedInit() (Setting, bool) { + for hasNeedInit() { + item := heap.Pop(needInit) + s := item.Setting + if s.Inited() { + continue + } + return s, true + } + return nil, false +} + type Setting interface { Name() string Type() model.SettingType Group() model.SettingGroup Init(string) error + Inited() bool SetInitPriority(int) InitPriority() int String() string @@ -49,6 +121,7 @@ type setting struct { settingType model.SettingType group model.SettingGroup initPriority int + inited bool } func (d *setting) Name() string { @@ -66,3 +139,11 @@ func (d *setting) Group() model.SettingGroup { func (d *setting) InitPriority() int { return d.initPriority } + +func (d *setting) Inited() bool { + return d.inited +} + +func (d *setting) SetInitPriority(priority int) { + d.initPriority = priority +} diff --git a/internal/settings/string.go b/internal/settings/string.go index 3e8cc684..30767ab2 100644 --- a/internal/settings/string.go +++ b/internal/settings/string.go @@ -85,10 +85,6 @@ func newString(name string, value string, group model.SettingGroup, options ...S return s } -func (s *String) SetInitPriority(priority int) { - s.initPriority = priority -} - func (s *String) SetBeforeInit(beforeInit func(StringSetting, string) (string, error)) { s.beforeInit = beforeInit } @@ -117,6 +113,10 @@ func (s *String) Stringify(value string) string { } func (s *String) Init(value string) error { + if s.Inited() { + return ErrSettingAlreadyInited + } + v, err := s.Parse(value) if err != nil { return err @@ -135,6 +135,8 @@ func (s *String) Init(value string) error { s.afterInit(s, v) } + s.inited = true + return nil } @@ -238,9 +240,10 @@ func CoverStringSetting(k string, v string, g model.SettingGroup, options ...Str s := newString(k, v, g, options...) Settings[k] = s if GroupSettings[g] == nil { - GroupSettings[g] = make(map[string]Setting) + GroupSettings[g] = make(map[model.SettingGroup]Setting) } GroupSettings[g][k] = s + pushNeedInit(s) return s }