MPROMEditor now calls its columns "Opcode" and "muPC"
[Mograsim.git] / plugins / net.mograsim.logic.model / src / net / mograsim / logic / model / snippets / highlevelstatehandlers / standard / atomic / DelegatingAtomicHighLevelStateHandler.java
1 package net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.atomic;
2
3 import java.util.function.Consumer;
4
5 import net.mograsim.logic.model.model.components.ModelComponent;
6 import net.mograsim.logic.model.model.components.submodels.SubmodelComponent;
7 import net.mograsim.logic.model.serializing.IdentifyParams;
8 import net.mograsim.logic.model.snippets.SnippetDefinintion;
9 import net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.StandardHighLevelStateHandlerSnippetSuppliers;
10
11 public class DelegatingAtomicHighLevelStateHandler implements AtomicHighLevelStateHandler
12 {
13         private final SubmodelComponent parentComponent;
14         private ModelComponent delegateTarget;
15         private String subStateID;
16
17         public DelegatingAtomicHighLevelStateHandler(SubmodelComponent component)
18         {
19                 this(component, null);
20         }
21
22         public DelegatingAtomicHighLevelStateHandler(SubmodelComponent component, DelegatingAtomicHighLevelStateHandlerParams params)
23         {
24                 this.parentComponent = component;
25                 if (params != null)
26                 {
27                         // TODO document this
28                         if (params.delegateTarget == null)
29                                 setDelegateTarget(parentComponent);
30                         else
31                         {
32                                 ModelComponent delegateTarget = parentComponent.submodel.getComponentsByName().get(params.delegateTarget);
33                                 if (delegateTarget == null)
34                                         throw new NullPointerException("No subcomponent with name " + params.delegateTarget);
35                                 setDelegateTarget(delegateTarget);
36                         }
37                         setSubStateID(params.subStateID);
38                 }
39                 parentComponent.submodel.addComponentRemovedListener(c ->
40                 {
41                         if (delegateTarget == c)
42                                 delegateTarget = null;
43                 });
44         }
45
46         public void set(ModelComponent delegateTarget, String subStateID)
47         {
48                 setDelegateTarget(delegateTarget);
49                 setSubStateID(subStateID);
50         }
51
52         public void setDelegateTarget(ModelComponent delegateTarget)
53         {
54                 if (delegateTarget == null)
55                         this.delegateTarget = parentComponent;
56                 else if (parentComponent.submodel.getComponentsByName().get(delegateTarget.getName()) != delegateTarget)
57                         throw new IllegalArgumentException(
58                                         "Can only set components belonging to the submodel of the parent component of this handler as the delegate target");
59                 this.delegateTarget = delegateTarget;
60         }
61
62         public ModelComponent getDelegateTarget()
63         {
64                 return delegateTarget;
65         }
66
67         public void setSubStateID(String subStateID)
68         {
69                 this.subStateID = subStateID;
70         }
71
72         public String getSubStateID()
73         {
74                 return subStateID;
75         }
76
77         @Override
78         public Object getHighLevelState()
79         {
80                 checkTarget();
81                 return delegateTarget.getHighLevelState(subStateID);
82         }
83
84         @Override
85         public void setHighLevelState(Object newState)
86         {
87                 checkTarget();
88                 delegateTarget.setHighLevelState(subStateID, newState);
89         }
90
91         @Override
92         public void addListener(Consumer<Object> stateChanged)
93         {
94                 checkTarget();
95                 delegateTarget.addHighLevelStateListener(subStateID, stateChanged);
96         }
97
98         @Override
99         public void removeListener(Consumer<Object> stateChanged)
100         {
101                 checkTarget();
102                 delegateTarget.removeHighLevelStateListener(subStateID, stateChanged);
103         }
104
105         private void checkTarget()
106         {
107                 if (delegateTarget == null)
108                         throw new IllegalStateException("Delegating to a component that was destroyed");
109         }
110
111         @Override
112         public String getIDForSerializing(IdentifyParams idParams)
113         {
114                 return "delegating";
115         }
116
117         @Override
118         public DelegatingAtomicHighLevelStateHandlerParams getParamsForSerializing(IdentifyParams idParams)
119         {
120                 checkTarget();
121                 DelegatingAtomicHighLevelStateHandlerParams params = new DelegatingAtomicHighLevelStateHandlerParams();
122                 params.delegateTarget = delegateTarget == parentComponent ? null : delegateTarget.getName();
123                 params.subStateID = subStateID;
124                 return params;
125         }
126
127         public static class DelegatingAtomicHighLevelStateHandlerParams
128         {
129                 public String delegateTarget;
130                 public String subStateID;
131         }
132
133         static
134         {
135                 StandardHighLevelStateHandlerSnippetSuppliers.atomicHandlerSupplier.setSnippetSupplier(
136                                 DelegatingAtomicHighLevelStateHandler.class.getCanonicalName(),
137                                 SnippetDefinintion.create(DelegatingAtomicHighLevelStateHandlerParams.class, DelegatingAtomicHighLevelStateHandler::new));
138         }
139 }