You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
synctv/internal/settings/setting.go

150 lines
2.8 KiB
Go

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 {
Setting
priority int
}
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
SetString(string) error
DefaultString() string
DefaultInterface() any
Interface() any
}
func SetValue(name string, value any) error {
s, ok := Settings[name]
if !ok {
return fmt.Errorf("setting %s not found", name)
}
switch s.Type() {
case model.SettingTypeBool:
return s.(BoolSetting).Set(json.Wrap(value).ToBool())
case model.SettingTypeInt64:
return s.(Int64Setting).Set(json.Wrap(value).ToInt64())
case model.SettingTypeFloat64:
return s.(Float64Setting).Set(json.Wrap(value).ToFloat64())
case model.SettingTypeString:
return s.(StringSetting).Set(json.Wrap(value).ToString())
}
return s.SetString(json.Wrap(value).ToString())
}
type setting struct {
name string
settingType model.SettingType
group model.SettingGroup
initPriority int
inited bool
}
func (d *setting) Name() string {
return d.name
}
func (d *setting) Type() model.SettingType {
return d.settingType
}
func (d *setting) Group() model.SettingGroup {
return d.group
}
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
}