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