Improved rendering:
authorDaniel Kirschten <daniel.kirschten@gmx.de>
Mon, 3 Jun 2019 13:28:27 +0000 (15:28 +0200)
committerDaniel Kirschten <daniel.kirschten@gmx.de>
Mon, 3 Jun 2019 13:35:02 +0000 (15:35 +0200)
-Splitted LogicUICanvas and LogicUIRenderer
-The ViewModel hierarchy supports redraw listeners

net.mograsim.logic.ui/src/net/mograsim/logic/ui/LogicUICanvas.java
net.mograsim.logic.ui/src/net/mograsim/logic/ui/LogicUIRenderer.java [new file with mode: 0644]
net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/ViewModel.java
net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/GUIBitDisplay.java
net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/GUIComponent.java
net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/components/GUIManualSwitch.java
net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/wires/GUIWire.java
net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/wires/Pin.java
net.mograsim.logic.ui/src/net/mograsim/logic/ui/model/wires/WireCrossPoint.java

index 3a08097..08dc4eb 100644 (file)
@@ -1,19 +1,14 @@
 package net.mograsim.logic.ui;
 
-import java.util.function.Consumer;
-
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Event;
 
-import net.haspamelodica.swt.helper.gcs.GeneralGC;
 import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
 import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle;
 import net.haspamelodica.swt.helper.zoomablecanvas.ZoomableCanvas;
 import net.mograsim.logic.ui.model.ViewModel;
 import net.mograsim.logic.ui.model.components.GUIComponent;
-import net.mograsim.logic.ui.model.wires.GUIWire;
-import net.mograsim.logic.ui.model.wires.Pin;
 
 /**
  * Simulation visualizer canvas.
@@ -22,8 +17,6 @@ import net.mograsim.logic.ui.model.wires.Pin;
  */
 public class LogicUICanvas extends ZoomableCanvas
 {
-       private static final boolean DRAW_PINS = false;
-
        private final ViewModel model;
 
        public LogicUICanvas(Composite parent, int style, ViewModel model)
@@ -32,72 +25,13 @@ public class LogicUICanvas extends ZoomableCanvas
 
                this.model = model;
 
-               Consumer<Object> redrawConsumer = o -> redrawThreadsafe();
-               Consumer<Pin> pinAddedListener = p ->
-               {
-                       p.addPinMovedListener(redrawConsumer);
-                       redrawThreadsafe();
-               };
-               Consumer<Pin> pinRemovedListener = p ->
-               {
-                       p.removePinMovedListener(redrawConsumer);
-                       redrawThreadsafe();
-               };
-               Consumer<? super GUIComponent> componentAddedListener = c ->
-               {
-                       c.addComponentLookChangedListener(redrawConsumer);
-                       c.addComponentMovedListener(redrawConsumer);
-                       c.addPinAddedListener(pinAddedListener);
-                       c.addPinRemovedListener(pinRemovedListener);
-                       redrawThreadsafe();
-               };
-               model.addComponentAddedListener(componentAddedListener);
-               model.getComponents().forEach(componentAddedListener);
-               model.addComponentRemovedListener(c ->
-               {
-                       c.removeComponentLookChangedListener(redrawConsumer);
-                       c.removeComponentMovedListener(redrawConsumer);
-                       c.removePinAddedListener(pinAddedListener);
-                       c.removePinRemovedListener(pinRemovedListener);
-                       redrawThreadsafe();
-               });
-               Consumer<? super GUIWire> wireAddedListener = w ->
-               {
-                       w.addWireLookChangedListener(redrawConsumer);
-                       redrawThreadsafe();
-               };
-               model.addWireAddedListener(wireAddedListener);
-               model.getWires().forEach(wireAddedListener);
-               model.addWireRemovedListener(w ->
-               {
-                       w.removeWireLookChangedListener(redrawConsumer);
-                       redrawThreadsafe();
-               });
+               LogicUIRenderer renderer = new LogicUIRenderer(model);
+               addZoomedRenderer(gc -> renderer.render(gc, new Rectangle(offX, offY, gW / zoom, gH / zoom)));
+               model.addRedrawListener(this::redrawThreadsafe);
 
-               addZoomedRenderer(gc ->
-               {
-                       gc.setLineWidth(.5);
-                       model.getWires().forEach(w -> w.render(gc));
-                       Rectangle visibleRegion = new Rectangle(offX, offY, gW / zoom, gH / zoom);
-                       model.getComponents().forEach(c -> drawComponent(gc, c, visibleRegion));
-               });
                addListener(SWT.MouseDown, this::mouseDown);
        }
 
