implemented watchpoint visualization +
saving current zoom and divider locations in simulation configs
This commit is contained in:
parent
b63322ebb1
commit
a39b87f214
1 changed files with 105 additions and 27 deletions
|
@ -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: TimeLine.java,v 1.6 2009/06/08 11:55:58 fros4943 Exp $
|
* $Id: TimeLine.java,v 1.7 2009/06/11 10:02:53 fros4943 Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package se.sics.cooja.plugins;
|
package se.sics.cooja.plugins;
|
||||||
|
@ -93,7 +93,8 @@ public class TimeLine extends VisPlugin {
|
||||||
private MoteRuler timelineMoteRuler;
|
private MoteRuler timelineMoteRuler;
|
||||||
private JComponent timeline;
|
private JComponent timeline;
|
||||||
private Box eventCheckboxes;
|
private Box eventCheckboxes;
|
||||||
|
private JSplitPane splitPane;
|
||||||
|
|
||||||
private ArrayList<MoteObservation> activeMoteObservers = new ArrayList<MoteObservation>();
|
private ArrayList<MoteObservation> activeMoteObservers = new ArrayList<MoteObservation>();
|
||||||
|
|
||||||
private ArrayList<MoteEvents> allMoteEvents = new ArrayList<MoteEvents>();
|
private ArrayList<MoteEvents> allMoteEvents = new ArrayList<MoteEvents>();
|
||||||
|
@ -119,6 +120,7 @@ public class TimeLine extends VisPlugin {
|
||||||
eventCheckboxes = Box.createVerticalBox();
|
eventCheckboxes = Box.createVerticalBox();
|
||||||
JCheckBox eventCheckBox;
|
JCheckBox eventCheckBox;
|
||||||
eventCheckBox = createEventCheckbox("Radio RX/TX", "Show radio transmissions, receptions, and collisions");
|
eventCheckBox = createEventCheckbox("Radio RX/TX", "Show radio transmissions, receptions, and collisions");
|
||||||
|
eventCheckBox.setSelected(showRadioRXTX);
|
||||||
eventCheckBox.setName("showRadioRXTX");
|
eventCheckBox.setName("showRadioRXTX");
|
||||||
eventCheckBox.addActionListener(new ActionListener() {
|
eventCheckBox.addActionListener(new ActionListener() {
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
@ -128,6 +130,7 @@ public class TimeLine extends VisPlugin {
|
||||||
});
|
});
|
||||||
eventCheckboxes.add(eventCheckBox);
|
eventCheckboxes.add(eventCheckBox);
|
||||||
eventCheckBox = createEventCheckbox("Radio channels", "Show different radio channels");
|
eventCheckBox = createEventCheckbox("Radio channels", "Show different radio channels");
|
||||||
|
eventCheckBox.setSelected(showRadioChannels);
|
||||||
eventCheckBox.setName("showRadioChannels");
|
eventCheckBox.setName("showRadioChannels");
|
||||||
eventCheckBox.addActionListener(new ActionListener() {
|
eventCheckBox.addActionListener(new ActionListener() {
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
@ -137,6 +140,7 @@ public class TimeLine extends VisPlugin {
|
||||||
});
|
});
|
||||||
/*eventCheckboxes.add(eventCheckBox);*/
|
/*eventCheckboxes.add(eventCheckBox);*/
|
||||||
eventCheckBox = createEventCheckbox("Radio ON/OFF", "Show radio hardware state");
|
eventCheckBox = createEventCheckbox("Radio ON/OFF", "Show radio hardware state");
|
||||||
|
eventCheckBox.setSelected(showRadioHW);
|
||||||
eventCheckBox.setName("showRadioHW");
|
eventCheckBox.setName("showRadioHW");
|
||||||
eventCheckBox.addActionListener(new ActionListener() {
|
eventCheckBox.addActionListener(new ActionListener() {
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
@ -146,6 +150,7 @@ public class TimeLine extends VisPlugin {
|
||||||
});
|
});
|
||||||
eventCheckboxes.add(eventCheckBox);
|
eventCheckboxes.add(eventCheckBox);
|
||||||
eventCheckBox = createEventCheckbox("LEDs", "Show LED state");
|
eventCheckBox = createEventCheckbox("LEDs", "Show LED state");
|
||||||
|
eventCheckBox.setSelected(showLEDs);
|
||||||
eventCheckBox.setName("showLEDs");
|
eventCheckBox.setName("showLEDs");
|
||||||
eventCheckBox.addActionListener(new ActionListener() {
|
eventCheckBox.addActionListener(new ActionListener() {
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
@ -155,6 +160,7 @@ public class TimeLine extends VisPlugin {
|
||||||
});
|
});
|
||||||
eventCheckboxes.add(eventCheckBox);
|
eventCheckboxes.add(eventCheckBox);
|
||||||
eventCheckBox = createEventCheckbox("Log output", "Show mote log output, such as by printf()'s");
|
eventCheckBox = createEventCheckbox("Log output", "Show mote log output, such as by printf()'s");
|
||||||
|
eventCheckBox.setSelected(showLogOutputs);
|
||||||
eventCheckBox.setName("showLogOutput");
|
eventCheckBox.setName("showLogOutput");
|
||||||
eventCheckBox.addActionListener(new ActionListener() {
|
eventCheckBox.addActionListener(new ActionListener() {
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
@ -163,7 +169,8 @@ public class TimeLine extends VisPlugin {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
/*eventCheckboxes.add(eventCheckBox);*/
|
/*eventCheckboxes.add(eventCheckBox);*/
|
||||||
eventCheckBox = createEventCheckbox("Watchpoints", "Show code watchpoints configurable on MSPSim based motes");
|
eventCheckBox = createEventCheckbox("Watchpoints", "Show code watchpoints (for MSPSim-based motes)");
|
||||||
|
eventCheckBox.setSelected(showWatchpoints);
|
||||||
eventCheckBox.setName("showWatchpoints");
|
eventCheckBox.setName("showWatchpoints");
|
||||||
eventCheckBox.addActionListener(new ActionListener() {
|
eventCheckBox.addActionListener(new ActionListener() {
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
@ -171,7 +178,7 @@ public class TimeLine extends VisPlugin {
|
||||||
recalculateMoteHeight();
|
recalculateMoteHeight();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
/*eventCheckboxes.add(eventCheckBox);*/
|
eventCheckboxes.add(eventCheckBox);
|
||||||
|
|
||||||
/* Panel: timeline canvas w. scroll pane and add mote button */
|
/* Panel: timeline canvas w. scroll pane and add mote button */
|
||||||
timeline = new Timeline();
|
timeline = new Timeline();
|
||||||
|
@ -191,13 +198,12 @@ public class TimeLine extends VisPlugin {
|
||||||
timelineScrollPane.setCorner(JScrollPane.LOWER_LEFT_CORNER, timelineAddMoteButton);
|
timelineScrollPane.setCorner(JScrollPane.LOWER_LEFT_CORNER, timelineAddMoteButton);
|
||||||
timelineScrollPane.setBackground(Color.WHITE);
|
timelineScrollPane.setBackground(Color.WHITE);
|
||||||
|
|
||||||
JSplitPane splitPane = new JSplitPane(
|
splitPane = new JSplitPane(
|
||||||
JSplitPane.HORIZONTAL_SPLIT,
|
JSplitPane.HORIZONTAL_SPLIT,
|
||||||
eventCheckboxes,
|
new JScrollPane(eventCheckboxes),
|
||||||
timelineScrollPane
|
timelineScrollPane
|
||||||
);
|
);
|
||||||
splitPane.setOneTouchExpandable(true);
|
splitPane.setOneTouchExpandable(true);
|
||||||
splitPane.setResizeWeight(0.0);
|
|
||||||
|
|
||||||
getContentPane().add(splitPane);
|
getContentPane().add(splitPane);
|
||||||
|
|
||||||
|
@ -424,12 +430,22 @@ public class TimeLine extends VisPlugin {
|
||||||
private Observable observable;
|
private Observable observable;
|
||||||
private Mote mote;
|
private Mote mote;
|
||||||
|
|
||||||
|
private WatchpointMote watchpointMote; /* XXX */
|
||||||
|
private ActionListener watchpointListener; /* XXX */
|
||||||
|
|
||||||
public MoteObservation(Mote mote, Observable observable, Observer observer) {
|
public MoteObservation(Mote mote, Observable observable, Observer observer) {
|
||||||
this.mote = mote;
|
this.mote = mote;
|
||||||
this.observable = observable;
|
this.observable = observable;
|
||||||
this.observer = observer;
|
this.observer = observer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* XXX Special case, should be generalized */
|
||||||
|
public MoteObservation(Mote mote, WatchpointMote watchpointMote, ActionListener listener) {
|
||||||
|
this.mote = mote;
|
||||||
|
this.watchpointMote = watchpointMote;
|
||||||
|
this.watchpointListener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
public Mote getMote() {
|
public Mote getMote() {
|
||||||
return mote;
|
return mote;
|
||||||
}
|
}
|
||||||
|
@ -438,18 +454,26 @@ public class TimeLine extends VisPlugin {
|
||||||
* Disconnect observer from observable (stop observing) and clean up resources (remove pointers).
|
* Disconnect observer from observable (stop observing) and clean up resources (remove pointers).
|
||||||
*/
|
*/
|
||||||
public void dispose() {
|
public void dispose() {
|
||||||
observable.deleteObserver(observer);
|
if (observable != null) {
|
||||||
mote = null;
|
observable.deleteObserver(observer);
|
||||||
observable = null;
|
mote = null;
|
||||||
observer = null;
|
observable = null;
|
||||||
|
observer = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* XXX */
|
||||||
|
if (watchpointMote != null) {
|
||||||
|
watchpointMote.removeWatchpointListener(watchpointListener);
|
||||||
|
watchpointMote = null;
|
||||||
|
watchpointListener = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addMoteObservers(Mote mote, final MoteEvents moteEvents) {
|
private void addMoteObservers(Mote mote, final MoteEvents moteEvents) {
|
||||||
/* TODO Watchpoints */
|
|
||||||
/* TODO Log: final Log moteLog = mote.getInterfaces().getLog(); */
|
/* TODO Log: final Log moteLog = mote.getInterfaces().getLog(); */
|
||||||
/* TODO Unknown state event */
|
/* TODO Unknown state event */
|
||||||
|
|
||||||
/* LEDs */
|
/* LEDs */
|
||||||
final LED moteLEDs = mote.getInterfaces().getLED();
|
final LED moteLEDs = mote.getInterfaces().getLED();
|
||||||
if (moteLEDs != null) {
|
if (moteLEDs != null) {
|
||||||
|
@ -517,20 +541,43 @@ public class TimeLine extends VisPlugin {
|
||||||
moteRadio.addObserver(observer);
|
moteRadio.addObserver(observer);
|
||||||
activeMoteObservers.add(new MoteObservation(mote, moteRadio, observer));
|
activeMoteObservers.add(new MoteObservation(mote, moteRadio, observer));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* XXX Experimental: Watchpoints */
|
||||||
|
if (mote instanceof WatchpointMote) {
|
||||||
|
final WatchpointMote watchpointMote = ((WatchpointMote)mote);
|
||||||
|
ActionListener listener = new ActionListener() {
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
if (watchpointMote.getLastWatchpoint() == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
WatchpointEvent ev = new WatchpointEvent(
|
||||||
|
simulation.getSimulationTime(),
|
||||||
|
watchpointMote.getLastWatchpoint()
|
||||||
|
);
|
||||||
|
|
||||||
|
moteEvents.addWatchpoint(ev);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
watchpointMote.addWatchpointListener(listener);
|
||||||
|
activeMoteObservers.add(new MoteObservation(mote, watchpointMote, listener));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addMote(Mote newMote) {
|
private void addMote(Mote newMote) {
|
||||||
if (newMote != null) {
|
if (newMote == null) {
|
||||||
for (MoteEvents moteEvents: allMoteEvents) {
|
return;
|
||||||
if (moteEvents.mote == newMote) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MoteEvents newMoteLog = new MoteEvents(newMote);
|
|
||||||
allMoteEvents.add(newMoteLog);
|
|
||||||
addMoteObservers(newMote, newMoteLog);
|
|
||||||
}
|
}
|
||||||
|
for (MoteEvents moteEvents: allMoteEvents) {
|
||||||
|
if (moteEvents.mote == newMote) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MoteEvents newMoteLog = new MoteEvents(newMote);
|
||||||
|
allMoteEvents.add(newMoteLog);
|
||||||
|
addMoteObservers(newMote, newMoteLog);
|
||||||
|
|
||||||
numberMotesWasUpdated();
|
numberMotesWasUpdated();
|
||||||
}
|
}
|
||||||
|
@ -641,6 +688,14 @@ public class TimeLine extends VisPlugin {
|
||||||
config.add(element);
|
config.add(element);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
element = new Element("split");
|
||||||
|
element.addContent("" + splitPane.getDividerLocation());
|
||||||
|
config.add(element);
|
||||||
|
|
||||||
|
element = new Element("zoom");
|
||||||
|
element.addContent("" + zoomLevel);
|
||||||
|
config.add(element);
|
||||||
|
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -676,6 +731,11 @@ public class TimeLine extends VisPlugin {
|
||||||
showLogOutputs = true;
|
showLogOutputs = true;
|
||||||
} else if ("showWatchpoints".equals(name)) {
|
} else if ("showWatchpoints".equals(name)) {
|
||||||
showWatchpoints = true;
|
showWatchpoints = true;
|
||||||
|
} else if ("split".equals(name)) {
|
||||||
|
splitPane.setDividerLocation(Integer.parseInt(element.getText()));
|
||||||
|
} else if ("zoom".equals(name)) {
|
||||||
|
zoomLevel = Integer.parseInt(element.getText())-1;
|
||||||
|
zoomOutAction.actionPerformed(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1185,8 +1245,6 @@ public class TimeLine extends VisPlugin {
|
||||||
this.green = green;
|
this.green = green;
|
||||||
this.blue = blue;
|
this.blue = blue;
|
||||||
this.color = new Color(red?255:0, green?255:0, blue?255:0);
|
this.color = new Color(red?255:0, green?255:0, blue?255:0);
|
||||||
prev = null;
|
|
||||||
next = null;
|
|
||||||
}
|
}
|
||||||
public Color getEventColor() {
|
public Color getEventColor() {
|
||||||
if (!red && !green && !blue) {
|
if (!red && !green && !blue) {
|
||||||
|
@ -1214,11 +1272,19 @@ public class TimeLine extends VisPlugin {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class WatchpointEvent extends MoteEvent {
|
class WatchpointEvent extends MoteEvent {
|
||||||
public WatchpointEvent(long time) {
|
Watchpoint watchpoint;
|
||||||
|
Color color = Color.RED;
|
||||||
|
public WatchpointEvent(long time, Watchpoint watchpoint) {
|
||||||
super(time);
|
super(time);
|
||||||
|
this.watchpoint = watchpoint;
|
||||||
}
|
}
|
||||||
public Color getEventColor() {
|
public Color getEventColor() {
|
||||||
return Color.GRAY; /* TODO Implement me */
|
return color;
|
||||||
|
}
|
||||||
|
public String toString() {
|
||||||
|
return
|
||||||
|
"Watchpoint triggered at time (ms): " + time/Simulation.MILLISECOND + ".<br>"
|
||||||
|
+ watchpoint.getDescription() + "<br>";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class MoteEvents {
|
class MoteEvents {
|
||||||
|
@ -1315,6 +1381,18 @@ public class TimeLine extends VisPlugin {
|
||||||
logEvents.add(ev);
|
logEvents.add(ev);
|
||||||
}
|
}
|
||||||
public void addWatchpoint(WatchpointEvent ev) {
|
public void addWatchpoint(WatchpointEvent ev) {
|
||||||
|
/* Automatically toggle colors */
|
||||||
|
/* TODO Move color decision to watchpoint interface? */
|
||||||
|
if (lastWatchpointEvent != null) {
|
||||||
|
if (((WatchpointEvent)lastWatchpointEvent).color == Color.RED) {
|
||||||
|
((WatchpointEvent)ev).color = Color.GREEN;
|
||||||
|
} else if (((WatchpointEvent)lastWatchpointEvent).color == Color.GREEN) {
|
||||||
|
((WatchpointEvent)ev).color = Color.BLUE;
|
||||||
|
} else {
|
||||||
|
((WatchpointEvent)ev).color = Color.RED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Link with previous events */
|
/* Link with previous events */
|
||||||
if (lastWatchpointEvent != null) {
|
if (lastWatchpointEvent != null) {
|
||||||
ev.prev = lastWatchpointEvent;
|
ev.prev = lastWatchpointEvent;
|
||||||
|
|
Loading…
Reference in a new issue