package net.mograsim.logic.model;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;
import org.eclipse.swt.SWT;
import net.mograsim.logic.model.model.LogicModel;
import net.mograsim.logic.model.model.components.ModelComponent;
import net.mograsim.logic.model.model.components.submodels.SubmodelComponent;
-import net.mograsim.logic.model.model.components.submodels.SubmodelInterface;
-import net.mograsim.logic.model.model.wires.ModelWireCrossPoint;
+import net.mograsim.logic.model.snippets.highlevelstatehandlers.DefaultHighLevelStateHandler;
import net.mograsim.preferences.Preferences;
/**
*/
public class LogicUICanvas extends ZoomableCanvas
{
- private static final boolean OPEN_DEBUG_SETHIGHLEVELSTATE_SHELL = false;
-
private final LogicModel model;
public LogicUICanvas(Composite parent, int style, LogicModel model)
setBackground(background);// this.setBackground, not gc.setBackground to have the background fill the canvas
renderer.render(gc, new Rectangle(-offX / zoom, -offY / zoom, gW / zoom, gH / zoom));
});
- model.setRedrawHandler(this::redrawThreadsafe);
+ model.setRedrawHandler(() ->
+ {
+ if (!isDisposed())
+ redrawThreadsafe();
+ });
addListener(SWT.MouseDown, this::mouseDown);
- if (OPEN_DEBUG_SETHIGHLEVELSTATE_SHELL)
+ if (Preferences.current().getBoolean("net.mograsim.logic.model.debug.openhlsshell"))
openDebugSetHighLevelStateShell(model);
}
private void mouseDown(Event e)
{
- if (e.button == 1)
+ if (e.button == Preferences.current().getInt("net.mograsim.logic.model.button.action"))
{
Point click = canvasToWorldCoords(e.x, e.y);
for (ModelComponent component : model.getComponentsByName().values())
List<ModelComponent> componentsByItemIndex = new ArrayList<>();
List<LogicModel> models = new ArrayList<>();
AtomicBoolean recalculateQueued = new AtomicBoolean();
- AtomicReference<Consumer<? super ModelComponent>> compAdded = new AtomicReference<>();
- AtomicReference<Consumer<? super ModelComponent>> 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);
+ @SuppressWarnings("unchecked")
+ Consumer<? super ModelComponent>[] compAdded = new Consumer[1];
+ @SuppressWarnings("unchecked")
+ Consumer<? super ModelComponent>[] compRemoved = new Consumer[1];
+ compAdded[0] = c -> compsChanged(compAdded[0], compRemoved[0], c, models, componentsByItemIndex, componentSelector, model,
+ recalculateQueued, true);
+ compRemoved[0] = c -> compsChanged(compAdded[0], compRemoved[0], c, models, componentsByItemIndex, componentSelector, model,
+ recalculateQueued, false);
+ iterateModelTree(compAdded[0], compRemoved[0], model, models, true);
debugShell.addListener(SWT.Dispose, e -> models.forEach(m ->
{
- m.removeComponentAddedListener(compAdded.get());
- m.removeComponentRemovedListener(compRemoved.get());
+ m.removeComponentAddedListener(compAdded[0]);
+ m.removeComponentRemovedListener(compRemoved[0]);
}));
queueRecalculateComponentSelector(recalculateQueued, componentsByItemIndex, componentSelector, model);
new Label(debugShell, SWT.NONE).setText("Target state ID: ");
valueText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
Button send = new Button(debugShell, SWT.PUSH);
send.setText("Send!");
+ Button addListener = new Button(debugShell, SWT.PUSH);
+ addListener.setText("Add sysout listener");
Button get = new Button(debugShell, SWT.PUSH);
get.setText("Get!");
+ Button removeListener = new Button(debugShell, SWT.PUSH);
+ removeListener.setText("Remove sysout listener");
Text output = new Text(debugShell, SWT.READ_ONLY);
output.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1));
Listener sendAction = e ->
{
try
{
- if (componentSelector.getSelectionIndex() >= componentsByItemIndex.size())
- throw new RuntimeException("No valid component selected");
+ int componentIndex = componentSelector.getSelectionIndex();
+ if (componentIndex < 0 || componentIndex >= componentsByItemIndex.size())
+ throw new RuntimeException("No component selected");
output.setText("Success! Value: \r\n"
+ componentsByItemIndex.get(componentSelector.getSelectionIndex()).getHighLevelState(stateIDText.getText()));
}
valueText.addListener(SWT.DefaultSelection, sendAction);
get.addListener(SWT.Selection, getAction);
stateIDText.addListener(SWT.DefaultSelection, getAction);
+ Map<ModelComponent, Map<String, Consumer<Object>>> sysoutListenersPerHLSPerTarget = new HashMap<>();
+ addListener.addListener(SWT.Selection, e ->
+ {
+ try
+ {
+ int componentIndex = componentSelector.getSelectionIndex();
+ if (componentIndex < 0 || componentIndex >= componentsByItemIndex.size())
+ throw new RuntimeException("No component selected");
+ ModelComponent target = componentsByItemIndex.get(componentIndex);
+ Map<String, Consumer<Object>> sysoutListenersPerHLS = sysoutListenersPerHLSPerTarget.computeIfAbsent(target,
+ k -> new HashMap<>());
+ String stateIDString = stateIDText.getText();
+ if (sysoutListenersPerHLS.containsKey(stateIDString))
+ throw new RuntimeException("Listener already registered");
+ Consumer<Object> sysoutListener = v -> System.out.println(stateIDString + ": " + v);
+ target.addHighLevelStateListener(stateIDString, sysoutListener);
+ sysoutListenersPerHLS.put(stateIDString, sysoutListener);
+ output.setText("Success!");
+ }
+ catch (Exception x)
+ {
+ output.setText(x.getClass().getSimpleName() + (x.getMessage() == null ? "" : ": " + x.getMessage()));
+ }
+ });
+ removeListener.addListener(SWT.Selection, e ->
+ {
+ try
+ {
+ int componentIndex = componentSelector.getSelectionIndex();
+ if (componentIndex < 0 || componentIndex >= componentsByItemIndex.size())
+ throw new RuntimeException("No component selected");
+ ModelComponent target = componentsByItemIndex.get(componentIndex);
+ Map<String, Consumer<Object>> sysoutListenersPerHLS = sysoutListenersPerHLSPerTarget.get(target);
+ if (sysoutListenersPerHLS == null)
+ throw new RuntimeException("Listener not registered");
+ String stateIDString = stateIDText.getText();
+ Consumer<Object> sysoutListener = sysoutListenersPerHLS.remove(stateIDString);
+ if (sysoutListener == null)
+ throw new RuntimeException("Listener not registered");
+ target.removeHighLevelStateListener(stateIDString, sysoutListener);
+ output.setText("Success!");
+ }
+ catch (Exception x)
+ {
+ output.setText(x.getClass().getSimpleName() + (x.getMessage() == null ? "" : ": " + x.getMessage()));
+ }
+ });
debugShell.open();
+ addDisposeListener(e -> debugShell.dispose());
}
private void compsChanged(Consumer<? super ModelComponent> compAdded, Consumer<? super ModelComponent> compRemoved, ModelComponent c,
recalculateQueued.set(false);
componentsByItemIndex.clear();
componentSelector.setItems();
- addComponentSelectorItems(componentsByItemIndex, "", componentSelector, model);
+ addComponentSelectorItems(componentsByItemIndex, "", componentSelector, model,
+ Preferences.current().getInt("net.mograsim.logic.model.debug.hlsshelldepth") - 1);
}
private void addComponentSelectorItems(List<ModelComponent> componentsByItemIndex, String base, Combo componentSelector,
- LogicModel model)
+ LogicModel model, int depth)
{
model.getComponentsByName().values().stream().sorted((c1, c2) -> c1.getName().compareTo(c2.getName())).forEach(c ->
{
- if (!(c instanceof ModelWireCrossPoint || c instanceof SubmodelInterface))
+ if (!(c.getHighLevelStateHandler() instanceof DefaultHighLevelStateHandler))
{
String item = base + c.getName();
componentsByItemIndex.add(c);
componentSelector.add(item);
- if (c instanceof SubmodelComponent)
- addComponentSelectorItems(componentsByItemIndex, item + " -> ", componentSelector, ((SubmodelComponent) c).submodel);
+ // this causes negative numbers to result in infinite depth
+ if (depth != 0 && c instanceof SubmodelComponent)
+ addComponentSelectorItems(componentsByItemIndex, item + " -> ", componentSelector, ((SubmodelComponent) c).submodel,
+ depth - 1);
}
});
}