-       private void drawComponent(GeneralGC gc, GUIComponent component, Rectangle visibleRegion)
-       {
-               component.render(gc, visibleRegion);
-               if (DRAW_PINS)
-               {
-                       gc.setBackground(getDisplay().getSystemColor(SWT.COLOR_DARK_CYAN));
-                       for (Pin p : component.getPins())
-                       {
-                               Point pos = p.getPos();
-                               gc.fillOval(pos.x - 1, pos.y - 1, 2, 2);
-                       }
-               }
-       }
-
        private void mouseDown(Event e)
        {
                if (e.button == 1)
diff --git a/net.mograsim.logic.ui/src/net/mograsim/logic/ui/LogicUIRenderer.java b/net.mograsim.logic.ui/src/net/mograsim/logic/ui/LogicUIRenderer.java
new file mode 100644 (file)
index 0000000..ce20459
--- /dev/null
@@ -0,0 +1,44 @@
+package net.mograsim.logic.ui;
+
+import org.eclipse.swt.SWT;
+
+import net.haspamelodica.swt.helper.gcs.GeneralGC;
+import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
+import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle;
+import net.mograsim.logic.ui.model.ViewModel;
+import net.mograsim.logic.ui.model.components.GUIComponent;
+import net.mograsim.logic.ui.model.wires.Pin;
+
+public class LogicUIRenderer
+{
+       private static final boolean DRAW_PINS = false;
+
+       private final ViewModel model;
+
+       public LogicUIRenderer(ViewModel model)
+       {
+               this.model = model;
+       }
+
+       public void render(GeneralGC gc, Rectangle visibleRegion)
+       {
+               gc.setLineWidth(.5);
+               model.getWires().forEach(w -> w.render(gc));
+               model.getComponents().forEach(c -> drawComponent(gc, c, visibleRegion));
+       }
+
+       private static void drawComponent(GeneralGC gc, GUIComponent component, Rectangle visibleRegion)
+       {
+               component.render(gc, visibleRegion);
+               if (DRAW_PINS)
+               {
+                       gc.setBackground(gc.getDevice().getSystemColor(SWT.COLOR_DARK_CYAN));
+                       for (Pin p : component.getPins())
+                       {
+                               Point pos = p.getPos();
+                               gc.fillOval(pos.x - 1, pos.y - 1, 2, 2);
+                       }
+               }
+       }
+
+}
\ No newline at end of file
index 717ee13..7f9b113 100644 (file)
@@ -19,6 +19,9 @@ public class ViewModel
        private final List<Consumer<? super GUIComponent>> componentRemovedListeners;
        private final List<Consumer<? super GUIWire>> wireAddedListeners;
        private final List<Consumer<? super GUIWire>> wireRemovedListeners;
+       private final List<Runnable> redrawListeners;
+
+       private final Runnable redrawListenerForSubcomponents;
 
        public ViewModel()
        {
@@ -31,6 +34,9 @@ public class ViewModel
                componentRemovedListeners = new ArrayList<>();
                wireAddedListeners = new ArrayList<>();
                wireRemovedListeners = new ArrayList<>();
+               redrawListeners = new ArrayList<>();
+
+               redrawListenerForSubcomponents = this::callRedrawListeners;
        }
 
        /**
@@ -43,6 +49,8 @@ public class ViewModel
                        throw new IllegalStateException("Don't add the same component twice!");
                components.add(component);
                callComponentAddedListeners(component);
+               component.addRedrawListener(redrawListenerForSubcomponents);
+               callRedrawListeners();
        }
 
        /**
@@ -55,6 +63,8 @@ public class ViewModel
                        throw new IllegalStateException("Don't remove the same component twice!");
                components.remove(component);
                callComponentRemovedListeners(component);
+               component.removeRedrawListener(redrawListenerForSubcomponents);
+               callRedrawListeners();
        }
 
        /**
@@ -67,6 +77,8 @@ public class ViewModel
                        throw new IllegalStateException("Don't add the same wire twice!");
                wires.add(wire);
                callWireAddedListeners(wire);
+               wire.addRedrawListener(redrawListenerForSubcomponents);
+               callRedrawListeners();
        }
 
        /**
@@ -79,6 +91,8 @@ public class ViewModel
                        throw new IllegalStateException("Don't remove the same wire twice!");
                wires.remove(wire);
                callWireRemovedListeners(wire);
+               wire.removeRedrawListener(redrawListenerForSubcomponents);
+               callRedrawListeners();
        }
 
        public List<GUIComponent> getComponents()
@@ -91,20 +105,28 @@ public class ViewModel
                return wiresUnmodifiable;
        }
 
+//     public void requestRedraw()
+//     {
+//             callRedrawListeners();
+//     }
+
        // @formatter:off
-       public void addComponentAddedListener     (Consumer<? super GUIComponent> listener){componentAddedListeners  .add   (listener);}
-       public void addComponentRemovedListener   (Consumer<? super GUIComponent> listener){componentRemovedListeners.add   (listener);}
-       public void addWireAddedListener          (Consumer<? super GUIWire     > listener){wireAddedListeners       .add   (listener);}
-       public void addWireRemovedListener        (Consumer<? super GUIWire     > listener){wireRemovedListeners     .add   (listener);}
+       public void addComponentAddedListener     (Consumer<? super GUIComponent> listener) {componentAddedListeners  .add   (listener);}
+       public void addComponentRemovedListener   (Consumer<? super GUIComponent> listener) {componentRemovedListeners.add   (listener);}
+       public void addWireAddedListener          (Consumer<? super GUIWire     > listener) {wireAddedListeners       .add   (listener);}
+       public void addWireRemovedListener        (Consumer<? super GUIWire     > listener) {wireRemovedListeners     .add   (listener);}
+       public void addRedrawListener             (Runnable                       listener) {redrawListeners          .add   (listener);}
 
-       public void removeComponentAddedListener  (Consumer<? super GUIComponent> listener){componentAddedListeners  .remove(listener);}
-       public void removeComponentRemovedListener(Consumer<? super GUIComponent> listener){componentRemovedListeners.remove(listener);}
-       public void removeWireAddedListener       (Consumer<? super GUIWire     > listener){wireAddedListeners       .remove(listener);}
-       public void removeWireRemovedListener     (Consumer<? super GUIWire     > listener){wireRemovedListeners     .remove(listener);}
+       public void removeComponentAddedListener  (Consumer<? super GUIComponent> listener) {componentAddedListeners  .remove(listener);}
+       public void removeComponentRemovedListener(Consumer<? super GUIComponent> listener) {componentRemovedListeners.remove(listener);}
+       public void removeWireAddedListener       (Consumer<? super GUIWire     > listener) {wireAddedListeners       .remove(listener);}
+       public void removeWireRemovedListener     (Consumer<? super GUIWire     > listener) {wireRemovedListeners     .remove(listener);}
+       public void removeRedrawListener          (Runnable                       listener) {redrawListeners          .remove(listener);}
 
        private void callComponentAddedListeners  (GUIComponent c) {componentAddedListeners  .forEach(l -> l.accept(c));}
        private void callComponentRemovedListeners(GUIComponent c) {componentRemovedListeners.forEach(l -> l.accept(c));}
        private void callWireAddedListeners       (GUIWire w     ) {wireAddedListeners       .forEach(l -> l.accept(w));}
        private void callWireRemovedListeners     (GUIWire w     ) {wireRemovedListeners     .forEach(l -> l.accept(w));}
+       private void callRedrawListeners          (              ) {redrawListeners          .forEach(l -> l.run(    ));}
        // @formatter:on
 }
\ No newline at end of file
index 4a75f54..abaec56 100644 (file)
@@ -25,7 +25,7 @@ public class GUIBitDisplay extends GUIComponent
        public GUIBitDisplay(ViewModel model)
        {
                super(model);
-               logicObs = (i) -> callComponentLookChangedListeners();
+               logicObs = (i) -> requestRedraw();
 
                setSize(width, height);
                addPin(this.inputPin = new Pin(this, 1, 0, height / 2));
index 9cea86a..ca21622 100644 (file)
@@ -17,10 +17,12 @@ public abstract class GUIComponent
        private final List<Pin> pins;
        protected final List<Pin> pinsUnmodifiable;
 
-       private final List<Consumer<? super GUIComponent>> componentLookChangedListeners;
        private final List<Consumer<? super GUIComponent>> componentMovedListeners;
        private final List<Consumer<? super Pin>> pinAddedListeners;
        private final List<Consumer<? super Pin>> pinRemovedListeners;
+       private final List<Runnable> redrawListeners;
+
+       private final Runnable redrawListenerForSubcomponents;
 
        public GUIComponent(ViewModel model)
        {
@@ -29,10 +31,12 @@ public abstract class GUIComponent
                this.pins = new ArrayList<>();
                this.pinsUnmodifiable = Collections.unmodifiableList(pins);
 
-               this.componentLookChangedListeners = new ArrayList<>();
                this.componentMovedListeners = new ArrayList<>();
                this.pinAddedListeners = new ArrayList<>();
                this.pinRemovedListeners = new ArrayList<>();
+               this.redrawListeners = new ArrayList<>();
+
+               redrawListenerForSubcomponents = this::callRedrawListeners;
 
                model.componentCreated(this);
        }
@@ -77,43 +81,52 @@ public abstract class GUIComponent
        }
 
        // @formatter:off
-       public void addComponentLookChangedListener   (Consumer<? super GUIComponent> listener) {componentLookChangedListeners.add   (listener);}
-       public void addComponentMovedListener         (Consumer<? super GUIComponent> listener) {componentMovedListeners      .add   (listener);}
-       public void addPinAddedListener               (Consumer<? super Pin         > listener) {pinAddedListeners            .add   (listener);}
-       public void addPinRemovedListener             (Consumer<? super Pin         > listener) {pinRemovedListeners          .add   (listener);}
-                                                  
-       public void removeComponentLookChangedListener(Consumer<? super GUIComponent> listener) {componentLookChangedListeners.remove(listener);}
-       public void removeComponentMovedListener      (Consumer<? super GUIComponent> listener) {componentMovedListeners      .remove(listener);}
-       public void removePinAddedListener            (Consumer<? super Pin         > listener) {pinAddedListeners            .remove(listener);}
-       public void removePinRemovedListener          (Consumer<? super Pin         > listener) {pinRemovedListeners          .remove(listener);}
-
-       protected void callComponentLookChangedListeners(     ) {componentLookChangedListeners.forEach(l -> l.accept(this));}
-       private   void callComponentMovedListeners      (     ) {componentMovedListeners      .forEach(l -> l.accept(this));}
-       private   void callPinAddedListeners            (Pin p) {pinAddedListeners            .forEach(l -> l.accept(p   ));}
-       private   void callPinRemovedListeners          (Pin p) {pinRemovedListeners          .forEach(l -> l.accept(p   ));}
-       // @form  atter:on
+       public void addComponentMovedListener   (Consumer<? super GUIComponent> listener) {componentMovedListeners.add   (listener);}
+       public void addPinAddedListener         (Consumer<? super Pin         > listener) {pinAddedListeners      .add   (listener);}
+       public void addPinRemovedListener       (Consumer<? super Pin         > listener) {pinRemovedListeners    .add   (listener);}
+       public void addRedrawListener           (Runnable                       listener) {redrawListeners        .add   (listener);}
+
+       public void removeComponentMovedListener(Consumer<? super GUIComponent> listener) {componentMovedListeners .remove(listener);}
+       public void removePinAddedListener      (Consumer<? super Pin         > listener) {pinAddedListeners       .remove(listener);}
+       public void removePinRemovedListener    (Consumer<? super Pin         > listener) {pinRemovedListeners     .remove(listener);}
+       public void removeRedrawListener        (Runnable                       listener) {redrawListeners         .remove(listener);}
+
+       private void callComponentMovedListeners(     ) {componentMovedListeners.forEach(l -> l.accept(this));}
+       private void callPinAddedListeners      (Pin p) {pinAddedListeners      .forEach(l -> l.accept(p   ));}
+       private void callPinRemovedListeners    (Pin p) {pinRemovedListeners    .forEach(l -> l.accept(p   ));}
+       private void callRedrawListeners        (     ) {redrawListeners        .forEach(l -> l.run(       ));}
+       // @formatter:on
 
        /**
         * Render this component to the given gc.
         */
        public abstract void render(GeneralGC gc, Rectangle visibleRegion);
 
+       protected void requestRedraw()
+       {
+               callRedrawListeners();
+       }
+
        protected void setSize(double width, double height)
        {
                bounds.width = width;
                bounds.height = height;
-               callComponentLookChangedListeners();
+               callRedrawListeners();
        }
 
        protected void addPin(Pin pin)
        {
                pins.add(pin);
                callPinAddedListeners(pin);
+               pin.addRedrawListener(redrawListenerForSubcomponents);
+               callRedrawListeners();
        }
 
        protected void removePin(Pin pin)
        {
                pins.remove(pin);
                callPinRemovedListeners(pin);
+               pin.removeRedrawListener(redrawListenerForSubcomponents);
+               callRedrawListeners();
        }
 }
