Improved some snippets (HighLevelStateHandlers and PinNamesRenderer)
authorDaniel Kirschten <daniel.kirschten@gmx.de>
Wed, 11 Sep 2019 15:22:51 +0000 (17:22 +0200)
committerDaniel Kirschten <daniel.kirschten@gmx.de>
Wed, 11 Sep 2019 15:24:11 +0000 (17:24 +0200)
net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/highlevelstatehandlers/standard/StandardHighLevelStateHandler.java
net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/highlevelstatehandlers/standard/atomic/BitVectorSplittingAtomicHighLevelStateHandler.java
net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/highlevelstatehandlers/standard/atomic/DelegatingAtomicHighLevelStateHandler.java
net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/highlevelstatehandlers/standard/atomic/WireForcingAtomicHighLevelStateHandler.java
net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/highlevelstatehandlers/standard/subcomponent/DelegatingSubcomponentHighLevelStateHandler.java
net.mograsim.logic.model/src/net/mograsim/logic/model/snippets/symbolrenderers/PinNamesSymbolRenderer.java

index af3ad22..490b267 100644 (file)
@@ -1,5 +1,6 @@
 package net.mograsim.logic.model.snippets.highlevelstatehandlers.standard;
 
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Map.Entry;
@@ -20,7 +21,9 @@ public class StandardHighLevelStateHandler implements HighLevelStateHandler
 {
        private final SubmodelComponent component;
        private final Map<String, SubcomponentHighLevelStateHandler> subcomponentHighLevelStateHandlers;
+       private final Map<String, SubcomponentHighLevelStateHandler> subcomponentHighLevelStateHandlersUnmodifiable;
        private final Map<String, AtomicHighLevelStateHandler> atomicHighLevelStateHandlers;
+       private final Map<String, AtomicHighLevelStateHandler> atomicHighLevelStateHandlersUnmodifiable;
 
        public StandardHighLevelStateHandler(SubmodelComponent component)
        {
@@ -31,7 +34,9 @@ public class StandardHighLevelStateHandler implements HighLevelStateHandler
        {
                this.component = component;
                this.subcomponentHighLevelStateHandlers = new HashMap<>();
+               this.subcomponentHighLevelStateHandlersUnmodifiable = Collections.unmodifiableMap(subcomponentHighLevelStateHandlers);
                this.atomicHighLevelStateHandlers = new HashMap<>();
+               this.atomicHighLevelStateHandlersUnmodifiable = Collections.unmodifiableMap(atomicHighLevelStateHandlers);
                if (params != null)
                {
                        params.subcomponentHighLevelStates.forEach(this::addSubcomponentHighLevelState);
@@ -68,6 +73,17 @@ public class StandardHighLevelStateHandler implements HighLevelStateHandler
                subcomponentHighLevelStateHandlers.put(subcomponentStateID, handler);
        }
 
+       public void removeSubcomponentHighLevelState(String subcomponentStateID)
+       {
+               checkHighLevelStateIDPart(subcomponentStateID);
+               subcomponentHighLevelStateHandlers.remove(subcomponentStateID);
+       }
+
+       public Map<String, SubcomponentHighLevelStateHandler> getSubcomponentHighLevelStates()
+       {
+               return subcomponentHighLevelStateHandlersUnmodifiable;
+       }
+
        public AtomicHighLevelStateHandler addAtomicHighLevelState(String atomicStateID, AtomicHighLevelStateHandlerParams handlerParams)
        {
                return addAtomicHighLevelState(atomicStateID,
@@ -96,6 +112,17 @@ public class StandardHighLevelStateHandler implements HighLevelStateHandler
                atomicHighLevelStateHandlers.put(atomicStateID, handler);
        }
 
+       public void removeAtomicHighLevelState(String atomicStateID)
+       {
+               checkHighLevelStateIDPart(atomicStateID);
+               atomicHighLevelStateHandlers.remove(atomicStateID);
+       }
+
+       public Map<String, AtomicHighLevelStateHandler> getAtomicHighLevelStates()
+       {
+               return atomicHighLevelStateHandlersUnmodifiable;
+       }
+
        private static void checkHighLevelStateIDPart(String stateIDPart)
        {
                if (stateIDPart.indexOf('.') != -1)
index b5630a5..4b9e2d6 100644 (file)
@@ -1,6 +1,7 @@
 package net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.atomic;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 
 import net.mograsim.logic.core.types.Bit;
@@ -13,9 +14,11 @@ import net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.Standar
 
 public class BitVectorSplittingAtomicHighLevelStateHandler implements AtomicHighLevelStateHandler
 {
-       private SubmodelComponent component;
+       private final SubmodelComponent component;
        private final List<String> vectorPartTargets;
+       private final List<String> vectorPartTargetsUnmodifiable;
        private final List<Integer> vectorPartLengthes;
+       private final List<Integer> vectorPartLengthesUnmodifiable;
        private int length;
 
        public BitVectorSplittingAtomicHighLevelStateHandler(HighLevelStateHandlerContext context)
@@ -28,7 +31,9 @@ public class BitVectorSplittingAtomicHighLevelStateHandler implements AtomicHigh
        {
                this.component = context.component;
                this.vectorPartTargets = new ArrayList<>();
+               this.vectorPartTargetsUnmodifiable = Collections.unmodifiableList(vectorPartTargets);
                this.vectorPartLengthes = new ArrayList<>();
+               this.vectorPartLengthesUnmodifiable = Collections.unmodifiableList(vectorPartLengthes);
                if (params != null)
                        setVectorParts(params.vectorPartTargets, params.vectorPartLengthes);
        }
@@ -62,6 +67,16 @@ public class BitVectorSplittingAtomicHighLevelStateHandler implements AtomicHigh
                length += lengthes.stream().mapToInt(Integer::intValue).sum();
        }
 
+       public List<String> getVectorPartTargets()
+       {
+               return vectorPartTargetsUnmodifiable;
+       }
+
+       public List<Integer> getVectorPartLenghtes()
+       {
+               return vectorPartLengthesUnmodifiable;
+       }
+
        @Override
        public Object getHighLevelState()
        {
index 621dde3..1deabde 100644 (file)
@@ -27,9 +27,19 @@ public class DelegatingAtomicHighLevelStateHandler implements AtomicHighLevelSta
                        if (params.delegateTarget == null)
                                setDelegateTarget(parentComponent);
                        else
-                               setDelegateTarget(parentComponent.submodel.getComponentsByName().get(params.delegateTarget));
+                       {
+                               ModelComponent delegateTarget = parentComponent.submodel.getComponentsByName().get(params.delegateTarget);
+                               if (delegateTarget == null)
+                                       throw new NullPointerException("No subcomponent with name " + params.delegateTarget);
+                               setDelegateTarget(delegateTarget);
+                       }
                        setSubStateID(params.subStateID);
                }
+               parentComponent.submodel.addComponentRemovedListener(c ->
+               {
+                       if (delegateTarget == c)
+                               delegateTarget = null;
+               });
        }
 
        public void set(ModelComponent delegateTarget, String subStateID)
@@ -48,20 +58,34 @@ public class DelegatingAtomicHighLevelStateHandler implements AtomicHighLevelSta
                this.delegateTarget = delegateTarget;
        }
 
+       public ModelComponent getDelegateTarget()
+       {
+               return delegateTarget;
+       }
+
        public void setSubStateID(String subStateID)
        {
                this.subStateID = subStateID;
        }
 
+       public String getSubStateID()
+       {
+               return subStateID;
+       }
+
        @Override
        public Object getHighLevelState()
        {
+               if (delegateTarget == null)
+                       throw new IllegalStateException("Delegating to a component that was destroyed");
                return delegateTarget.getHighLevelState(subStateID);
        }
 
        @Override
        public void setHighLevelState(Object newState)
        {
+               if (delegateTarget == null)
+                       throw new IllegalStateException("Delegating to a component that was destroyed");
                delegateTarget.setHighLevelState(subStateID, newState);
        }
 
index ecf3a4d..ac0f8a4 100644 (file)
@@ -1,6 +1,7 @@
 package net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.atomic;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.function.Function;
@@ -17,10 +18,12 @@ import net.mograsim.logic.model.snippets.highlevelstatehandlers.standard.Standar
 
 public class WireForcingAtomicHighLevelStateHandler implements AtomicHighLevelStateHandler
 {
-       private SubmodelComponent component;
+       private final SubmodelComponent component;
        private int logicWidth;
        private final List<ModelWire> wiresToForce;
+       private final List<ModelWire> wiresToForceUnmodifiable;
        private final List<ModelWire> wiresToForceInverted;
+       private final List<ModelWire> wiresToForceInvertedUnmodifiable;
 
        public WireForcingAtomicHighLevelStateHandler(HighLevelStateHandlerContext context)
        {
@@ -31,13 +34,20 @@ public class WireForcingAtomicHighLevelStateHandler implements AtomicHighLevelSt
        {
                this.component = context.component;
                this.wiresToForce = new ArrayList<>();
+               this.wiresToForceUnmodifiable = Collections.unmodifiableList(wiresToForce);
                this.wiresToForceInverted = new ArrayList<>();
+               this.wiresToForceInvertedUnmodifiable = Collections.unmodifiableList(wiresToForceInverted);
                if (params != null)
                {
                        Map<String, ModelWire> wiresByName = component.submodel.getWiresByName();
                        setWiresToForce(params.wiresToForce.stream().map((Function<String, ModelWire>) wiresByName::get).collect(Collectors.toList()),
                                        params.wiresToForceInverted.stream().map((Function<String, ModelWire>) wiresByName::get).collect(Collectors.toList()));
                }
+               component.submodel.addWireRemovedListener(w ->
+               {
+                       wiresToForce.removeIf(w::equals);
+                       wiresToForceInverted.removeIf(w::equals);
+               });
        }
 
        public void set(List<ModelWire> wiresToForce, List<ModelWire> wiresToForceInverted)
@@ -62,6 +72,8 @@ public class WireForcingAtomicHighLevelStateHandler implements AtomicHighLevelSt
                        logicWidth = wire.logicWidth;
                else if (wire.logicWidth != logicWidth)
                        throw new IllegalArgumentException("Can only force wires of the same logic width");
+               // this can add the same wire multiple times, but maybe there is a weird configuration where it is neccessary, due to race
+               // conditions, to force the same wire twice.
                if (inverted)
                        wiresToForceInverted.add(wire);
                else
@@ -75,6 +87,16 @@ public class WireForcingAtomicHighLevelStateHandler implements AtomicHighLevelSt
                logicWidth = 0;
        }
 
+       public List<ModelWire> getWiresToForce()
+       {
+               return wiresToForceUnmodifiable;
+       }
+
+       public List<ModelWire> getWiresToForceInverted()
+       {
+               return wiresToForceInvertedUnmodifiable;
+       }
+
        @Override
        public Object getHighLevelState()
        {
index fc3c6bd..069a6cb 100644 (file)
@@ -28,9 +28,19 @@ public class DelegatingSubcomponentHighLevelStateHandler implements Subcomponent
                        if (params.delegateTarget == null)
                                setDelegateTarget(parentComponent);
                        else
-                               this.delegateTarget = parentComponent.submodel.getComponentsByName().get(params.delegateTarget);
+                       {
+                               ModelComponent delegateTarget = parentComponent.submodel.getComponentsByName().get(params.delegateTarget);
+                               if (delegateTarget == null)
+                                       throw new NullPointerException("No subcomponent with name " + params.delegateTarget);
+                               setDelegateTarget(delegateTarget);
+                       }
                        setPrefix(params.prefix);
                }
+               parentComponent.submodel.addComponentRemovedListener(c ->
+               {
+                       if (delegateTarget == c)
+                               delegateTarget = null;
+               });
        }
 
        public void set(ModelComponent delegateTarget, String prefix)
@@ -49,20 +59,34 @@ public class DelegatingSubcomponentHighLevelStateHandler implements Subcomponent
                this.delegateTarget = delegateTarget;
        }
 
+       public ModelComponent getDelegateTarget()
+       {
+               return delegateTarget;
+       }
+
        public void setPrefix(String prefix)
        {
                this.prefix = prefix;
        }
 
+       public String getPrefix()
+       {
+               return prefix;
+       }
+
        @Override
        public Object getHighLevelState(String subStateID)
        {
+               if (delegateTarget == null)
+                       throw new IllegalStateException("Delegating to a component that was destroyed");
                return delegateTarget.getHighLevelState(getDelegateTargetHighLevelStateID(subStateID));
        }
 
        @Override
        public void setHighLevelState(String subStateID, Object newState)
        {
+               if (delegateTarget == null)
+                       throw new IllegalStateException("Delegating to a component that was destroyed");
                delegateTarget.setHighLevelState(getDelegateTargetHighLevelStateID(subStateID), newState);
        }
 
index a638013..ede8710 100644 (file)
@@ -30,6 +30,7 @@ public class PinNamesSymbolRenderer implements Renderer
                this.pinLabelMargin = params.pinLabelMargin;
                if (params.pinNamePositions != null)
                        params.pinNamePositions.forEach(this::setPinPosition);
+               component.addPinRemovedListener(p -> setPinPosition(p, null));
        }
 
        public void setPinPosition(String pinName, Position position)