From 9e0665527c4813950f523164cd753652feacbd21 Mon Sep 17 00:00:00 2001 From: Daniel Kirschten Date: Mon, 2 Sep 2019 13:09:41 +0200 Subject: [PATCH] Fixed ViewModels being modifiable via GUIComponent/Wire#destroy. --- .../ReserializeJSONsSettingUsages.java | 2 +- .../model/editor/handles/ComponentHandle.java | 7 ++-- .../model/editor/handles/HandleManager.java | 4 +-- .../model/editor/handles/WireHandle.java | 7 ++-- .../mograsim/logic/model/model/ViewModel.java | 33 +++++++++++++------ .../model/model/ViewModelModifiable.java | 17 +++++----- .../model/model/components/GUIComponent.java | 10 +++--- .../logic/model/model/wires/GUIWire.java | 10 +++--- 8 files changed, 54 insertions(+), 36 deletions(-) diff --git a/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/examples/ReserializeJSONsSettingUsages.java b/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/examples/ReserializeJSONsSettingUsages.java index d5faf7ed..2f411539 100644 --- a/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/examples/ReserializeJSONsSettingUsages.java +++ b/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/examples/ReserializeJSONsSettingUsages.java @@ -75,7 +75,7 @@ public class ReserializeJSONsSettingUsages { Set wiresConnectedToPin = comp.submodel.getWiresByName().values().stream() .filter(w -> w.getPin1() == interfacePin || w.getPin2() == interfacePin).collect(Collectors.toSet()); - wiresConnectedToPin.forEach(GUIWire::destroy); + wiresConnectedToPin.forEach(comp.getSubmodelModifiable()::destroyWire); comp.removeSubmodelInterface(interfacePin.name); comp.addSubmodelInterface( new MovablePin(comp, interfacePin.name, interfacePin.logicWidth, usage, interfacePin.getRelX(), interfacePin.getRelY())); diff --git a/net.mograsim.logic.model.editor/src/net/mograsim/logic/model/editor/handles/ComponentHandle.java b/net.mograsim.logic.model.editor/src/net/mograsim/logic/model/editor/handles/ComponentHandle.java index b44f1cf0..fedca497 100644 --- a/net.mograsim.logic.model.editor/src/net/mograsim/logic/model/editor/handles/ComponentHandle.java +++ b/net.mograsim.logic.model.editor/src/net/mograsim/logic/model/editor/handles/ComponentHandle.java @@ -10,19 +10,22 @@ import net.haspamelodica.swt.helper.swtobjectwrappers.Point; import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle; import net.mograsim.logic.model.editor.Editor; import net.mograsim.logic.model.editor.Editor.ComponentInfo; +import net.mograsim.logic.model.model.ViewModelModifiable; import net.mograsim.logic.model.model.components.GUIComponent; import net.mograsim.logic.model.serializing.IdentifierGetter; public class ComponentHandle extends Handle { + private final ViewModelModifiable model; public final GUIComponent parent; private final static double POS_OFFSET = 2.0d; private final static double LENGTH_OFFSET = POS_OFFSET * 2; boolean selected = false; - public ComponentHandle(GUIComponent parent) + public ComponentHandle(ViewModelModifiable model, GUIComponent parent) { super(4); + this.model = model; this.parent = parent; Rectangle bounds = parent.getBounds(); setSize(bounds.width, bounds.height); @@ -80,7 +83,7 @@ public class ComponentHandle extends Handle @Override public void reqDelete() { - parent.destroy(); + model.destroyComponent(parent); } @Override diff --git a/net.mograsim.logic.model.editor/src/net/mograsim/logic/model/editor/handles/HandleManager.java b/net.mograsim.logic.model.editor/src/net/mograsim/logic/model/editor/handles/HandleManager.java index 24eb36d7..51890038 100644 --- a/net.mograsim.logic.model.editor/src/net/mograsim/logic/model/editor/handles/HandleManager.java +++ b/net.mograsim.logic.model.editor/src/net/mograsim/logic/model/editor/handles/HandleManager.java @@ -154,7 +154,7 @@ public class HandleManager private void addComponentHandle(GUIComponent c) { - ComponentHandle h = new ComponentHandle(c); + ComponentHandle h = new ComponentHandle(editor.getSubmodel(), c); handlePerComp.put(c, h); addHandle(h); } @@ -240,7 +240,7 @@ public class HandleManager private void addWireHandle(GUIWire w) { - WireHandle h = new WireHandle(w); + WireHandle h = new WireHandle(editor.getSubmodel(), w); handlePerWire.put(w, h); addHandle(h); } diff --git a/net.mograsim.logic.model.editor/src/net/mograsim/logic/model/editor/handles/WireHandle.java b/net.mograsim.logic.model.editor/src/net/mograsim/logic/model/editor/handles/WireHandle.java index 7629dcb1..be9a5ca6 100644 --- a/net.mograsim.logic.model.editor/src/net/mograsim/logic/model/editor/handles/WireHandle.java +++ b/net.mograsim.logic.model.editor/src/net/mograsim/logic/model/editor/handles/WireHandle.java @@ -9,6 +9,7 @@ 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.model.editor.states.EditorState; +import net.mograsim.logic.model.model.ViewModelModifiable; import net.mograsim.logic.model.model.wires.GUIWire; public class WireHandle extends Handle @@ -16,11 +17,13 @@ public class WireHandle extends Handle private boolean selected = false; private final static double WIDTH = 2.0; private final static double WIDTH_SQUARED = WIDTH * WIDTH; + private final ViewModelModifiable model; public final GUIWire parent; - public WireHandle(GUIWire parent) + public WireHandle(ViewModelModifiable model, GUIWire parent) { super(5); + this.model = model; this.parent = parent; parent.addPathChangedListener(c -> updateBounds()); updateBounds(); @@ -68,7 +71,7 @@ public class WireHandle extends Handle @Override public void reqDelete() { - parent.destroy(); + model.destroyWire(parent); } @Override diff --git a/net.mograsim.logic.model/src/net/mograsim/logic/model/model/ViewModel.java b/net.mograsim.logic.model/src/net/mograsim/logic/model/model/ViewModel.java index c85f1fd3..cf679cd1 100644 --- a/net.mograsim.logic.model/src/net/mograsim/logic/model/model/ViewModel.java +++ b/net.mograsim.logic.model/src/net/mograsim/logic/model/model/ViewModel.java @@ -13,8 +13,10 @@ import net.mograsim.logic.model.model.wires.GUIWire; public class ViewModel { private final Map components; + private final Map componentDestroyFunctions; private final Map componentsUnmodifiable; private final Map wires; + private final Map wireDestroyFunctions; private final Map wiresUnmodifiable; private final List> componentAddedListeners; @@ -28,8 +30,10 @@ public class ViewModel protected ViewModel() { components = new HashMap<>(); + componentDestroyFunctions = new HashMap<>(); componentsUnmodifiable = Collections.unmodifiableMap(components); wires = new HashMap<>(); + wireDestroyFunctions = new HashMap<>(); wiresUnmodifiable = Collections.unmodifiableMap(wires); componentAddedListeners = new ArrayList<>(); @@ -42,22 +46,27 @@ public class ViewModel /** * Adds the given component to the list of components and calls all componentAddedListeners. Don't call this method from application * code as it is automatically called in {@link GUIComponent}'s constructor. + * + * @author Daniel Kirschten */ - protected void componentCreated(GUIComponent component) + protected void componentCreated(GUIComponent component, Runnable destroyed) { if (components.containsKey(component.name)) throw new IllegalStateException("Don't add the same component twice!"); components.put(component.name, component); + componentDestroyFunctions.put(component.name, destroyed); callComponentAddedListeners(component); requestRedraw(); } /** - * Removes the given component from the list of components and calls all componentRemovedListeners. Don't call this method from - * application code as it is automatically called in {@link GUIComponent#destroy()}. + * Destroyes the given component, removes it from the list of components and calls all componentRemovedListeners. + * + * @author Daniel Kirschten */ - protected void componentDestroyed(GUIComponent component) + protected void destroyComponent(GUIComponent component) { + componentDestroyFunctions.get(component.name).run(); if (!components.containsKey(component.name)) throw new IllegalStateException("Don't remove the same component twice!"); components.remove(component.name); @@ -66,24 +75,28 @@ public class ViewModel } /** - * Adds the given wire to the list of wires and calls all wireAddedListeners. Don't call this method from application code as it is - * automatically called in {@link GUIWire}'s constructor(s). + * Adds the given wire to the list of wires and calls all wireAddedListeners. + * + * @author Daniel Kirschten */ - protected void wireCreated(GUIWire wire) + protected void wireCreated(GUIWire wire, Runnable destroyed) { if (wires.containsKey(wire.name)) throw new IllegalStateException("Don't add the same wire twice!"); wires.put(wire.name, wire); + wireDestroyFunctions.put(wire.name, destroyed); callWireAddedListeners(wire); requestRedraw(); } /** - * Removes the given wire from the list of wires and calls all wireRemovedListeners. Don't call this method from application code as it - * is automatically called in {@link GUIWire#destroy()}. + * Destroys the given wire, removes it from the list of wires and calls all wireRemovedListeners. + * + * @author Daniel Kirschten */ - protected void wireDestroyed(GUIWire wire) + protected void destroyWire(GUIWire wire) { + wireDestroyFunctions.get(wire.name).run(); if (!wires.containsKey(wire.name)) throw new IllegalStateException("Don't remove the same wire twice!"); wires.remove(wire.name); diff --git a/net.mograsim.logic.model/src/net/mograsim/logic/model/model/ViewModelModifiable.java b/net.mograsim.logic.model/src/net/mograsim/logic/model/model/ViewModelModifiable.java index 97993a7d..b4fa4f53 100644 --- a/net.mograsim.logic.model/src/net/mograsim/logic/model/model/ViewModelModifiable.java +++ b/net.mograsim.logic.model/src/net/mograsim/logic/model/model/ViewModelModifiable.java @@ -5,7 +5,6 @@ import java.util.Set; import net.mograsim.logic.model.model.components.GUIComponent; import net.mograsim.logic.model.model.wires.GUIWire; -//TODO a ViewModel is modifiable without casting to ViewModelModifiable via GUIWire::destroy and GUIComponent::destroy public class ViewModelModifiable extends ViewModel { public String getDefaultComponentName(GUIComponent component) @@ -41,26 +40,26 @@ public class ViewModelModifiable extends ViewModel } @Override - public void componentCreated(GUIComponent component) + public void componentCreated(GUIComponent component, Runnable destroyed) { - super.componentCreated(component); + super.componentCreated(component, destroyed); } @Override - public void componentDestroyed(GUIComponent component) + public void destroyComponent(GUIComponent component) { - super.componentDestroyed(component); + super.destroyComponent(component); } @Override - public void wireCreated(GUIWire wire) + public void wireCreated(GUIWire wire, Runnable destroyed) { - super.wireCreated(wire); + super.wireCreated(wire, destroyed); } @Override - public void wireDestroyed(GUIWire wire) + public void destroyWire(GUIWire wire) { - super.wireDestroyed(wire); + super.destroyWire(wire); } } \ No newline at end of file diff --git a/net.mograsim.logic.model/src/net/mograsim/logic/model/model/components/GUIComponent.java b/net.mograsim.logic.model/src/net/mograsim/logic/model/model/components/GUIComponent.java index 60e8fb2a..11c4334d 100644 --- a/net.mograsim.logic.model/src/net/mograsim/logic/model/model/components/GUIComponent.java +++ b/net.mograsim.logic.model/src/net/mograsim/logic/model/model/components/GUIComponent.java @@ -70,19 +70,19 @@ public abstract class GUIComponent implements JSONSerializable // TODO this will crash the high level state debug shell because submodel is not yet set. // The same problem exists in ViewModelModifiable.getDefaultComponentName; see there - model.componentCreated(this); + model.componentCreated(this, this::destroyed); } /** - * Destroys this component. This method implicitly calls {@link ViewModelModifiable#componentDestroyed(GUIComponent) - * componentDestroyed()} for the model this component is a part of. + * Destroys this component. This method is called from {@link ViewModelModifiable#componentDestroyed(GUIComponent) destroyComponent()} + * of the model this component is a part of.
+ * When overriding, make sure to also call the original implementation. * * @author Daniel Kirschten */ - public void destroy() + protected void destroyed() { pinsByName.values().forEach(p -> pinRemovedListeners.forEach(l -> l.accept(p))); - model.componentDestroyed(this); } // pins diff --git a/net.mograsim.logic.model/src/net/mograsim/logic/model/model/wires/GUIWire.java b/net.mograsim.logic.model/src/net/mograsim/logic/model/model/wires/GUIWire.java index 99241a3e..8b91fc4d 100644 --- a/net.mograsim.logic.model/src/net/mograsim/logic/model/model/wires/GUIWire.java +++ b/net.mograsim.logic.model/src/net/mograsim/logic/model/model/wires/GUIWire.java @@ -252,18 +252,18 @@ public class GUIWire recalculateEffectivePath(); - model.wireCreated(this); + model.wireCreated(this, this::destroyed); } /** - * Destroys this wire. This method implicitly calls {@link ViewModelModifiable#wireDestroyed(GUIWire) wireDestroyed()} for the model - * this component is a part of. + * Destroys this wire. This method is called from {@link ViewModelModifiable#wireDestroyed(GUIWire) wireDestroyed()} of the model this + * wire is a part of. * * @author Daniel Kirschten */ - public void destroy() + private void destroyed() { - model.wireDestroyed(this); + // nothing to do } // pins -- 2.17.1