\ No newline at end of file
index 0d418ce..8d63596 100644 (file)
@@ -27,7 +27,7 @@ public class GUIManualSwitch extends GUIComponent
        public GUIManualSwitch(ViewModel model)\r
        {\r
                super(model);\r
-               logicObs = (i) -> callComponentLookChangedListeners();\r
+               logicObs = (i) -> requestRedraw();\r
 \r
                setSize(width, height);\r
                addPin(this.outputPin = new Pin(this, 1, width, height / 2));\r
index 86a545d..82fdf4b 100644 (file)
@@ -2,14 +2,15 @@ package net.mograsim.logic.ui.model.wires;
 \r
 import java.util.ArrayList;\r
 import java.util.List;\r
-import java.util.function.Consumer;\r
 \r
-import net.mograsim.logic.ui.ColorHelper;\r
-import net.mograsim.logic.ui.model.ViewModel;\r
 import net.haspamelodica.swt.helper.gcs.GeneralGC;\r
 import net.haspamelodica.swt.helper.swtobjectwrappers.Point;\r
+import net.mograsim.logic.core.LogicObservable;\r
+import net.mograsim.logic.core.LogicObserver;\r
 import net.mograsim.logic.core.types.BitVectorFormatter;\r
 import net.mograsim.logic.core.wires.Wire.ReadEnd;\r
+import net.mograsim.logic.ui.ColorHelper;\r
+import net.mograsim.logic.ui.model.ViewModel;\r
 \r
 public class GUIWire\r
 {\r
@@ -19,12 +20,14 @@ public class GUIWire
        private Pin pin2;\r
        private double[] path;\r
 \r
-       private final List<Consumer<? super GUIWire>> wireLookChangedListeners;\r
+       private final List<Runnable> redrawListeners;\r
 \r
+       private final LogicObserver logicObs;\r
        private ReadEnd end;\r
 \r
        public GUIWire(ViewModel model, Pin pin1, Pin pin2, Point... path)\r
        {\r
+               logicObs = (i) -> callRedrawListeners();\r
                this.model = model;\r
                this.logicWidth = pin1.logicWidth;\r
                if (pin2.logicWidth != pin1.logicWidth)\r
@@ -39,7 +42,7 @@ public class GUIWire
                this.pin1 = pin1;\r
                this.pin2 = pin2;\r
 \r
-               wireLookChangedListeners = new ArrayList<>();\r
+               redrawListeners = new ArrayList<>();\r
 \r
                pin1.addPinMovedListener(p -> pin1Moved());\r
                pin2.addPinMovedListener(p -> pin2Moved());\r
@@ -54,6 +57,7 @@ public class GUIWire
                Point pos = pin1.getPos();\r
                this.path[0] = pos.x;\r
                this.path[1] = pos.y;\r
+               callRedrawListeners();\r
        }\r
 \r
        private void pin2Moved()\r
@@ -61,6 +65,7 @@ public class GUIWire
                Point pos = pin2.getPos();\r
                this.path[this.path.length - 2] = pos.x;\r
                this.path[this.path.length - 1] = pos.y;\r
+               callRedrawListeners();\r
        }\r
 \r
        public void destroy()\r
@@ -75,8 +80,21 @@ public class GUIWire
 \r
        public void setLogicModelBinding(ReadEnd end)\r
        {\r
+               deregisterLogicObs(this.end);\r
                this.end = end;\r
-               end.registerObserver((i) -> callWireLookChangedListeners());\r
+               registerLogicObs(end);\r
+       }\r
+\r
+       private void registerLogicObs(LogicObservable observable)\r
+       {\r
+               if (observable != null)\r
+                       observable.registerObserver(logicObs);\r
+       }\r
+\r
+       private void deregisterLogicObs(LogicObservable observable)\r
+       {\r
+               if (observable != null)\r
+                       observable.deregisterObserver(logicObs);\r
        }\r
 \r
        public Pin getPin1()\r
@@ -90,11 +108,11 @@ public class GUIWire
        }\r
 \r
        // @formatter:off\r
