milliseconds -> microseconds update + more effective repainting using swing timers (avoid AWT event floods)

This commit is contained in:
fros4943 2009-05-26 14:27:00 +00:00
parent e5219e0d8b
commit 7985a9310b
5 changed files with 109 additions and 85 deletions

View File

@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* $Id: LogListener.java,v 1.12 2008/10/03 14:30:51 fros4943 Exp $ * $Id: LogListener.java,v 1.13 2009/05/26 14:27:00 fros4943 Exp $
*/ */
package se.sics.cooja.plugins; package se.sics.cooja.plugins;
@ -88,7 +88,7 @@ public class LogListener extends VisPlugin {
if (lastMessage.length() > 0 && lastMessage.charAt(lastMessage.length() - 1) == '\n') { if (lastMessage.length() > 0 && lastMessage.charAt(lastMessage.length() - 1) == '\n') {
lastMessage = lastMessage.substring(0, lastMessage.length() - 1); lastMessage = lastMessage.substring(0, lastMessage.length() - 1);
} }
String outputString = "TIME:" + simulation.getSimulationTime() + "\t"; String outputString = "TIME:" + simulation.getSimulationTimeMillis() + "\t";
if (mote != null && mote.getInterfaces().getMoteID() != null) { if (mote != null && mote.getInterfaces().getMoteID() != null) {
outputString += "ID:" + mote.getInterfaces().getMoteID().getMoteID() + "\t"; outputString += "ID:" + mote.getInterfaces().getMoteID().getMoteID() + "\t";
} }
@ -247,8 +247,8 @@ public class LogListener extends VisPlugin {
setTitle("Log Listener - Listening on " + nrLogs + " mote logs"); setTitle("Log Listener - Listening on " + nrLogs + " mote logs");
pack(); pack();
setSize(gui.getDesktopPane().getWidth(), getHeight()); setSize(gui.getDesktopPane().getWidth(), 150);
setLocation(0, gui.getDesktopPane().getHeight() - getHeight()); setLocation(0, gui.getDesktopPane().getHeight() - 300);
try { try {
setSelected(true); setSelected(true);

View File

@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* $Id: ScriptParser.java,v 1.4 2009/01/15 13:11:56 fros4943 Exp $ * $Id: ScriptParser.java,v 1.5 2009/05/26 14:27:00 fros4943 Exp $
*/ */
package se.sics.cooja.plugins; package se.sics.cooja.plugins;
@ -38,6 +38,8 @@ import javax.script.ScriptException;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import se.sics.cooja.Simulation;
public class ScriptParser { public class ScriptParser {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private static Logger logger = Logger.getLogger(ScriptParser.class); private static Logger logger = Logger.getLogger(ScriptParser.class);
@ -130,7 +132,7 @@ public class ScriptParser {
throw new ScriptSyntaxErrorException("Only one timeout handler allowed"); throw new ScriptSyntaxErrorException("Only one timeout handler allowed");
} }
timeoutTime = Long.parseLong(matcher.group(1)); timeoutTime = Long.parseLong(matcher.group(1))*Simulation.MILLISECOND;
timeoutCode = ";"; timeoutCode = ";";
matcher.reset(code); matcher.reset(code);
@ -161,7 +163,7 @@ public class ScriptParser {
throw new ScriptSyntaxErrorException("Only one timeout handler allowed"); throw new ScriptSyntaxErrorException("Only one timeout handler allowed");
} }
timeoutTime = Long.parseLong(matcher.group(1)); timeoutTime = Long.parseLong(matcher.group(1))*Simulation.MILLISECOND;
timeoutCode = matcher.group(2); timeoutCode = matcher.group(2);
matcher.reset(code); matcher.reset(code);
@ -228,7 +230,7 @@ public class ScriptParser {
Matcher matcher = pattern.matcher(code); Matcher matcher = pattern.matcher(code);
while (matcher.find()) { while (matcher.find()) {
long time = Long.parseLong(matcher.group(1)); long time = Long.parseLong(matcher.group(1))*Simulation.MILLISECOND;
String msg = matcher.group(2); String msg = matcher.group(2);
code = matcher.replaceFirst( code = matcher.replaceFirst(

View File

@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* $Id: ScriptRunner.java,v 1.17 2009/04/23 08:54:10 fros4943 Exp $ * $Id: ScriptRunner.java,v 1.18 2009/05/26 14:27:00 fros4943 Exp $
*/ */
package se.sics.cooja.plugins; package se.sics.cooja.plugins;
@ -86,8 +86,8 @@ public class ScriptRunner implements Plugin {
" */\n" + " */\n" +
"\n" + "\n" +
"/* Make test automatically fail (timeout) after 100 simulated seconds */\n" + "/* Make test automatically fail (timeout) after 100 simulated seconds */\n" +
"//TIMEOUT(100000); /* no action at timeout */\n" + "//TIMEOUT(100000); /* milliseconds. no action at timeout */\n" +
"TIMEOUT(100000, log.log(\"last msg: \" + msg + \"\\n\")); /* print last msg at timeout */\n" + "TIMEOUT(100000, log.log(\"last msg: \" + msg + \"\\n\")); /* milliseconds. print last msg at timeout */\n" +
"\n" + "\n" +
"log.log(\"first mote output: '\" + msg + \"'\\n\");\n" + "log.log(\"first mote output: '\" + msg + \"'\\n\");\n" +
"\n" + "\n" +

View File

@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* $Id: SimControl.java,v 1.13 2009/04/23 08:48:01 fros4943 Exp $ * $Id: SimControl.java,v 1.14 2009/05/26 14:27:00 fros4943 Exp $
*/ */
package se.sics.cooja.plugins; package se.sics.cooja.plugins;
@ -38,6 +38,7 @@ import java.beans.PropertyChangeListener;
import java.text.NumberFormat; import java.text.NumberFormat;
import java.util.*; import java.util.*;
import javax.swing.*; import javax.swing.*;
import javax.swing.Timer;
import javax.swing.event.*; import javax.swing.event.*;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
@ -59,16 +60,14 @@ public class SimControl extends VisPlugin {
private static final int SLIDE_MAX = 921; // e^9.21 => ~10000 private static final int SLIDE_MAX = 921; // e^9.21 => ~10000
private static final int TIME_MAX = 10000; private static final int TIME_MAX = 10000;
private static final int LABEL_UPDATE_INTERVAL = 100;
private JSlider sliderDelay; private JSlider sliderDelay;
private JLabel simulationTime, delayLabel; private JLabel simulationTime, delayLabel;
private JButton startButton, stopButton; private JButton startButton, stopButton;
private JFormattedTextField stopTimeTextField; private JFormattedTextField stopTimeTextField;
private int simulationStopTime = -1;
private Observer simObserver; private Observer simObserver;
private Observer tickObserver;
private long lastTextUpdateTime = -1;
/** /**
* Create a new simulation control panel. * Create a new simulation control panel.
@ -83,55 +82,42 @@ public class SimControl extends VisPlugin {
JButton button; JButton button;
JPanel smallPanel; JPanel smallPanel;
SwingUtilities.invokeLater(new Runnable() { /* Update current time label when simulation is running */
public void run() { if (simulation.isRunning()) {
// Register as tickobserver updateLabelTimer.start();
simulation.addTickObserver(tickObserver = new Observer() { }
public void update(Observable obs, Object obj) {
if (simulation == null || simulationTime == null) {
return;
}
// During simulation running, only update text 10 times each second /* Observe current simulation */
if (lastTextUpdateTime < System.currentTimeMillis() - 100) { simulation.addObserver(simObserver = new Observer() {
lastTextUpdateTime = System.currentTimeMillis(); public void update(Observable obs, Object obj) {
simulationTime.setText("Current simulation time: " + simulation.getSimulationTime()); if (simulation.isRunning()) {
} startButton.setEnabled(false);
stopButton.setEnabled(true);
if (simulationStopTime > 0 && simulationStopTime <= simulation.getSimulationTime() && simulation.isRunning()) {
// Time to stop simulation now /* Start label update timer */
simulation.stopSimulation(); if (!updateLabelTimer.isRunning()) {
simulationStopTime = -1; updateLabelTimer.start();
stopTimeTextField.setValue(simulation.getSimulationTime());
}
} }
}); } else {
startButton.setEnabled(true);
stopButton.setEnabled(false);
// Register as simulation observer /* Update simulation stop text field */
simulation.addObserver(simObserver = new Observer() { if (!stopEvent.isScheduled()) {
public void update(Observable obs, Object obj) { stopTimeTextField.setValue(simulation.getSimulationTimeMillis());
if (simulation.isRunning()) { }
startButton.setEnabled(false); }
stopButton.setEnabled(true);
} else {
startButton.setEnabled(true);
stopButton.setEnabled(false);
if (simulationStopTime < 0) { SwingUtilities.invokeLater(new Runnable() {
stopTimeTextField.setValue(simulation.getSimulationTime()); public void run() {
} sliderDelay.setValue(convertTimeToSlide(simulation.getDelayTime()));
} simulationTime.setText("Current simulation time: " + simulation.getSimulationTimeMillis());
simulationTime.setToolTipText("Simulation time in microseconds: " + simulation.getSimulationTime());
if (sliderDelay != null) {
sliderDelay.setValue(convertTimeToSlide(simulation.getDelayTime()));
simulationTime.setText("Current simulation time: " + simulation.getSimulationTime());
}
} }
}); });
} }
}); });
// Main panel // Main panel
JPanel controlPanel = new JPanel(); JPanel controlPanel = new JPanel();
controlPanel.setLayout(new BoxLayout(controlPanel, BoxLayout.Y_AXIS)); controlPanel.setLayout(new BoxLayout(controlPanel, BoxLayout.Y_AXIS));
@ -177,20 +163,26 @@ public class SimControl extends VisPlugin {
stopTimeTextField = new JFormattedTextField(integerFormat); stopTimeTextField = new JFormattedTextField(integerFormat);
stopTimeTextField.addPropertyChangeListener("value", new PropertyChangeListener() { stopTimeTextField.addPropertyChangeListener("value", new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent e) { public void propertyChange(PropertyChangeEvent e) {
/* Remove already scheduled stop event */
if (stopEvent.isScheduled()) {
stopEvent.remove();
}
JFormattedTextField numberTextField = (JFormattedTextField) e.getSource(); JFormattedTextField numberTextField = (JFormattedTextField) e.getSource();
int untilTime = ((Number) numberTextField.getValue()).intValue(); long stopTime = ((Number) numberTextField.getValue()).intValue()*Simulation.MILLISECOND;
if (untilTime <= simulation.getSimulationTime()) { if (stopTime <= simulation.getSimulationTime()) {
/* No simulation stop scheduled */
numberTextField.setBackground(Color.LIGHT_GRAY); numberTextField.setBackground(Color.LIGHT_GRAY);
numberTextField.setToolTipText("Enter future simulation time"); numberTextField.setToolTipText("Enter future simulation time");
simulationStopTime = -1;
} else { } else {
/* Schedule simulation stop */
numberTextField.setBackground(Color.WHITE); numberTextField.setBackground(Color.WHITE);
numberTextField.setToolTipText("Simulation will stop at time: " + untilTime); numberTextField.setToolTipText("Simulation will stop at time (us): " + stopTime);
simulationStopTime = untilTime; simulation.scheduleEvent(stopEvent, stopTime);
} }
} }
}); });
stopTimeTextField.setValue(simulation.getSimulationTime()); stopTimeTextField.setValue(simulation.getSimulationTimeMillis());
stopTimeTextField.setSize(100, stopTimeTextField.getHeight()); stopTimeTextField.setSize(100, stopTimeTextField.getHeight());
smallPanel.add(stopTimeTextField); smallPanel.add(stopTimeTextField);
@ -204,7 +196,7 @@ public class SimControl extends VisPlugin {
smallPanel.setLayout(new BoxLayout(smallPanel, BoxLayout.X_AXIS)); smallPanel.setLayout(new BoxLayout(smallPanel, BoxLayout.X_AXIS));
smallPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 0, 5)); smallPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 0, 5));
label = new JLabel("Current simulation time: " + simulation.getSimulationTime()); label = new JLabel("Current simulation time: " + simulation.getSimulationTimeMillis());
smallPanel.add(label); smallPanel.add(label);
simulationTime = label; simulationTime = label;
@ -296,7 +288,7 @@ public class SimControl extends VisPlugin {
simulation.stopSimulation(); simulation.stopSimulation();
} }
} else if (e.getActionCommand().equals("single_ms")) { } else if (e.getActionCommand().equals("single_ms")) {
simulation.tickSimulation(); simulation.stepMillisecondSimulation();
} else { } else {
logger.debug("Unhandled action: " + e.getActionCommand()); logger.debug("Unhandled action: " + e.getActionCommand());
} }
@ -304,14 +296,35 @@ public class SimControl extends VisPlugin {
} MyEventHandler myEventHandler = new MyEventHandler(); } MyEventHandler myEventHandler = new MyEventHandler();
public void closePlugin() { public void closePlugin() {
// Remove log observer from all log interfaces /* Remove simulation observer */
if (simObserver != null) { if (simObserver != null) {
simulation.deleteObserver(simObserver); simulation.deleteObserver(simObserver);
} }
if (tickObserver != null) { /* Remove stop event */
simulation.deleteTickObserver(tickObserver); if (stopEvent.isScheduled()) {
stopEvent.remove();
} }
/* Remove label update timer */
updateLabelTimer.stop();
} }
private TimeEvent stopEvent = new TimeEvent(0) {
public void execute(long t) {
/* Stop simulation */
simulation.stopSimulation();
}
};
private Timer updateLabelTimer = new Timer(LABEL_UPDATE_INTERVAL, new ActionListener() {
public void actionPerformed(ActionEvent e) {
simulationTime.setText("Current simulation time: " + simulation.getSimulationTimeMillis());
/* Automatically stop if simulation is no longer running */
if (!simulation.isRunning()) {
updateLabelTimer.stop();
}
}
});
} }

