forked from pion/mediadevices
/
state.go
64 lines (53 loc) · 1.52 KB
/
state.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
package driver
import "fmt"
// State represents driver's state
type State string
const (
// StateClosed means that the driver has not been opened. In this state,
// all information related to the hardware are still unknown. For example,
// if it's a video driver, the pixel format information is still unknown.
StateClosed State = "closed"
// StateOpened means that the driver is already opened and information about
// the hardware are already known and may be extracted from the driver.
StateOpened = "opened"
// StateRunning means that the driver has been sending data. The caller
// who started the driver may start reading data from the hardware.
StateRunning = "running"
)
// Update updates current state, s, to next. If f fails to execute,
// s will stay unchanged. Otherwise, s will be updated to next
func (s *State) Update(next State, f func() error) error {
type checkFunc func() error
m := map[State]checkFunc{
StateOpened: s.toOpened,
StateClosed: s.toClosed,
StateRunning: s.toRunning,
}
err := m[next]()
if err != nil {
return err
}
err = f()
if err == nil {
*s = next
}
return err
}
func (s *State) toOpened() error {
if *s != StateClosed {
return fmt.Errorf("invalid state: driver is already opened")
}
return nil
}
func (s *State) toClosed() error {
return nil
}
func (s *State) toRunning() error {
if *s == StateClosed {
return fmt.Errorf("invalid state: driver is closed")
}
if *s == StateRunning {
return fmt.Errorf("invalid state: driver is already running")
}
return nil
}