-       public void addWireLookChangedListener   (Consumer<? super GUIWire> listener) {wireLookChangedListeners.add   (listener);}\r
+       public void addRedrawListener   (Runnable listener) {redrawListeners         .add   (listener);}\r
 \r
-       public void removeWireLookChangedListener(Consumer<? super GUIWire> listener) {wireLookChangedListeners.remove(listener);}\r
+       public void removeRedrawListener(Runnable listener) {redrawListeners         .remove(listener);}\r
 \r
-       private void callWireLookChangedListeners() {wireLookChangedListeners.forEach(l -> l.accept(this));}\r
+       private void callRedrawListeners() {redrawListeners.forEach(l -> l.run());}\r
        // @formatter:on\r
 \r
 }
\ No newline at end of file
index 5163583..8c0333a 100644 (file)
@@ -18,6 +18,7 @@ public class Pin
        protected double relY;
 
        private final List<Consumer<? super Pin>> pinMovedListeners;
+       private final List<Runnable> redrawListeners;
 
        public Pin(GUIComponent component, int logicWidth, double relX, double relY)
        {
@@ -27,6 +28,7 @@ public class Pin
                this.relY = relY;
 
                this.pinMovedListeners = new ArrayList<>();
+               this.redrawListeners = new ArrayList<>();
 
                component.addComponentMovedListener(c -> callPinMovedListeners());
        }
