-
Notifications
You must be signed in to change notification settings - Fork 3
/
model.go
108 lines (91 loc) · 2.55 KB
/
model.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
package mode
import (
"context"
"time"
"github.com/smart-core-os/sc-api/go/traits"
"github.com/smart-core-os/sc-golang/pkg/resource"
)
// DefaultModes define the available modes of a Model if none are provided.
var DefaultModes = &traits.Modes{
Modes: []*traits.Modes_Mode{
{Name: "temperature", Ordered: true, Values: []*traits.Modes_Value{
{Name: "delicates"},
{Name: "medium"},
{Name: "whites"},
}},
{Name: "spin", Ordered: false, Values: []*traits.Modes_Value{
{Name: "auto"},
{Name: "slow"},
{Name: "fast"},
}},
},
}
// Model provides a data structure for supporting the Fan Speed trait.
// Unless configured otherwise, this model supports DefaultModes presets.
type Model struct {
modeValues *resource.Value // of *traits.ModeValues
modes *traits.Modes
}
// NewModel is like NewModelModes(DefaultModes).
func NewModel() *Model {
return NewModelModes(DefaultModes)
}
// NewModelModes constructs a Model with the given modes.
// The first value of each mode will be selected.
func NewModelModes(modes *traits.Modes) *Model {
modeValues := &traits.ModeValues{
Values: make(map[string]string),
}
for _, mode := range modes.Modes {
modeValues.Values[mode.Name] = mode.Values[0].Name
}
model := &Model{
modes: DefaultModes,
modeValues: resource.NewValue(
resource.WithInitialValue(modeValues),
),
}
return model
}
// ModeValues gets the current mode values.
func (m *Model) ModeValues(opts ...resource.ReadOption) *traits.ModeValues {
return m.modeValues.Get(opts...).(*traits.ModeValues)
}
func (m *Model) UpdateModeValues(values *traits.ModeValues, opts ...resource.WriteOption) (*traits.ModeValues, error) {
res, err := m.modeValues.Set(values, opts...)
if res == nil {
return nil, err
}
return res.(*traits.ModeValues), err
}
//goland:noinspection GoNameStartsWithPackageName
type ModeValuesChange struct {
Value *traits.ModeValues
ChangeTime time.Time
}
func (m *Model) PullModeValues(ctx context.Context, opts ...resource.ReadOption) <-chan ModeValuesChange {
send := make(chan ModeValuesChange)
go func() {
defer close(send)
for change := range m.modeValues.Pull(ctx, opts...) {
val := change.Value.(*traits.ModeValues)
select {
case <-ctx.Done():
return
case send <- ModeValuesChange{Value: val, ChangeTime: change.ChangeTime}:
}
}
}()
return send
}
func (m *Model) Modes() *traits.Modes {
return m.modes
}
func (m *Model) AvailableValues(modeName string) []*traits.Modes_Value {
for _, mode := range m.Modes().Modes {
if mode.Name == modeName {
return mode.Values
}
}
return nil
}