-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathInputTriggerMap.java
More file actions
196 lines (172 loc) · 4.55 KB
/
Copy pathInputTriggerMap.java
File metadata and controls
196 lines (172 loc) · 4.55 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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
package bdv.behaviour;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import javax.swing.InputMap;
/**
* Similar to {@link InputMap}, this provides bindings from {@link InputTrigger}
* to {@link Behaviour} keys, and is chainable (see
* {@link #setParent(InputTriggerMap)}).
* <p>
* In contrast to {@code InputMap}, one {@link InputTrigger} can map to multiple
* {@link Behaviour} keys.
*
* @author Tobias Pietzsch <tobias.pietzsch@gmail.com>
*/
public class InputTriggerMap
{
/**
* Maps {@link InputTrigger} to a set of {@link Behaviour} keys.
*/
private final Map< InputTrigger, Set< String > > triggerToKeys;
/**
* Parent that handles any bindings we don't contain.
*/
private InputTriggerMap parent;
private int expectedParentModCount;
private int modCount;
/**
* Creates an {@link InputTriggerMap} with no parent and no mappings.
*/
public InputTriggerMap()
{
triggerToKeys = new HashMap<>();
parent = null;
expectedParentModCount = 0;
modCount = 0;
}
/**
* Sets this {@link InputTriggerMap}'s parent.
*
* @param map
* the map that is the parent of this one
*/
public void setParent( final InputTriggerMap map )
{
this.parent = map;
if ( map != null )
expectedParentModCount = parent.modCount();
++modCount;
}
/**
* Gets this {@link InputTriggerMap}'s parent.
*
* @return map the map that is the parent of this one, or {@code null} if
* this map has no parent
*/
public InputTriggerMap getParent()
{
return parent;
}
/**
* Adds a binding for {@code inputTrigger} to {@code behaviourKey}.
*
* @param inputTrigger
* @param behaviourKey
*/
public synchronized void put( final InputTrigger inputTrigger, final String behaviourKey )
{
Set< String > behaviourKeys = triggerToKeys.get( inputTrigger );
if ( behaviourKeys == null )
{
behaviourKeys = new HashSet<>();
triggerToKeys.put( inputTrigger, behaviourKeys );
}
behaviourKeys.add( behaviourKey );
++modCount;
}
/**
* Get the set of all bindings for {@code inputTrigger} defined in this map
* and its parents.
*
* @param inputTrigger
* @return bindings for {@code inputTrigger}.
*/
public synchronized Set< String > get( final InputTrigger inputTrigger )
{
Set< String > keys = null;
if ( parent != null )
keys = parent.get( inputTrigger );
else
keys = new HashSet<>();
keys.addAll( triggerToKeys.get( inputTrigger ) );
return keys;
}
/**
* Remove the specific binding from {@code inputTrigger} to {@code behaviourKey} from this map.
*
* @param inputTrigger
* @param behaviourKey
*/
public synchronized void remove( final InputTrigger inputTrigger, final String behaviourKey )
{
final Set< String > behaviourKeys = triggerToKeys.get( inputTrigger );
if ( behaviourKeys == null )
return;
behaviourKeys.remove( behaviourKey );
if ( behaviourKeys.isEmpty() )
triggerToKeys.remove( behaviourKeys );
++modCount;
}
/**
* Remove all bindings for {@code inputTrigger} from this map.
* @param inputTrigger
*/
public synchronized void removeAll( final InputTrigger inputTrigger )
{
triggerToKeys.remove( inputTrigger );
++modCount;
}
/**
* Remove all bindings from this map.
*/
public synchronized void clear()
{
triggerToKeys.clear();
++modCount;
}
/**
* Get all bindings defined in this map and its parents. Note the returned
* map <em>not</em> backed by the {@link InputTriggerMap}, i.e., it will not
* reflect changes to the {@link InputTriggerMap}.
*
* @return all bindings defined in this map and its parents.
*/
public synchronized Map< InputTrigger, Set< String > > getAllBindings()
{
final Map< InputTrigger, Set< String > > allBindings;
if ( parent != null )
allBindings = parent.getAllBindings();
else
allBindings = new HashMap<>();
for ( final Entry< InputTrigger, Set< String > > entry : triggerToKeys.entrySet() )
{
final InputTrigger inputTrigger = entry.getKey();
if ( entry.getValue() == null || entry.getValue().isEmpty() )
continue;
Set< String > behaviourKeys = allBindings.get( inputTrigger );
if ( behaviourKeys == null )
{
behaviourKeys = new HashSet<>();
allBindings.put( inputTrigger, behaviourKeys );
}
behaviourKeys.addAll( entry.getValue() );
}
return allBindings;
}
protected int modCount()
{
if ( parent != null )
{
final int m = parent.modCount();
if ( m != expectedParentModCount )
{
expectedParentModCount = m;
++modCount;
}
}
return modCount;
}
}