@@ -52,18 +54,23 @@ public class Pin
                return new Point(relX + componentBounds.x, relY + componentBounds.y);
        }
 
+       protected void setRelPos(double relX, double relY)
+       {
+               this.relX = relX;
+               this.relY = relY;
+               callPinMovedListeners();
+               callRedrawListeners();
+       }
+
        // @formatter:off
        public void addPinMovedListener   (Consumer<? super Pin> listener){pinMovedListeners.add   (listener);}
+       public void addRedrawListener     (Runnable              listener){redrawListeners  .add   (listener);}
 
        public void removePinMovedListener(Consumer<? super Pin> listener){pinMovedListeners.remove(listener);}
+       public void removeRedrawListener  (Runnable              listener){redrawListeners  .remove(listener);}
 
        private void callPinMovedListeners() {pinMovedListeners.forEach(l -> l.accept(this));}
+       private void callRedrawListeners  () {redrawListeners  .forEach(l -> l.run   (    ));}
        // @formatter:on
 
-       protected void setRelPos(double relX, double relY)
-       {
-               this.relX = relX;
-               this.relY = relY;
-               callPinMovedListeners();
-       }
 }
\ No newline at end of file
index b4aaa98..fb161ac 100644 (file)
@@ -1,23 +1,28 @@
 package net.mograsim.logic.ui.model.wires;\r
 \r
