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