SimpleRectangularHardcodedGUIComponent now supports HighLevelStates
[Mograsim.git] / net.mograsim.logic.model / src / net / mograsim / logic / model / model / components / atomic / SimpleRectangularHardcodedGUIComponent.java
index bad9b94..c06ec14 100644 (file)
@@ -1,7 +1,7 @@
 package net.mograsim.logic.model.model.components.atomic;
 
-import java.util.HashMap;
 import java.util.Map;
+import java.util.concurrent.atomic.AtomicReference;
 
 import net.haspamelodica.swt.helper.gcs.GeneralGC;
 import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle;
@@ -12,6 +12,8 @@ import net.mograsim.logic.model.model.components.GUIComponent;
 import net.mograsim.logic.model.model.wires.Pin;
 import net.mograsim.logic.model.modeladapter.ViewLogicModelAdapter;
 import net.mograsim.logic.model.modeladapter.componentadapters.SimpleRectangularHardcodedGUIComponentAdapter;
+import net.mograsim.logic.model.serializing.IdentifierGetter;
+import net.mograsim.logic.model.snippets.HighLevelStateHandler;
 import net.mograsim.logic.model.snippets.outlinerenderers.DefaultOutlineRenderer;
 import net.mograsim.logic.model.snippets.symbolrenderers.CenteredTextSymbolRenderer;
 import net.mograsim.logic.model.snippets.symbolrenderers.CenteredTextSymbolRenderer.CenteredTextParams;
@@ -25,19 +27,18 @@ public abstract class SimpleRectangularHardcodedGUIComponent extends GUIComponen
        private static final double pinNamesHeight = 3.5;
        private static final double pinNamesMargin = .5;
 
-       // TODO maybe make this more general?
-       private final Map<Pin, Usage> pinUsages;
-
        private final DefaultOutlineRenderer outlineRenderer;
        private final CenteredTextSymbolRenderer centerTextRenderer;
        private final PinNamesSymbolRenderer pinNamesRenderer;
 
+       private AtomicReference<Object> state;
+       private Runnable recalculate;
+
        // creation and destruction
 
        public SimpleRectangularHardcodedGUIComponent(ViewModelModifiable model, String name, String centerText)
        {
                super(model, name);
-               pinUsages = new HashMap<>();
                this.outlineRenderer = new DefaultOutlineRenderer(this);
                CenteredTextParams centeredTextParams = new CenteredTextParams();
                centeredTextParams.text = centerText;
@@ -48,31 +49,67 @@ public abstract class SimpleRectangularHardcodedGUIComponent extends GUIComponen
                pinNamesParams.pinLabelMargin = pinNamesMargin;
                this.pinNamesRenderer = new PinNamesSymbolRenderer(this, pinNamesParams);
                addPinRemovedListener(this::pinRemoved);
+               setHighLevelStateHandler(new HighLevelStateHandler()
+               {
+                       @Override
+                       public Object getParamsForSerializing(IdentifierGetter idGetter)
+                       {
+                               return null;
+                       }
+
+                       @Override
+                       public Object getHighLevelState(String stateID)
+                       {
+                               return SimpleRectangularHardcodedGUIComponent.this.getHighLevelState(state.get(), stateID);
+                       }
+
+                       @Override
+                       public void setHighLevelState(String stateID, Object newState)
+                       {
+                               state.updateAndGet(s -> SimpleRectangularHardcodedGUIComponent.this.setHighLevelState(s, stateID, newState));
+                               recalculate.run();
+                       }
+               });
        }
 
        // pins
 
-       protected void addPin(Pin pin, Usage usage, Position namePosition)
+       protected void addPin(Pin pin, Position namePosition)
        {
                super.addPin(pin); // do this first to catch errors
-               pinUsages.put(pin, usage);
                pinNamesRenderer.setPinPosition(pin, namePosition);
        }
 
        private void pinRemoved(Pin pin)
        {
-               pinUsages.remove(pin);
                pinNamesRenderer.setPinPosition(pin, null);
        }
 
-       public Usage getPinUsage(Pin pin)
+       // high-level access
+
+       @SuppressWarnings({ "static-method", "unused" }) // this method is intended to be overridden
+       protected Object getHighLevelState(Object state, String stateID)
        {
-               return pinUsages.get(pin);
+               throw new IllegalArgumentException("No high level state with ID " + stateID);
+       }
+
+       @SuppressWarnings({ "static-method", "unused" }) // this method is intended to be overridden
+       protected Object setHighLevelState(Object lastState, String stateID, Object newHighLevelState)
+       {
+               throw new IllegalArgumentException("No high level state with ID " + stateID);
        }
 
        // logic
 
-       protected abstract void recalculate(Map<String, ReadEnd> readEnds, Map<String, ReadWriteEnd> readWriteEnds);
+       public abstract Object recalculate(Object lastState, Map<String, ReadEnd> readEnds, Map<String, ReadWriteEnd> readWriteEnds);
+
+       // logic model binding
+
+       public void setLogicModelBindingAndResetState(AtomicReference<Object> state, Runnable recalculate)
+       {
+               this.state = state;
+               this.recalculate = recalculate;
+       }
 
        // "graphical" operations
 
@@ -89,16 +126,11 @@ public abstract class SimpleRectangularHardcodedGUIComponent extends GUIComponen
        @Override
        protected void addPin(Pin pin)
        {
-               throw new UnsupportedOperationException("Can't add pins without setting usage, call addPin(Pin, Usage [, Position]) instead");
-       }
-
-       public static enum Usage
-       {
-               INPUT, OUTPUT, TRISTATE;
+               throw new UnsupportedOperationException("Can't add pins without setting usage, call addPin(Pin [, Position]) instead");
        }
 
        static
        {
-               ViewLogicModelAdapter.addComponentAdapter(new SimpleRectangularHardcodedGUIComponentAdapter(c -> c::recalculate));
+               ViewLogicModelAdapter.addComponentAdapter(new SimpleRectangularHardcodedGUIComponentAdapter());
        }
 }
\ No newline at end of file