-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathswitchboard.py
More file actions
152 lines (128 loc) · 4.1 KB
/
switchboard.py
File metadata and controls
152 lines (128 loc) · 4.1 KB
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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
"""SwitchBoard."""
def _idle(state_machine, switch_states, index):
"""
No switches are pressed.
press -> _one_switch
hold -> invalid
release -> invalid
"""
if switch_states[index] == 0:
# release
# invalid in this context, but invalid keystates happen,
# for example if a key is held while harmony is started
# TODO: issue a warning
return []
elif switch_states[index] == 1:
# press
state_machine.change_state(_one_switch)
return [[switch_states, index, 1, False]]
if switch_states[index] == 3:
# hold
return []
def _one_switch(state_machine, switch_states, index):
"""
One switch is pressed.
press -> _two_switch
hold -> nothing
release -> _idle
"""
if switch_states[index] == 0:
# release
state_machine.change_state(_idle)
return [
[switch_states, index, 1, True],
[switch_states, index, 0, True]]
elif switch_states[index] == 1:
# press
state_machine.change_state(_two_switch)
return [[switch_states, index, 1, True]]
elif switch_states[index] == 2:
# hold
return [[switch_states, index, 2, False]]
def _one_switch_used(state_machine, switch_states, index):
"""
One switch is pressed, but is has been used in a chord already.
press -> _two_switch
hold -> nothing
release -> _idle
"""
if switch_states[index] == 0:
# release
state_machine.change_state(_idle)
return [[switch_states, index, 0, False]]
elif switch_states[index] == 1:
# press
state_machine.change_state(_two_switch)
return [[switch_states, index, 1, True]]
elif switch_states[index] == 2:
# hold
return [[switch_states, index, 2, False]]
def _two_switch(state_machine, switch_states, index):
"""
Two switches are pressed.
press -> _many_switch
hold -> nothing
release -> _one_switch_used
"""
if switch_states[index] == 0:
# release
state_machine.change_state(_one_switch_used)
return [[switch_states, index, 0, True]]
elif switch_states[index] == 1:
# press
state_machine.change_state(_many_switch)
return [[switch_states, index, 1, False]]
elif switch_states[index] == 2:
# hold
return [[switch_states, index, 2, True]]
def _many_switch(state_machine, switch_states, index):
"""
More than two switches are or were pressed.
This state stays active until we can safely return to _idle.
press -> nothing
hold -> nothing
release -> _idle if num_pressed == 0
"""
if switch_states[index] == 0:
# release
if switch_states.count(0) == len(switch_states):
state_machine.change_state(_idle)
return [[switch_states, index, 0, False]]
elif switch_states[index] == 1:
# press
return [[switch_states, index, 1, False]]
elif switch_states[index] == 2:
# hold
return [[switch_states, index, 2, False]]
class SwitchBoard(object):
"""Keep track of key states and determine chord state."""
def __init__(self, config):
"""Store basic info."""
self._state = _idle
num_switches = config['config']['n_switches']
self._switches = []
for i in range(num_switches):
self._switches.append(config['config']['switch%d' % i])
self._switch_states = [0] * num_switches
def change_state(self, new_state):
"""Change state."""
self._state = new_state
def process_event(self, event):
"""
Act on event.
Return format:
list of zero or more events in the form of:
[
switch_states(list of ints),
index_of_change(int),
event(0=release, 1=press, 2=hold),
is_chord(bool)
]
"""
index = self._switches.index(event.keycode)
self._switch_states[index] = event.keystate
result = self._state(
self,
self._switch_states,
index)
return result