-
Notifications
You must be signed in to change notification settings - Fork 0
/
configfile.go
133 lines (114 loc) · 3.17 KB
/
configfile.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
package main
import (
"fmt"
"os"
"path/filepath"
"time"
"github.com/adrg/xdg"
"gopkg.in/yaml.v3"
)
// ConfigFile .
type ConfigFile struct {
Presets map[string]ConfigPreset `yaml:"presets"`
}
// ConfigPreset .
type ConfigPreset struct {
Values []ConfigPresetValue `yaml:"values"`
}
// ConfigPresetValue .
type ConfigPresetValue struct {
ID ControlID `yaml:"id"`
Value int32 `yaml:"value"`
}
func LoadConfigFile() (ConfigFile, error) {
configFilePath, err := xdg.ConfigFile("webcam/config.yml")
if err != nil {
return ConfigFile{}, fmt.Errorf("can't get config file path: %w", err)
}
configDir := filepath.Dir(configFilePath)
if err := os.MkdirAll(configDir, 0700); err != nil {
return ConfigFile{}, fmt.Errorf("could not create directory for config file: %w", err)
}
var config ConfigFile
configData, err := os.ReadFile(configFilePath)
if err == nil {
if err := yaml.Unmarshal(configData, &config); err != nil {
return ConfigFile{}, fmt.Errorf("error parsing config gile: %w", err)
}
}
if config.Presets == nil {
config.Presets = make(map[string]ConfigPreset)
}
return config, nil
}
func SaveConfigFile(config ConfigFile) error {
configFilePath, err := xdg.ConfigFile("webcam/config.yml")
if err != nil {
return fmt.Errorf("can't get config file path: %w", err)
}
data, err := yaml.Marshal(&config)
if err != nil {
return fmt.Errorf("could not render config file: %w", err)
}
if err := os.WriteFile(configFilePath, data, 0700); err != nil {
return fmt.Errorf("could not write confi gile: %w", err)
}
return nil
}
func newPreset(wc *Webcam) (ConfigPreset, error) {
var values []ConfigPresetValue
controls := wc.getControls()
for _, c := range controls {
values = append(values, ConfigPresetValue{
ID: c.ID,
Value: c.Value,
})
}
return ConfigPreset{
Values: values,
}, nil
}
func applyPreset(wc *Webcam, preset ConfigPreset) error {
presetValuesMap := make(map[ControlID]ConfigPresetValue)
for _, v := range preset.Values {
presetValuesMap[v.ID] = v
}
allControls := wc.getControls()
var boolAndMenuControls []Control
var integerControls []Control
for _, c := range allControls {
if c.Type == c_menu || c.Type == c_bool {
boolAndMenuControls = append(boolAndMenuControls, c)
} else {
integerControls = append(integerControls, c)
}
}
// my webcam is not correctly reporting locked controls so we try to set
// all controls a number of times hoping that whatever controls are locking
// other controls are resolved during the rety process.
for _, controls := range [][]Control{boolAndMenuControls, integerControls} {
todo := make(map[ControlID]any)
for _, c := range controls {
todo[c.ID] = struct{}{}
}
var retries int
for len(todo) > 0 && (retries < len(todo)*10) {
// rand.Shuffle(len(controls), func(i, j int) {
// controls[i], controls[j] = controls[j], controls[i]
// })
for _, v := range controls {
if _, ok := todo[v.ID]; !ok {
continue
}
if err := wc.webcam.SetControl(v.ID, presetValuesMap[v.ID].Value); err != nil {
time.Sleep(25 * time.Millisecond)
retries++
continue
}
time.Sleep(5 * time.Millisecond)
delete(todo, v.ID)
}
}
}
return nil
}