View File

@ -26,14 +26,17 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* $Id: SimInformation.java,v 1.5 2009/03/10 21:20:30 fros4943 Exp $ * $Id: SimInformation.java,v 1.6 2009/05/26 14:27:00 fros4943 Exp $
*/ */
package se.sics.cooja.plugins; package se.sics.cooja.plugins;
import java.awt.*; import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.*; import java.util.*;
import javax.swing.*; import javax.swing.*;
import javax.swing.Timer;
import se.sics.cooja.*; import se.sics.cooja.*;
@ -45,9 +48,10 @@ import se.sics.cooja.*;
@ClassDescription("Simulation Information") @ClassDescription("Simulation Information")
@PluginType(PluginType.SIM_PLUGIN) @PluginType(PluginType.SIM_PLUGIN)
public class SimInformation extends VisPlugin { public class SimInformation extends VisPlugin {
private static final long serialVersionUID = 1L;
private Simulation simulation; private Simulation simulation;
private static final int LABEL_UPDATE_INTERVAL = 100;
private final static int LABEL_WIDTH = 170; private final static int LABEL_WIDTH = 170;
private final static int LABEL_HEIGHT = 15; private final static int LABEL_HEIGHT = 15;
@ -57,7 +61,6 @@ public class SimInformation extends VisPlugin {
private JLabel labelNrMoteTypes; private JLabel labelNrMoteTypes;
private Observer simObserver; private Observer simObserver;
private Observer tickObserver;
/** /**
* Create a new simulation information window. * Create a new simulation information window.
@ -112,7 +115,7 @@ public class SimInformation extends VisPlugin {
smallPane.add(Box.createHorizontalGlue()); smallPane.add(Box.createHorizontalGlue());
label = new JLabel(); label = new JLabel();
label.setText("" + simulation.getSimulationTime()); label.setText("" + simulation.getSimulationTimeMillis());
labelSimTime = label; labelSimTime = label;
smallPane.add(label); smallPane.add(label);
@ -199,24 +202,20 @@ public class SimInformation extends VisPlugin {
} }
if (simulation.isRunning()) { if (simulation.isRunning()) {
labelStatus.setText("RUNNING"); labelStatus.setText("RUNNING");
updateLabelTimer.start();
} else { } else {
labelStatus.setText("STOPPED"); labelStatus.setText("STOPPED");
} }
labelNrMotes.setText("" + simulation.getMotesCount()); labelNrMotes.setText("" + simulation.getMotesCount());
labelNrMoteTypes.setText("" + simulation.getMoteTypes().length); labelNrMoteTypes.setText("" + simulation.getMoteTypes().length);
}
});
// Register as tick observer
simulation.addTickObserver(tickObserver = new Observer() {
public void update(Observable obs, Object obj) {
if (labelSimTime != null) {
labelSimTime.setText("" + simulation.getSimulationTime());
}
} }
}); });
/* Update current time label when simulation is running */
if (simulation.isRunning()) {
updateLabelTimer.start();
}
try { try {
setSelected(true); setSelected(true);
} catch (java.beans.PropertyVetoException e) { } catch (java.beans.PropertyVetoException e) {
@ -231,9 +230,19 @@ public class SimInformation extends VisPlugin {
simulation.deleteObserver(simObserver); simulation.deleteObserver(simObserver);
} }
if (tickObserver != null) { /* Remove label update timer */
simulation.deleteTickObserver(tickObserver); updateLabelTimer.stop();
}
} }
private Timer updateLabelTimer = new Timer(LABEL_UPDATE_INTERVAL, new ActionListener() {
public void actionPerformed(ActionEvent e) {
labelSimTime.setText("" + simulation.getSimulationTimeMillis());
/* Automatically stop if simulation is no longer running */
if (!simulation.isRunning()) {
updateLabelTimer.stop();
}
}
});
} }