1 package net.mograsim.logic.model.editor.handles;
3 import java.util.ArrayList;
4 import java.util.Collection;
5 import java.util.Collections;
6 import java.util.HashMap;
7 import java.util.HashSet;
11 import java.util.function.Consumer;
12 import java.util.stream.Collectors;
14 import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
15 import net.mograsim.logic.model.editor.Editor;
16 import net.mograsim.logic.model.editor.states.EditorState;
17 import net.mograsim.logic.model.model.ViewModelModifiable;
18 import net.mograsim.logic.model.model.components.GUIComponent;
19 import net.mograsim.logic.model.model.wires.GUIWire;
20 import net.mograsim.logic.model.model.wires.MovablePin;
21 import net.mograsim.logic.model.model.wires.Pin;
23 public class HandleManager
25 private final Map<Pin, StaticPinHandle> handlePerPin;
26 private final Map<Pin, InterfacePinHandle> handlePerInterfacePin;
27 private final Map<GUIWire, List<WirePointHandle>> pointHandlesPerWire;
28 private final Map<GUIWire, WireHandle> handlePerWire;
29 private final Set<Handle> handles;
30 private final Set<WirePointHandle> wirePointHandles;
31 private final Map<GUIComponent, ComponentHandle> handlePerComp;
33 private final Collection<Consumer<Handle>> handleAddedListeners;
34 private final Collection<Consumer<Handle>> handleRemovedListeners;
35 private final Editor editor;
36 private boolean initialized = false;
38 private CornerHandle cornerHandle;
40 public HandleManager(Editor editor)
43 handlePerPin = new HashMap<>();
44 handlePerInterfacePin = new HashMap<>();
45 pointHandlesPerWire = new HashMap<>();
46 handlePerComp = new HashMap<>();
47 handles = new HashSet<>();
48 wirePointHandles = new HashSet<>();
49 handlePerWire = new HashMap<>();
51 handleAddedListeners = new ArrayList<>();
52 handleRemovedListeners = new ArrayList<>();
54 ViewModelModifiable model = editor.getSubmodel();
56 model.addComponentAddedListener(c -> registerComponent(c));
58 model.addComponentRemovedListener(c ->
60 removeComponentHandle(c);
63 model.addWireAddedListener(w ->
68 model.addWireRemovedListener(w ->
71 removeWirePointHandles(w);
75 ////////////////////////////////////////
76 // -- Setting up initial handles -- ///
77 //////////////////////////////////////
82 System.err.println("Warning! HandleManager was already initialized.");
85 ViewModelModifiable model = editor.getSubmodel();
86 Map<String, GUIComponent> compsByName = model.getComponentsByName();
87 Set<GUIComponent> comps = new HashSet<>(compsByName.values());
88 GUIComponent interfaceComp = compsByName.get("_submodelinterface");
89 comps.remove(interfaceComp);
90 registerInterfaceComponent(interfaceComp);
91 comps.forEach(c -> registerComponent(c));
93 model.getWires().forEach(w -> registerWire(w));
94 addHandle(cornerHandle = new CornerHandle(editor.toBeEdited));
98 private void registerInterfaceComponent(GUIComponent c)
100 c.getPins().values().forEach(p -> addInterfacePinHandle(p));
101 c.addPinAddedListener(p -> addInterfacePinHandle(p));
102 c.addPinRemovedListener(p -> removeInterfacePinHandle(p));
105 private void registerComponent(GUIComponent c)
107 addComponentHandle(c);
109 c.getPins().values().forEach(p -> addPinHandle(p));
111 c.addPinAddedListener(p -> addPinHandle(p));
112 c.addPinRemovedListener(p -> removePinHandle(p));
115 private void registerWire(GUIWire wire)
117 wire.addPathChangedListener((w, diff) ->
123 for(int i = 0; i < diff; i++)
124 addWirePointHandle(w);
127 List<WirePointHandle> wpHandles = pointHandlesPerWire.get(w);
128 int size = wpHandles.size();
129 for(int i = 0; i < size; i++)
131 wpHandles.get(i).setIndex(i);
134 pointHandlesPerWire.get(w).forEach(h -> h.updatePos());
137 if (wire.getPath() == null)
139 for (int i = 0; i < wire.getPath().length; i++)
141 addWirePointHandle(wire);
145 /////////////////////////////////////
146 // -- Adding/Removing handles -- ///
147 ///////////////////////////////////
149 private void addComponentHandle(GUIComponent c)
151 ComponentHandle h = new ComponentHandle(c);
152 handlePerComp.put(c, h);
156 private void removeComponentHandle(GUIComponent c)
158 ComponentHandle h = handlePerComp.get(c);
159 handlePerComp.remove(c);
163 private void addPinHandle(Pin owner)
165 StaticPinHandle h = new StaticPinHandle(owner);
166 handlePerPin.put(owner, h);
170 private void removePinHandle(Pin owner)
172 StaticPinHandle h = handlePerPin.get(owner);
173 handlePerPin.remove(owner);
177 private void addInterfacePinHandle(Pin p)
179 //The following is not an alternative to the cast, because the new pin is not yet in the map, when the listener is called
180 //editor.toBeEdited.getSubmodelMovablePins().get(p.name);
181 MovablePin pM = (MovablePin) p;
182 InterfacePinHandle h = new InterfacePinHandle(pM, editor.toBeEdited);
183 handlePerInterfacePin.put(pM, h);
187 private void removeInterfacePinHandle(Pin p)
189 InterfacePinHandle h = handlePerInterfacePin.get(p);
190 handlePerInterfacePin.remove(p);
194 private void addWirePointHandle(GUIWire w)
196 List<WirePointHandle> wireHandles = pointHandlesPerWire.get(w);
198 if (wireHandles != null)
199 wireHandles.add(h = new WirePointHandle(this, w, wireHandles.size()));
202 wireHandles = new ArrayList<>();
203 h = new WirePointHandle(this, w, 0);
205 pointHandlesPerWire.put(h.parent, wireHandles);
207 this.wirePointHandles.add(h);
211 void destroyWirePointHandle(GUIWire owner, WirePointHandle h)
213 List<WirePointHandle> handles = pointHandlesPerWire.get(owner);
214 int pointIndex = handles.indexOf(h);
215 handles.remove(pointIndex);
217 owner.removePathPoint(pointIndex);
220 private void removeWirePointHandles(GUIWire owner)
222 if(!pointHandlesPerWire.containsKey(owner))
224 pointHandlesPerWire.get(owner).forEach(h ->
226 wirePointHandles.remove(h);
229 pointHandlesPerWire.remove(owner);
232 private void addWireHandle(GUIWire w)
234 WireHandle h = new WireHandle(w);
235 handlePerWire.put(w, h);
239 private void removeWireHandle(GUIWire w)
241 WireHandle h = handlePerWire.get(w);
242 handlePerWire.remove(w);
246 private void addHandle(Handle h)
249 callHandleAddedListeners(h);
252 private void removeHandle(Handle h)
255 callHandleRemovedListeners(h);
259 public StaticPinHandle getHandle(Pin parent)
261 return handlePerPin.get(parent);
264 public ComponentHandle getHandle(GUIComponent parent)
266 return handlePerComp.get(parent);
269 public WireHandle getHandle(GUIWire parent)
271 return handlePerWire.get(parent);
274 public Handle getInterfacePinHandle(Pin p)
276 return handlePerInterfacePin.get(p);
280 * @return A Collection of the registered {@link WirePointHandle}s of the specified wire
282 public Collection<WirePointHandle> getWirePointHandles(GUIWire parent)
284 return pointHandlesPerWire.get(parent).stream().collect(Collectors.toSet());
288 * @return An unmodifiable view of all registered {@link Handle}s
290 public Collection<Handle> getHandles()
292 return Collections.unmodifiableCollection(handles);
296 * @return An unmodifiable view of all registered {@link StaticPinHandle}s
298 public Collection<StaticPinHandle> getPinHandles()
300 return Collections.unmodifiableCollection(handlePerPin.values());
304 * @return An unmodifiable view of all registered {@link InterfacePinHandle}s
306 public Collection<InterfacePinHandle> getInterfacePinHandles()
308 return Collections.unmodifiableCollection(handlePerInterfacePin.values());
312 * @return An unmodifiable view of all registered {@link ComponentHandle}s
314 public Collection<ComponentHandle> getComponentHandles()
316 return Collections.unmodifiableCollection(handlePerComp.values());
320 * @return An unmodifiable view of all registered {@link WireHandle}s
322 public Collection<WireHandle> getWireHandles()
324 return Collections.unmodifiableCollection(handlePerWire.values());
328 * @return An unmodifiable view of all registered {@link WirePointHandle}s
330 public Collection<WirePointHandle> getWirePointHandles()
332 return Collections.unmodifiableSet(wirePointHandles);
335 public void click(Point clicked, int stateMask)
337 EditorState entryState = editor.stateManager.getState();
339 if (!cornerHandle.click(clicked.x, clicked.y, stateMask, entryState))
340 if (!click(handlePerPin.values(), clicked, entryState, stateMask))
341 if (!click(handlePerInterfacePin.values(), clicked, entryState, stateMask))
342 if (!click(getWirePointHandles(), clicked, entryState, stateMask))
343 if (!click(getWireHandles(), clicked, entryState, stateMask))
344 if (!click(handlePerComp.values(), clicked, entryState, stateMask))
345 entryState.clickedEmpty(clicked, stateMask);
346 entryState.clicked(clicked, stateMask);
349 private boolean click(Collection<? extends Handle> handles, Point clicked, EditorState state, int stateMask)
351 for (Handle h : handles)
352 if (h.click(clicked.x, clicked.y, stateMask, state))
357 public void addHandleAddedListener(Consumer<Handle> c)
359 handleAddedListeners.add(c);
362 private void callHandleAddedListeners(Handle added)
364 handleAddedListeners.forEach(l -> l.accept(added));
367 public void removeHandleAddedListener(Consumer<Handle> c)
369 handleAddedListeners.remove(c);
372 public void addHandleRemovedListener(Consumer<Handle> c)
374 handleRemovedListeners.add(c);
377 private void callHandleRemovedListeners(Handle removed)
379 handleRemovedListeners.forEach(l -> l.accept(removed));
382 public void removeHandleRemovedListener(Consumer<Handle> c)
384 handleRemovedListeners.remove(c);