/** * Jeff Rupp * Master's Thesis * 2005 * * Base simulator, this is the class with the main() that is used to run the * simulation * * Singleton class, to allow central communication point */ package jdr.mobisim; import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.event.*; import java.util.*; import java.io.*; import org.apache.log4j.*; import jdr.utils.*; public class MobileSimulator extends JPanel implements java.awt.event.WindowListener { private static Logger m_logger = Logger.getLogger(MobileSimulator.class); private static MobileSimulator s_instance; public static final boolean s_FORM_CLUSTER_AUTOMATICALLY = true; private JMenuBar m_memuBar = new JMenuBar(); private JMenu m_fileMenu = new JMenu("File"); private JMenuItem m_openMenuItem = new JMenuItem("Open Setup..."); private JMenuItem m_saveMenuItem = new JMenuItem("Save Setup..."); private JMenuItem m_exitMenuItem = new JMenuItem("Exit"); private JFileChooser m_fileChooser = new JFileChooser(); private File m_openFile = null; private File m_saveFile = null; private JMenu m_setupMenu = new JMenu("Setup"); private JMenuItem m_setupMenuItem = new JMenuItem("Setup Sim Parameters..."); private SimSetupDialog m_simSetupDialog = new SimSetupDialog(); private JMenu m_graphMenu = new JMenu("Graphs"); private JMenuItem m_graphMenuItem = new JMenuItem("Graphing..."); private DataGraph m_graph = new DataGraph(); private JDialog m_graphDialog = null; private JMenu m_helpMenu = new JMenu("Help"); private JMenuItem m_helpMenuItem = new JMenuItem("Help"); private JMenuItem m_aboutMenuItem = new JMenuItem("About"); private TopographyPanel m_topoPanel = new TopographyPanel(); private JCheckBox m_enableTopoCheck = new JCheckBox("Enable Visualization"); private JPanel m_simControlsPanel = new JPanel(); private JButton m_goButton = new JButton("Go"); private JButton m_pauseButton = new JButton("Pause"); private JButton m_restartButton = new JButton("Restart"); private JSlider m_speedSlider = new JSlider(0, 1000, 995); // for debugging, buttons to dump various values on queue private JButton m_openDebugDialogButton = new JButton("Debug..."); private DebugDialog m_debugDialog = null; private JButton m_showNodeColorKeyDialogButton = new JButton("Color Key"); private JDialog m_nodeColorKeyDialog = null; private JLabel m_currentSimTimeLabel = new JLabel("Sim Time: "); private SimTimeUpdateThread m_simTimeUpdater = null; private JLabel m_currentRampedValueLabel = new JLabel("RampValue: "); private boolean m_isPaused = false; private PerformNextStepThread m_performNextStepThread = null; private long m_simStartedTime = 0; private LineInfo m_rampedValueVersusTotalTicsLif = new LineInfo(); private LineInfo m_rampedValueVersusAverageNodePowerLeftLif = new LineInfo(); private LineInfo m_rampedValueVersusAverageNumHopsPerPacketLif = new LineInfo(); private LineInfo m_rampedValueVersusAveragePowerPerPacketLif = new LineInfo(); private LineInfo m_rampedValueVersusTotalNumPacketsLif = new LineInfo(); private LineInfo m_rampedValueVersusTotalDataBitsLif = new LineInfo(); public MobileSimulator() { try { java.lang.Object parent = null; parent = this.getParent(); while(parent != null) { if(parent instanceof JFrame) { break; } parent = this.getParent(); } m_graphDialog = new JDialog((JFrame)null, "Jeff Rupp Mobile Simulator: Graphs", false); m_graphDialog.setSize(800, 400); m_graphDialog.setLocation(40,40); m_graphDialog.getContentPane().add(m_graph, BorderLayout.CENTER); m_debugDialog = new DebugDialog((JFrame)null); m_nodeColorKeyDialog = new JDialog(); Panel colorKeyPnl = new NodeColorKeyPanel(); m_nodeColorKeyDialog.setSize(NodeColorKeyPanel.s_SIZE.width+8, NodeColorKeyPanel.s_SIZE.height+30); m_nodeColorKeyDialog.getContentPane().add(colorKeyPnl, BorderLayout.CENTER); initGui(); m_rampedValueVersusTotalTicsLif.setLabels("", "Total Tics"); m_rampedValueVersusTotalTicsLif.setContainingComponent(m_graph); m_graph.AddLine(m_rampedValueVersusTotalTicsLif); m_rampedValueVersusAverageNodePowerLeftLif.setLabels("", "Avg Pwr"); m_rampedValueVersusAverageNodePowerLeftLif.setContainingComponent(m_graph); m_graph.AddLine(m_rampedValueVersusAverageNodePowerLeftLif); m_rampedValueVersusAverageNumHopsPerPacketLif.setLabels("", "Avg Num Hops"); m_rampedValueVersusAverageNumHopsPerPacketLif.setContainingComponent(m_graph); m_graph.AddLine(m_rampedValueVersusAverageNumHopsPerPacketLif); m_rampedValueVersusAveragePowerPerPacketLif.setLabels("", "Avg Pwr per Packet"); m_rampedValueVersusAveragePowerPerPacketLif.setContainingComponent(m_graph); m_graph.AddLine(m_rampedValueVersusAveragePowerPerPacketLif); m_rampedValueVersusTotalNumPacketsLif.setLabels("", "Num Packets"); m_rampedValueVersusTotalNumPacketsLif.setContainingComponent(m_graph); m_graph.AddLine(m_rampedValueVersusTotalNumPacketsLif); m_rampedValueVersusTotalDataBitsLif.setLabels("", "Total Data Bits"); m_rampedValueVersusTotalDataBitsLif.setContainingComponent(m_graph); m_graph.AddLine(m_rampedValueVersusTotalDataBitsLif); m_simTimeUpdater = new SimTimeUpdateThread(); m_simTimeUpdater.start(); m_performNextStepThread = new PerformNextStepThread(); m_performNextStepThread.start(); } catch(Exception ex) { m_logger.error("could not create gui", ex); } } /** * singleton getter */ public static MobileSimulator Instance() { if(s_instance == null) { s_instance = new MobileSimulator(); } return s_instance; } /** * adds the GUI elements */ private void initGui() { setLayout(new BorderLayout()); // set up the menu bar m_fileMenu.add(m_openMenuItem); m_fileMenu.add(m_saveMenuItem); m_fileMenu.addSeparator(); m_fileMenu.add(m_exitMenuItem); m_setupMenu.add(m_setupMenuItem); m_graphMenu.add(m_graphMenuItem); m_helpMenu.add(m_helpMenuItem); m_helpMenu.addSeparator(); m_helpMenu.add(m_aboutMenuItem); m_memuBar.add(m_fileMenu); m_memuBar.add(m_setupMenu); m_memuBar.add(m_graphMenu); m_memuBar.add(m_helpMenu); add(m_memuBar, BorderLayout.NORTH); // topo network visualization area add(m_topoPanel, BorderLayout.CENTER); // simulation controls m_goButton.setToolTipText("Resume a paused simulation, or start one if none running"); m_restartButton.setToolTipText("Reset simulation to begining, and re-start"); m_speedSlider.setToolTipText("Farther left slows the simulation execution, useful only with visualization on"); m_simControlsPanel.add(m_goButton); m_simControlsPanel.add(m_pauseButton); m_simControlsPanel.add(m_restartButton); m_simControlsPanel.add(m_speedSlider); m_simControlsPanel.add(m_enableTopoCheck); m_simControlsPanel.add(m_openDebugDialogButton); m_simControlsPanel.add(m_showNodeColorKeyDialogButton); JPanel southPnl = new JPanel(new BorderLayout()); southPnl.add(m_simControlsPanel, BorderLayout.NORTH); JPanel statusPnl = new JPanel(); statusPnl.add(m_currentRampedValueLabel); statusPnl.add(m_currentSimTimeLabel); southPnl.add(statusPnl, BorderLayout.SOUTH); add(southPnl, BorderLayout.SOUTH); m_enableTopoCheck.setSelected(true); EnableTopo(true); ConnectGuiEventHandlers(); ShowSetupDialog(); EnableGoPauseResetartButtons(true); m_goButton.setEnabled(false); } private void ConnectGuiEventHandlers() { m_openMenuItem.addActionListener(new ActionListener() { public void actionPerformed(java.awt.event.ActionEvent A) { OpenSetupFile(); } }); m_saveMenuItem.addActionListener(new ActionListener() { public void actionPerformed(java.awt.event.ActionEvent A) { SaveSetupFile(); } }); m_exitMenuItem.addActionListener(new ActionListener() { public void actionPerformed(java.awt.event.ActionEvent A) { windowClosing(null); System.exit(0); } }); m_setupMenuItem.addActionListener(new ActionListener() { public void actionPerformed(java.awt.event.ActionEvent A) { ShowSetupDialog(); } }); m_graphMenuItem.addActionListener(new ActionListener() { public void actionPerformed(java.awt.event.ActionEvent A) { ShowGraphDialog(); } }); m_helpMenuItem.addActionListener(new ActionListener() { public void actionPerformed(java.awt.event.ActionEvent A) { ShowHelp(); } }); m_aboutMenuItem.addActionListener(new ActionListener() { public void actionPerformed(java.awt.event.ActionEvent A) { ShowAbout(); } }); m_goButton.addActionListener(new ActionListener() { public void actionPerformed(java.awt.event.ActionEvent A) { ResumeSimulation(); EnableGoPauseResetartButtons(false); } }); m_pauseButton.addActionListener(new ActionListener() { public void actionPerformed(java.awt.event.ActionEvent A) { PauseSimulation(); EnableGoPauseResetartButtons(true); } }); m_restartButton.addActionListener(new ActionListener() { public void actionPerformed(java.awt.event.ActionEvent A) { m_simStartedTime = System.currentTimeMillis(); System.out.println("Simulation started"); RunSimulation(true); EnableGoPauseResetartButtons(false); } }); m_enableTopoCheck.addActionListener(new ActionListener() { public void actionPerformed(java.awt.event.ActionEvent A) { EnableTopo(m_enableTopoCheck.isSelected()); } }); m_speedSlider.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent e) { SpeedSliderChanged(); } }); m_openDebugDialogButton.addActionListener(new ActionListener() { public void actionPerformed(java.awt.event.ActionEvent A) { m_debugDialog.setVisible(true); } }); m_showNodeColorKeyDialogButton.addActionListener(new ActionListener() { public void actionPerformed(java.awt.event.ActionEvent A) { m_nodeColorKeyDialog.setVisible(true); } }); } private void OpenSetupFile() { if(m_fileChooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) { m_openFile = m_fileChooser.getSelectedFile(); m_logger.debug("apply settings from file: "+ m_openFile.getName()); m_simSetupDialog.RestoreFromFile(m_openFile); } else { m_logger.debug("apply settings from file canceled"); } } private void SaveSetupFile() { if(m_fileChooser.showSaveDialog(this) == JFileChooser.APPROVE_OPTION) { m_saveFile = m_fileChooser.getSelectedFile(); m_logger.debug("save settings to file: "+ m_saveFile.getName()); m_simSetupDialog.SaveToFile(m_saveFile); } else { m_logger.debug("save settings to file canceled"); } } private void ShowSetupDialog() { if(m_simSetupDialog == null) { m_simSetupDialog = new SimSetupDialog(); } m_simSetupDialog.setVisible(true); } private void ShowGraphDialog() { m_graphDialog.setVisible(true); } private void ShowHelp() { JOptionPane.showMessageDialog(this, "Not very helpful yet"); } private void ShowAbout() { JOptionPane.showMessageDialog(this, "Jeff Rupp\r\n2005 Masters Thesis\r\n"+ "Wireless Network Simulator"); } private void SpeedSliderChanged() { Scheduler.getInstance().SetSimulationSpeedPercentage((double)m_speedSlider.getValue() / (double)m_speedSlider.getMaximum()); } /** * re-start from beginning */ public void RunSimulation(boolean isFirstRun) { // pause to get everybody stopped for the moment PauseSimulation(); // apply configuration values boolean rampingOn = false; if(isFirstRun) { PacketIF.setInstanceClassName(m_simSetupDialog.getpacketClassName()); ProtocolIF.setInstanceClassName(m_simSetupDialog.getprotocolClassName()); PropagationIF.setInstanceClassName(m_simSetupDialog.getpropagationClassName()); Scheduler.getInstance().setThreadPoolSize(m_simSetupDialog.getThreadPoolSize()); FloatPoint sinkLoc = new FloatPoint((float)m_simSetupDialog.getSinkX(), (float)m_simSetupDialog.getSinkY()); m_topoPanel.SetSinkLocation(sinkLoc); m_debugDialog.setSinkNodeLocation(sinkLoc); rampingOn = m_simSetupDialog.TakeFirstRampStep(); m_rampedValueVersusTotalTicsLif.clearPoints(); m_rampedValueVersusAverageNodePowerLeftLif.clearPoints(); m_rampedValueVersusAverageNumHopsPerPacketLif.clearPoints(); m_rampedValueVersusAveragePowerPerPacketLif.clearPoints(); m_rampedValueVersusTotalNumPacketsLif.clearPoints(); m_rampedValueVersusTotalDataBitsLif.clearPoints(); } double runToPercent = m_simSetupDialog.getRunToPercent(); double percentAtRunToPercent = m_simSetupDialog.getPercentOfNodesAtRunToPercent(); if(runToPercent > 0) { m_performNextStepThread.SetSimRunToPercent(runToPercent); m_performNextStepThread.SetSimPercentAtRunToPercent(percentAtRunToPercent); m_performNextStepThread.SetSimRunDurationTics(-1); } else { long runDurationSimTics = new Double(m_simSetupDialog.getSimulationRunTics()).longValue(); m_performNextStepThread.SetSimRunDurationTics(runDurationSimTics); } Scheduler.getInstance().ClearSchedule(); Scheduler.getInstance().SetSimulationTime(0); MobileNode.ResetNodeCount(); MobileNodeHeed.ResetNodeCount(); MobileNodeLeach.ResetNodeCount(); MobileNodeNoClustering.ResetNodeCount(); // create all the nodes String nodeClassname = m_simSetupDialog.getNodeClassName(); double numNodes = m_simSetupDialog.getNumberOfNodes(); if(rampingOn || ! isFirstRun) { m_currentRampedValueLabel.setText(m_simSetupDialog.getRampedValueName()+ ": "+m_simSetupDialog.getRampedValueCurrentValue()+" "); } else { m_currentRampedValueLabel.setText(""); } double width = m_simSetupDialog.getareaWidth(); double height = m_simSetupDialog.getareaHeight(); AllNodes.Instance().ClearNodes(); PacketIF.ClearPacketHistory(); AllNodes.Instance().setWidthHeight(width, height); double avgNodesPer1000UnitsSquareArea = m_simSetupDialog.getAvergeNodesPer1000UnitsArea(); m_logger.debug("creating "+numNodes+" nodes, of type: "+nodeClassname); setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); try { // get values for various changeable node params, to log int dataheaderSize = (int)m_simSetupDialog.getHeaderSizeBytes(); int dataSize = (int)m_simSetupDialog.getDataSizeBytes(); int dataInterval = (int)(m_simSetupDialog.getdataTransmitIntervalTics()); byte numLevels = (byte)m_simSetupDialog.getNumberOfPowerLevels(); double rehelloPercent = m_simSetupDialog.getHelloLevelPercent(); double nodesPerCluster = m_simSetupDialog.getNumberOfNodesPerCluster(); double dataRate = m_simSetupDialog.getMaximumBitRateBps(); double wattHours = m_simSetupDialog.getWattHoursCapacity(); m_logger.debug("node values, "+ "\n dataheaderSize: "+dataheaderSize+ "\n dataSize: "+dataSize+ "\n dataInterval: "+dataInterval+ "\n numLevels: "+numLevels+ "\n rehelloPercent: "+rehelloPercent+ "\n nodesPerCluster: "+nodesPerCluster+ "\n dataRate: "+dataRate+ "\n wattHours: "+wattHours); NodeIF newNode = null; Class cls = Class.forName(nodeClassname); for(double i = 0; i < numNodes; ++i) { newNode = (NodeIF)cls.newInstance(); FloatPoint loc = AllNodes.Instance().AddNode(avgNodesPer1000UnitsSquareArea, newNode); m_logger.debug("Created node at location: "+loc.toString()); // apply configuration values newNode.setSensorDataHeaderSizeBytes(dataheaderSize); newNode.setSensorDataSizeBytes(dataSize); newNode.setSensorDataTicsBetweenTransmits(dataInterval); newNode.setNumberOfHelloTransmitLevels(numLevels); newNode.setRehelloPercent(rehelloPercent); newNode.setLocation(loc); newNode.SetNumNodesPerCluster(nodesPerCluster); newNode.SetDataRate(dataRate); newNode.SetWattHours(wattHours); } } catch(Exception ex) { m_logger.error("Unable to create nodes of type: "+nodeClassname, ex); } m_topoPanel.setVisualizationEnabled(m_enableTopoCheck.isSelected()); m_topoPanel.reDraw(); Scheduler.getInstance().RestartSimulation(); if(isFirstRun) { // automatically form clusters once the hello process is done, // decide based on the Scheduler queue being empty for a while m_performNextStepThread.WantToFormClusters(s_FORM_CLUSTER_AUTOMATICALLY); m_performNextStepThread.ClustersFormed(false); m_performNextStepThread.SimRunFinished(false); m_performNextStepThread.EnableRamping(rampingOn); } m_isPaused = false; m_performNextStepThread.PauseThread(false); setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); // for testing the graphing if(false) { LineInfo lif = new LineInfo(); lif.clearPoints(); float x; float y; FloatPoint pt = null; java.util.Random rnd = new java.util.Random(System.currentTimeMillis()); lif.setLabels("x: "+rnd.nextInt(), " y: "+rnd.nextInt()); for(int i = 0; i < 100; ++i) { x = i; y = rnd.nextInt(100); pt = new FloatPoint(x, y); lif.addPoint(pt); } m_graph.AddLine(lif); } } private void ResumeSimulation() { Scheduler.getInstance().StartSimulation(); m_isPaused = false; m_performNextStepThread.PauseThread(false); } /** * pause the simulation */ private void PauseSimulation() { Scheduler.getInstance().StopSimulation(); m_performNextStepThread.PauseThread(true); m_isPaused = true; } /** * turns the active visualization in the topographic representation on/off */ private void EnableTopo(boolean enableTopo) { m_topoPanel.setVisualizationEnabled(enableTopo); m_speedSlider.setEnabled(enableTopo); if(enableTopo) { SpeedSliderChanged(); } else { // no visualization == run as fast as possible Scheduler.getInstance().SetSimulationSpeedPercentage(1.0); } } public void AddNode(jdr.utils.FloatPoint location, NodeIF node) { AllNodes.Instance().AddNode(location, node); } /** * getter for the graph instance, so that other classes can add lines */ public DataGraph getGraph() { return m_graph; } private void EnableGoPauseResetartButtons(boolean isPaused) { m_goButton.setEnabled(isPaused); m_pauseButton.setEnabled(!isPaused); m_restartButton.setEnabled(isPaused); } public TopographyPanel GetTopographyPanel() { return m_topoPanel; } public void RecordMetrics() { // need to record pertinent metrics to their appropriate LineInfo // sim tics versus ramped value: double rampedValue = m_simSetupDialog.getRampedValueCurrentValue(); String rampedName = m_simSetupDialog.getRampedValueName(); // total tics long totalTics = Scheduler.getInstance().GetSimulationTime(); FloatPoint pt = new FloatPoint((float)rampedValue, totalTics); m_rampedValueVersusTotalTicsLif.addPoint(pt); m_rampedValueVersusTotalTicsLif.setLabels(rampedName, "Total Tics"); // average node power double avgPwr = 0.0; int numNodes = 0; // calc avg power left in each node avgPwr = AllNodes.Instance().GetAverageNodeWattsRemaining(); pt = new FloatPoint((float)rampedValue, (float)avgPwr); m_rampedValueVersusAverageNodePowerLeftLif.addPoint(pt); m_rampedValueVersusAverageNodePowerLeftLif.setLabels(rampedName, "Avg Power"); // average num hops per packet pt = new FloatPoint((float)rampedValue, (float)PacketIF.GetAverageNumHops()); m_rampedValueVersusAverageNumHopsPerPacketLif.addPoint(pt); m_rampedValueVersusAverageNumHopsPerPacketLif.setLabels(rampedName, "Avg Num Hops"); // average power per packet pt = new FloatPoint((float)rampedValue, (float)PacketIF.GetAveragePowerConsumed()); m_rampedValueVersusAveragePowerPerPacketLif.addPoint(pt); m_rampedValueVersusAveragePowerPerPacketLif.setLabels(rampedName, "Avg Pwr per Packet"); // num packets pt = new FloatPoint((float)rampedValue, (float)PacketIF.GetTotalNumberPackets()); m_rampedValueVersusTotalNumPacketsLif.addPoint(pt); m_rampedValueVersusTotalNumPacketsLif.setLabels(rampedName, "Num Packets"); // total data bits pt = new FloatPoint((float)rampedValue, (float)PacketIF.GetTotalBitsTransmitted()); m_rampedValueVersusTotalDataBitsLif.addPoint(pt); m_rampedValueVersusTotalDataBitsLif.setLabels(rampedName, "Total Data Bits"); System.out.println("RecordMetrics "+rampedName+": "+rampedValue+ " finished at time elapsed: " + (System.currentTimeMillis() - m_simStartedTime)/60000.0 + " minutes" ); } protected class SimTimeUpdateThread extends Thread { private boolean m_okToKeepRunning = true; public SimTimeUpdateThread() { super("SimTimeDisplay"); } public void run() { while(m_okToKeepRunning) { // relies on the setText method being ok to call outside the main awt thread. m_currentSimTimeLabel.setText("Sim Time: " + Scheduler.getInstance().GetSimulationTime()); try { sleep(400); } catch(InterruptedException iex) { } } } public void StopThread() { m_okToKeepRunning = false; } } protected class PerformNextStepThread extends Thread { private boolean m_okToKeepRunning = true; private boolean m_wantToFormClusters = false; private boolean m_pause = true; private boolean m_rampingEnabled = false; private boolean m_clustersFormed = false; private boolean m_simRunFinished = false; private boolean m_toldNodesToStartPeriodicTransmits = false; private long m_simRunStartedAtTics = -1; private long m_simRunStopTics = -1; private long m_simRunDurationTics = -1; private double m_simRunToPercent = 0.0; private double m_simPercentAtRunToPercent = 100.0; public PerformNextStepThread() { super("AutoFormClusters"); } public void run() { while(m_okToKeepRunning) { if(!m_pause && m_wantToFormClusters) { if(Scheduler.getInstance().QueueHasBeenEmpty(500)) { m_wantToFormClusters = false; m_debugDialog.FormClustersNow(); ClustersFormed(true); m_toldNodesToStartPeriodicTransmits = false; } } if(!m_pause && m_clustersFormed && !m_simRunFinished) { if(Scheduler.getInstance().QueueHasBeenEmpty(500)) { // tell nodes it is ok to start their periodic transmissions if(!m_toldNodesToStartPeriodicTransmits) { // record the current sim tics to know when to stop the // free-running simulation of nodes just talking m_simRunStartedAtTics = Scheduler.getInstance().GetSimulationTime(); m_simRunStopTics = m_simRunStartedAtTics + m_simRunDurationTics; m_logger.debug("PerformNextStepThread setting m_simRunStopTics to: "+ m_simRunStopTics); // how to tell nodes it is OK to start transmitting m_debugDialog.BeginNormalCommNow(); m_toldNodesToStartPeriodicTransmits = true; } } else if(m_toldNodesToStartPeriodicTransmits) { if(m_simRunDurationTics >= 0) { // doing specific number of tics if(Scheduler.getInstance().GetSimulationTime() >= m_simRunStopTics) { // tell scheduler to stop m_logger.debug("Post form tics exceeded: "+m_simRunDurationTics+ " Stopping simulation"); Scheduler.getInstance().StopSimulation(m_simRunStopTics); m_simRunFinished = true; } } else { // running until a percentage of nodes are at a percentage of // original power double percentAt = AllNodes.Instance().GetPercentageOfNodesBelowPercentPower(m_simRunToPercent); if(percentAt >= m_simPercentAtRunToPercent) { // tell scheduler to stop m_logger.debug("Percentage of nodes below pwr level expired: "+ +percentAt + " >= " + m_simPercentAtRunToPercent+ " % of the nodes were below "+m_simRunToPercent+" %"+ " Stopping simulation"); Scheduler.getInstance().StopSimulation(m_simRunStopTics); m_simRunFinished = true; } } } } if(!m_pause && m_clustersFormed && m_simRunFinished && m_rampingEnabled) { if(Scheduler.getInstance().QueueHasBeenEmpty(500)) { RecordMetrics(); m_clustersFormed = false; m_simRunFinished = false; // take next step m_rampingEnabled = m_simSetupDialog.TakeNextRampStep(); if(m_rampingEnabled) // not done ramping { RunSimulation(false); m_wantToFormClusters = true; } } } else if(!m_pause && m_clustersFormed && m_simRunFinished && !m_rampingEnabled) { // record in the case of a single run if(Scheduler.getInstance().QueueHasBeenEmpty(500)) { RecordMetrics(); } } try { sleep(200); } catch(InterruptedException iex) { } } } public void StopThread() { m_okToKeepRunning = false; } public void PauseThread(boolean pause) { m_pause = pause; } public void WantToFormClusters(boolean formClusters) { m_wantToFormClusters = formClusters; } public void EnableRamping(boolean rampOn) { m_rampingEnabled = rampOn; } public void ClustersFormed(boolean formed) { m_clustersFormed = formed; } public void SimRunFinished(boolean finished) { m_simRunFinished = finished; } public void SetSimRunDurationTics(long ticsToRun) { m_simRunDurationTics = ticsToRun; } public void SetSimRunToPercent(double runToPercent) { m_simRunToPercent = runToPercent; } public void SetSimPercentAtRunToPercent(double percent) { m_simPercentAtRunToPercent = percent; } } //===================================================================================== // window listener methods //===================================================================================== public void windowActivated(WindowEvent e) { } public void windowOpened(WindowEvent e) { } public void windowClosing(WindowEvent e) { m_rampedValueVersusTotalTicsLif.Closing(); m_rampedValueVersusAverageNodePowerLeftLif.Closing(); m_rampedValueVersusAverageNumHopsPerPacketLif.Closing(); m_rampedValueVersusAveragePowerPerPacketLif.Closing(); m_rampedValueVersusTotalNumPacketsLif.Closing(); m_rampedValueVersusTotalDataBitsLif.Closing(); } public void windowDeactivated(WindowEvent e) { } public void windowClosed(WindowEvent e) { } public void windowIconified(WindowEvent e) { } public void windowDeiconified(WindowEvent e) { } /** * main to run the gui */ public static void main(String [] args) { JFrame frame = new JFrame("Jeff Rupp Mobile Simulator, 2005 Masters Thesis"); MobileSimulator simGui = MobileSimulator.Instance(); frame.getContentPane().add(simGui); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.addWindowListener(simGui); //frame.setLocationRelativeTo(null); frame.setSize(new Dimension(800,660)); frame.setVisible(true); } } // end class definition