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/core/VSProcess.java | 33 +- sources/core/VSTaskManager.java | 23 + sources/core/time/VSVectorTime.java | 7 + sources/prefs/VSDefaultPrefs.java | 1 + sources/prefs/editors/VSSimulationEditor.java | 77 --- sources/prefs/editors/VSSimulatorEditor.java | 77 +++ sources/simulator/VSLogging.java | 4 +- sources/simulator/VSMain.java | 2 +- sources/simulator/VSSimulation.java | 930 ------------------------- sources/simulator/VSSimulationCanvas.java | 875 ----------------------- sources/simulator/VSSimulator.java | 953 ++++++++++++++++++++++++++ sources/simulator/VSSimulatorCanvas.java | 949 +++++++++++++++++++++++++ sources/simulator/VSSimulatorFrame.java | 38 +- 13 files changed, 2060 insertions(+), 1909 deletions(-) delete mode 100644 sources/prefs/editors/VSSimulationEditor.java create mode 100644 sources/prefs/editors/VSSimulatorEditor.java delete mode 100644 sources/simulator/VSSimulation.java delete mode 100644 sources/simulator/VSSimulationCanvas.java create mode 100644 sources/simulator/VSSimulator.java create mode 100644 sources/simulator/VSSimulatorCanvas.java diff --git a/sources/core/VSProcess.java b/sources/core/VSProcess.java index e5e8c9d..5612d89 100644 --- a/sources/core/VSProcess.java +++ b/sources/core/VSProcess.java @@ -22,7 +22,7 @@ public class VSProcess extends VSPrefs { private VSLogging logging; private VSPrefs prefs; private VSRandom random; - private VSSimulationCanvas simulationCanvas; + private VSSimulatorCanvas simulationCanvas; private VSTask randomCrashTask; private VSVectorTime vectorTime; private boolean hasCrashed; @@ -33,7 +33,8 @@ public class VSProcess extends VSPrefs { private boolean timeModified; private double clockOffset; private float clockVariance; - private int processID; + private int processID; // Represents the PID of a process + private int processNum; // Represents the array index of the process, for internal usage private long globalTime; private long lamportTime; private long localTime; @@ -84,8 +85,9 @@ public class VSProcess extends VSPrefs { private static final String DEFAULT_STRING_VALUE_KEYS[] = { }; - public VSProcess(VSPrefs prefs, VSSimulationCanvas simulationCanvas, VSLogging logging) { + public VSProcess(VSPrefs prefs, int processNum, VSSimulatorCanvas simulationCanvas, VSLogging logging) { this.protocolsToReset = new ArrayList(); + this.processNum = processNum; this.prefs = prefs; this.simulationCanvas = simulationCanvas; this.logging = logging; @@ -257,6 +259,10 @@ public class VSProcess extends VSPrefs { return processID; } + public synchronized int getProcessNum() { + return processNum; + } + public synchronized void setProcessID(int processID) { this.processID = processID; } @@ -418,7 +424,7 @@ public class VSProcess extends VSPrefs { } public synchronized void increaseVectorTime() { - vectorTime.set(processID-1, new Long(vectorTime.get(processID-1).longValue()+1)); + vectorTime.set(processNum, new Long(vectorTime.get(processNum).longValue()+1)); vectorTime.setGlobalTime(globalTime); vectorTimeHistory.add(vectorTime.getCopy()); } @@ -427,7 +433,7 @@ public class VSProcess extends VSPrefs { final int size = vectorTime.size(); for (int i = 0; i < size; ++i) { - if (i == processID-1) + if (i == processNum) vectorTime.set(i, new Long(vectorTime.get(i).longValue()+1)); else if (vectorTimeUpdate.get(i) > vectorTime.get(i)) vectorTime.set(i, vectorTimeUpdate.get(i)); @@ -518,7 +524,7 @@ public class VSProcess extends VSPrefs { return process.getProcessID() == processID; } - public VSSimulationCanvas getSimulationCanvas() { + public VSSimulatorCanvas getSimulationCanvas() { return simulationCanvas; } @@ -530,6 +536,21 @@ public class VSProcess extends VSPrefs { processCounter = 0; } + public void removeProcessAtIndex(int index) { + if (index < processNum) + --processNum; + + vectorTime.remove(index); + for (VSVectorTime vectorTime : vectorTimeHistory) + vectorTime.remove(index); + } + + public void addedAProcess() { + vectorTime.add(new Long(0)); + for (VSVectorTime vectorTime : vectorTimeHistory) + vectorTime.add(new Long(0)); + } + public VSProtocol getProtocolObject(String protocolClassname) { VSProtocol protocol = null; diff --git a/sources/core/VSTaskManager.java b/sources/core/VSTaskManager.java index 66913fc..6b419cf 100644 --- a/sources/core/VSTaskManager.java +++ b/sources/core/VSTaskManager.java @@ -216,6 +216,29 @@ public class VSTaskManager { return false; } + public synchronized void removeTasksOf(VSProcess process) { + ArrayList removeThose = new ArrayList(); + for (VSTask task : fullfilledProgrammedTasks) + if (task.isProcess(process)) + removeThose.add(task); + for (VSTask task : removeThose) + fullfilledProgrammedTasks.remove(task); + + removeThose.clear(); + for (VSTask task : globalTasks) + if (task.isProcess(process)) + removeThose.add(task); + for (VSTask task : removeThose) + globalTasks.remove(task); + + removeThose.clear(); + for (VSTask task : tasks) + if (task.isProcess(process)) + removeThose.add(task); + for (VSTask task : removeThose) + tasks.remove(task); + } + public synchronized VSPriorityQueue getLocalTasks() { VSPriorityQueue processTasks = new VSPriorityQueue(); diff --git a/sources/core/time/VSVectorTime.java b/sources/core/time/VSVectorTime.java index 55a9b49..7d0f371 100644 --- a/sources/core/time/VSVectorTime.java +++ b/sources/core/time/VSVectorTime.java @@ -49,4 +49,11 @@ public class VSVectorTime extends ArrayList implements VSTime { return buffer.toString(); } + + public Long get(int index) { + if (index >= super.size()) + return new Long(0); + + return super.get(index); + } } diff --git a/sources/prefs/VSDefaultPrefs.java b/sources/prefs/VSDefaultPrefs.java index 25e3ef9..3446184 100644 --- a/sources/prefs/VSDefaultPrefs.java +++ b/sources/prefs/VSDefaultPrefs.java @@ -88,6 +88,7 @@ public class VSDefaultPrefs extends VSPrefs { initString("lang.prefs.protocols", "Protokolleinstellungen"); initString("lang.prefs.simulation", "Simulationseinstellungen"); initString("lang.process", "Prozess"); + initString("lang.process.add.new", "Neuen Prozess hinzufügen"); initString("lang.process.crash", "Prozess abstürzen"); initString("lang.process.remove", "Prozess entfernen"); initString("lang.process.edit", "Prozess editieren"); diff --git a/sources/prefs/editors/VSSimulationEditor.java b/sources/prefs/editors/VSSimulationEditor.java deleted file mode 100644 index 4637ec9..0000000 --- a/sources/prefs/editors/VSSimulationEditor.java +++ /dev/null @@ -1,77 +0,0 @@ -package prefs.editors; - -import java.awt.*; -import java.awt.event.*; -import javax.swing.*; -import javax.swing.border.*; -import javax.swing.filechooser.*; -import java.util.*; -import java.io.File; - -import simulator.*; -import utils.*; -import prefs.*; - -public class VSSimulationEditor extends VSBetterEditor { - private VSSimulatorFrame simulatorFrame; - private VSSimulation simulation; - public static boolean TAKEOVER_BUTTON; - private boolean dontStartNewSimulation; - - public VSSimulationEditor(VSPrefs prefs, VSSimulatorFrame simulatorFrame, VSSimulation simulation) { - super(prefs, prefs, prefs.getString("lang.name") - + " - " + prefs.getString("lang.prefs")); - this.dontStartNewSimulation = true;//simulation != null; - this.simulatorFrame = simulatorFrame; - this.simulation = simulation; - } - - public VSSimulationEditor(VSPrefs prefs, VSSimulatorFrame simulatorFrame) { - super(prefs, prefs, prefs.getString("lang.name") - + " - " + prefs.getString("lang.prefs")); - this.simulatorFrame = simulatorFrame; - } - - protected void addToButtonPanelFront(JPanel buttonPanel) { - if (TAKEOVER_BUTTON) { - TAKEOVER_BUTTON = false; - JButton takeoverButton = new JButton( - prefs.getString("lang.takeover")); - takeoverButton.setMnemonic(prefs.getInteger("keyevent.takeover")); - takeoverButton.addActionListener(this); - buttonPanel.add(takeoverButton); - } - } - - public void actionPerformed(ActionEvent e) { - String actionCommand = e.getActionCommand(); - - if (actionCommand.equals(prefs.getString("lang.takeover"))) { - savePrefs(); - - if (simulation != null) { - if (expertModeChanged()) - simulation.fireExpertModeChanged(); - simulation.updateFromPrefs(); - } - - } else if (actionCommand.equals(prefs.getString("lang.cancel"))) { - if (!dontStartNewSimulation) - simulatorFrame.dispose(); - - } else if (actionCommand.equals(prefs.getString("lang.ok"))) { - savePrefs(); - if (expertModeChanged()) { - if (simulation != null) - simulation.fireExpertModeChanged(); - } - if (!dontStartNewSimulation) - simulatorFrame.addSimulation(new VSSimulation(prefsToEdit, simulatorFrame)); - else if (simulation != null) - simulation.updateFromPrefs(); - - } else { - super.actionPerformed(e); - } - } -} diff --git a/sources/prefs/editors/VSSimulatorEditor.java b/sources/prefs/editors/VSSimulatorEditor.java new file mode 100644 index 0000000..0ea2332 --- /dev/null +++ b/sources/prefs/editors/VSSimulatorEditor.java @@ -0,0 +1,77 @@ +package prefs.editors; + +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; +import javax.swing.border.*; +import javax.swing.filechooser.*; +import java.util.*; +import java.io.File; + +import simulator.*; +import utils.*; +import prefs.*; + +public class VSSimulatorEditor extends VSBetterEditor { + private VSSimulatorFrame simulatorFrame; + private VSSimulator simulation; + public static boolean TAKEOVER_BUTTON; + private boolean dontStartNewSimulation; + + public VSSimulatorEditor(VSPrefs prefs, VSSimulatorFrame simulatorFrame, VSSimulator simulation) { + super(prefs, prefs, prefs.getString("lang.name") + + " - " + prefs.getString("lang.prefs")); + this.dontStartNewSimulation = true;//simulation != null; + this.simulatorFrame = simulatorFrame; + this.simulation = simulation; + } + + public VSSimulatorEditor(VSPrefs prefs, VSSimulatorFrame simulatorFrame) { + super(prefs, prefs, prefs.getString("lang.name") + + " - " + prefs.getString("lang.prefs")); + this.simulatorFrame = simulatorFrame; + } + + protected void addToButtonPanelFront(JPanel buttonPanel) { + if (TAKEOVER_BUTTON) { + TAKEOVER_BUTTON = false; + JButton takeoverButton = new JButton( + prefs.getString("lang.takeover")); + takeoverButton.setMnemonic(prefs.getInteger("keyevent.takeover")); + takeoverButton.addActionListener(this); + buttonPanel.add(takeoverButton); + } + } + + public void actionPerformed(ActionEvent e) { + String actionCommand = e.getActionCommand(); + + if (actionCommand.equals(prefs.getString("lang.takeover"))) { + savePrefs(); + + if (simulation != null) { + if (expertModeChanged()) + simulation.fireExpertModeChanged(); + simulation.updateFromPrefs(); + } + + } else if (actionCommand.equals(prefs.getString("lang.cancel"))) { + if (!dontStartNewSimulation) + simulatorFrame.dispose(); + + } else if (actionCommand.equals(prefs.getString("lang.ok"))) { + savePrefs(); + if (expertModeChanged()) { + if (simulation != null) + simulation.fireExpertModeChanged(); + } + if (!dontStartNewSimulation) + simulatorFrame.addSimulation(new VSSimulator(prefsToEdit, simulatorFrame)); + else if (simulation != null) + simulation.updateFromPrefs(); + + } else { + super.actionPerformed(e); + } + } +} diff --git a/sources/simulator/VSLogging.java b/sources/simulator/VSLogging.java index 9ab9cec..c303bec 100644 --- a/sources/simulator/VSLogging.java +++ b/sources/simulator/VSLogging.java @@ -11,7 +11,7 @@ public class VSLogging { private String filterText; private ArrayList pauseLines; private ArrayList loggingLines; - private VSSimulationCanvas simulationCanvas; + private VSSimulatorCanvas simulationCanvas; private boolean isFiltered; private boolean isPaused; private Pattern filterPattern; @@ -26,7 +26,7 @@ public class VSLogging { filterText = ""; } - public void setSimulationCanvas(VSSimulationCanvas simulationCanvas) { + public void setSimulationCanvas(VSSimulatorCanvas simulationCanvas) { this.simulationCanvas = simulationCanvas; } diff --git a/sources/simulator/VSMain.java b/sources/simulator/VSMain.java index 926f450..7e6639e 100644 --- a/sources/simulator/VSMain.java +++ b/sources/simulator/VSMain.java @@ -19,7 +19,7 @@ public class VSMain { private void init(VSPrefs prefs, Component relativeTo) { VSSimulatorFrame simulatorFrame = new VSSimulatorFrame(prefs, relativeTo); - new VSEditorFrame(prefs, relativeTo, new VSSimulationEditor(prefs, simulatorFrame)); + new VSEditorFrame(prefs, relativeTo, new VSSimulatorEditor(prefs, simulatorFrame)); } public static void main(String[] args) { diff --git a/sources/simulator/VSSimulation.java b/sources/simulator/VSSimulation.java deleted file mode 100644 index 17400cb..0000000 --- a/sources/simulator/VSSimulation.java +++ /dev/null @@ -1,930 +0,0 @@ -package simulator; - -import java.awt.*; -import java.awt.event.*; -import java.util.*; -import javax.swing.*; -import javax.swing.border.*; -import javax.swing.event.*; -import javax.swing.table.*; - -import core.*; -import events.*; -import events.implementations.*; -import events.internal.*; -import prefs.*; -import prefs.editors.*; -import protocols.*; -import utils.*; - -public class VSSimulation extends JPanel { - private ArrayList globalTextFields; - private ArrayList localTextFields; - private ArrayList createTasks; - private JCheckBox filterActiveCheckBox; - private JCheckBox lamportActiveCheckBox; - private JCheckBox vectorTimeActiveCheckBox; - private JComboBox globalPIDComboBox; - private JComboBox localPIDComboBox; - private JComboBox processesComboBox; - private JPanel globalAddPanel; - private JPanel localAddPanel; - private JPanel localPanel; - private JPanel loggingPanel; - private JPanel toolsPanel; - private JSplitPane splitPane1; - private JSplitPane splitPaneH; - private JSplitPane splitPaneV; - private JTabbedPane tabbedPane; - private JTextArea loggingArea; - private JTextField filterTextField; - private JTextField globalTextField; - private JTextField localTextField; - private Thread thread; - private VSLogging logging; - private VSMenuItemStates menuItemStates; - private VSPrefs prefs; - private VSSimulationCanvas simulationCanvas; - private VSSimulatorFrame simulatorFrame; - private VSTaskManager taskManager; - private VSTaskManagerTableModel taskManagerGlobalModel; - private VSTaskManagerTableModel taskManagerLocalModel; - private boolean hasStarted = false; - private int lastSelectedProcessNum; - private static int simulationCounter; - private static int simulationNum; - - public class VSMenuItemStates { - private volatile boolean pause; - private volatile boolean replay; - private volatile boolean reset; - private volatile boolean start; - - public VSMenuItemStates(boolean pause, boolean replay, boolean reset, boolean start) { - this.pause = pause; - this.replay = replay; - this.reset = reset; - this.start = start; - } - - public void setPause(boolean pause) { - this.pause = pause; - } - - public void setReplay(boolean replay) { - this.replay = replay; - } - - public void setReset(boolean reset) { - this.reset = reset; - } - - public void setStart(boolean start) { - this.start = start; - } - - public boolean getPause() { - return pause; - } - - public boolean getReplay() { - return replay; - } - - public boolean getReset() { - return reset; - } - - public boolean getStart() { - return start; - } - } - - public VSSimulation(VSPrefs prefs, VSSimulatorFrame simulatorFrame) { - this.prefs = prefs; - this.simulatorFrame = simulatorFrame; - this.logging = new VSLogging(); - this.simulationNum = ++simulationCounter; - this.menuItemStates = new VSMenuItemStates(false, false, false, true); - this.localTextFields = new ArrayList(); - this.globalTextFields = new ArrayList(); - - logging.logg(prefs.getString("lang.simulation.new")); - fillContentPane(); - updateFromPrefs(); - splitPaneH.setDividerLocation( - prefs.getInteger("div.window.splitsize")); - - splitPaneV.setDividerLocation( - prefs.getInteger("div.window.ysize") - - prefs.getInteger("div.window.loggsize")); - - splitPane1.setDividerLocation((int) (getPaintSize()/2) - 20); - - int numProcesses = simulationCanvas.getNumProcesses(); - for (int i = 0; i <= numProcesses; ++i) { - localTextFields.add("0000"); - globalTextFields.add("0000"); - } - - processesComboBox.setSelectedIndex(0); - localPIDComboBox.setSelectedIndex(0); - globalPIDComboBox.setSelectedIndex(0); - - thread = new Thread(simulationCanvas); - thread.start(); - } - - private void fillContentPane() { - loggingArea = logging.getLoggingArea(); - - splitPaneH = new JSplitPane(); - splitPaneV = new JSplitPane(); - - simulationCanvas = new VSSimulationCanvas(prefs, this, logging); - taskManager = simulationCanvas.getTaskManager(); - logging.setSimulationCanvas(simulationCanvas); - - JPanel canvasPanel = new JPanel(); - canvasPanel.setLayout(new GridLayout(1, 1, 3, 3)); - canvasPanel.add(simulationCanvas); - canvasPanel.setMinimumSize(new Dimension(0, 0)); - canvasPanel.setMaximumSize(new Dimension(0, 0)); - - loggingPanel = new JPanel(new BorderLayout()); - loggingPanel.add(new JScrollPane(loggingArea), BorderLayout.CENTER); - loggingPanel.add(createToolsPanel(), BorderLayout.SOUTH); - loggingPanel.setPreferredSize(new Dimension(200, 1)); - - splitPaneH.setOrientation(JSplitPane.HORIZONTAL_SPLIT); - splitPaneH.setLeftComponent(createProcessPane()); - splitPaneH.setRightComponent(canvasPanel); - splitPaneH.setContinuousLayout(true); - splitPaneH.setOneTouchExpandable(true); - - splitPaneV.setOrientation(JSplitPane.VERTICAL_SPLIT); - splitPaneV.setTopComponent(splitPaneH); - splitPaneV.setBottomComponent(loggingPanel); - splitPaneV.setContinuousLayout(true); - - this.add(splitPaneV); - } - - private boolean lastExpertState; - private JPanel createToolsPanel() { - JPanel toolsPanel = new JPanel(); - boolean expertMode = prefs.getBoolean("sim.mode.expert"); - - toolsPanel.setLayout(new BoxLayout(toolsPanel, BoxLayout.X_AXIS)); - - JCheckBox expertActiveCheckBox = new JCheckBox(prefs.getString("lang.mode.expert")); - expertActiveCheckBox.setSelected(expertMode); - expertActiveCheckBox.addChangeListener(new ChangeListener() { - public void stateChanged(ChangeEvent ce) { - AbstractButton abstractButton = (AbstractButton) ce.getSource(); - ButtonModel buttonModel = abstractButton.getModel(); - boolean newState = buttonModel.isSelected(); - if (lastExpertState != newState) { - lastExpertState = newState; - prefs.setBoolean("sim.mode.expert", newState); - fireExpertModeChanged(); - } - } - }); - toolsPanel.add(expertActiveCheckBox); - - if (expertMode) { - lamportActiveCheckBox = new JCheckBox(prefs.getString("lang.time.lamport")); - lamportActiveCheckBox.setSelected(false); - lamportActiveCheckBox.addChangeListener(new ChangeListener() { - public void stateChanged(ChangeEvent ce) { - AbstractButton abstractButton = (AbstractButton) ce.getSource(); - ButtonModel buttonModel = abstractButton.getModel(); - simulationCanvas.showLamport(buttonModel.isSelected()); - if (buttonModel.isSelected()) - vectorTimeActiveCheckBox.setSelected(false); - } - }); - toolsPanel.add(lamportActiveCheckBox); - - vectorTimeActiveCheckBox = new JCheckBox(prefs.getString("lang.time.vector")); - vectorTimeActiveCheckBox.setSelected(false); - vectorTimeActiveCheckBox.addChangeListener(new ChangeListener() { - public void stateChanged(ChangeEvent ce) { - AbstractButton abstractButton = (AbstractButton) ce.getSource(); - ButtonModel buttonModel = abstractButton.getModel(); - simulationCanvas.showVectorTime(buttonModel.isSelected()); - if (buttonModel.isSelected()) - lamportActiveCheckBox.setSelected(false); - } - }); - toolsPanel.add(vectorTimeActiveCheckBox); - - JCheckBox antiAliasing = new JCheckBox(prefs.getString("lang.antialiasing")); - antiAliasing.setSelected(false); - antiAliasing.addChangeListener(new ChangeListener() { - public void stateChanged(ChangeEvent ce) { - AbstractButton abstractButton = (AbstractButton) ce.getSource(); - ButtonModel buttonModel = abstractButton.getModel(); - simulationCanvas.isAntiAliased(buttonModel.isSelected()); - } - }); - toolsPanel.add(antiAliasing); - } - - JCheckBox loggingActiveCheckBox = new JCheckBox(prefs.getString("lang.logging.active")); - loggingActiveCheckBox.setSelected(true); - loggingActiveCheckBox.addChangeListener(new ChangeListener() { - public void stateChanged(ChangeEvent ce) { - AbstractButton abstractButton = (AbstractButton) ce.getSource(); - ButtonModel buttonModel = abstractButton.getModel(); - logging.isPaused(!buttonModel.isSelected()); - } - }); - toolsPanel.add(loggingActiveCheckBox); - - if (expertMode) { - filterActiveCheckBox = new JCheckBox(prefs.getString("lang.filter")); - filterActiveCheckBox.setSelected(false); - filterActiveCheckBox.addChangeListener(new ChangeListener() { - public void stateChanged(ChangeEvent ce) { - AbstractButton abstractButton = (AbstractButton) ce.getSource(); - ButtonModel buttonModel = abstractButton.getModel(); - logging.isFiltered(buttonModel.isSelected()); - if (buttonModel.isSelected()) - logging.setFilterText(filterTextField.getText()); - } - }); - toolsPanel.add(filterActiveCheckBox); - - filterTextField = new JTextField(); - filterTextField.getDocument().addDocumentListener(new DocumentListener() { - public void insertUpdate(DocumentEvent de) { - logging.setFilterText(filterTextField.getText()); - } - - public void removeUpdate(DocumentEvent de) { - logging.setFilterText(filterTextField.getText()); - } - - public void changedUpdate(DocumentEvent de) { - logging.setFilterText(filterTextField.getText()); - } - }); - toolsPanel.add(filterTextField); - - JButton clearButton = new JButton(prefs.getString("lang.logging.clear")); - clearButton.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent ae) { - String actionCommand = ae.getActionCommand(); - if (actionCommand.equals(prefs.getString("lang.logging.clear"))) { - logging.clear(); - } - } - }); - toolsPanel.add(clearButton); - } - - return toolsPanel; - } - - private JPanel createProcessPane() { - JPanel editPanel = new JPanel(new GridBagLayout()); - boolean expertMode = prefs.getBoolean("sim.mode.expert"); - editPanel.setLayout(new BoxLayout(editPanel, BoxLayout.Y_AXIS)); - - processesComboBox = new JComboBox(); - localPIDComboBox = new JComboBox(); - globalPIDComboBox = new JComboBox(); - - lastSelectedProcessNum = 0; - int numProcesses = simulationCanvas.getNumProcesses(); - String processString = prefs.getString("lang.process"); - - for (int i = 0; i < numProcesses; ++i) { - int pid = simulationCanvas.getProcess(i).getProcessID(); - processesComboBox.addItem(processString + " " + pid); - localPIDComboBox.addItem("PID: " + pid); - globalPIDComboBox.addItem("PID: " + pid); - } - - processesComboBox.addItem(prefs.getString("lang.processes.all")); - localPIDComboBox.addItem(prefs.getString("lang.all")); - globalPIDComboBox.addItem(prefs.getString("lang.all")); - - tabbedPane = new JTabbedPane(JTabbedPane.TOP, JTabbedPane.WRAP_TAB_LAYOUT); - localPanel = createTaskLabel(VSTaskManagerTableModel.LOCAL); - JPanel globalPanel = createTaskLabel(VSTaskManagerTableModel.GLOBAL); - - splitPane1 = new JSplitPane(); - splitPane1.setOrientation(JSplitPane.VERTICAL_SPLIT); - splitPane1.setTopComponent(localPanel); - splitPane1.setBottomComponent(globalPanel); - splitPane1.setOneTouchExpandable(true); - - if (expertMode) - tabbedPane.addTab(prefs.getString("lang.events"), splitPane1); - - else - tabbedPane.addTab(prefs.getString("lang.events"), localPanel); - - processesComboBox.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent ae) { - localTextFields.set(lastSelectedProcessNum, localTextField.getText()); - globalTextFields.set(lastSelectedProcessNum, globalTextField.getText()); - updateTaskManagerTable(); - - int processNum = getSelectedProcessNum(); - localTextField.setText(localTextFields.get(processNum)); - globalTextField.setText(globalTextFields.get(processNum)); - localTextField.setBackground(Color.WHITE); - globalTextField.setBackground(Color.WHITE); - lastSelectedProcessNum = processNum; - - localPIDComboBox.setSelectedIndex(processNum); - globalPIDComboBox.setSelectedIndex(processNum); - - if (processNum == simulationCanvas.getNumProcesses()) { - tabbedPane.setEnabledAt(1, false); - if (tabbedPane.getSelectedIndex() == 1) - tabbedPane.setSelectedIndex(0); - - } else if (!tabbedPane.isEnabledAt(1)) { - tabbedPane.setEnabledAt(1, true); - } - - if (processNum != simulationCanvas.getNumProcesses()) { - VSProcess process = getSelectedProcess(); - VSProcessEditor processEditor = new VSProcessEditor(prefs, process); - tabbedPane.setComponentAt(1, processEditor.getContentPane()); - } - } - }); - - tabbedPane.add(prefs.getString("lang.variables"), null); - - editPanel.add(processesComboBox); - editPanel.add(tabbedPane); - - return editPanel; - } - - private JPanel createLabelPanel(String text) { - JPanel panel = new JPanel(); - JLabel label = new JLabel(text); - panel.add(label); - - return panel; - } - - private JPanel createTaskLabel(boolean localTasks) { - JPanel panel = new JPanel(new GridBagLayout()); - panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); - - if (localTasks) - panel.add(createLabelPanel(prefs.getString("lang.timed.local"))); - else - panel.add(createLabelPanel(prefs.getString("lang.timed.global"))); - - JScrollPane scrollPane = new JScrollPane(createTaskTable(localTasks)); - panel.add(scrollPane); - - if (localTasks) - localAddPanel = initAddPanel(panel, localTasks); - else - globalAddPanel = initAddPanel(panel, localTasks); - - return panel; - } - - private class VSCreateTask { - private String eventClassname; - private String protocolClassname; - private String shortname; - - /* Those 3 values are for ProtocolEvent events */ - private boolean isProtocolActivation; - private boolean isProtocolDeactivation; - private boolean isClientProtocol; - - /* Those values are for ProtocolClient onStart events */ - private boolean isClientRequest; - - public VSCreateTask(String eventClassname) { - this.eventClassname = eventClassname; - } - - public void isProtocolActivation(boolean isProtocolActivation) { - this.isProtocolActivation = isProtocolActivation; - - if (isProtocolActivation) - isProtocolDeactivation(false); - } - - public void isProtocolDeactivation(boolean isProtocolDeactivation) { - this.isProtocolDeactivation = isProtocolDeactivation; - - if (isProtocolDeactivation) - isProtocolActivation(false); - } - - public void isClientProtocol(boolean isClientProtocol) { - this.isClientProtocol = isClientProtocol; - } - - public void isClientRequest(boolean isClientRequest) { - this.isClientRequest = isClientRequest; - } - - public void setProtocolClassname(String protocolClassname) { - this.protocolClassname = protocolClassname; - } - - public void setShortname(String shortname) { - this.shortname = shortname; - } - - public VSTask createTask(VSProcess process, long time, boolean localTimedTask) { - VSEvent event = null; - - if (isClientRequest) { - event = process.getProtocolObject(eventClassname); - - } else { - event = VSRegisteredEvents.createEventInstanceByClassname(eventClassname, process); - } - - event.init(process); - if (shortname != null) - event.setShortname(shortname); - - if (isProtocolActivation || isProtocolDeactivation) { - ProtocolEvent protocolEvent = (ProtocolEvent) event; - protocolEvent.setProtocolClassname(protocolClassname); - protocolEvent.isProtocolActivation(isProtocolActivation); - protocolEvent.isClientProtocol(isClientProtocol); - } - - return new VSTask(time, process, event, localTimedTask); - } - } - - private class VSTaskManagerTableModel extends AbstractTableModel implements MouseListener { - public static final boolean LOCAL = true; - public static final boolean GLOBAL = false; - public static final boolean ALL_PROCESSES = true; - public static final boolean ONE_PROCESS = false; - public boolean allProcesses; - private VSPriorityQueue tasks; - private String columnNames[]; - private int numColumns; - private JTable table; - - public VSTaskManagerTableModel(VSProcess process, boolean localTask) { - set(process, localTask, ONE_PROCESS); - columnNames = new String[3]; - columnNames[0]= prefs.getString("lang.time") + " (ms)"; - columnNames[1] = prefs.getString("lang.process.id"); - columnNames[2] = prefs.getString("lang.event"); - numColumns = 3; - } - - public void setTable(JTable table) { - this.table = table; - } - - public void set(VSProcess process, boolean localTasks, boolean allProcesses) { - this.allProcesses = allProcesses; - - if (allProcesses) { - this.tasks = localTasks - ? taskManager.getLocalTasks() - : taskManager.getGlobalTasks(); - } else { - this.tasks = localTasks - ? taskManager.getProcessLocalTasks(process) - : taskManager.getProcessGlobalTasks(process); - } - - fireTableDataChanged(); - } - - public String getColumnName(int col) { - return columnNames[col]; - } - - public int getRowCount() { - return tasks == null ? 0 : tasks.size(); - } - - public int getColumnCount() { - return numColumns; - } - - public Object getValueAt(int row, int col) { - VSTask task = tasks.get(row); - - switch (col) { - case 0: - return task.getTaskTime(); - case 1: - return task.getProcess().getProcessID(); - } - - return task.getEvent().getShortname(); - } - - public boolean isCellEditable(int row, int col) { - return false; - } - - public void setValueAt(Object value, int row, int col) { - fireTableDataChanged(); - } - - public void addTask(VSTask task) { - tasks.add(task); - fireTableDataChanged(); - } - - private void removeTaskAtRow(int row) { - VSTask task = tasks.get(row); - tasks.remove(task); - taskManager.removeTask(task); - fireTableDataChanged(); - } - - public void mouseClicked(MouseEvent me) { - JTable source = (JTable) me.getSource(); - final int row = source.rowAtPoint(me.getPoint()); - final int col = source.columnAtPoint(me.getPoint()); - - if (SwingUtilities.isRightMouseButton(me)) { - ActionListener actionListener = new ActionListener() { - public void actionPerformed(ActionEvent ae) { - String actionCommand = ae.getActionCommand(); - if (actionCommand.equals(prefs.getString("lang.remove"))) { - removeTaskAtRow(row); - } - } - }; - - JPopupMenu popup = new JPopupMenu(); - JMenuItem item = new JMenuItem(prefs.getString("lang.remove")); - item.addActionListener(actionListener); - popup.add(item); - - popup.show(me.getComponent(), me.getX(), me.getY()); - } - } - - public void mouseEntered(MouseEvent me) { } - public void mouseExited(MouseEvent me) { } - public void mousePressed(MouseEvent me) { } - public void mouseReleased(MouseEvent me) { } - } - - private JTable createTaskTable(boolean localTasks) { - VSProcess process = getSelectedProcess(); - VSTaskManagerTableModel model = new VSTaskManagerTableModel(process, localTasks); - - if (localTasks) - taskManagerLocalModel = model; - else - taskManagerGlobalModel = model; - - JTable table = new JTable(model); - model.setTable(table); - table.addMouseListener(model); - - TableColumn col = table.getColumnModel().getColumn(0); - col.setMaxWidth(62); - col.setResizable(false); - - col = table.getColumnModel().getColumn(1); - col.setMaxWidth(23); - col.setResizable(false); - - col = table.getColumnModel().getColumn(2); - col.sizeWidthToFit(); - table.setBackground(Color.WHITE); - - return table; - } - - private JPanel initAddPanel(JPanel panel, final boolean localTasks) { - JPanel addPanel = new JPanel(); - addPanel.setLayout(new BoxLayout(addPanel, BoxLayout.X_AXIS)); - boolean expertMode = prefs.getBoolean("sim.mode.expert"); - - final JTextField textField = new JTextField(); - if (localTasks) - localTextField = textField; - else - globalTextField = textField; - - textField.setText("0000"); - textField.setBackground(Color.WHITE); - addPanel.add(textField); - - addPanel.add(new JLabel(" ms ")); - - if (localTasks) { - if (expertMode) - addPanel.add(localPIDComboBox); - } else { - addPanel.add(globalPIDComboBox); - } - - final JComboBox comboBox = new JComboBox(); - JButton takeoverButton = new JButton(prefs.getString("lang.takeover")); - takeoverButton.addActionListener(new ActionListener() { - private boolean isRed; - - public void actionPerformed(ActionEvent ae) { - String textValue = textField.getText(); - Long longValue = null; - - try { - longValue = Long.valueOf(textValue); - - if (longValue.longValue() < 0) { - makeRed(); - return; - } - - if (isRed) { - makeWhite(); - } - - } catch (NumberFormatException e) { - makeRed(); - } - - if (longValue == null) - return; - - if (takeover(longValue.longValue())) { - if (isRed) - makeWhite(); - - } else { - makeRed(); - } - } - - private void makeWhite() { - textField.setBackground(Color.WHITE); - isRed = false; - } - - private void makeRed() { - textField.setBackground(Color.RED); - isRed = true; - } - - private boolean takeover(long time) { - VSProcess selectedProcess = getSelectedProcess(); - int index = comboBox.getSelectedIndex(); - VSCreateTask createTask = createTasks.get(index); - - if (createTask == null) - return false; - - ArrayList processes = getConcernedProcesses(localTasks); - - for (VSProcess process : processes) { - VSTask task = createTask.createTask(process, time, localTasks); - taskManager.addTask(task, VSTaskManager.PROGRAMMED); - - if (selectedProcess == null || process.equals(selectedProcess)) { - if (localTasks) - taskManagerLocalModel.addTask(task); - else - taskManagerGlobalModel.addTask(task); - } - } - - return true; - } - }); - - addPanel.add(takeoverButton); - - boolean flag = createTasks == null; - if (flag) createTasks = new ArrayList(); - - Vector eventClassnames = VSRegisteredEvents.getNonProtocolClassnames(); - - comboBox.setMaximumRowCount(15); - comboBox.addItem("-- " + prefs.getString("lang.events.process") + " --"); - if (flag) - createTasks.add(null); - - for (String eventClassname : eventClassnames) { - String eventShortname = VSRegisteredEvents.getShortname(eventClassname); - comboBox.addItem(eventShortname); - if (flag) - createTasks.add(new VSCreateTask(eventClassname)); - } - - comboBox.addItem("-- " + prefs.getString("lang.requests") + " --"); - if (flag) - createTasks.add(null); - String clientrequest = prefs.getString("lang.clientrequest.start"); - - eventClassnames = VSRegisteredEvents.getProtocolClassnames(); - for (String eventClassname : eventClassnames) { - String eventShortname = VSRegisteredEvents.getShortname(eventClassname) - + " " + clientrequest; - - comboBox.addItem(eventShortname); - - if (flag) { - VSCreateTask createTask = new VSCreateTask(eventClassname); - createTask.setShortname(eventShortname); - createTask.isClientRequest(true); - createTasks.add(createTask); - } - } - - comboBox.addItem("-- " + prefs.getString("lang.events.protocol") + " --"); - if (flag) - createTasks.add(null); - - eventClassnames = VSRegisteredEvents.getProtocolClassnames(); - String activate = prefs.getString("lang.activate"); - String deactivate = prefs.getString("lang.deactivate"); - String client = prefs.getString("lang.client"); - String server = prefs.getString("lang.server"); - String protocolEventClassname = "events.internal.ProtocolEvent"; - - for (String eventClassname : eventClassnames) { - String eventShortname_ = VSRegisteredEvents.getShortname(eventClassname); - - String eventShortname = eventShortname_ + " " + client + " " + activate; - comboBox.addItem(eventShortname); - if (flag) { - VSCreateTask createTask = new VSCreateTask(protocolEventClassname); - createTask.isProtocolActivation(true); - createTask.isClientProtocol(true); - createTask.setProtocolClassname(eventClassname); - createTask.setShortname(eventShortname); - createTasks.add(createTask); - } - - eventShortname = eventShortname_ + " " + client + " " + deactivate; - comboBox.addItem(eventShortname); - if (flag) { - VSCreateTask createTask = new VSCreateTask(protocolEventClassname); - createTask.isProtocolDeactivation(true); - createTask.isClientProtocol(true); - createTask.setProtocolClassname(eventClassname); - createTask.setShortname(eventShortname); - createTasks.add(createTask); - } - - eventShortname = eventShortname_ + " " + server + " " + activate; - comboBox.addItem(eventShortname); - if (flag) { - VSCreateTask createTask = new VSCreateTask(protocolEventClassname); - createTask.isProtocolActivation(true); - createTask.isClientProtocol(false); - createTask.setProtocolClassname(eventClassname); - createTask.setShortname(eventShortname); - createTasks.add(createTask); - } - - eventShortname = eventShortname_ + " " + server + " " + deactivate; - comboBox.addItem(eventShortname); - if (flag) { - VSCreateTask createTask = new VSCreateTask(protocolEventClassname); - createTask.isProtocolDeactivation(true); - createTask.isClientProtocol(false); - createTask.setProtocolClassname(eventClassname); - createTask.setShortname(eventShortname); - createTasks.add(createTask); - } - } - - panel.add(comboBox); - panel.add(addPanel); - - return addPanel; - } - - public int getSplitSize() { - return splitPaneH.getDividerLocation(); - } - - public int getPaintSize() { - return splitPaneV.getDividerLocation(); - } - - private int getSelectedProcessNum() { - return processesComboBox.getSelectedIndex(); - } - - private VSProcess getSelectedProcess() { - int processNum = getSelectedProcessNum(); - return simulationCanvas.getProcess(processNum); - } - - private ArrayList getConcernedProcesses(boolean localTasks) { - int processNum = localTasks - ? localPIDComboBox.getSelectedIndex() - : globalPIDComboBox.getSelectedIndex(); - - if (processNum == simulationCanvas.getNumProcesses()) - return simulationCanvas.getProcessesArray(); - - ArrayList arr = new ArrayList(); - arr.add(simulationCanvas.getProcess(processNum)); - - return arr; - } - - public void updateTaskManagerTable() { - VSProcess process = getSelectedProcess(); - boolean allProcesses = process == null; - taskManagerLocalModel.set(process, VSTaskManagerTableModel.LOCAL, allProcesses); - taskManagerGlobalModel.set(process, VSTaskManagerTableModel.GLOBAL, allProcesses); - } - - public void finish() { - menuItemStates.setStart(false); - menuItemStates.setPause(false); - menuItemStates.setReset(true); - menuItemStates.setReplay(true); - simulatorFrame.updateSimulationMenu(); - } - - public int getSimulationNum() { - return simulationNum; - } - - public VSSimulation.VSMenuItemStates getMenuItemStates() { - return menuItemStates; - } - - public VSSimulationCanvas getSimulationCanvas() { - return simulationCanvas; - } - - public VSSimulatorFrame getSimulatorFrame() { - return simulatorFrame; - } - - public void updateFromPrefs() { - simulationCanvas.setBackground(prefs.getColor("col.background")); - simulationCanvas.updateFromPrefs(); - } - - public void removeProcessAtIndex(int index) { - globalPIDComboBox.removeItemAt(index); - localPIDComboBox.removeItemAt(index); - processesComboBox.removeItemAt(index); - simulatorFrame.updateEditMenu(); - } - - public void fireExpertModeChanged() { - boolean expertMode = prefs.getBoolean("sim.mode.expert"); - - /* Update the Task Manager GUI */ - int selectedIndex = tabbedPane.getSelectedIndex(); - - if (expertMode) { - tabbedPane.remove(localPanel); - tabbedPane.insertTab(prefs.getString("lang.events"), null, splitPane1, null, 0); - splitPane1.setTopComponent(localPanel); - splitPane1.setDividerLocation((int) (getPaintSize()/2) - 20); - - /* addPanel */ - localAddPanel.add(localPIDComboBox, 2); - - } else { - tabbedPane.remove(splitPane1); - tabbedPane.insertTab(prefs.getString("lang.events"), null, localPanel, null, 0); - - /* addPanel */ - localAddPanel.remove(2); - } - tabbedPane.setSelectedIndex(selectedIndex); - - /* Update the 'Variables tab' */ - if (getSelectedProcessNum() != simulationCanvas.getNumProcesses()) { - VSProcess process = getSelectedProcess(); - VSProcessEditor editor = new VSProcessEditor(prefs, process); - tabbedPane.setComponentAt(1, editor.getContentPane()); - } - - /* Update the tools panel */ - loggingPanel.remove(1); - loggingPanel.add(createToolsPanel(), BorderLayout.SOUTH); - updateUI(); - } - - public VSPrefs getPrefs() { - return prefs; - } -} diff --git a/sources/simulator/VSSimulationCanvas.java b/sources/simulator/VSSimulationCanvas.java deleted file mode 100644 index 8444785..0000000 --- a/sources/simulator/VSSimulationCanvas.java +++ /dev/null @@ -1,875 +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 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 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 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; - - recalcOnChange(); - paint(); - } - - public void recalcOnChange() { - 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 Vector(); - - numProcesses = prefs.getInteger("sim.process.num"); - updateFromPrefs(); - - VSProcess.resetProcessCounter(); - for (int i = 0; i < numProcesses; ++i) - addProcess(); - - 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"); - - 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(Color.WHITE); - if (isAntiAliased) - g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); - } - } - } - - public VSProcess addProcess() { - 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) { - 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(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 = simulationTime; - - 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 }; - - 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.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.process.edit"))) { - editProcess(process); - - } else if (actionCommand.equals(prefs.getString("lang.process.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.process.recover"))) { - VSEvent event = new ProcessRecoverEvent(); - //event.init(process); - taskManager.addTask(new VSTask(process.getGlobalTime(), process, event, VSTask.GLOBAL)); - - } else if (actionCommand.equals(prefs.getString("lang.process.remove"))) { - removeProcess(process); - } - } - }; - - - JPopupMenu popup = new JPopupMenu(); - JMenuItem item = new JMenuItem(prefs.getString("lang.process.edit")); - item.addActionListener(actionListener); - popup.add(item); - - item = new JMenuItem(prefs.getString("lang.process.crash")); - if (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.isCrashed() || isPaused || time == 0 || isFinished) - item.setEnabled(false); - else - item.addActionListener(actionListener); - popup.add(item); - - item = new JMenuItem(prefs.getString("lang.process.remove")); - item.addActionListener(actionListener); - popup.add(item); - - popup.addSeparator(); - - 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(); - } - - public void removeProcess(VSProcess process) { - if (numProcesses == 1) { - simulation.getSimulatorFrame().removeSimulation(simulation); - - } else { - int index = processes.indexOf(process); - processes.remove(index); - numProcesses = processes.size(); - recalcOnChange(); - simulation.removeProcessAtIndex(index); - } - } -} diff --git a/sources/simulator/VSSimulator.java b/sources/simulator/VSSimulator.java new file mode 100644 index 0000000..097d198 --- /dev/null +++ b/sources/simulator/VSSimulator.java @@ -0,0 +1,953 @@ +package simulator; + +import java.awt.*; +import java.awt.event.*; +import java.util.*; +import javax.swing.*; +import javax.swing.border.*; +import javax.swing.event.*; +import javax.swing.table.*; + +import core.*; +import events.*; +import events.implementations.*; +import events.internal.*; +import prefs.*; +import prefs.editors.*; +import protocols.*; +import utils.*; + +public class VSSimulator extends JPanel { + private ArrayList globalTextFields; + private ArrayList localTextFields; + private ArrayList createTasks; + private JCheckBox filterActiveCheckBox; + private JCheckBox lamportActiveCheckBox; + private JCheckBox vectorTimeActiveCheckBox; + private JComboBox globalPIDComboBox; + private JComboBox localPIDComboBox; + private JComboBox processesComboBox; + private JPanel globalAddPanel; + private JPanel localAddPanel; + private JPanel localPanel; + private JPanel loggingPanel; + private JPanel toolsPanel; + private JSplitPane splitPane1; + private JSplitPane splitPaneH; + private JSplitPane splitPaneV; + private JTabbedPane tabbedPane; + private JTextArea loggingArea; + private JTextField filterTextField; + private JTextField globalTextField; + private JTextField localTextField; + private Thread thread; + private VSLogging logging; + private VSMenuItemStates menuItemStates; + private VSPrefs prefs; + private VSSimulatorCanvas simulationCanvas; + private VSSimulatorFrame simulatorFrame; + private VSTaskManager taskManager; + private VSTaskManagerTableModel taskManagerGlobalModel; + private VSTaskManagerTableModel taskManagerLocalModel; + private boolean hasStarted = false; + private int lastSelectedProcessNum; + private static int simulationCounter; + private static int simulationNum; + + public class VSMenuItemStates { + private volatile boolean pause; + private volatile boolean replay; + private volatile boolean reset; + private volatile boolean start; + + public VSMenuItemStates(boolean pause, boolean replay, boolean reset, boolean start) { + this.pause = pause; + this.replay = replay; + this.reset = reset; + this.start = start; + } + + public void setPause(boolean pause) { + this.pause = pause; + } + + public void setReplay(boolean replay) { + this.replay = replay; + } + + public void setReset(boolean reset) { + this.reset = reset; + } + + public void setStart(boolean start) { + this.start = start; + } + + public boolean getPause() { + return pause; + } + + public boolean getReplay() { + return replay; + } + + public boolean getReset() { + return reset; + } + + public boolean getStart() { + return start; + } + } + + public VSSimulator(VSPrefs prefs, VSSimulatorFrame simulatorFrame) { + this.prefs = prefs; + this.simulatorFrame = simulatorFrame; + this.logging = new VSLogging(); + this.simulationNum = ++simulationCounter; + this.menuItemStates = new VSMenuItemStates(false, false, false, true); + this.localTextFields = new ArrayList(); + this.globalTextFields = new ArrayList(); + + logging.logg(prefs.getString("lang.simulation.new")); + fillContentPane(); + updateFromPrefs(); + splitPaneH.setDividerLocation( + prefs.getInteger("div.window.splitsize")); + + splitPaneV.setDividerLocation( + prefs.getInteger("div.window.ysize") + - prefs.getInteger("div.window.loggsize")); + + splitPane1.setDividerLocation((int) (getPaintSize()/2) - 20); + + int numProcesses = simulationCanvas.getNumProcesses(); + for (int i = 0; i <= numProcesses; ++i) { + localTextFields.add("0000"); + globalTextFields.add("0000"); + } + + processesComboBox.setSelectedIndex(0); + localPIDComboBox.setSelectedIndex(0); + globalPIDComboBox.setSelectedIndex(0); + + thread = new Thread(simulationCanvas); + thread.start(); + } + + private void fillContentPane() { + loggingArea = logging.getLoggingArea(); + + splitPaneH = new JSplitPane(); + splitPaneV = new JSplitPane(); + + simulationCanvas = new VSSimulatorCanvas(prefs, this, logging); + taskManager = simulationCanvas.getTaskManager(); + logging.setSimulationCanvas(simulationCanvas); + + JPanel canvasPanel = new JPanel(); + canvasPanel.setLayout(new GridLayout(1, 1, 3, 3)); + canvasPanel.add(simulationCanvas); + canvasPanel.setMinimumSize(new Dimension(0, 0)); + canvasPanel.setMaximumSize(new Dimension(0, 0)); + + loggingPanel = new JPanel(new BorderLayout()); + loggingPanel.add(new JScrollPane(loggingArea), BorderLayout.CENTER); + loggingPanel.add(createToolsPanel(), BorderLayout.SOUTH); + loggingPanel.setPreferredSize(new Dimension(200, 1)); + + splitPaneH.setOrientation(JSplitPane.HORIZONTAL_SPLIT); + splitPaneH.setLeftComponent(createProcessPane()); + splitPaneH.setRightComponent(canvasPanel); + splitPaneH.setContinuousLayout(true); + splitPaneH.setOneTouchExpandable(true); + + splitPaneV.setOrientation(JSplitPane.VERTICAL_SPLIT); + splitPaneV.setTopComponent(splitPaneH); + splitPaneV.setBottomComponent(loggingPanel); + splitPaneV.setContinuousLayout(true); + + this.add(splitPaneV); + } + + private boolean lastExpertState; + private JPanel createToolsPanel() { + JPanel toolsPanel = new JPanel(); + boolean expertMode = prefs.getBoolean("sim.mode.expert"); + + toolsPanel.setLayout(new BoxLayout(toolsPanel, BoxLayout.X_AXIS)); + + JCheckBox expertActiveCheckBox = new JCheckBox(prefs.getString("lang.mode.expert")); + expertActiveCheckBox.setSelected(expertMode); + expertActiveCheckBox.addChangeListener(new ChangeListener() { + public void stateChanged(ChangeEvent ce) { + AbstractButton abstractButton = (AbstractButton) ce.getSource(); + ButtonModel buttonModel = abstractButton.getModel(); + boolean newState = buttonModel.isSelected(); + if (lastExpertState != newState) { + lastExpertState = newState; + prefs.setBoolean("sim.mode.expert", newState); + fireExpertModeChanged(); + } + } + }); + toolsPanel.add(expertActiveCheckBox); + + if (expertMode) { + lamportActiveCheckBox = new JCheckBox(prefs.getString("lang.time.lamport")); + lamportActiveCheckBox.setSelected(false); + lamportActiveCheckBox.addChangeListener(new ChangeListener() { + public void stateChanged(ChangeEvent ce) { + AbstractButton abstractButton = (AbstractButton) ce.getSource(); + ButtonModel buttonModel = abstractButton.getModel(); + simulationCanvas.showLamport(buttonModel.isSelected()); + if (buttonModel.isSelected()) + vectorTimeActiveCheckBox.setSelected(false); + } + }); + toolsPanel.add(lamportActiveCheckBox); + + vectorTimeActiveCheckBox = new JCheckBox(prefs.getString("lang.time.vector")); + vectorTimeActiveCheckBox.setSelected(false); + vectorTimeActiveCheckBox.addChangeListener(new ChangeListener() { + public void stateChanged(ChangeEvent ce) { + AbstractButton abstractButton = (AbstractButton) ce.getSource(); + ButtonModel buttonModel = abstractButton.getModel(); + simulationCanvas.showVectorTime(buttonModel.isSelected()); + if (buttonModel.isSelected()) + lamportActiveCheckBox.setSelected(false); + } + }); + toolsPanel.add(vectorTimeActiveCheckBox); + + JCheckBox antiAliasing = new JCheckBox(prefs.getString("lang.antialiasing")); + antiAliasing.setSelected(false); + antiAliasing.addChangeListener(new ChangeListener() { + public void stateChanged(ChangeEvent ce) { + AbstractButton abstractButton = (AbstractButton) ce.getSource(); + ButtonModel buttonModel = abstractButton.getModel(); + simulationCanvas.isAntiAliased(buttonModel.isSelected()); + } + }); + toolsPanel.add(antiAliasing); + } + + JCheckBox loggingActiveCheckBox = new JCheckBox(prefs.getString("lang.logging.active")); + loggingActiveCheckBox.setSelected(true); + loggingActiveCheckBox.addChangeListener(new ChangeListener() { + public void stateChanged(ChangeEvent ce) { + AbstractButton abstractButton = (AbstractButton) ce.getSource(); + ButtonModel buttonModel = abstractButton.getModel(); + logging.isPaused(!buttonModel.isSelected()); + } + }); + toolsPanel.add(loggingActiveCheckBox); + + if (expertMode) { + filterActiveCheckBox = new JCheckBox(prefs.getString("lang.filter")); + filterActiveCheckBox.setSelected(false); + filterActiveCheckBox.addChangeListener(new ChangeListener() { + public void stateChanged(ChangeEvent ce) { + AbstractButton abstractButton = (AbstractButton) ce.getSource(); + ButtonModel buttonModel = abstractButton.getModel(); + logging.isFiltered(buttonModel.isSelected()); + if (buttonModel.isSelected()) + logging.setFilterText(filterTextField.getText()); + } + }); + toolsPanel.add(filterActiveCheckBox); + + filterTextField = new JTextField(); + filterTextField.getDocument().addDocumentListener(new DocumentListener() { + public void insertUpdate(DocumentEvent de) { + logging.setFilterText(filterTextField.getText()); + } + + public void removeUpdate(DocumentEvent de) { + logging.setFilterText(filterTextField.getText()); + } + + public void changedUpdate(DocumentEvent de) { + logging.setFilterText(filterTextField.getText()); + } + }); + toolsPanel.add(filterTextField); + + JButton clearButton = new JButton(prefs.getString("lang.logging.clear")); + clearButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent ae) { + String actionCommand = ae.getActionCommand(); + if (actionCommand.equals(prefs.getString("lang.logging.clear"))) { + logging.clear(); + } + } + }); + toolsPanel.add(clearButton); + } + + return toolsPanel; + } + + private JPanel createProcessPane() { + JPanel editPanel = new JPanel(new GridBagLayout()); + boolean expertMode = prefs.getBoolean("sim.mode.expert"); + editPanel.setLayout(new BoxLayout(editPanel, BoxLayout.Y_AXIS)); + + processesComboBox = new JComboBox(); + localPIDComboBox = new JComboBox(); + globalPIDComboBox = new JComboBox(); + + lastSelectedProcessNum = 0; + int numProcesses = simulationCanvas.getNumProcesses(); + String processString = prefs.getString("lang.process"); + + for (int i = 0; i < numProcesses; ++i) { + int pid = simulationCanvas.getProcess(i).getProcessID(); + processesComboBox.addItem(processString + " " + pid); + localPIDComboBox.addItem("PID: " + pid); + globalPIDComboBox.addItem("PID: " + pid); + } + + processesComboBox.addItem(prefs.getString("lang.processes.all")); + localPIDComboBox.addItem(prefs.getString("lang.all")); + globalPIDComboBox.addItem(prefs.getString("lang.all")); + + tabbedPane = new JTabbedPane(JTabbedPane.TOP, JTabbedPane.WRAP_TAB_LAYOUT); + localPanel = createTaskLabel(VSTaskManagerTableModel.LOCAL); + JPanel globalPanel = createTaskLabel(VSTaskManagerTableModel.GLOBAL); + + splitPane1 = new JSplitPane(); + splitPane1.setOrientation(JSplitPane.VERTICAL_SPLIT); + splitPane1.setTopComponent(localPanel); + splitPane1.setBottomComponent(globalPanel); + splitPane1.setOneTouchExpandable(true); + + if (expertMode) + tabbedPane.addTab(prefs.getString("lang.events"), splitPane1); + + else + tabbedPane.addTab(prefs.getString("lang.events"), localPanel); + + processesComboBox.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent ae) { + localTextFields.set(lastSelectedProcessNum, localTextField.getText()); + globalTextFields.set(lastSelectedProcessNum, globalTextField.getText()); + updateTaskManagerTable(); + + int processNum = getSelectedProcessNum(); + localTextField.setText(localTextFields.get(processNum)); + globalTextField.setText(globalTextFields.get(processNum)); + localTextField.setBackground(Color.WHITE); + globalTextField.setBackground(Color.WHITE); + lastSelectedProcessNum = processNum; + + localPIDComboBox.setSelectedIndex(processNum); + globalPIDComboBox.setSelectedIndex(processNum); + + if (processNum == simulationCanvas.getNumProcesses()) { + tabbedPane.setEnabledAt(1, false); + if (tabbedPane.getSelectedIndex() == 1) + tabbedPane.setSelectedIndex(0); + + } else if (!tabbedPane.isEnabledAt(1)) { + tabbedPane.setEnabledAt(1, true); + } + + if (processNum != simulationCanvas.getNumProcesses()) { + VSProcess process = getSelectedProcess(); + VSProcessEditor processEditor = new VSProcessEditor(prefs, process); + tabbedPane.setComponentAt(1, processEditor.getContentPane()); + } + } + }); + + tabbedPane.add(prefs.getString("lang.variables"), null); + + editPanel.add(processesComboBox); + editPanel.add(tabbedPane); + + return editPanel; + } + + private JPanel createLabelPanel(String text) { + JPanel panel = new JPanel(); + JLabel label = new JLabel(text); + panel.add(label); + + return panel; + } + + private JPanel createTaskLabel(boolean localTasks) { + JPanel panel = new JPanel(new GridBagLayout()); + panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); + + if (localTasks) + panel.add(createLabelPanel(prefs.getString("lang.timed.local"))); + else + panel.add(createLabelPanel(prefs.getString("lang.timed.global"))); + + JScrollPane scrollPane = new JScrollPane(createTaskTable(localTasks)); + panel.add(scrollPane); + + if (localTasks) + localAddPanel = initAddPanel(panel, localTasks); + else + globalAddPanel = initAddPanel(panel, localTasks); + + return panel; + } + + private class VSCreateTask { + private String eventClassname; + private String protocolClassname; + private String shortname; + + /* Those 3 values are for ProtocolEvent events */ + private boolean isProtocolActivation; + private boolean isProtocolDeactivation; + private boolean isClientProtocol; + + /* Those values are for ProtocolClient onStart events */ + private boolean isClientRequest; + + public VSCreateTask(String eventClassname) { + this.eventClassname = eventClassname; + } + + public void isProtocolActivation(boolean isProtocolActivation) { + this.isProtocolActivation = isProtocolActivation; + + if (isProtocolActivation) + isProtocolDeactivation(false); + } + + public void isProtocolDeactivation(boolean isProtocolDeactivation) { + this.isProtocolDeactivation = isProtocolDeactivation; + + if (isProtocolDeactivation) + isProtocolActivation(false); + } + + public void isClientProtocol(boolean isClientProtocol) { + this.isClientProtocol = isClientProtocol; + } + + public void isClientRequest(boolean isClientRequest) { + this.isClientRequest = isClientRequest; + } + + public void setProtocolClassname(String protocolClassname) { + this.protocolClassname = protocolClassname; + } + + public void setShortname(String shortname) { + this.shortname = shortname; + } + + public VSTask createTask(VSProcess process, long time, boolean localTimedTask) { + VSEvent event = null; + + if (isClientRequest) { + event = process.getProtocolObject(eventClassname); + + } else { + event = VSRegisteredEvents.createEventInstanceByClassname(eventClassname, process); + } + + event.init(process); + if (shortname != null) + event.setShortname(shortname); + + if (isProtocolActivation || isProtocolDeactivation) { + ProtocolEvent protocolEvent = (ProtocolEvent) event; + protocolEvent.setProtocolClassname(protocolClassname); + protocolEvent.isProtocolActivation(isProtocolActivation); + protocolEvent.isClientProtocol(isClientProtocol); + } + + return new VSTask(time, process, event, localTimedTask); + } + } + + private class VSTaskManagerTableModel extends AbstractTableModel implements MouseListener { + public static final boolean LOCAL = true; + public static final boolean GLOBAL = false; + public static final boolean ALL_PROCESSES = true; + public static final boolean ONE_PROCESS = false; + public boolean allProcesses; + private VSPriorityQueue tasks; + private String columnNames[]; + private int numColumns; + private JTable table; + + public VSTaskManagerTableModel(VSProcess process, boolean localTask) { + set(process, localTask, ONE_PROCESS); + columnNames = new String[3]; + columnNames[0]= prefs.getString("lang.time") + " (ms)"; + columnNames[1] = prefs.getString("lang.process.id"); + columnNames[2] = prefs.getString("lang.event"); + numColumns = 3; + } + + public void setTable(JTable table) { + this.table = table; + } + + public void set(VSProcess process, boolean localTasks, boolean allProcesses) { + this.allProcesses = allProcesses; + + if (allProcesses) { + this.tasks = localTasks + ? taskManager.getLocalTasks() + : taskManager.getGlobalTasks(); + } else { + this.tasks = localTasks + ? taskManager.getProcessLocalTasks(process) + : taskManager.getProcessGlobalTasks(process); + } + + fireTableDataChanged(); + } + + public String getColumnName(int col) { + return columnNames[col]; + } + + public int getRowCount() { + return tasks == null ? 0 : tasks.size(); + } + + public int getColumnCount() { + return numColumns; + } + + public Object getValueAt(int row, int col) { + VSTask task = tasks.get(row); + + switch (col) { + case 0: + return task.getTaskTime(); + case 1: + return task.getProcess().getProcessID(); + } + + return task.getEvent().getShortname(); + } + + public boolean isCellEditable(int row, int col) { + return false; + } + + public void setValueAt(Object value, int row, int col) { + fireTableDataChanged(); + } + + public void addTask(VSTask task) { + tasks.add(task); + fireTableDataChanged(); + } + + private void removeTaskAtRow(int row) { + VSTask task = tasks.get(row); + tasks.remove(task); + taskManager.removeTask(task); + fireTableDataChanged(); + } + + public void mouseClicked(MouseEvent me) { + JTable source = (JTable) me.getSource(); + final int row = source.rowAtPoint(me.getPoint()); + final int col = source.columnAtPoint(me.getPoint()); + + if (SwingUtilities.isRightMouseButton(me)) { + ActionListener actionListener = new ActionListener() { + public void actionPerformed(ActionEvent ae) { + String actionCommand = ae.getActionCommand(); + if (actionCommand.equals(prefs.getString("lang.remove"))) { + removeTaskAtRow(row); + } + } + }; + + JPopupMenu popup = new JPopupMenu(); + JMenuItem item = new JMenuItem(prefs.getString("lang.remove")); + item.addActionListener(actionListener); + popup.add(item); + + popup.show(me.getComponent(), me.getX(), me.getY()); + } + } + + public void mouseEntered(MouseEvent me) { } + public void mouseExited(MouseEvent me) { } + public void mousePressed(MouseEvent me) { } + public void mouseReleased(MouseEvent me) { } + } + + private JTable createTaskTable(boolean localTasks) { + VSProcess process = getSelectedProcess(); + VSTaskManagerTableModel model = new VSTaskManagerTableModel(process, localTasks); + + if (localTasks) + taskManagerLocalModel = model; + else + taskManagerGlobalModel = model; + + JTable table = new JTable(model); + model.setTable(table); + table.addMouseListener(model); + + TableColumn col = table.getColumnModel().getColumn(0); + col.setMaxWidth(62); + col.setResizable(false); + + col = table.getColumnModel().getColumn(1); + col.setMaxWidth(23); + col.setResizable(false); + + col = table.getColumnModel().getColumn(2); + col.sizeWidthToFit(); + table.setBackground(Color.WHITE); + + return table; + } + + private JPanel initAddPanel(JPanel panel, final boolean localTasks) { + JPanel addPanel = new JPanel(); + addPanel.setLayout(new BoxLayout(addPanel, BoxLayout.X_AXIS)); + boolean expertMode = prefs.getBoolean("sim.mode.expert"); + + final JTextField textField = new JTextField(); + if (localTasks) + localTextField = textField; + else + globalTextField = textField; + + textField.setText("0000"); + textField.setBackground(Color.WHITE); + addPanel.add(textField); + + addPanel.add(new JLabel(" ms ")); + + if (localTasks) { + if (expertMode) + addPanel.add(localPIDComboBox); + } else { + addPanel.add(globalPIDComboBox); + } + + final JComboBox comboBox = new JComboBox(); + JButton takeoverButton = new JButton(prefs.getString("lang.takeover")); + takeoverButton.addActionListener(new ActionListener() { + private boolean isRed; + + public void actionPerformed(ActionEvent ae) { + String textValue = textField.getText(); + Long longValue = null; + + try { + longValue = Long.valueOf(textValue); + + if (longValue.longValue() < 0) { + makeRed(); + return; + } + + if (isRed) { + makeWhite(); + } + + } catch (NumberFormatException e) { + makeRed(); + } + + if (longValue == null) + return; + + if (takeover(longValue.longValue())) { + if (isRed) + makeWhite(); + + } else { + makeRed(); + } + } + + private void makeWhite() { + textField.setBackground(Color.WHITE); + isRed = false; + } + + private void makeRed() { + textField.setBackground(Color.RED); + isRed = true; + } + + private boolean takeover(long time) { + VSProcess selectedProcess = getSelectedProcess(); + int index = comboBox.getSelectedIndex(); + VSCreateTask createTask = createTasks.get(index); + + if (createTask == null) + return false; + + ArrayList processes = getConcernedProcesses(localTasks); + + for (VSProcess process : processes) { + VSTask task = createTask.createTask(process, time, localTasks); + taskManager.addTask(task, VSTaskManager.PROGRAMMED); + + if (selectedProcess == null || process.equals(selectedProcess)) { + if (localTasks) + taskManagerLocalModel.addTask(task); + else + taskManagerGlobalModel.addTask(task); + } + } + + return true; + } + }); + + addPanel.add(takeoverButton); + + boolean flag = createTasks == null; + if (flag) createTasks = new ArrayList(); + + Vector eventClassnames = VSRegisteredEvents.getNonProtocolClassnames(); + + comboBox.setMaximumRowCount(15); + comboBox.addItem("-- " + prefs.getString("lang.events.process") + " --"); + if (flag) + createTasks.add(null); + + for (String eventClassname : eventClassnames) { + String eventShortname = VSRegisteredEvents.getShortname(eventClassname); + comboBox.addItem(eventShortname); + if (flag) + createTasks.add(new VSCreateTask(eventClassname)); + } + + comboBox.addItem("-- " + prefs.getString("lang.requests") + " --"); + if (flag) + createTasks.add(null); + String clientrequest = prefs.getString("lang.clientrequest.start"); + + eventClassnames = VSRegisteredEvents.getProtocolClassnames(); + for (String eventClassname : eventClassnames) { + String eventShortname = VSRegisteredEvents.getShortname(eventClassname) + + " " + clientrequest; + + comboBox.addItem(eventShortname); + + if (flag) { + VSCreateTask createTask = new VSCreateTask(eventClassname); + createTask.setShortname(eventShortname); + createTask.isClientRequest(true); + createTasks.add(createTask); + } + } + + comboBox.addItem("-- " + prefs.getString("lang.events.protocol") + " --"); + if (flag) + createTasks.add(null); + + eventClassnames = VSRegisteredEvents.getProtocolClassnames(); + String activate = prefs.getString("lang.activate"); + String deactivate = prefs.getString("lang.deactivate"); + String client = prefs.getString("lang.client"); + String server = prefs.getString("lang.server"); + String protocolEventClassname = "events.internal.ProtocolEvent"; + + for (String eventClassname : eventClassnames) { + String eventShortname_ = VSRegisteredEvents.getShortname(eventClassname); + + String eventShortname = eventShortname_ + " " + client + " " + activate; + comboBox.addItem(eventShortname); + if (flag) { + VSCreateTask createTask = new VSCreateTask(protocolEventClassname); + createTask.isProtocolActivation(true); + createTask.isClientProtocol(true); + createTask.setProtocolClassname(eventClassname); + createTask.setShortname(eventShortname); + createTasks.add(createTask); + } + + eventShortname = eventShortname_ + " " + client + " " + deactivate; + comboBox.addItem(eventShortname); + if (flag) { + VSCreateTask createTask = new VSCreateTask(protocolEventClassname); + createTask.isProtocolDeactivation(true); + createTask.isClientProtocol(true); + createTask.setProtocolClassname(eventClassname); + createTask.setShortname(eventShortname); + createTasks.add(createTask); + } + + eventShortname = eventShortname_ + " " + server + " " + activate; + comboBox.addItem(eventShortname); + if (flag) { + VSCreateTask createTask = new VSCreateTask(protocolEventClassname); + createTask.isProtocolActivation(true); + createTask.isClientProtocol(false); + createTask.setProtocolClassname(eventClassname); + createTask.setShortname(eventShortname); + createTasks.add(createTask); + } + + eventShortname = eventShortname_ + " " + server + " " + deactivate; + comboBox.addItem(eventShortname); + if (flag) { + VSCreateTask createTask = new VSCreateTask(protocolEventClassname); + createTask.isProtocolDeactivation(true); + createTask.isClientProtocol(false); + createTask.setProtocolClassname(eventClassname); + createTask.setShortname(eventShortname); + createTasks.add(createTask); + } + } + + panel.add(comboBox); + panel.add(addPanel); + + return addPanel; + } + + public int getSplitSize() { + return splitPaneH.getDividerLocation(); + } + + public int getPaintSize() { + return splitPaneV.getDividerLocation(); + } + + private int getSelectedProcessNum() { + return processesComboBox.getSelectedIndex(); + } + + private VSProcess getSelectedProcess() { + int processNum = getSelectedProcessNum(); + return simulationCanvas.getProcess(processNum); + } + + private ArrayList getConcernedProcesses(boolean localTasks) { + int processNum = localTasks + ? localPIDComboBox.getSelectedIndex() + : globalPIDComboBox.getSelectedIndex(); + + if (processNum == simulationCanvas.getNumProcesses()) + return simulationCanvas.getProcessesArray(); + + ArrayList arr = new ArrayList(); + arr.add(simulationCanvas.getProcess(processNum)); + + return arr; + } + + public void updateTaskManagerTable() { + VSProcess process = getSelectedProcess(); + boolean allProcesses = process == null; + taskManagerLocalModel.set(process, VSTaskManagerTableModel.LOCAL, allProcesses); + taskManagerGlobalModel.set(process, VSTaskManagerTableModel.GLOBAL, allProcesses); + } + + public void finish() { + menuItemStates.setStart(false); + menuItemStates.setPause(false); + menuItemStates.setReset(true); + menuItemStates.setReplay(true); + simulatorFrame.updateSimulationMenu(); + } + + public int getSimulationNum() { + return simulationNum; + } + + public VSSimulator.VSMenuItemStates getMenuItemStates() { + return menuItemStates; + } + + public VSSimulatorCanvas getSimulationCanvas() { + return simulationCanvas; + } + + public VSSimulatorFrame getSimulatorFrame() { + return simulatorFrame; + } + + public void updateFromPrefs() { + simulationCanvas.setBackground(prefs.getColor("col.background")); + simulationCanvas.updateFromPrefs(); + } + + public void removeProcessAtIndex(int index) { + if (lastSelectedProcessNum >= index) + --lastSelectedProcessNum; + if (lastSelectedProcessNum < 0) + lastSelectedProcessNum = 0; + + globalTextFields.remove(index); + localTextFields.remove(index); + + globalPIDComboBox.removeItemAt(index); + localPIDComboBox.removeItemAt(index); + + processesComboBox.removeItemAt(index); + simulatorFrame.updateEditMenu(); + } + + public void addProcessAtIndex(int index) { + int processID = simulationCanvas.getProcess(index).getProcessID(); + String processString = prefs.getString("lang.process"); + + localTextFields.add(index, "0000"); + globalTextFields.add(index, "0000"); + + localPIDComboBox.insertItemAt("PID: " + processID, index); + globalPIDComboBox.insertItemAt("PID: " + processID, index); + + processesComboBox.insertItemAt(processString + " " + processID, index); + simulatorFrame.updateEditMenu(); + } + + public void fireExpertModeChanged() { + boolean expertMode = prefs.getBoolean("sim.mode.expert"); + + /* Update the Task Manager GUI */ + int selectedIndex = tabbedPane.getSelectedIndex(); + + if (expertMode) { + tabbedPane.remove(localPanel); + tabbedPane.insertTab(prefs.getString("lang.events"), null, splitPane1, null, 0); + splitPane1.setTopComponent(localPanel); + splitPane1.setDividerLocation((int) (getPaintSize()/2) - 20); + + /* addPanel */ + localAddPanel.add(localPIDComboBox, 2); + + } else { + tabbedPane.remove(splitPane1); + tabbedPane.insertTab(prefs.getString("lang.events"), null, localPanel, null, 0); + + /* addPanel */ + localAddPanel.remove(2); + } + tabbedPane.setSelectedIndex(selectedIndex); + + /* Update the 'Variables tab' */ + if (getSelectedProcessNum() != simulationCanvas.getNumProcesses()) { + VSProcess process = getSelectedProcess(); + VSProcessEditor editor = new VSProcessEditor(prefs, process); + tabbedPane.setComponentAt(1, editor.getContentPane()); + } + + /* Update the tools panel */ + loggingPanel.remove(1); + loggingPanel.add(createToolsPanel(), BorderLayout.SOUTH); + updateUI(); + } + + public VSPrefs getPrefs() { + return prefs; + } +} 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); + } +} diff --git a/sources/simulator/VSSimulatorFrame.java b/sources/simulator/VSSimulatorFrame.java index c4abdb3..e4e0d18 100644 --- a/sources/simulator/VSSimulatorFrame.java +++ b/sources/simulator/VSSimulatorFrame.java @@ -30,15 +30,15 @@ public class VSSimulatorFrame extends VSFrame implements ActionListener { private JMenu menuSimulation; private JToolBar toolBar; private VSPrefs prefs; - private Vector simulations; - private VSSimulation currentSimulation; + private Vector simulations; + private VSSimulator currentSimulation; private JTabbedPane tabbedPane; //private JSlider speedSlider; public VSSimulatorFrame(VSPrefs prefs, Component relativeTo) { super(prefs.getString("lang.name"), relativeTo); this.prefs = prefs; - this.simulations = new Vector(); + this.simulations = new Vector(); setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); @@ -172,7 +172,7 @@ public class VSSimulatorFrame extends VSFrame implements ActionListener { tabbedPane.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent ce) { JTabbedPane pane = (JTabbedPane) ce.getSource(); - currentSimulation = (VSSimulation) pane.getSelectedComponent(); + currentSimulation = (VSSimulator) pane.getSelectedComponent(); currentSimulation.getSimulationCanvas().paint(); updateEditMenu(); updateSimulationMenu(); @@ -192,13 +192,14 @@ public class VSSimulatorFrame extends VSFrame implements ActionListener { globalPrefsItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) { VSPrefs simulationPrefs = currentSimulation.getPrefs(); - VSSimulationEditor.TAKEOVER_BUTTON = true; - VSSimulationEditor simulationEditor = new VSSimulationEditor( + VSSimulatorEditor.TAKEOVER_BUTTON = true; + VSSimulatorEditor simulationEditor = new VSSimulatorEditor( simulationPrefs, VSSimulatorFrame.this, currentSimulation); new VSEditorFrame(prefs, VSSimulatorFrame.this, simulationEditor); } }); menuEdit.add(globalPrefsItem); + menuEdit.addSeparator(); if (currentSimulation == null) return; @@ -211,8 +212,9 @@ public class VSSimulatorFrame extends VSFrame implements ActionListener { for (VSProcess process : arr) { int processID = process.getProcessID(); JMenuItem processItem = new JMenuItem(processString + " " + processID); - processItem.setAccelerator(KeyStroke.getKeyStroke(0x31+processID, - ActionEvent.ALT_MASK)); + if (processNum < 10) + processItem.setAccelerator(KeyStroke.getKeyStroke(0x31+processNum, + ActionEvent.ALT_MASK)); final int finalProcessNum = processNum++; processItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) { @@ -225,7 +227,7 @@ public class VSSimulatorFrame extends VSFrame implements ActionListener { /* updateSimulationMenu can be called from concurrent threads */ public synchronized void updateSimulationMenu() { - VSSimulation.VSMenuItemStates menuItemState = currentSimulation.getMenuItemStates(); + VSSimulator.VSMenuItemStates menuItemState = currentSimulation.getMenuItemStates(); pauseItem.setEnabled(menuItemState.getPause()); replayItem.setEnabled(menuItemState.getReplay()); @@ -240,7 +242,7 @@ public class VSSimulatorFrame extends VSFrame implements ActionListener { public void dispose() { synchronized (simulations) { - for (VSSimulation simulation : simulations) + for (VSSimulator simulation : simulations) simulation.getSimulationCanvas().stopThread(); } super.dispose(); @@ -260,7 +262,7 @@ public class VSSimulatorFrame extends VSFrame implements ActionListener { } else if (sourceText.equals(prefs.getString("lang.simulation.new"))) { VSPrefs newPrefs = VSDefaultPrefs.init(); - new VSEditorFrame(newPrefs, this, new VSSimulationEditor(newPrefs, this)); + new VSEditorFrame(newPrefs, this, new VSSimulatorEditor(newPrefs, this)); } else if (sourceText.equals(prefs.getString("lang.window.new"))) { new VSMain(VSDefaultPrefs.init(), this); @@ -275,7 +277,7 @@ public class VSSimulatorFrame extends VSFrame implements ActionListener { System.exit(0); } else if (sourceText.equals(prefs.getString("lang.start"))) { - VSSimulation.VSMenuItemStates menuItemState = currentSimulation.getMenuItemStates(); + VSSimulator.VSMenuItemStates menuItemState = currentSimulation.getMenuItemStates(); menuItemState.setStart(false); menuItemState.setPause(true); menuItemState.setReset(false); @@ -284,7 +286,7 @@ public class VSSimulatorFrame extends VSFrame implements ActionListener { updateSimulationMenu(); } else if (sourceText.equals(prefs.getString("lang.pause"))) { - VSSimulation.VSMenuItemStates menuItemState = currentSimulation.getMenuItemStates(); + VSSimulator.VSMenuItemStates menuItemState = currentSimulation.getMenuItemStates(); menuItemState.setStart(true); menuItemState.setPause(false); menuItemState.setReset(true); @@ -293,7 +295,7 @@ public class VSSimulatorFrame extends VSFrame implements ActionListener { updateSimulationMenu(); } else if (sourceText.equals(prefs.getString("lang.reset"))) { - VSSimulation.VSMenuItemStates menuItemState = currentSimulation.getMenuItemStates(); + VSSimulator.VSMenuItemStates menuItemState = currentSimulation.getMenuItemStates(); menuItemState.setStart(true); menuItemState.setPause(false); menuItemState.setReset(false); @@ -302,7 +304,7 @@ public class VSSimulatorFrame extends VSFrame implements ActionListener { updateSimulationMenu(); } else if (sourceText.equals(prefs.getString("lang.replay"))) { - VSSimulation.VSMenuItemStates menuItemState = currentSimulation.getMenuItemStates(); + VSSimulator.VSMenuItemStates menuItemState = currentSimulation.getMenuItemStates(); menuItemState.setStart(false); menuItemState.setPause(true); menuItemState.setReset(false); @@ -313,7 +315,7 @@ public class VSSimulatorFrame extends VSFrame implements ActionListener { } } - public void addSimulation(VSSimulation simulation) { + public void addSimulation(VSSimulator simulation) { simulation.setLayout(new GridLayout(1, 1, 3, 3)); simulation.setMinimumSize(new Dimension(0, 0)); simulation.setMaximumSize(new Dimension(0, 0)); @@ -330,7 +332,7 @@ public class VSSimulatorFrame extends VSFrame implements ActionListener { } } - public void removeSimulation(VSSimulation simulationToRemove) { + public void removeSimulation(VSSimulator simulationToRemove) { if (simulations.size() == 1) { dispose(); @@ -345,7 +347,7 @@ public class VSSimulatorFrame extends VSFrame implements ActionListener { removeSimulation(currentSimulation); } - public VSSimulation getCurrentSimulation() { + public VSSimulator getCurrentSimulation() { return currentSimulation; } -- cgit v1.2.3