{
Set<GUIWire> 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()));
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);
@Override
public void reqDelete()
{
- parent.destroy();
+ model.destroyComponent(parent);
}
@Override
private void addComponentHandle(GUIComponent c)
{
- ComponentHandle h = new ComponentHandle(c);
+ ComponentHandle h = new ComponentHandle(editor.getSubmodel(), c);
handlePerComp.put(c, h);
addHandle(h);
}
private void addWireHandle(GUIWire w)
{
- WireHandle h = new WireHandle(w);
+ WireHandle h = new WireHandle(editor.getSubmodel(), w);
handlePerWire.put(w, h);
addHandle(h);
}
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
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();
@Override
public void reqDelete()
{
- parent.destroy();
+ model.destroyWire(parent);
}
@Override
public class ViewModel
{
private final Map<String, GUIComponent> components;
+ private final Map<String, Runnable> componentDestroyFunctions;
private final Map<String, GUIComponent> componentsUnmodifiable;
private final Map<String, GUIWire> wires;
+ private final Map<String, Runnable> wireDestroyFunctions;
private final Map<String, GUIWire> wiresUnmodifiable;
private final List<Consumer<? super GUIComponent>> componentAddedListeners;
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<>();
/**
* 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);
}
/**
- * 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);
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)
}
@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
// 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.<br>
+ * 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
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