mirror of https://github.com/synctv-org/synctv
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.
150 lines
2.8 KiB
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
|
|
}
|