import net.haspamelodica.swt.helper.zoomablecanvas.helper.ZoomableCanvasOverlay;\r
import net.haspamelodica.swt.helper.zoomablecanvas.helper.ZoomableCanvasUserInput;\r
\r
+/**\r
+ * Standalone simulation visualizer.\r
+ * \r
+ * @author Daniel Kirschten\r
+ */\r
public class LogicUI\r
{\r
- private final Display display;\r
- private final Shell shell;\r
- private final ZoomableCanvas canvas;\r
- private final Set<BasicGUIComponent> components;\r
- private final Map<BasicGUIComponent, Point> componentPositions;\r
- private final Set<GUIWire> wires;\r
+ private final Display display;\r
+ private final Shell shell;\r
+ private final ZoomableCanvas canvas;\r
+ private final Set<BasicGUIComponent> components;\r
+ private final Map<BasicGUIComponent, Point> componentPositions;\r
+ private final Set<GUIWire> wires;\r
\r
public LogicUI()\r
{\r
new ZoomableCanvasOverlay(canvas, null).enableScale();\r
canvas.addListener(SWT.MouseDown, this::mouseDown);\r
}\r
+\r
/**\r
- * Returns the given component for convenience.\r
+ * Add a component to be drawn. Returns the given component for convenience.\r
+ * \r
+ * @author Daniel Kirschten\r
*/\r
public <C extends BasicGUIComponent> C addComponent(C component, double x, double y)\r
{\r
componentPositions.put(component, new Point(x, y));\r
return component;\r
}\r
- public void addWire(BasicGUIComponent component1, int component1ConnectionIndex, BasicGUIComponent component2, int component2ConnectionIndex, Point... path)\r
+\r
+ /**\r
+ * Add a graphical wire between the given connection points of the given components. The given components have to be added and the given\r
+ * connection points have to be connected logically first.\r
+ * \r
+ * @author Daniel Kirschten\r
+ */\r
+ public void addWire(BasicGUIComponent component1, int component1ConnectionIndex, BasicGUIComponent component2,\r
+ int component2ConnectionIndex, Point... path)\r
{\r
- wires.add(new GUIWire(canvas::redrawThreadsafe, component1, component1ConnectionIndex, componentPositions.get(component1), component2, component2ConnectionIndex, componentPositions.get(component2), path));\r
+ wires.add(new GUIWire(canvas::redrawThreadsafe, component1, component1ConnectionIndex, componentPositions.get(component1),\r
+ component2, component2ConnectionIndex, componentPositions.get(component2), path));\r
}\r
+\r
private void drawComponent(GeneralGC gc, BasicGUIComponent component)\r
{\r
TranslatedGC tgc = new TranslatedGC(gc, componentPositions.get(component));\r
component.render(tgc);\r
tgc.setBackground(display.getSystemColor(SWT.COLOR_BLUE));\r
-// for(int i = 0; i < component.getConnectedWireArraysCount(); i ++)\r
-// {\r
-// Point connectionPoint = component.getWireArrayConnectionPoint(i);\r
-// if(connectionPoint != null)\r
-// tgc.fillOval(connectionPoint.x - 1, connectionPoint.y - 1, 2, 2);\r
-// }\r
}\r
+\r
private void mouseDown(Event e)\r
{\r
- if(e.button == 1)\r
+ if (e.button == 1)\r
{\r
Point click = canvas.displayToWorldCoords(e.x, e.y);\r
- for(BasicGUIComponent component : components)\r
- if(component.getBounds().translate(componentPositions.get(component)).contains(click))\r
+ for (BasicGUIComponent component : components)\r
+ if (component.getBounds().translate(componentPositions.get(component)).contains(click))\r
{\r
- if(component.clicked(click.x, click.y))\r
+ if (component.clicked(click.x, click.y))\r
canvas.redraw();\r
break;\r
}\r
}\r
}\r
\r
+ /**\r
+ * Start the simulation timeline, and open the UI shell. Returns when the shell is closed.\r
+ */\r
public void run()\r
{\r
AtomicBoolean running = new AtomicBoolean(true);\r
Thread simulationThread = new Thread(() ->\r
{\r
- while(running.get())\r
+ while (running.get())\r
{\r
- //always execute to keep timeline from "hanging behind" for too long\r
+ // always execute to keep timeline from "hanging behind" for too long\r
Simulation.TIMELINE.executeUpTo(System.currentTimeMillis(), System.currentTimeMillis() + 10);\r
long sleepTime;\r
- if(Simulation.TIMELINE.hasNext())\r
- {\r
+ if (Simulation.TIMELINE.hasNext())\r
sleepTime = Simulation.TIMELINE.nextEventTime() - System.currentTimeMillis();\r
- } else\r
- sleepTime = 100;\r
+ else\r
+ sleepTime = 10;\r
try\r
{\r
- if(sleepTime > 0)\r
+ if (sleepTime > 0)\r
Thread.sleep(sleepTime);\r
- } catch(InterruptedException e)\r
- {} //it is normal execution flow to be interrupted\r
+ }\r
+ catch (InterruptedException e)\r
+ {\r
+ } // it is normal execution flow to be interrupted\r
}\r
});\r
simulationThread.start();\r
Simulation.TIMELINE.addEventAddedListener(event ->\r
{\r
- if(event.getTiming() >= System.currentTimeMillis() / (double) 1)\r
+ if (event.getTiming() <= System.currentTimeMillis())\r
simulationThread.interrupt();\r
});\r
\r
shell.open();\r
- while(!shell.isDisposed())\r
- if(!display.readAndDispatch())\r
+ while (!shell.isDisposed())\r
+ if (!display.readAndDispatch())\r
display.sleep();\r
running.set(false);\r
simulationThread.interrupt();\r