From 222d028fac58233a451e2de875353252a3dc9f63 Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Sat, 24 May 2008 21:06:15 +0000 Subject: PRocesses now get removed properly. Removed all VSSimulation* classes. --- sources/simulator/VSSimulatorCanvas.java | 949 +++++++++++++++++++++++++++++++ 1 file changed, 949 insertions(+) create mode 100644 sources/simulator/VSSimulatorCanvas.java (limited to 'sources/simulator/VSSimulatorCanvas.java') diff --git a/sources/simulator/VSSimulatorCanvas.java b/sources/simulator/VSSimulatorCanvas.java new file mode 100644 index 0000000..6e24270 --- /dev/null +++ b/sources/simulator/VSSimulatorCanvas.java @@ -0,0 +1,949 @@ +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 VSSimulatorCanvas extends Canvas implements Runnable, MouseMotionListener, MouseListener, HierarchyBoundsListener { + private VSProcess highlightedProcess; + private VSSimulator simulation; + private VSPrefs prefs; + private VSLogging logging; + private volatile 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 Vector processes; + private double clockSpeed; + private double clockOffset; + private long simulationTime; + + /* 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 Color backgroundColor; + + private long messageLineCounter; + 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; + private long messageLineNum; + private VSTask task; + + public VSMessageLine(VSProcess receiverProcess, long sendTime, long recvTime, long outageTime, int senderNum , int receiverNum, VSTask task) { + this.receiverProcess = receiverProcess; + this.sendTime = sendTime; + this.recvTime = recvTime; + this.outageTime = outageTime; + this.senderNum = senderNum; + this.receiverNum = receiverNum; + this.isArrived = false; + this.isLost = false; + this.messageLineNum = ++messageLineCounter; + this.task = task; + + 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+1) + offset1; + + recalcOnChange(); + paint(); + } + + public void recalcOnChange() { + x1 = getTimeXPosition(sendTime); + y1 = getProcessYPosition(senderNum+1) + offset1; + x2 = getTimeXPosition(recvTime); + y2 = getProcessYPosition(receiverNum+1) + 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 boolean removeProcessAtIndex(int index) { + if (index == receiverNum || index == senderNum) + return true; + + if (index < receiverNum) + --receiverNum; + + if (index < senderNum) + --senderNum; + + recalcOnChange(); + + return false; + } + + public long getMessageLineNum() { + return messageLineNum; + } + + public boolean equals(VSMessageLine line) { + return messageLineNum == line.getMessageLineNum(); + } + + public VSTask getTask() { + return task; + } + } + + public VSSimulatorCanvas(VSPrefs prefs, VSSimulator simulation, VSLogging logging) { + this.prefs = prefs; + this.simulation = simulation; + this.logging = logging; + this.taskManager = new VSTaskManager(prefs); + this.messageLines = new LinkedList(); + this.processes = new Vector(); + + numProcesses = prefs.getInteger("sim.process.num"); + updateFromPrefs(); + + VSProcess.resetProcessCounter(); + for (int i = 0; i < numProcesses; ++i) + processes.add(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 recalcOnChange() { + processlineColor = prefs.getColor("col.process.line"); + processSecondlineColor = prefs.getColor("col.process.secondline"); + processSeplineColor = prefs.getColor("col.process.sepline"); + messageArrivedColor = prefs.getColor("col.message.arrived"); + messageSendingColor = prefs.getColor("col.message.sending"); + messageLostColor = prefs.getColor("col.message.lost"); + backgroundColor = prefs.getColor("col.background"); + + 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.recalcOnChange(); + + /* 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(backgroundColor); + if (isAntiAliased) + g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + } + } + } + + private void updateSimulation(final long globalTime, final long lastGlobalTime) { + if (isPaused || isFinished) + return; + + final long lastSimulationTime = simulationTime; + long offset = globalTime - lastGlobalTime; + + clockOffset += offset * clockSpeed; + + while (clockOffset >= 1) { + --clockOffset; + ++simulationTime; + } + + if (simulationTime > untilTime) + simulationTime = untilTime; + + offset = simulationTime - lastSimulationTime; + + for (long l = 0; l < offset; ++l) + taskManager.runTasks(l, offset, lastSimulationTime); + + synchronized (processes) { + for (VSProcess process : processes) + process.syncTime(simulationTime); + } + } + + public void paint() { + while (getBufferStrategy() == null) { + createBufferStrategy(3); + strategy = getBufferStrategy(); + + if (strategy != null) { + g = (Graphics2D) strategy.getDrawGraphics(); + g.setColor(backgroundColor); + } + } + + 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 = simulationTime; + + globalTimeXPosition = getTimeXPosition(globalTime); + paintSecondlines(g); + paintProcesses(g, globalTime); + paintGlobalTime(g, globalTime); + + synchronized (messageLines) { + for (VSMessageLine line : messageLines) + line.draw(g, globalTime); + } + + g.setColor(backgroundColor); + + 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 }; + + synchronized (processes) { + 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 simulationTime; + } + + 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() { + 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); + + if (simulationTime == untilTime) { + finish(); + break; + } + + paint(); + lastTime = time; + time = System.currentTimeMillis() - startTime; + + } + + updateSimulation(time, lastTime); + paint(); + } + } + + public void play() { + logging.logg(prefs.getString("lang.simulation.started")); + final long currentTime = System.currentTimeMillis(); + + synchronized (processes) { + 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() { + synchronized (processes) { + for (VSProcess p : processes) + p.finish(); + } + + simulation.finish(); + isFinished = true; + + logging.logg(prefs.getString("lang.simulation.finished")); + paint(); + } + + public void pause() { + isPaused = true; + synchronized (processes) { + for (VSProcess p : processes) + p.pause(); + } + + pauseTime = System.currentTimeMillis(); + + logging.logg(prefs.getString("lang.simulation.paused")); + paint(); + } + + 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; + clockOffset = 0; + simulationTime = 0; + + synchronized (processes) { + for (VSProcess process : processes) + process.reset(); + } + + /* Reset the task manager AFTER the processes, for the programmed tasks */ + taskManager.reset(); + + synchronized (processes) { + for (VSProcess process : processes) + process.createRandomCrashTask(); + } + + 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"); + + synchronized (processes) { + 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.getProcessNum(), + receiverProcess.getProcessNum(), task)); + } + } + } + } + } + + public void mouseClicked(MouseEvent me) { + final VSProcess process = getProcessAtYPos(me.getY()); + + if (SwingUtilities.isRightMouseButton(me)) { + ActionListener actionListener = new ActionListener() { + public void actionPerformed(ActionEvent ae) { + String actionCommand = ae.getActionCommand(); + if (actionCommand.equals(prefs.getString("lang.process.edit"))) { + editProcess(process); + + } else if (actionCommand.equals(prefs.getString("lang.process.crash"))) { + VSEvent event = new ProcessCrashEvent(); + taskManager.addTask(new VSTask(process.getGlobalTime(), process, event, VSTask.GLOBAL)); + + } else if (actionCommand.equals(prefs.getString("lang.process.recover"))) { + VSEvent event = new ProcessRecoverEvent(); + taskManager.addTask(new VSTask(process.getGlobalTime(), process, event, VSTask.GLOBAL)); + + } else if (actionCommand.equals(prefs.getString("lang.process.remove"))) { + removeProcess(process); + + } else if (actionCommand.equals(prefs.getString("lang.process.add.new"))) { + addProcess(); + } + } + }; + + + JPopupMenu popup = new JPopupMenu(); + JMenuItem item = new JMenuItem(prefs.getString("lang.process.edit")); + if (process == null) + item.setEnabled(false); + else + item.addActionListener(actionListener); + popup.add(item); + + item = new JMenuItem(prefs.getString("lang.process.crash")); + if (process == null || process.isCrashed() || isPaused || time == 0 || isFinished) + item.setEnabled(false); + else + item.addActionListener(actionListener); + popup.add(item); + + item = new JMenuItem(prefs.getString("lang.process.recover")); + if (process == null || !process.isCrashed() || isPaused || time == 0 || isFinished) + item.setEnabled(false); + else + item.addActionListener(actionListener); + popup.add(item); + + item = new JMenuItem(prefs.getString("lang.process.remove")); + if (process == null) + item.setEnabled(false); + else + item.addActionListener(actionListener); + popup.add(item); + + popup.addSeparator(); + + item = new JMenuItem(prefs.getString("lang.process.add.new")); + 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 VSEditorFrame(prefs, simulation.getSimulatorFrame(), + new VSProcessEditor(prefs, 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) { + recalcOnChange(); + } + + public ArrayList getProcessesArray() { + ArrayList arr = new ArrayList(); + + synchronized (processes) { + for (VSProcess process : processes) + arr.add(process); + } + + return arr; + } + + public void updateFromPrefs() { + untilTime = prefs.getInteger("sim.seconds") * 1000; + clockSpeed = prefs.getFloat("sim.clock.speed"); + + secondsSpaceing = (int) (untilTime / 15000); + if (secondsSpaceing == 0) + secondsSpaceing = 1; + + threadSleep = (int) (untilTime / 7500); + if (threadSleep == 0) + threadSleep = 1; + + recalcOnChange(); + } + + private void removeProcess(VSProcess process) { + if (numProcesses == 1) { + simulation.getSimulatorFrame().removeSimulation(simulation); + + } else { + int index = processes.indexOf(process); + processes.remove(index); + synchronized (processes) { + for (VSProcess p : processes) { + p.removeProcessAtIndex(index); + } + } + numProcesses = processes.size(); + simulation.removeProcessAtIndex(index); + recalcOnChange(); + + ArrayList removeThose = new ArrayList(); + synchronized (messageLines) { + for (VSMessageLine line : messageLines) + if (line.removeProcessAtIndex(index)) + removeThose.add(line); + for (VSMessageLine line : removeThose) { + VSTask deliverTask = line.getTask(); + if (deliverTask != null) + taskManager.removeTask(deliverTask); + messageLines.remove(line); + } + } + + taskManager.removeTasksOf(process); + } + } + + private VSProcess createProcess(int processNum) { + VSProcess process = new VSProcess(prefs, processNum, this, logging); + logging.logg(prefs.getString("lang.process.new") + "; " + process); + return process; + } + + private void addProcess() { + numProcesses = processes.size() + 1; + VSProcess newProcess = createProcess(processes.size()); + processes.add(newProcess); + synchronized (processes) { + for (VSProcess process : processes) + if (!process.equals(newProcess)) + process.addedAProcess(); + } + recalcOnChange(); + simulation.addProcessAtIndex(processes.size()-1); + } +} -- cgit v1.2.3