From ef5e2356312e8354e1fe0addef6e24636f95ad78 Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Tue, 20 May 2008 21:45:17 +0000 Subject: A new package events.internal has been introduced. It only contains events which are for internal usage. the events which are in the events.implementations menu are the events which are editable in the task manager. --- sources/core/VSProcess.java | 24 +- sources/core/VSTask.java | 3 +- sources/events/VSRegisteredEvents.java | 8 +- .../implementations/MessageReceiveEvent.java | 46 -- sources/events/implementations/ProtocolEvent.java | 55 -- sources/events/internal/MessageReceiveEvent.java | 46 ++ sources/events/internal/ProtocolEvent.java | 55 ++ sources/protocols/VSProtocol.java | 2 +- sources/simulator/VSSimulation.java | 45 +- sources/simulator/VSSimulationCanvas.java | 810 +++++++++++++++++++++ sources/simulator/VSSimulationPanel.java | 809 -------------------- sources/simulator/VSSimulatorFrame.java | 20 +- 12 files changed, 963 insertions(+), 960 deletions(-) delete mode 100644 sources/events/implementations/MessageReceiveEvent.java delete mode 100644 sources/events/implementations/ProtocolEvent.java create mode 100644 sources/events/internal/MessageReceiveEvent.java create mode 100644 sources/events/internal/ProtocolEvent.java create mode 100644 sources/simulator/VSSimulationCanvas.java delete mode 100644 sources/simulator/VSSimulationPanel.java (limited to 'sources') diff --git a/sources/core/VSProcess.java b/sources/core/VSProcess.java index dbb37ba..0d0f3d2 100644 --- a/sources/core/VSProcess.java +++ b/sources/core/VSProcess.java @@ -22,7 +22,7 @@ public final class VSProcess extends VSPrefs { private VSLogging logging; private VSPrefs prefs; private VSRandom random; - private VSSimulationPanel simulationPanel; + private VSSimulationCanvas simulationCanvas; private VSTask randomCrashTask; private VSVectorTime vectorTime; private boolean hasCrashed; @@ -84,10 +84,10 @@ public final class VSProcess extends VSPrefs { private static final String DEFAULT_STRING_VALUE_KEYS[] = { }; - public VSProcess(VSPrefs prefs, VSSimulationPanel simulationPanel, VSLogging logging) { + public VSProcess(VSPrefs prefs, VSSimulationCanvas simulationCanvas, VSLogging logging) { this.protocolsToReset = new ArrayList(); this.prefs = prefs; - this.simulationPanel = simulationPanel; + this.simulationCanvas = simulationCanvas; this.logging = logging; random = new VSRandom(processID+processCounter); @@ -120,7 +120,7 @@ public final class VSProcess extends VSPrefs { vectorTimeHistory = new ArrayList(); crashHistory = new ArrayList(); - final int numProcesses = simulationPanel.getNumProcesses(); + final int numProcesses = simulationCanvas.getNumProcesses(); for (int i = 0; i < numProcesses; ++i) vectorTime.add(new Long(0)); } @@ -133,7 +133,7 @@ public final class VSProcess extends VSPrefs { vectorTimeHistory.clear(); crashHistory.clear(); - final int numProcesses = simulationPanel.getNumProcesses(); + final int numProcesses = simulationCanvas.getNumProcesses(); for (int i = numProcesses; i > 0; --i) vectorTime.add(new Long(0)); } @@ -147,7 +147,7 @@ public final class VSProcess extends VSPrefs { setProcessID(getInteger("sim.process.id")); setLocalTime(getLong("sim.process.localtime")); crashedColor = getColor("process.crashed"); - simulationPanel.repaint(); + simulationCanvas.repaint(); createRandomCrashTask(); } @@ -217,7 +217,7 @@ public final class VSProcess extends VSPrefs { private void createRandomCrashTask() { if (!isCrashed) { - VSTaskManager taskManager = simulationPanel.getTaskManager(); + VSTaskManager taskManager = simulationCanvas.getTaskManager(); long crashTime = getARandomCrashTime(); if (randomCrashTask != null) @@ -358,7 +358,7 @@ public final class VSProcess extends VSPrefs { /* Check if the message will have an outage or not */ if (random.nextInt(100) <= getInteger("sim.message.prob.outage")) { /* Calculate the random outage time! */ - final long outageTime = globalTime + random.nextLong(durationTime+1) % simulationPanel.getUntilTime(); + final long outageTime = globalTime + random.nextLong(durationTime+1) % simulationCanvas.getUntilTime(); return outageTime; } @@ -370,7 +370,7 @@ public final class VSProcess extends VSPrefs { /* Check if the process will crash or not */ if (random.nextInt(100) <= getInteger("sim.process.prob.crash")) { /* Calculate the random crash time! */ - final long crashTime = random.nextLong(simulationPanel.getUntilTime()+1) % simulationPanel.getUntilTime(); + final long crashTime = random.nextLong(simulationCanvas.getUntilTime()+1) % simulationCanvas.getUntilTime(); return crashTime; } @@ -468,7 +468,7 @@ public final class VSProcess extends VSPrefs { buffer.append("; "); buffer.append(message.toStringFull()); logg(buffer.toString()); - simulationPanel.sendMessage(message); + simulationCanvas.sendMessage(message); } public void logg(String message) { @@ -519,8 +519,8 @@ public final class VSProcess extends VSPrefs { return process.getProcessID() == processID; } - public VSSimulationPanel getSimulationPanel() { - return simulationPanel; + public VSSimulationCanvas getSimulationCanvas() { + return simulationCanvas; } public VSPrefs getPrefs() { diff --git a/sources/core/VSTask.java b/sources/core/VSTask.java index eff5daa..b8a773a 100644 --- a/sources/core/VSTask.java +++ b/sources/core/VSTask.java @@ -2,6 +2,7 @@ package core; import events.*; import events.implementations.*; +import events.internal.*; import prefs.VSPrefs; import protocols.VSProtocol; import simulator.*; @@ -33,7 +34,7 @@ public class VSTask implements Comparable { } public boolean isMessageReceiveEvent() { - return event instanceof events.implementations.MessageReceiveEvent; + return event instanceof events.internal.MessageReceiveEvent; } public boolean isProcessRecoverEvent() { diff --git a/sources/events/VSRegisteredEvents.java b/sources/events/VSRegisteredEvents.java index cd375cd..79fd31c 100644 --- a/sources/events/VSRegisteredEvents.java +++ b/sources/events/VSRegisteredEvents.java @@ -33,7 +33,7 @@ public final class VSRegisteredEvents { Vector vector = new Vector(); for (String eventName : set) - if (getClassname(eventName).startsWith("protocols")) + if (getClassname(eventName).startsWith("protocols.implementations")) vector.add(eventName); Collections.sort(vector); @@ -46,7 +46,7 @@ public final class VSRegisteredEvents { Vector vector = new Vector(); for (String eventClassname : set) - if (eventClassname.startsWith("protocols")) + if (eventClassname.startsWith("protocols.implementations")) vector.add(eventClassname); Collections.sort(vector); @@ -59,7 +59,7 @@ public final class VSRegisteredEvents { Vector vector = new Vector(); for (String eventName : set) - if (getClassname(eventName).startsWith("events")) + if (getClassname(eventName).startsWith("events.implementations")) vector.add(eventName); Collections.sort(vector); @@ -72,7 +72,7 @@ public final class VSRegisteredEvents { Vector vector = new Vector(); for (String eventClassname : set) - if (eventClassname.startsWith("events")) + if (eventClassname.startsWith("events.implementations")) vector.add(eventClassname); Collections.sort(vector); diff --git a/sources/events/implementations/MessageReceiveEvent.java b/sources/events/implementations/MessageReceiveEvent.java deleted file mode 100644 index d5c1416..0000000 --- a/sources/events/implementations/MessageReceiveEvent.java +++ /dev/null @@ -1,46 +0,0 @@ -package events.implementations; - -import core.VSMessage; -import core.VSProcess; -import events.VSEvent; -import protocols.VSProtocol; - -public class MessageReceiveEvent extends VSEvent { - private VSMessage message; - - public MessageReceiveEvent(VSMessage message) { - this.message = message; - } - - protected void onInit() { - setClassname(getClass().toString()); - } - - public void onStart() { - String eventName = message.getName(); - String protocolClassname = message.getProtocolClassname(); - - process.updateLamportTime(message.getLamportTime()+1); - process.updateVectorTime(message.getVectorTime()); - - Object protocolObj = null; - - if (process.objectExists(protocolClassname)) - protocolObj = process.getObject(protocolClassname); - - StringBuffer buffer = new StringBuffer(); - buffer.append(prefs.getString("lang.message.recv")); - buffer.append("; "); - buffer.append(message);; - - if (protocolObj == null) { - logg(buffer.toString()); - - } else { - final VSProtocol protocol = (VSProtocol) protocolObj; - logg(buffer.toString()); - protocol.onMessageRecv(message); - } - - } -} diff --git a/sources/events/implementations/ProtocolEvent.java b/sources/events/implementations/ProtocolEvent.java deleted file mode 100644 index 6b21d8c..0000000 --- a/sources/events/implementations/ProtocolEvent.java +++ /dev/null @@ -1,55 +0,0 @@ -package events.implementations; - -import core.VSProcess; -import events.*; -import protocols.VSProtocol; - -public class ProtocolEvent extends VSEvent { - private String protocolClassname; - private boolean isClientProtocol; /* true = client, false = server */ - private boolean isProtocolActivation; /* true = activate, false = deactivate */ - - protected void onInit() { - setClassname(getClass().toString()); - } - - public void isClientProtocol(boolean isClientProtocol) { - this.isClientProtocol = isClientProtocol; - } - - public boolean isClientProtocol() { - return isClientProtocol; - } - - public void isProtocolActivation(boolean isProtocolActivation) { - this.isProtocolActivation = isProtocolActivation; - } - - public boolean isProtocolActivation() { - return isProtocolActivation; - } - - public void setProtocolClassname(String protocolClassname) { - this.protocolClassname = protocolClassname; - } - - public void onStart() { - VSProtocol protocol = process.getProtocolObject(protocolClassname); - - if (isClientProtocol) - protocol.isClient(isProtocolActivation); - - else - protocol.isServer(isProtocolActivation); - - StringBuffer buffer = new StringBuffer(); - buffer.append(VSRegisteredEvents.getShortname(protocolClassname)); - buffer.append(" "); - buffer.append(isClientProtocol - ? prefs.getString("lang.client") : prefs.getString("lang.server")); - buffer.append(" "); - buffer.append(isProtocolActivation - ? prefs.getString("lang.activated") : prefs.getString("lang.deactivated")); - logg(buffer.toString()); - } -} diff --git a/sources/events/internal/MessageReceiveEvent.java b/sources/events/internal/MessageReceiveEvent.java new file mode 100644 index 0000000..d499899 --- /dev/null +++ b/sources/events/internal/MessageReceiveEvent.java @@ -0,0 +1,46 @@ +package events.internal; + +import core.VSMessage; +import core.VSProcess; +import events.VSEvent; +import protocols.VSProtocol; + +public class MessageReceiveEvent extends VSEvent { + private VSMessage message; + + public MessageReceiveEvent(VSMessage message) { + this.message = message; + } + + protected void onInit() { + setClassname(getClass().toString()); + } + + public void onStart() { + String eventName = message.getName(); + String protocolClassname = message.getProtocolClassname(); + + process.updateLamportTime(message.getLamportTime()+1); + process.updateVectorTime(message.getVectorTime()); + + Object protocolObj = null; + + if (process.objectExists(protocolClassname)) + protocolObj = process.getObject(protocolClassname); + + StringBuffer buffer = new StringBuffer(); + buffer.append(prefs.getString("lang.message.recv")); + buffer.append("; "); + buffer.append(message);; + + if (protocolObj == null) { + logg(buffer.toString()); + + } else { + final VSProtocol protocol = (VSProtocol) protocolObj; + logg(buffer.toString()); + protocol.onMessageRecv(message); + } + + } +} diff --git a/sources/events/internal/ProtocolEvent.java b/sources/events/internal/ProtocolEvent.java new file mode 100644 index 0000000..61b5890 --- /dev/null +++ b/sources/events/internal/ProtocolEvent.java @@ -0,0 +1,55 @@ +package events.internal; + +import core.VSProcess; +import events.*; +import protocols.VSProtocol; + +public class ProtocolEvent extends VSEvent { + private String protocolClassname; + private boolean isClientProtocol; /* true = client, false = server */ + private boolean isProtocolActivation; /* true = activate, false = deactivate */ + + protected void onInit() { + setClassname(getClass().toString()); + } + + public void isClientProtocol(boolean isClientProtocol) { + this.isClientProtocol = isClientProtocol; + } + + public boolean isClientProtocol() { + return isClientProtocol; + } + + public void isProtocolActivation(boolean isProtocolActivation) { + this.isProtocolActivation = isProtocolActivation; + } + + public boolean isProtocolActivation() { + return isProtocolActivation; + } + + public void setProtocolClassname(String protocolClassname) { + this.protocolClassname = protocolClassname; + } + + public void onStart() { + VSProtocol protocol = process.getProtocolObject(protocolClassname); + + if (isClientProtocol) + protocol.isClient(isProtocolActivation); + + else + protocol.isServer(isProtocolActivation); + + StringBuffer buffer = new StringBuffer(); + buffer.append(VSRegisteredEvents.getShortname(protocolClassname)); + buffer.append(" "); + buffer.append(isClientProtocol + ? prefs.getString("lang.client") : prefs.getString("lang.server")); + buffer.append(" "); + buffer.append(isProtocolActivation + ? prefs.getString("lang.activated") : prefs.getString("lang.deactivated")); + logg(buffer.toString()); + } +} diff --git a/sources/protocols/VSProtocol.java b/sources/protocols/VSProtocol.java index df22e51..291b778 100644 --- a/sources/protocols/VSProtocol.java +++ b/sources/protocols/VSProtocol.java @@ -72,7 +72,7 @@ abstract public class VSProtocol extends VSEvent { abstract protected void onServerRecv(VSMessage message); protected int getNumProcesses() { - return process.getSimulationPanel().getNumProcesses(); + return process.getSimulationCanvas().getNumProcesses(); } public String toString() { diff --git a/sources/simulator/VSSimulation.java b/sources/simulator/VSSimulation.java index 558eeaf..1866813 100644 --- a/sources/simulator/VSSimulation.java +++ b/sources/simulator/VSSimulation.java @@ -11,6 +11,7 @@ import javax.swing.table.*; import core.*; import events.*; import events.implementations.*; +import events.internal.*; import prefs.*; import protocols.*; import utils.*; @@ -37,7 +38,7 @@ public class VSSimulation extends JPanel { private Thread thread; private VSLogging logging; private VSPrefs prefs; - private VSSimulationPanel simulationPanel; + private VSSimulationCanvas simulationCanvas; private boolean hasStarted = false; private VSTaskManagerTableModel taskManagerLocalModel; private VSTaskManagerTableModel taskManagerGlobalModel; @@ -102,7 +103,7 @@ public class VSSimulation extends JPanel { logging.logg(prefs.getString("lang.simulation.new")); fillContentPane(); - int numProcesses = simulationPanel.getNumProcesses(); + int numProcesses = simulationCanvas.getNumProcesses(); for (int i = 0; i <= numProcesses; ++i) { localTextFields.add("0000"); @@ -113,7 +114,7 @@ public class VSSimulation extends JPanel { localPIDComboBox.setSelectedIndex(0); globalPIDComboBox.setSelectedIndex(0); - thread = new Thread(simulationPanel); + thread = new Thread(simulationCanvas); thread.start(); } @@ -129,18 +130,18 @@ public class VSSimulation extends JPanel { prefs.getInteger("window.ysize") - prefs.getInteger("window.loggsize")); - simulationPanel = new VSSimulationPanel(prefs, this, logging); - taskManager = simulationPanel.getTaskManager(); - logging.setSimulationPanel(simulationPanel); - simulationPanel.setBackground(prefs.getColor("paintarea.background")); + simulationCanvas = new VSSimulationCanvas(prefs, this, logging); + taskManager = simulationCanvas.getTaskManager(); + logging.setSimulationCanvas(simulationCanvas); + simulationCanvas.setBackground(prefs.getColor("paintarea.background")); JPanel canvasPanel = new JPanel(); canvasPanel.setLayout(new GridLayout(1, 1, 3, 3)); - canvasPanel.add(simulationPanel); + canvasPanel.add(simulationCanvas); canvasPanel.setMinimumSize(new Dimension(0, 0)); canvasPanel.setMaximumSize(new Dimension(0, 0)); - //JScrollPane paintScrollPane = new JScrollPane(simulationPanel); + //JScrollPane paintScrollPane = new JScrollPane(simulationCanvas); JScrollPane textScrollPane = new JScrollPane(loggingArea); JPanel toolsPanel = createToolsPanel(); @@ -175,7 +176,7 @@ public class VSSimulation extends JPanel { public void stateChanged(ChangeEvent ce) { AbstractButton abstractButton = (AbstractButton) ce.getSource(); ButtonModel buttonModel = abstractButton.getModel(); - simulationPanel.showLamport(buttonModel.isSelected()); + simulationCanvas.showLamport(buttonModel.isSelected()); if (buttonModel.isSelected()) vectorTimeActiveCheckBox.setSelected(false); } @@ -188,7 +189,7 @@ public class VSSimulation extends JPanel { public void stateChanged(ChangeEvent ce) { AbstractButton abstractButton = (AbstractButton) ce.getSource(); ButtonModel buttonModel = abstractButton.getModel(); - simulationPanel.showVectorTime(buttonModel.isSelected()); + simulationCanvas.showVectorTime(buttonModel.isSelected()); if (buttonModel.isSelected()) lamportActiveCheckBox.setSelected(false); } @@ -201,7 +202,7 @@ public class VSSimulation extends JPanel { public void stateChanged(ChangeEvent ce) { AbstractButton abstractButton = (AbstractButton) ce.getSource(); ButtonModel buttonModel = abstractButton.getModel(); - simulationPanel.isAntiAliased(buttonModel.isSelected()); + simulationCanvas.isAntiAliased(buttonModel.isSelected()); } }); toolsPanel.add(antiAliasing); @@ -269,11 +270,11 @@ public class VSSimulation extends JPanel { globalPIDComboBox = new JComboBox(); lastSelectedProcessNum = 0; - int numProcesses = simulationPanel.getNumProcesses(); + int numProcesses = simulationCanvas.getNumProcesses(); String processString = prefs.getString("lang.process"); for (int i = 0; i < numProcesses; ++i) { - int pid = simulationPanel.getProcess(i).getProcessID(); + int pid = simulationCanvas.getProcess(i).getProcessID(); processesComboBox.addItem(processString + " " + pid); localPIDComboBox.addItem("PID: " + pid); globalPIDComboBox.addItem("PID: " + pid); @@ -701,7 +702,7 @@ public class VSSimulation extends JPanel { String deactivate = prefs.getString("lang.deactivate"); String client = prefs.getString("lang.client"); String server = prefs.getString("lang.server"); - String protocolEventClassname = "events.implementations.ProtocolEvent"; + String protocolEventClassname = "events.internal.ProtocolEvent"; for (String eventClassname : eventClassnames) { String eventShortname_ = VSRegisteredEvents.getShortname(eventClassname); @@ -772,12 +773,12 @@ public class VSSimulation extends JPanel { } catch (NumberFormatException e) { } - return simulationPanel.getNumProcesses(); + return simulationCanvas.getNumProcesses(); } private VSProcess getSelectedProcess() { int processNum = getSelectedProcessNum(); - return simulationPanel.getProcess(processNum); + return simulationCanvas.getProcess(processNum); } private ArrayList getConcernedProcesses(boolean localTasks) { @@ -785,11 +786,11 @@ public class VSSimulation extends JPanel { ? localPIDComboBox.getSelectedIndex() : globalPIDComboBox.getSelectedIndex(); - if (processNum == simulationPanel.getNumProcesses()) - return simulationPanel.getProcessesArray(); + if (processNum == simulationCanvas.getNumProcesses()) + return simulationCanvas.getProcessesArray(); ArrayList arr = new ArrayList(); - arr.add(simulationPanel.getProcess(processNum)); + arr.add(simulationCanvas.getProcess(processNum)); return arr; } @@ -817,8 +818,8 @@ public class VSSimulation extends JPanel { return menuItemStates; } - public VSSimulationPanel getSimulationPanel() { - return simulationPanel; + public VSSimulationCanvas getSimulationCanvas() { + return simulationCanvas; } public VSFrame getSimulatorFrame() { diff --git a/sources/simulator/VSSimulationCanvas.java b/sources/simulator/VSSimulationCanvas.java new file mode 100644 index 0000000..37f5f51 --- /dev/null +++ b/sources/simulator/VSSimulationCanvas.java @@ -0,0 +1,810 @@ +package simulator; + +import java.awt.*; +import java.awt.event.*; +import java.awt.geom.*; +import java.awt.image.*; +import java.util.*; +import javax.swing.*; + +import core.*; +import core.time.*; +import events.*; +import events.implementations.*; +import events.internal.*; +import prefs.*; +import prefs.editors.*; +import utils.*; + +public class VSSimulationCanvas extends Canvas implements Runnable, MouseMotionListener, MouseListener, HierarchyBoundsListener { + private VSProcess highlightedProcess; + private VSSimulation simulation; + private VSPrefs prefs; + private VSLogging logging; + private int numProcesses; + private int secondsSpaceing; + private int threadSleep; + private long untilTime; + private volatile boolean isPaused = true; + private volatile boolean isThreadStopped = false; + private volatile boolean isFinished = false; + private volatile boolean isResetted = false; + private volatile boolean isAntiAliased = false; + private volatile boolean isAntiAliasedChanged = false; + private volatile boolean showLamport = false; + private volatile boolean showVectorTime = false; + private volatile long pauseTime; + private volatile long startTime; + private volatile long time; + private volatile long lastTime; + private VSTaskManager taskManager; + private LinkedList messageLines; + private LinkedList processes; + + /* GFX buffering */ + private BufferStrategy strategy; + private Graphics2D g; + + /* Static constats */ + private static final int LINE_WIDTH = 5; + private static final int SEPLINE_WIDTH = 2; + private static final int XOFFSET = 50; + private static final int YOFFSET = 30; + private static final int YOUTER_SPACEING = 15; + private static final int YSEPLINE_SPACEING = 20; + private static final int TEXT_SPACEING = 10; + private static final int ROW_HEIGHT = 14; + + /* Constats, which have to get calculated once after start */ + private Color processlineColor; + private Color processSecondlineColor; + private Color processSeplineColor; + private Color messageArrivedColor; + private Color messageSendingColor; + private Color messageLostColor; + + private class VSMessageLine { + private VSProcess receiverProcess; + private Color color; + private long sendTime; + private long recvTime; + private int senderNum; + private int receiverNum; + private int offset1; + private int offset2; + private boolean isArrived; + private boolean isLost; + private double x1; + private double y1; + private double x2; + private double y2; + private double x; + private double y; + private long outageTime; + private long z; + + public VSMessageLine(VSProcess receiverProcess, long sendTime, long recvTime, long outageTime, int senderNum , int receiverNum) { + this.receiverProcess = receiverProcess; + this.sendTime = sendTime; + this.recvTime = recvTime; + this.outageTime = outageTime; + this.senderNum = senderNum; + this.receiverNum = receiverNum; + this.isArrived = false; + this.isLost = false; + + if (senderNum > receiverNum) { + //offset1 = 1; + offset2 = LINE_WIDTH; + } else { + offset1 = LINE_WIDTH - 1; + //offset2 = 1; + } + + /* Needed if the message gets lost after 0ms */ + this.x = getTimeXPosition(sendTime); + this.y = getProcessYPosition(senderNum) + offset1; + + recalcOnWindowChanged(); + paint(); + } + + public void recalcOnWindowChanged() { + x1 = getTimeXPosition(sendTime); + y1 = getProcessYPosition(senderNum) + offset1; + x2 = getTimeXPosition(recvTime); + y2 = getProcessYPosition(receiverNum) + offset2; + + if (isLost) { + x = getTimeXPosition(z); + y = y1 + ( ( (y2-y1) / (x2-x1)) * (x-x1)); + } + + } + + public void draw(final Graphics2D g, final long globalTime) { + if (isArrived) { + g.setColor(color); + g.drawLine((int) x1, (int) y1, (int) x2, (int) y2); + + } else if (isLost) { + g.setColor(messageLostColor); + g.drawLine((int) x1, (int) y1, (int) x, (int) y); + + } else if (globalTime >= recvTime) { + isArrived = true; + if (receiverProcess.isCrashed()) + color = messageLostColor; + else + color = messageArrivedColor; + draw(g, globalTime); + + } else if (outageTime >= 0 && outageTime <= globalTime){ + isLost = true; + draw(g, globalTime);; + + } else { + z = globalTime; + x = globalTimeXPosition; + y = y1 + ( ( (y2-y1) / (x2-x1)) * (x-x1)); + g.setColor(messageSendingColor); + g.drawLine((int) x1, (int) y1, (int) x, (int) y); + } + } + } + + public VSSimulationCanvas(VSPrefs prefs, VSSimulation simulation, VSLogging logging) { + this.prefs = prefs; + this.simulation = simulation; + this.logging = logging; + this.taskManager = new VSTaskManager(prefs); + this.messageLines = new LinkedList(); + this.processes = new LinkedList(); + + numProcesses = prefs.getInteger("sim.process.num"); + untilTime = prefs.getInteger("sim.seconds") * 1000; + recalcOnWindowChanged(); + + secondsSpaceing = (int) untilTime / 15000; + if (secondsSpaceing == 0) + secondsSpaceing = 1; + + threadSleep = (int) untilTime / 7500; + if (threadSleep == 0) + threadSleep = 1; + + VSProcess.resetProcessCounter(); + for (int i = 0; i < numProcesses; ++i) + createProcess(i); + + addMouseListener(this); + addMouseMotionListener(this); + addHierarchyBoundsListener(this); + } + + double xPaintSize; + double paintSize; + double yDistance; + double globalTimeXPosition; + + int xoffset_plus_xpaintsize; + double xpaintsize_dividedby_untiltime; + int paintProcessesOffset; + + int paintSecondlinesSeconds; + int paintSecondlinesLine[] = new int[4]; + int paintSecondlinesYStringPos1; + int paintSecondlinesYStringPos2; + int paintGlobalTimeYPosition; + + /* This method contains very ugly code. But this has to be in order to gain performance! */ + private void recalcOnWindowChanged() { + processlineColor = prefs.getColor("process.line"); + processSecondlineColor = prefs.getColor("process.secondline"); + processSeplineColor = prefs.getColor("process.sepline"); + messageArrivedColor = prefs.getColor("message.arrived"); + messageSendingColor = prefs.getColor("message.sending"); + messageLostColor = prefs.getColor("message.lost"); + + paintSize = simulation.getPaintSize(); + xPaintSize = simulation.getWidth() - (3 * XOFFSET + simulation.getSplitSize()); + yDistance = (simulation.getPaintSize() - 2 * (YOFFSET + YOUTER_SPACEING))/ numProcesses; + xpaintsize_dividedby_untiltime = xPaintSize / (double) untilTime; + + for (VSMessageLine messageLine : messageLines) + messageLine.recalcOnWindowChanged(); + + /* paintProcesses optimization, precalc things */ + { + xoffset_plus_xpaintsize = XOFFSET + (int) xPaintSize; + if (numProcesses > 1) + paintProcessesOffset = (int) ((paintSize-2*(YOFFSET+YOUTER_SPACEING+YSEPLINE_SPACEING))/(numProcesses-1)); + else + paintProcessesOffset = (int) ((paintSize-2*(YOFFSET+YOUTER_SPACEING+YSEPLINE_SPACEING))); + } + + /* paintSecondlines optimization, precalc things */ + { + int yMax = YOFFSET + YOUTER_SPACEING + (int) (numProcesses * yDistance); + paintSecondlinesSeconds = (int) untilTime / 1000; + paintSecondlinesLine[1] = YOFFSET; + paintSecondlinesLine[3] = yMax; + paintSecondlinesYStringPos1 = paintSecondlinesLine[1] - 5; + paintSecondlinesYStringPos2 = paintSecondlinesLine[3] + 15; + } + + /* paitnGlobalTime optimization, precalc things */ + { + paintGlobalTimeYPosition = YOFFSET + YOUTER_SPACEING + (int) (numProcesses * yDistance); + } + + if (strategy != null) { + synchronized (strategy) { + g = (Graphics2D) strategy.getDrawGraphics(); + g.setColor(Color.WHITE); + if (isAntiAliased) + g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + } + } + } + + public VSProcess createProcess(int i) { + VSProcess process = new VSProcess(prefs, this, logging); + processes.add(process); + logging.logg(prefs.getString("lang.process.new") + "; " + process); + + return process; + } + + private void updateSimulation(final long globalTime, final long lastGlobalTime) { + final long offset = globalTime - lastGlobalTime; + for (long l = 0; l < offset; ++l) + taskManager.runTasks(l, offset, lastGlobalTime); + + for (VSProcess process : processes) + process.syncTime(globalTime); + } + + public void paint() { + while (getBufferStrategy() == null) { + createBufferStrategy(3); + strategy = getBufferStrategy(); + + if (strategy != null) { + g = (Graphics2D) strategy.getDrawGraphics(); + g.setColor(Color.WHITE); + } + } + + synchronized (strategy) { + if (isAntiAliasedChanged) { + if (isAntiAliased) + g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + else + g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); + isAntiAliasedChanged = false; + } + + g.fillRect(0, 0, getWidth(), getHeight()); + final long globalTime = time; + + globalTimeXPosition = getTimeXPosition(globalTime); + paintSecondlines(g); + paintProcesses(g, globalTime); + paintGlobalTime(g, globalTime); + + synchronized (messageLines) { + for (VSMessageLine line : messageLines) + line.draw(g, globalTime); + } + + g.setColor(Color.WHITE); + + strategy.show(); + } + } + + private void paintProcesses(Graphics2D g, long globalTime) { + /* First paint the horizontal process timelines + * Second paint the processes + */ + final int yOffset = YOFFSET + YOUTER_SPACEING + YSEPLINE_SPACEING; + final int xPoints[] = { XOFFSET, xoffset_plus_xpaintsize, xoffset_plus_xpaintsize, XOFFSET, XOFFSET }; + final int yPoints[] = { yOffset, yOffset, yOffset + LINE_WIDTH, yOffset + LINE_WIDTH, yOffset }; + + for (VSProcess process : processes) { + final long localTime = process.getTime(); + + g.setColor(process.getColor()); + g.fillPolygon(xPoints, yPoints, 5); + + if (process.hasCrashed()) { + g.setColor(process.getCrashedColor()); + final Long crashHistory[] = process.getCrashHistoryArray(); + final int length = crashHistory.length; + + for (int i = 0; i < length; i += 2) { + final int crashStartPos = (int) getTimeXPosition(crashHistory[i].longValue()); + int crashEndPos; + + if (i == length - 1) + crashEndPos = xoffset_plus_xpaintsize; + else + crashEndPos = (int) getTimeXPosition(crashHistory[i+1].longValue()); + + final int xPointsCrashed[] = { crashStartPos, crashEndPos, + crashEndPos, crashStartPos, crashStartPos + }; + g.fillPolygon(xPointsCrashed, yPoints, 5); + } + } + + g.setColor(process.getColor()); + g.drawString("P" + process.getProcessID() + ":", XOFFSET - 30, yPoints[0] + LINE_WIDTH); + + final long tmp = localTime > untilTime ? untilTime : localTime; + final int xPos = 1 + (int) getTimeXPosition(tmp); + final int yStart = yPoints[0] - 14; + final int yEnd = yPoints[0]; + + g.setColor(processlineColor); + g.drawLine(xPos, yStart, xPos, yEnd); + g.drawString(localTime+"ms", xPos + 2, yStart + TEXT_SPACEING); + + if (showLamport) + paintTime(g, process.getLamportTimeArray(), process, yStart, 25); + else if (showVectorTime) + paintTime(g, process.getVectorTimeArray(), process, yStart, 20 * numProcesses); + + for (int i = 0; i < 5; ++i) + yPoints[i] += paintProcessesOffset; + } + } + + private void paintTime(final Graphics2D g, final VSTime times[], final VSProcess process, + final int yStart, final int distance) { + + final int lastPos[] = { -1, -1, -1, -1 }; + + for (VSTime time : times) { + int xPos = (int) getTimeXPosition(time.getGlobalTime()); + int bestRow[] = { -1, -1 }; + + for (int i = 0; i < 4; ++i) { + if (lastPos[i] != -1) { + int diff = xPos - lastPos[i]; + if (diff > distance) { + bestRow[0] = i; + bestRow[1] = -1; + break; + } else if (bestRow[0] == -1) { + bestRow[0] = i; + bestRow[1] = diff; + } else if (diff > bestRow[1]) { + bestRow[0] = i; + bestRow[1] = diff; + } + } else { + bestRow[0] = i; + bestRow[1] = -1; + break; + } + } + + final int row = bestRow[0]; + if (bestRow[1] != -1) + xPos += distance - bestRow[1]; + + g.drawString(time.toString(), xPos + 2, yStart + 3 * TEXT_SPACEING + row * ROW_HEIGHT); + lastPos[row] = xPos; + } + } + + private void paintSecondlines(Graphics2D g) { + g.setColor(processSecondlineColor); + + int i; + for (i = 0; i <= paintSecondlinesSeconds; i += secondsSpaceing) { + paintSecondlinesLine[0] = paintSecondlinesLine[2] = (int) getTimeXPosition(i*1000); + g.drawLine(paintSecondlinesLine[0], paintSecondlinesLine[1], paintSecondlinesLine[2], paintSecondlinesLine[3]); + + final int xStringPos = paintSecondlinesLine[0] - 5; + g.drawString(i+"s", xStringPos, paintSecondlinesYStringPos1); + if (!showVectorTime && !showLamport) + g.drawString(i+"s", xStringPos, paintSecondlinesYStringPos2); + } + + if (i > paintSecondlinesSeconds) { + paintSecondlinesLine[0] = paintSecondlinesLine[2] = (int) getTimeXPosition(untilTime); + g.drawLine(paintSecondlinesLine[0], paintSecondlinesLine[1], paintSecondlinesLine[2], paintSecondlinesLine[3]); + } + } + + private void paintGlobalTime(Graphics2D g, long globalTime) { + g.setColor(processSeplineColor); + final int xOffset = (int) globalTimeXPosition; + + final int xPoints[] = { xOffset, xOffset + SEPLINE_WIDTH, xOffset + SEPLINE_WIDTH, xOffset, xOffset }; + final int yOffset = YOFFSET - 8; + final int yPoints[] = { yOffset, yOffset, paintGlobalTimeYPosition, paintGlobalTimeYPosition, yOffset }; + + g.fillPolygon(xPoints, yPoints, 5); + g.drawString(globalTime+"ms", xPoints[1]+1, yPoints[0]+TEXT_SPACEING); + } + + private VSProcess getProcessAtYPos(int yPos) { + final int reachDistance = (int) (yDistance/3); + int y = YOFFSET + YOUTER_SPACEING + YSEPLINE_SPACEING; + + int yOffset = numProcesses > 1 + ? (int) ((paintSize-2*(YOFFSET+YOUTER_SPACEING+YSEPLINE_SPACEING))/(numProcesses-1)) + : (int) ((paintSize-2*(YOFFSET+YOUTER_SPACEING+YSEPLINE_SPACEING))); + + //System.out.println("JO " + yPos + " " + yDistance + " " + yOffset); + for (int i = 0; i < numProcesses; ++i) { + if (yPos < y + reachDistance && yPos > y - reachDistance - LINE_WIDTH) + return processes.get(i); + y += yOffset; + } + + return null; + } + + private double getTimeXPosition(long time) { + return XOFFSET + xpaintsize_dividedby_untiltime * time; + } + + private int getProcessYPosition(int i) { + int y; + + if (numProcesses > 1) + y = (int) ((paintSize - + 2 * (YOFFSET + YOUTER_SPACEING + YSEPLINE_SPACEING))/ (numProcesses-1)); + else + y = (int) ((paintSize - + 2 * (YOFFSET + YOUTER_SPACEING + YSEPLINE_SPACEING))); + + return y * (i - 1) + YOFFSET + YOUTER_SPACEING + YSEPLINE_SPACEING; + } + + public long getTime() { + return time; + } + + public long getUntilTime() { + return untilTime; + } + + public long getStartTime() { + return startTime; + } + + public VSTaskManager getTaskManager() { + return taskManager; + } + + public int getNumProcesses() { + return numProcesses; + } + + public VSProcess getProcess(int processNum) { + if (processNum >= processes.size()) + return null; + + return processes.get(processNum); + } + + public void run() { + //play(); + + while (true) { + while (!isThreadStopped && (isPaused || isFinished || isResetted)) { + try { + Thread.sleep(100); + paint(); + } catch (Exception e) { + System.out.println(e); + } + } + + if (isThreadStopped) + break; /* Exit the thread */ + + while (!isPaused && !isThreadStopped) { + try { + Thread.sleep(threadSleep); + } catch (Exception e) { + System.out.println(e); + } + + updateSimulation(time, lastTime); + paint(); + + lastTime = time; + time = System.currentTimeMillis() - startTime; + + if (time > untilTime) + time = untilTime; + + if (time == untilTime) { + finish(); + break; + } + } + + if (isPaused) { + for (VSProcess p : processes) + p.pause(); + + pauseTime = System.currentTimeMillis(); + + logging.logg(prefs.getString("lang.simulation.paused")); + paint(); + } + + updateSimulation(time, lastTime); + paint(); + } + } + + public void play() { + logging.logg(prefs.getString("lang.simulation.started")); + final long currentTime = System.currentTimeMillis(); + + for (VSProcess p : processes) + p.play(); + + if (isResetted) + isResetted = false; + + else if (isFinished) + isFinished = false; + + if (isPaused) { + isPaused = false; + startTime += currentTime - pauseTime; + time = currentTime - startTime; + + } else { + startTime = currentTime; + time = 0; + } + + paint(); + } + + public void finish() { + for (VSProcess p : processes) + p.finish(); + + simulation.finish(); + isFinished = true; + + logging.logg(prefs.getString("lang.simulation.finished")); + paint(); + } + + public void pause() { + isPaused = true; + } + + public void reset() { + if (!isResetted) { + logging.logg(prefs.getString("lang.simulation.resetted")); + + isResetted = true; + isPaused = false; + isFinished = false; + startTime = System.currentTimeMillis(); + time = 0; + lastTime = 0; + + for (VSProcess p : processes) + p.reset(); + + /* Reset the task manager AFTER the processes, for the programmed tasks */ + taskManager.reset(); + + synchronized (messageLines) { + messageLines.clear(); + } + + paint(); + logging.clear(); + } + } + + public void stopThread() { + isThreadStopped = true; + } + + public boolean isThreadStopped() { + return isThreadStopped; + } + + public void showLamport(boolean showLamport) { + this.showLamport = showLamport; + if (isPaused) + paint(); + } + + public void showVectorTime(boolean showVectorTime) { + this.showVectorTime = showVectorTime; + if (isPaused) + paint(); + } + + public void isAntiAliased(boolean isAntiAliased) { + this.isAntiAliased = isAntiAliased; + this.isAntiAliasedChanged = true; + if (isPaused) + paint(); + } + + public void sendMessage(VSMessage message) { + VSTask task = null; + VSEvent messageReceiveEvent = null; + VSProcess sendingProcess = message.getSendingProcess(); + long deliverTime, outageTime, durationTime; + boolean recvOwn = prefs.getBoolean("sim.message.own.recv"); + + for (VSProcess receiverProcess : processes) { + if (receiverProcess.equals(sendingProcess)) { + if (recvOwn) { + deliverTime = sendingProcess.getGlobalTime(); + messageReceiveEvent = new MessageReceiveEvent(message); + task = new VSTask(deliverTime, receiverProcess, messageReceiveEvent, VSTask.GLOBAL); + taskManager.addTask(task); + } + + } else { + durationTime = sendingProcess.getDurationTime(); + deliverTime = sendingProcess.getGlobalTime() + durationTime; + outageTime = sendingProcess.getARandomMessageOutageTime(durationTime); + + /* Only add a 'receiving message' task if the message will not get lost! */ + if (outageTime == -1) { + messageReceiveEvent = new MessageReceiveEvent(message); + task = new VSTask(deliverTime, receiverProcess, messageReceiveEvent, VSTask.GLOBAL); + taskManager.addTask(task); + } + + synchronized (messageLines) { + messageLines.add( + new VSMessageLine(receiverProcess, sendingProcess.getGlobalTime(), + deliverTime, outageTime, sendingProcess.getProcessID(), + receiverProcess.getProcessID())); + } + } + } + } + + public void mouseClicked(MouseEvent me) { + final VSProcess process = getProcessAtYPos(me.getY()); + + if (process == null) + return; + + if (SwingUtilities.isRightMouseButton(me)) { + ActionListener actionListener = new ActionListener() { + public void actionPerformed(ActionEvent ae) { + String actionCommand = ae.getActionCommand(); + if (actionCommand.equals(prefs.getString("lang.edit"))) { + editProcess(process); + + } else if (actionCommand.equals(prefs.getString("lang.crash"))) { + VSEvent event = new ProcessCrashEvent(); + event.init(process); + taskManager.addTask(new VSTask(process.getGlobalTime(), process, event, VSTask.GLOBAL)); + + } else if (actionCommand.equals(prefs.getString("lang.recover"))) { + VSEvent event = new ProcessRecoverEvent(); + event.init(process); + taskManager.addTask(new VSTask(process.getGlobalTime(), process, event, VSTask.GLOBAL)); + } + } + }; + + + JPopupMenu popup = new JPopupMenu(); + JMenuItem item = new JMenuItem(prefs.getString("lang.edit")); + item.addActionListener(actionListener); + popup.add(item); + + item = new JMenuItem(prefs.getString("lang.crash")); + if (process.isCrashed() || isPaused || time == 0 || isFinished) + item.setEnabled(false); + else + item.addActionListener(actionListener); + popup.add(item); + + item = new JMenuItem(prefs.getString("lang.recover")); + if (!process.isCrashed() || isPaused || time == 0 || isFinished) + item.setEnabled(false); + else + item.addActionListener(actionListener); + popup.add(item); + + popup.show(me.getComponent(), me.getX(), me.getY()); + + } else { + editProcess(process); + } + } + + public void editProcess(int processNum) { + VSProcess process = processes.get(processNum); + editProcess(process); + } + + public void editProcess(VSProcess process) { + if (process != null) { + process.updatePrefs(); + new VSProcessEditor(prefs, simulation.getSimulatorFrame(), process); + } + } + + public void mouseEntered(MouseEvent e) { } + + public void mouseExited(MouseEvent e) { + if (highlightedProcess != null) { + highlightedProcess.highlightOff(); + highlightedProcess = null; + paint(); + } + } + + public void mousePressed(MouseEvent e) { + } + + public void mouseReleased(MouseEvent e) { + } + + public void mouseDragged(MouseEvent e) { + } + + public void mouseMoved(MouseEvent e) { + VSProcess p = getProcessAtYPos(e.getY()); + + if (p == null) { + if (highlightedProcess != null) { + highlightedProcess.highlightOff(); + highlightedProcess = null; + } + + if (isPaused) + paint(); + + return; + } + + if (highlightedProcess != null) { + if (highlightedProcess.getProcessID() != p.getProcessID()) { + highlightedProcess.highlightOff(); + highlightedProcess = p; + p.highlightOn(); + } + } else { + highlightedProcess = p; + p.highlightOn(); + } + + if (isPaused) + paint(); + } + + public void ancestorMoved(HierarchyEvent e) { } + + public void ancestorResized(HierarchyEvent e) { + recalcOnWindowChanged(); + } + + public ArrayList getProcessesArray() { + ArrayList arr = new ArrayList(); + + for (VSProcess process : processes) + arr.add(process); + + return arr; + } +} diff --git a/sources/simulator/VSSimulationPanel.java b/sources/simulator/VSSimulationPanel.java deleted file mode 100644 index d501f22..0000000 --- a/sources/simulator/VSSimulationPanel.java +++ /dev/null @@ -1,809 +0,0 @@ -package simulator; - -import java.awt.*; -import java.awt.event.*; -import java.awt.geom.*; -import java.awt.image.*; -import java.util.*; -import javax.swing.*; - -import core.*; -import core.time.*; -import events.*; -import events.implementations.*; -import prefs.*; -import prefs.editors.*; -import utils.*; - -public class VSSimulationPanel extends Canvas implements Runnable, MouseMotionListener, MouseListener, HierarchyBoundsListener { - private VSProcess highlightedProcess; - private VSSimulation simulation; - private VSPrefs prefs; - private VSLogging logging; - private int numProcesses; - private int secondsSpaceing; - private int threadSleep; - private long untilTime; - private volatile boolean isPaused = true; - private volatile boolean isThreadStopped = false; - private volatile boolean isFinished = false; - private volatile boolean isResetted = false; - private volatile boolean isAntiAliased = false; - private volatile boolean isAntiAliasedChanged = false; - private volatile boolean showLamport = false; - private volatile boolean showVectorTime = false; - private volatile long pauseTime; - private volatile long startTime; - private volatile long time; - private volatile long lastTime; - private VSTaskManager taskManager; - private LinkedList messageLines; - private LinkedList processes; - - /* GFX buffering */ - private BufferStrategy strategy; - private Graphics2D g; - - /* Static constats */ - private static final int LINE_WIDTH = 5; - private static final int SEPLINE_WIDTH = 2; - private static final int XOFFSET = 50; - private static final int YOFFSET = 30; - private static final int YOUTER_SPACEING = 15; - private static final int YSEPLINE_SPACEING = 20; - private static final int TEXT_SPACEING = 10; - private static final int ROW_HEIGHT = 14; - - /* Constats, which have to get calculated once after start */ - private Color processlineColor; - private Color processSecondlineColor; - private Color processSeplineColor; - private Color messageArrivedColor; - private Color messageSendingColor; - private Color messageLostColor; - - private class VSMessageLine { - private VSProcess receiverProcess; - private Color color; - private long sendTime; - private long recvTime; - private int senderNum; - private int receiverNum; - private int offset1; - private int offset2; - private boolean isArrived; - private boolean isLost; - private double x1; - private double y1; - private double x2; - private double y2; - private double x; - private double y; - private long outageTime; - private long z; - - public VSMessageLine(VSProcess receiverProcess, long sendTime, long recvTime, long outageTime, int senderNum , int receiverNum) { - this.receiverProcess = receiverProcess; - this.sendTime = sendTime; - this.recvTime = recvTime; - this.outageTime = outageTime; - this.senderNum = senderNum; - this.receiverNum = receiverNum; - this.isArrived = false; - this.isLost = false; - - if (senderNum > receiverNum) { - //offset1 = 1; - offset2 = LINE_WIDTH; - } else { - offset1 = LINE_WIDTH - 1; - //offset2 = 1; - } - - /* Needed if the message gets lost after 0ms */ - this.x = getTimeXPosition(sendTime); - this.y = getProcessYPosition(senderNum) + offset1; - - recalcOnWindowChanged(); - paint(); - } - - public void recalcOnWindowChanged() { - x1 = getTimeXPosition(sendTime); - y1 = getProcessYPosition(senderNum) + offset1; - x2 = getTimeXPosition(recvTime); - y2 = getProcessYPosition(receiverNum) + offset2; - - if (isLost) { - x = getTimeXPosition(z); - y = y1 + ( ( (y2-y1) / (x2-x1)) * (x-x1)); - } - - } - - public void draw(final Graphics2D g, final long globalTime) { - if (isArrived) { - g.setColor(color); - g.drawLine((int) x1, (int) y1, (int) x2, (int) y2); - - } else if (isLost) { - g.setColor(messageLostColor); - g.drawLine((int) x1, (int) y1, (int) x, (int) y); - - } else if (globalTime >= recvTime) { - isArrived = true; - if (receiverProcess.isCrashed()) - color = messageLostColor; - else - color = messageArrivedColor; - draw(g, globalTime); - - } else if (outageTime >= 0 && outageTime <= globalTime){ - isLost = true; - draw(g, globalTime);; - - } else { - z = globalTime; - x = globalTimeXPosition; - y = y1 + ( ( (y2-y1) / (x2-x1)) * (x-x1)); - g.setColor(messageSendingColor); - g.drawLine((int) x1, (int) y1, (int) x, (int) y); - } - } - } - - public VSSimulationPanel(VSPrefs prefs, VSSimulation simulation, VSLogging logging) { - this.prefs = prefs; - this.simulation = simulation; - this.logging = logging; - this.taskManager = new VSTaskManager(prefs); - this.messageLines = new LinkedList(); - this.processes = new LinkedList(); - - numProcesses = prefs.getInteger("sim.process.num"); - untilTime = prefs.getInteger("sim.seconds") * 1000; - recalcOnWindowChanged(); - - secondsSpaceing = (int) untilTime / 15000; - if (secondsSpaceing == 0) - secondsSpaceing = 1; - - threadSleep = (int) untilTime / 7500; - if (threadSleep == 0) - threadSleep = 1; - - VSProcess.resetProcessCounter(); - for (int i = 0; i < numProcesses; ++i) - createProcess(i); - - addMouseListener(this); - addMouseMotionListener(this); - addHierarchyBoundsListener(this); - } - - double xPaintSize; - double paintSize; - double yDistance; - double globalTimeXPosition; - - int xoffset_plus_xpaintsize; - double xpaintsize_dividedby_untiltime; - int paintProcessesOffset; - - int paintSecondlinesSeconds; - int paintSecondlinesLine[] = new int[4]; - int paintSecondlinesYStringPos1; - int paintSecondlinesYStringPos2; - int paintGlobalTimeYPosition; - - /* This method contains very ugly code. But this has to be in order to gain performance! */ - private void recalcOnWindowChanged() { - processlineColor = prefs.getColor("process.line"); - processSecondlineColor = prefs.getColor("process.secondline"); - processSeplineColor = prefs.getColor("process.sepline"); - messageArrivedColor = prefs.getColor("message.arrived"); - messageSendingColor = prefs.getColor("message.sending"); - messageLostColor = prefs.getColor("message.lost"); - - paintSize = simulation.getPaintSize(); - xPaintSize = simulation.getWidth() - (3 * XOFFSET + simulation.getSplitSize()); - yDistance = (simulation.getPaintSize() - 2 * (YOFFSET + YOUTER_SPACEING))/ numProcesses; - xpaintsize_dividedby_untiltime = xPaintSize / (double) untilTime; - - for (VSMessageLine messageLine : messageLines) - messageLine.recalcOnWindowChanged(); - - /* paintProcesses optimization, precalc things */ - { - xoffset_plus_xpaintsize = XOFFSET + (int) xPaintSize; - if (numProcesses > 1) - paintProcessesOffset = (int) ((paintSize-2*(YOFFSET+YOUTER_SPACEING+YSEPLINE_SPACEING))/(numProcesses-1)); - else - paintProcessesOffset = (int) ((paintSize-2*(YOFFSET+YOUTER_SPACEING+YSEPLINE_SPACEING))); - } - - /* paintSecondlines optimization, precalc things */ - { - int yMax = YOFFSET + YOUTER_SPACEING + (int) (numProcesses * yDistance); - paintSecondlinesSeconds = (int) untilTime / 1000; - paintSecondlinesLine[1] = YOFFSET; - paintSecondlinesLine[3] = yMax; - paintSecondlinesYStringPos1 = paintSecondlinesLine[1] - 5; - paintSecondlinesYStringPos2 = paintSecondlinesLine[3] + 15; - } - - /* paitnGlobalTime optimization, precalc things */ - { - paintGlobalTimeYPosition = YOFFSET + YOUTER_SPACEING + (int) (numProcesses * yDistance); - } - - if (strategy != null) { - synchronized (strategy) { - g = (Graphics2D) strategy.getDrawGraphics(); - g.setColor(Color.WHITE); - if (isAntiAliased) - g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); - } - } - } - - public VSProcess createProcess(int i) { - VSProcess process = new VSProcess(prefs, this, logging); - processes.add(process); - logging.logg(prefs.getString("lang.process.new") + "; " + process); - - return process; - } - - private void updateSimulation(final long globalTime, final long lastGlobalTime) { - final long offset = globalTime - lastGlobalTime; - for (long l = 0; l < offset; ++l) - taskManager.runTasks(l, offset, lastGlobalTime); - - for (VSProcess process : processes) - process.syncTime(globalTime); - } - - public void paint() { - while (getBufferStrategy() == null) { - createBufferStrategy(3); - strategy = getBufferStrategy(); - - if (strategy != null) { - g = (Graphics2D) strategy.getDrawGraphics(); - g.setColor(Color.WHITE); - } - } - - synchronized (strategy) { - if (isAntiAliasedChanged) { - if (isAntiAliased) - g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); - else - g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); - isAntiAliasedChanged = false; - } - - g.fillRect(0, 0, getWidth(), getHeight()); - final long globalTime = time; - - globalTimeXPosition = getTimeXPosition(globalTime); - paintSecondlines(g); - paintProcesses(g, globalTime); - paintGlobalTime(g, globalTime); - - synchronized (messageLines) { - for (VSMessageLine line : messageLines) - line.draw(g, globalTime); - } - - g.setColor(Color.WHITE); - - strategy.show(); - } - } - - private void paintProcesses(Graphics2D g, long globalTime) { - /* First paint the horizontal process timelines - * Second paint the processes - */ - final int yOffset = YOFFSET + YOUTER_SPACEING + YSEPLINE_SPACEING; - final int xPoints[] = { XOFFSET, xoffset_plus_xpaintsize, xoffset_plus_xpaintsize, XOFFSET, XOFFSET }; - final int yPoints[] = { yOffset, yOffset, yOffset + LINE_WIDTH, yOffset + LINE_WIDTH, yOffset }; - - for (VSProcess process : processes) { - final long localTime = process.getTime(); - - g.setColor(process.getColor()); - g.fillPolygon(xPoints, yPoints, 5); - - if (process.hasCrashed()) { - g.setColor(process.getCrashedColor()); - final Long crashHistory[] = process.getCrashHistoryArray(); - final int length = crashHistory.length; - - for (int i = 0; i < length; i += 2) { - final int crashStartPos = (int) getTimeXPosition(crashHistory[i].longValue()); - int crashEndPos; - - if (i == length - 1) - crashEndPos = xoffset_plus_xpaintsize; - else - crashEndPos = (int) getTimeXPosition(crashHistory[i+1].longValue()); - - final int xPointsCrashed[] = { crashStartPos, crashEndPos, - crashEndPos, crashStartPos, crashStartPos - }; - g.fillPolygon(xPointsCrashed, yPoints, 5); - } - } - - g.setColor(process.getColor()); - g.drawString("P" + process.getProcessID() + ":", XOFFSET - 30, yPoints[0] + LINE_WIDTH); - - final long tmp = localTime > untilTime ? untilTime : localTime; - final int xPos = 1 + (int) getTimeXPosition(tmp); - final int yStart = yPoints[0] - 14; - final int yEnd = yPoints[0]; - - g.setColor(processlineColor); - g.drawLine(xPos, yStart, xPos, yEnd); - g.drawString(localTime+"ms", xPos + 2, yStart + TEXT_SPACEING); - - if (showLamport) - paintTime(g, process.getLamportTimeArray(), process, yStart, 25); - else if (showVectorTime) - paintTime(g, process.getVectorTimeArray(), process, yStart, 20 * numProcesses); - - for (int i = 0; i < 5; ++i) - yPoints[i] += paintProcessesOffset; - } - } - - private void paintTime(final Graphics2D g, final VSTime times[], final VSProcess process, - final int yStart, final int distance) { - - final int lastPos[] = { -1, -1, -1, -1 }; - - for (VSTime time : times) { - int xPos = (int) getTimeXPosition(time.getGlobalTime()); - int bestRow[] = { -1, -1 }; - - for (int i = 0; i < 4; ++i) { - if (lastPos[i] != -1) { - int diff = xPos - lastPos[i]; - if (diff > distance) { - bestRow[0] = i; - bestRow[1] = -1; - break; - } else if (bestRow[0] == -1) { - bestRow[0] = i; - bestRow[1] = diff; - } else if (diff > bestRow[1]) { - bestRow[0] = i; - bestRow[1] = diff; - } - } else { - bestRow[0] = i; - bestRow[1] = -1; - break; - } - } - - final int row = bestRow[0]; - if (bestRow[1] != -1) - xPos += distance - bestRow[1]; - - g.drawString(time.toString(), xPos + 2, yStart + 3 * TEXT_SPACEING + row * ROW_HEIGHT); - lastPos[row] = xPos; - } - } - - private void paintSecondlines(Graphics2D g) { - g.setColor(processSecondlineColor); - - int i; - for (i = 0; i <= paintSecondlinesSeconds; i += secondsSpaceing) { - paintSecondlinesLine[0] = paintSecondlinesLine[2] = (int) getTimeXPosition(i*1000); - g.drawLine(paintSecondlinesLine[0], paintSecondlinesLine[1], paintSecondlinesLine[2], paintSecondlinesLine[3]); - - final int xStringPos = paintSecondlinesLine[0] - 5; - g.drawString(i+"s", xStringPos, paintSecondlinesYStringPos1); - if (!showVectorTime && !showLamport) - g.drawString(i+"s", xStringPos, paintSecondlinesYStringPos2); - } - - if (i > paintSecondlinesSeconds) { - paintSecondlinesLine[0] = paintSecondlinesLine[2] = (int) getTimeXPosition(untilTime); - g.drawLine(paintSecondlinesLine[0], paintSecondlinesLine[1], paintSecondlinesLine[2], paintSecondlinesLine[3]); - } - } - - private void paintGlobalTime(Graphics2D g, long globalTime) { - g.setColor(processSeplineColor); - final int xOffset = (int) globalTimeXPosition; - - final int xPoints[] = { xOffset, xOffset + SEPLINE_WIDTH, xOffset + SEPLINE_WIDTH, xOffset, xOffset }; - final int yOffset = YOFFSET - 8; - final int yPoints[] = { yOffset, yOffset, paintGlobalTimeYPosition, paintGlobalTimeYPosition, yOffset }; - - g.fillPolygon(xPoints, yPoints, 5); - g.drawString(globalTime+"ms", xPoints[1]+1, yPoints[0]+TEXT_SPACEING); - } - - private VSProcess getProcessAtYPos(int yPos) { - final int reachDistance = (int) (yDistance/3); - int y = YOFFSET + YOUTER_SPACEING + YSEPLINE_SPACEING; - - int yOffset = numProcesses > 1 - ? (int) ((paintSize-2*(YOFFSET+YOUTER_SPACEING+YSEPLINE_SPACEING))/(numProcesses-1)) - : (int) ((paintSize-2*(YOFFSET+YOUTER_SPACEING+YSEPLINE_SPACEING))); - - //System.out.println("JO " + yPos + " " + yDistance + " " + yOffset); - for (int i = 0; i < numProcesses; ++i) { - if (yPos < y + reachDistance && yPos > y - reachDistance - LINE_WIDTH) - return processes.get(i); - y += yOffset; - } - - return null; - } - - private double getTimeXPosition(long time) { - return XOFFSET + xpaintsize_dividedby_untiltime * time; - } - - private int getProcessYPosition(int i) { - int y; - - if (numProcesses > 1) - y = (int) ((paintSize - - 2 * (YOFFSET + YOUTER_SPACEING + YSEPLINE_SPACEING))/ (numProcesses-1)); - else - y = (int) ((paintSize - - 2 * (YOFFSET + YOUTER_SPACEING + YSEPLINE_SPACEING))); - - return y * (i - 1) + YOFFSET + YOUTER_SPACEING + YSEPLINE_SPACEING; - } - - public long getTime() { - return time; - } - - public long getUntilTime() { - return untilTime; - } - - public long getStartTime() { - return startTime; - } - - public VSTaskManager getTaskManager() { - return taskManager; - } - - public int getNumProcesses() { - return numProcesses; - } - - public VSProcess getProcess(int processNum) { - if (processNum >= processes.size()) - return null; - - return processes.get(processNum); - } - - public void run() { - //play(); - - while (true) { - while (!isThreadStopped && (isPaused || isFinished || isResetted)) { - try { - Thread.sleep(100); - paint(); - } catch (Exception e) { - System.out.println(e); - } - } - - if (isThreadStopped) - break; /* Exit the thread */ - - while (!isPaused && !isThreadStopped) { - try { - Thread.sleep(threadSleep); - } catch (Exception e) { - System.out.println(e); - } - - updateSimulation(time, lastTime); - paint(); - - lastTime = time; - time = System.currentTimeMillis() - startTime; - - if (time > untilTime) - time = untilTime; - - if (time == untilTime) { - finish(); - break; - } - } - - if (isPaused) { - for (VSProcess p : processes) - p.pause(); - - pauseTime = System.currentTimeMillis(); - - logging.logg(prefs.getString("lang.simulation.paused")); - paint(); - } - - updateSimulation(time, lastTime); - paint(); - } - } - - public void play() { - logging.logg(prefs.getString("lang.simulation.started")); - final long currentTime = System.currentTimeMillis(); - - for (VSProcess p : processes) - p.play(); - - if (isResetted) - isResetted = false; - - else if (isFinished) - isFinished = false; - - if (isPaused) { - isPaused = false; - startTime += currentTime - pauseTime; - time = currentTime - startTime; - - } else { - startTime = currentTime; - time = 0; - } - - paint(); - } - - public void finish() { - for (VSProcess p : processes) - p.finish(); - - simulation.finish(); - isFinished = true; - - logging.logg(prefs.getString("lang.simulation.finished")); - paint(); - } - - public void pause() { - isPaused = true; - } - - public void reset() { - if (!isResetted) { - logging.logg(prefs.getString("lang.simulation.resetted")); - - isResetted = true; - isPaused = false; - isFinished = false; - startTime = System.currentTimeMillis(); - time = 0; - lastTime = 0; - - for (VSProcess p : processes) - p.reset(); - - /* Reset the task manager AFTER the processes, for the programmed tasks */ - taskManager.reset(); - - synchronized (messageLines) { - messageLines.clear(); - } - - paint(); - logging.clear(); - } - } - - public void stopThread() { - isThreadStopped = true; - } - - public boolean isThreadStopped() { - return isThreadStopped; - } - - public void showLamport(boolean showLamport) { - this.showLamport = showLamport; - if (isPaused) - paint(); - } - - public void showVectorTime(boolean showVectorTime) { - this.showVectorTime = showVectorTime; - if (isPaused) - paint(); - } - - public void isAntiAliased(boolean isAntiAliased) { - this.isAntiAliased = isAntiAliased; - this.isAntiAliasedChanged = true; - if (isPaused) - paint(); - } - - public void sendMessage(VSMessage message) { - VSTask task = null; - VSEvent messageReceiveEvent = null; - VSProcess sendingProcess = message.getSendingProcess(); - long deliverTime, outageTime, durationTime; - boolean recvOwn = prefs.getBoolean("sim.message.own.recv"); - - for (VSProcess receiverProcess : processes) { - if (receiverProcess.equals(sendingProcess)) { - if (recvOwn) { - deliverTime = sendingProcess.getGlobalTime(); - messageReceiveEvent = new MessageReceiveEvent(message); - task = new VSTask(deliverTime, receiverProcess, messageReceiveEvent, VSTask.GLOBAL); - taskManager.addTask(task); - } - - } else { - durationTime = sendingProcess.getDurationTime(); - deliverTime = sendingProcess.getGlobalTime() + durationTime; - outageTime = sendingProcess.getARandomMessageOutageTime(durationTime); - - /* Only add a 'receiving message' task if the message will not get lost! */ - if (outageTime == -1) { - messageReceiveEvent = new MessageReceiveEvent(message); - task = new VSTask(deliverTime, receiverProcess, messageReceiveEvent, VSTask.GLOBAL); - taskManager.addTask(task); - } - - synchronized (messageLines) { - messageLines.add( - new VSMessageLine(receiverProcess, sendingProcess.getGlobalTime(), - deliverTime, outageTime, sendingProcess.getProcessID(), - receiverProcess.getProcessID())); - } - } - } - } - - public void mouseClicked(MouseEvent me) { - final VSProcess process = getProcessAtYPos(me.getY()); - - if (process == null) - return; - - if (SwingUtilities.isRightMouseButton(me)) { - ActionListener actionListener = new ActionListener() { - public void actionPerformed(ActionEvent ae) { - String actionCommand = ae.getActionCommand(); - if (actionCommand.equals(prefs.getString("lang.edit"))) { - editProcess(process); - - } else if (actionCommand.equals(prefs.getString("lang.crash"))) { - VSEvent event = new ProcessCrashEvent(); - event.init(process); - taskManager.addTask(new VSTask(process.getGlobalTime(), process, event, VSTask.GLOBAL)); - - } else if (actionCommand.equals(prefs.getString("lang.recover"))) { - VSEvent event = new ProcessRecoverEvent(); - event.init(process); - taskManager.addTask(new VSTask(process.getGlobalTime(), process, event, VSTask.GLOBAL)); - } - } - }; - - - JPopupMenu popup = new JPopupMenu(); - JMenuItem item = new JMenuItem(prefs.getString("lang.edit")); - item.addActionListener(actionListener); - popup.add(item); - - item = new JMenuItem(prefs.getString("lang.crash")); - if (process.isCrashed() || isPaused || time == 0 || isFinished) - item.setEnabled(false); - else - item.addActionListener(actionListener); - popup.add(item); - - item = new JMenuItem(prefs.getString("lang.recover")); - if (!process.isCrashed() || isPaused || time == 0 || isFinished) - item.setEnabled(false); - else - item.addActionListener(actionListener); - popup.add(item); - - popup.show(me.getComponent(), me.getX(), me.getY()); - - } else { - editProcess(process); - } - } - - public void editProcess(int processNum) { - VSProcess process = processes.get(processNum); - editProcess(process); - } - - public void editProcess(VSProcess process) { - if (process != null) { - process.updatePrefs(); - new VSProcessEditor(prefs, simulation.getSimulatorFrame(), process); - } - } - - public void mouseEntered(MouseEvent e) { } - - public void mouseExited(MouseEvent e) { - if (highlightedProcess != null) { - highlightedProcess.highlightOff(); - highlightedProcess = null; - paint(); - } - } - - public void mousePressed(MouseEvent e) { - } - - public void mouseReleased(MouseEvent e) { - } - - public void mouseDragged(MouseEvent e) { - } - - public void mouseMoved(MouseEvent e) { - VSProcess p = getProcessAtYPos(e.getY()); - - if (p == null) { - if (highlightedProcess != null) { - highlightedProcess.highlightOff(); - highlightedProcess = null; - } - - if (isPaused) - paint(); - - return; - } - - if (highlightedProcess != null) { - if (highlightedProcess.getProcessID() != p.getProcessID()) { - highlightedProcess.highlightOff(); - highlightedProcess = p; - p.highlightOn(); - } - } else { - highlightedProcess = p; - p.highlightOn(); - } - - if (isPaused) - paint(); - } - - public void ancestorMoved(HierarchyEvent e) { } - - public void ancestorResized(HierarchyEvent e) { - recalcOnWindowChanged(); - } - - public ArrayList getProcessesArray() { - ArrayList arr = new ArrayList(); - - for (VSProcess process : processes) - arr.add(process); - - return arr; - } -} diff --git a/sources/simulator/VSSimulatorFrame.java b/sources/simulator/VSSimulatorFrame.java index 41fd196..e27f896 100644 --- a/sources/simulator/VSSimulatorFrame.java +++ b/sources/simulator/VSSimulatorFrame.java @@ -145,7 +145,7 @@ public class VSSimulatorFrame extends VSFrame implements ActionListener { public void stateChanged(ChangeEvent ce) { JTabbedPane pane = (JTabbedPane) ce.getSource(); currentSimulation = (VSSimulation) pane.getSelectedComponent(); - currentSimulation.getSimulationPanel().paint(); + currentSimulation.getSimulationCanvas().paint(); updateEditMenu(); updateSimulationMenu(); } @@ -162,7 +162,7 @@ public class VSSimulatorFrame extends VSFrame implements ActionListener { return; final String processString = prefs.getString("lang.process"); - final int numProcesses = currentSimulation.getSimulationPanel().getNumProcesses(); + final int numProcesses = currentSimulation.getSimulationCanvas().getNumProcesses(); for (int i = 0; i < numProcesses; ++i) { JMenuItem processItem = new JMenuItem(processString + " " + (i+1)); @@ -171,7 +171,7 @@ public class VSSimulatorFrame extends VSFrame implements ActionListener { final int finalProcessNum = i; processItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) { - currentSimulation.getSimulationPanel().editProcess(finalProcessNum); + currentSimulation.getSimulationCanvas().editProcess(finalProcessNum); } }); menuEdit.add(processItem); @@ -189,7 +189,7 @@ public class VSSimulatorFrame extends VSFrame implements ActionListener { public void dispose() { for (VSSimulation simulation : simulations) - simulation.getSimulationPanel().stopThread(); + simulation.getSimulationCanvas().stopThread(); super.dispose(); } @@ -223,7 +223,7 @@ public class VSSimulatorFrame extends VSFrame implements ActionListener { menuItemState.setPause(true); menuItemState.setReset(false); menuItemState.setReplay(true); - currentSimulation.getSimulationPanel().play(); + currentSimulation.getSimulationCanvas().play(); updateSimulationMenu(); } else if (source.getText().equals(prefs.getString("lang.pause"))) { @@ -232,7 +232,7 @@ public class VSSimulatorFrame extends VSFrame implements ActionListener { menuItemState.setPause(false); menuItemState.setReset(true); menuItemState.setReplay(true); - currentSimulation.getSimulationPanel().pause(); + currentSimulation.getSimulationCanvas().pause(); updateSimulationMenu(); } else if (source.getText().equals(prefs.getString("lang.reset"))) { @@ -241,7 +241,7 @@ public class VSSimulatorFrame extends VSFrame implements ActionListener { menuItemState.setPause(false); menuItemState.setReset(false); menuItemState.setReplay(false); - currentSimulation.getSimulationPanel().reset(); + currentSimulation.getSimulationCanvas().reset(); updateSimulationMenu(); } else if (source.getText().equals(prefs.getString("lang.replay"))) { @@ -250,8 +250,8 @@ public class VSSimulatorFrame extends VSFrame implements ActionListener { menuItemState.setPause(true); menuItemState.setReset(false); menuItemState.setReplay(true); - currentSimulation.getSimulationPanel().reset(); - currentSimulation.getSimulationPanel().play(); + currentSimulation.getSimulationCanvas().reset(); + currentSimulation.getSimulationCanvas().play(); updateSimulationMenu(); } } @@ -271,6 +271,6 @@ public class VSSimulatorFrame extends VSFrame implements ActionListener { VSSimulation simulationToRemove = currentSimulation; simulations.remove(simulationToRemove); tabbedPane.remove(simulationToRemove); - simulationToRemove.getSimulationPanel().stopThread(); + simulationToRemove.getSimulationCanvas().stopThread(); } } -- cgit v1.2.3