/
watcher.go
147 lines (123 loc) · 3.39 KB
/
watcher.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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
// Copyright 2014 The Azul3D Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package keyboard
import (
"bytes"
"fmt"
"sync"
)
// Watcher watches the state of various keyboard keys.
type Watcher struct {
access sync.RWMutex
states map[Key]State
rawStates map[uint64]State
}
// String returns a multi-line string representation of this keyboard watcher
// and it's associated states (but not raw ones).
func (w *Watcher) String() string {
bb := new(bytes.Buffer)
fmt.Fprintf(bb, "keyboard.Watcher(\n")
for k, s := range w.States() {
fmt.Fprintf(bb, "\t%v: %v,\n", k, s)
}
fmt.Fprintf(bb, ")")
return bb.String()
}
// SetState specifies the current state of the specified key.
func (w *Watcher) SetState(k Key, s State) {
w.access.Lock()
defer w.access.Unlock()
w.states[k] = s
}
// States returns an copy of the internal key state map used by this watcher.
func (w *Watcher) States() map[Key]State {
w.access.RLock()
defer w.access.RUnlock()
cpy := make(map[Key]State, len(w.states))
for key, state := range w.states {
cpy[key] = state
}
return cpy
}
// EachState calls f with each known key to this watcher and it's current key
// state. It does so until the function returns false or there are no more keys
// known to the watcher.
func (w *Watcher) EachState(f func(k Key, s State) bool) {
w.access.RLock()
defer w.access.RUnlock()
for key, state := range w.states {
// Call the function without the lock being held, so they can access
// methods on this watcher still.
w.access.RUnlock()
cont := f(key, state)
w.access.RLock()
if !cont {
return
}
}
}
// State returns the current state of the specified key.
func (w *Watcher) State(k Key) State {
w.access.Lock()
defer w.access.Unlock()
state, ok := w.states[k]
if !ok {
w.states[k] = Up
return Up
}
return state
}
// Down tells whether the specified key is currently in the down state.
func (w *Watcher) Down(k Key) bool {
return w.State(k) == Down
}
// Up tells whether the specified key is currently in the up state.
func (w *Watcher) Up(k Key) bool {
return w.State(k) == Up
}
// SetRawState specifies the current state of the specified raw key value.
func (w *Watcher) SetRawState(raw uint64, s State) {
w.access.Lock()
defer w.access.Unlock()
w.rawStates[raw] = s
}
// RawStates returns an copy of the internal raw key state map used by this
// watcher.
func (w *Watcher) RawStates() map[uint64]State {
w.access.RLock()
defer w.access.RUnlock()
cpy := make(map[uint64]State, len(w.rawStates))
for raw, state := range w.rawStates {
cpy[raw] = state
}
return cpy
}
// RawState returns the current state of the specified raw key value.
func (w *Watcher) RawState(raw uint64) State {
w.access.Lock()
defer w.access.Unlock()
state, ok := w.rawStates[raw]
if !ok {
w.rawStates[raw] = Up
return Up
}
return state
}
// RawDown tells whether the specified raw key value is currently in the down
// state.
func (w *Watcher) RawDown(raw uint64) bool {
return w.RawState(raw) == Down
}
// RawUp tells whether the specified raw key value is currently in the up
// state.
func (w *Watcher) RawUp(raw uint64) bool {
return w.RawState(raw) == Up
}
// NewWatcher returns a new, initialized, watcher.
func NewWatcher() *Watcher {
w := new(Watcher)
w.states = make(map[Key]State)
w.rawStates = make(map[uint64]State)
return w
}