X-Git-Url: https://mograsim.net/gitweb/?a=blobdiff_plain;f=net.mograsim.logic.model%2Fsrc%2Fnet%2Fmograsim%2Flogic%2Fmodel%2FLogicUICanvas.java;h=812f401afc1b9423393e760346e79fa167d2f94c;hb=1ce42890e85c1a114bf647002d1aa2743ff9871a;hp=b0174373d0e92451840d58b17b43262e45c38a7d;hpb=3a52b6bffe52db5dd5ca907b4b3dfd368a58e14f;p=Mograsim.git diff --git a/net.mograsim.logic.model/src/net/mograsim/logic/model/LogicUICanvas.java b/net.mograsim.logic.model/src/net/mograsim/logic/model/LogicUICanvas.java index b0174373..812f401a 100644 --- a/net.mograsim.logic.model/src/net/mograsim/logic/model/LogicUICanvas.java +++ b/net.mograsim.logic.model/src/net/mograsim/logic/model/LogicUICanvas.java @@ -2,6 +2,8 @@ package net.mograsim.logic.model; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicReference; import java.util.function.Consumer; import org.eclipse.swt.SWT; @@ -36,7 +38,7 @@ import net.mograsim.preferences.Preferences; */ public class LogicUICanvas extends ZoomableCanvas { - private static final boolean OPEN_DEBUG_SETHIGHLEVELSTATE_SHELL = false; + private static final boolean OPEN_DEBUG_SETHIGHLEVELSTATE_SHELL = true; private final LogicModel model; @@ -84,15 +86,21 @@ public class LogicUICanvas extends ZoomableCanvas Combo componentSelector = new Combo(debugShell, SWT.DROP_DOWN | SWT.READ_ONLY); componentSelector.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); List componentsByItemIndex = new ArrayList<>(); - Consumer compsChanged = c -> recalculateComponentSelector(componentsByItemIndex, componentSelector, model); - model.addComponentAddedListener(compsChanged); - model.addComponentRemovedListener(compsChanged); - debugShell.addListener(SWT.Dispose, e -> + List models = new ArrayList<>(); + AtomicBoolean recalculateQueued = new AtomicBoolean(); + AtomicReference> compAdded = new AtomicReference<>(); + AtomicReference> compRemoved = new AtomicReference<>(); + compAdded.set(c -> compsChanged(compAdded.get(), compRemoved.get(), c, models, componentsByItemIndex, componentSelector, model, + recalculateQueued, true)); + compRemoved.set(c -> compsChanged(compAdded.get(), compRemoved.get(), c, models, componentsByItemIndex, componentSelector, model, + recalculateQueued, false)); + iterateModelTree(compAdded.get(), compRemoved.get(), model, models, true); + debugShell.addListener(SWT.Dispose, e -> models.forEach(m -> { - model.removeComponentAddedListener(compsChanged); - model.removeComponentRemovedListener(compsChanged); - }); - recalculateComponentSelector(componentsByItemIndex, componentSelector, model); + m.removeComponentAddedListener(compAdded.get()); + m.removeComponentRemovedListener(compRemoved.get()); + })); + queueRecalculateComponentSelector(recalculateQueued, componentsByItemIndex, componentSelector, model); new Label(debugShell, SWT.NONE).setText("Target state ID: "); Text stateIDText = new Text(debugShell, SWT.SINGLE | SWT.LEAD | SWT.BORDER); stateIDText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); @@ -161,20 +169,66 @@ public class LogicUICanvas extends ZoomableCanvas debugShell.open(); } - private void recalculateComponentSelector(List componentsByItemIndex, Combo componentSelector, LogicModel model) + private void compsChanged(Consumer compAdded, Consumer compRemoved, ModelComponent c, + List models, List componentsByItemIndex, Combo componentSelector, LogicModel model, + AtomicBoolean recalculateQueued, boolean add) + { + iterateSubmodelTree(compAdded, compRemoved, c, models, add); + queueRecalculateComponentSelector(recalculateQueued, componentsByItemIndex, componentSelector, model); + } + + private void iterateSubmodelTree(Consumer compAdded, Consumer compRemoved, + ModelComponent c, List models, boolean add) + { + if (c instanceof SubmodelComponent) + iterateModelTree(compAdded, compRemoved, ((SubmodelComponent) c).submodel, models, add); + } + + private void iterateModelTree(Consumer compAdded, Consumer compRemoved, + LogicModel model, List models, boolean add) + { + if (add ^ models.contains(model)) + { + if (add) + { + models.add(model); + model.addComponentAddedListener(compAdded); + model.addComponentRemovedListener(compRemoved); + } else + { + models.remove(model); + model.removeComponentAddedListener(compAdded); + model.removeComponentRemovedListener(compRemoved); + } + for (ModelComponent c : model.getComponentsByName().values()) + iterateSubmodelTree(compAdded, compRemoved, c, models, add); + } + } + + private void queueRecalculateComponentSelector(AtomicBoolean recalculateQueued, List componentsByItemIndex, + Combo componentSelector, LogicModel model) + { + if (recalculateQueued.compareAndSet(false, true)) + getDisplay().asyncExec(() -> recalculateComponentSelector(recalculateQueued, componentsByItemIndex, componentSelector, model)); + } + + private void recalculateComponentSelector(AtomicBoolean recalculateQueued, List componentsByItemIndex, + Combo componentSelector, LogicModel model) { + recalculateQueued.set(false); componentsByItemIndex.clear(); componentSelector.setItems(); addComponentSelectorItems(componentsByItemIndex, "", componentSelector, model); } - private void addComponentSelectorItems(List componentsByItemIndex, String base, Combo componentSelector, LogicModel model) + private void addComponentSelectorItems(List componentsByItemIndex, String base, Combo componentSelector, + LogicModel model) { - model.getComponentsByName().values().stream().sorted((c1, c2) -> c1.name.compareTo(c2.name)).forEach(c -> + model.getComponentsByName().values().stream().sorted((c1, c2) -> c1.getName().compareTo(c2.getName())).forEach(c -> { if (!(c instanceof ModelWireCrossPoint || c instanceof SubmodelInterface)) { - String item = base + c.name; + String item = base + c.getName(); componentsByItemIndex.add(c); componentSelector.add(item); if (c instanceof SubmodelComponent)