-import net.mograsim.logic.ui.ColorHelper;\r
-import net.mograsim.logic.ui.model.ViewModel;\r
-import net.mograsim.logic.ui.model.components.GUIComponent;\r
 import net.haspamelodica.swt.helper.gcs.GeneralGC;\r
 import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle;\r
+import net.mograsim.logic.core.LogicObservable;\r
+import net.mograsim.logic.core.LogicObserver;\r
 import net.mograsim.logic.core.types.BitVectorFormatter;\r
 import net.mograsim.logic.core.wires.Wire.ReadEnd;\r
+import net.mograsim.logic.ui.ColorHelper;\r
+import net.mograsim.logic.ui.model.ViewModel;\r
+import net.mograsim.logic.ui.model.components.GUIComponent;\r
 \r
 public class WireCrossPoint extends GUIComponent\r
 {\r
        private final Pin pin;\r
+       private final int logicWidth;\r
 \r
+       private final LogicObserver logicObs;\r
        private ReadEnd end;\r
-       private final int logicWidth;\r
 \r
        public WireCrossPoint(ViewModel model, int logicWidth)\r
        {\r
                super(model);\r
+               logicObs = (i) -> requestRedraw();\r
+\r
                this.logicWidth = logicWidth;\r
                setSize(0, 0);\r
                addPin(this.pin = new Pin(this, logicWidth, 0, 0));\r
@@ -33,8 +38,21 @@ public class WireCrossPoint extends GUIComponent
 \r
        public void setLogicModelBinding(ReadEnd end)\r
        {\r
+               deregisterLogicObs(this.end);\r
                this.end = end;\r
-               end.registerObserver((i) -> callComponentLookChangedListeners());\r
+               registerLogicObs(end);\r
+       }\r
+\r
+       private void registerLogicObs(LogicObservable observable)\r
+       {\r
+               if (observable != null)\r
+                       observable.registerObserver(logicObs);\r
+       }\r
+\r
+       private void deregisterLogicObs(LogicObservable observable)\r
+       {\r
+               if (observable != null)\r
+                       observable.deregisterObserver(logicObs);\r
        }\r
 \r
        public int getLogicWidth()\r