c60de3ed3f6facc69cb9477ad7977efb59479420
[Mograsim.git] / net.mograsim.logic.model / src / net / mograsim / logic / model / model / ViewModel.java
1 package net.mograsim.logic.model.model;
2
3 import java.util.ArrayList;
4 import java.util.Collections;
5 import java.util.HashMap;
6 import java.util.List;
7 import java.util.Map;
8 import java.util.function.Consumer;
9
10 import net.mograsim.logic.model.model.components.GUIComponent;
11 import net.mograsim.logic.model.model.wires.GUIWire;
12
13 public class ViewModel
14 {
15         private final Map<String, GUIComponent> components;
16         private final Map<String, GUIComponent> componentsUnmodifiable;
17         private final Map<String, GUIWire> wires;
18         private final Map<String, GUIWire> wiresUnmodifiable;
19
20         private final List<Consumer<? super GUIComponent>> componentAddedListeners;
21         private final List<Consumer<? super GUIComponent>> componentRemovedListeners;
22         private final List<Consumer<? super GUIWire>> wireAddedListeners;
23         private final List<Consumer<? super GUIWire>> wireRemovedListeners;
24
25         private Runnable redrawHandler;
26
27         protected ViewModel()
28         {
29                 components = new HashMap<>();
30                 componentsUnmodifiable = Collections.unmodifiableMap(components);
31                 wires = new HashMap<>();
32                 wiresUnmodifiable = Collections.unmodifiableMap(wires);
33
34                 componentAddedListeners = new ArrayList<>();
35                 componentRemovedListeners = new ArrayList<>();
36                 wireAddedListeners = new ArrayList<>();
37                 wireRemovedListeners = new ArrayList<>();
38         }
39
40         /**
41          * Adds the given component to the list of components and calls all componentAddedListeners. Don't call this method from application
42          * code as it is automatically called in {@link GUIComponent}'s constructor.
43          */
44         protected void componentCreated(GUIComponent component)
45         {
46                 if (components.containsKey(component.name))
47                         throw new IllegalStateException("Don't add the same component twice!");
48                 components.put(component.name, component);
49                 callComponentAddedListeners(component);
50                 requestRedraw();
51         }
52
53         /**
54          * Removes the given component from the list of components and calls all componentRemovedListeners. Don't call this method from
55          * application code as it is automatically called in {@link GUIComponent#destroy()}.
56          */
57         protected void componentDestroyed(GUIComponent component)
58         {
59                 if (!components.containsKey(component.name))
60                         throw new IllegalStateException("Don't remove the same component twice!");
61                 components.remove(component.name);
62                 callComponentRemovedListeners(component);
63                 requestRedraw();
64         }
65
66         /**
67          * Adds the given wire to the list of wires and calls all wireAddedListeners. Don't call this method from application code as it is
68          * automatically called in {@link GUIWire}'s constructor(s).
69          */
70         protected void wireCreated(GUIWire wire)
71         {
72                 if (wires.containsKey(wire.name))
73                         throw new IllegalStateException("Don't add the same wire twice!");
74                 wires.put(wire.name, wire);
75                 callWireAddedListeners(wire);
76                 requestRedraw();
77         }
78
79         /**
80          * Removes the given wire from the list of wires and calls all wireRemovedListeners. Don't call this method from application code as it
81          * is automatically called in {@link GUIWire#destroy()}.
82          */
83         protected void wireDestroyed(GUIWire wire)
84         {
85                 if (!wires.containsKey(wire.name))
86                         throw new IllegalStateException("Don't remove the same wire twice!");
87                 wires.remove(wire.name);
88                 callWireRemovedListeners(wire);
89                 requestRedraw();
90         }
91
92         public Map<String, GUIComponent> getComponentsByName()
93         {
94                 return componentsUnmodifiable;
95         }
96
97         public Map<String, GUIWire> getWiresByName()
98         {
99                 return wiresUnmodifiable;
100         }
101
102         // @formatter:off
103         public void addComponentAddedListener     (Consumer<? super GUIComponent> listener) {componentAddedListeners  .add   (listener);}
104         public void addComponentRemovedListener   (Consumer<? super GUIComponent> listener) {componentRemovedListeners.add   (listener);}
105         public void addWireAddedListener          (Consumer<? super GUIWire     > listener) {wireAddedListeners       .add   (listener);}
106         public void addWireRemovedListener        (Consumer<? super GUIWire     > listener) {wireRemovedListeners     .add   (listener);}
107
108         public void removeComponentAddedListener  (Consumer<? super GUIComponent> listener) {componentAddedListeners  .remove(listener);}
109         public void removeComponentRemovedListener(Consumer<? super GUIComponent> listener) {componentRemovedListeners.remove(listener);}
110         public void removeWireAddedListener       (Consumer<? super GUIWire     > listener) {wireAddedListeners       .remove(listener);}
111         public void removeWireRemovedListener     (Consumer<? super GUIWire     > listener) {wireRemovedListeners     .remove(listener);}
112
113         private void callComponentAddedListeners  (GUIComponent c) {componentAddedListeners  .forEach(l -> l.accept(c));}
114         private void callComponentRemovedListeners(GUIComponent c) {componentRemovedListeners.forEach(l -> l.accept(c));}
115         private void callWireAddedListeners       (GUIWire w     ) {wireAddedListeners       .forEach(l -> l.accept(w));}
116         private void callWireRemovedListeners     (GUIWire w     ) {wireRemovedListeners     .forEach(l -> l.accept(w));}
117         // @formatter:on
118
119         public void setRedrawHandler(Runnable handler)
120         {
121                 this.redrawHandler = handler;
122         }
123
124         public Runnable getRedrawHandler()
125         {
126                 return redrawHandler;
127         }
128
129         public void requestRedraw()
130         {
131                 if (redrawHandler != null)
132                         redrawHandler.run();
133         }
134 }