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