Added new annonation with which Cooja components (e.g. mote plugins) can be activated
or deactivated depending on the given argument (e.g. mote). This may for example be used by a mote plugin that only accepts emulated motes, and that consequently should be hidden in other non-emulated motes' plugin menues. The new annotation is currently only used by the MspCodeWatcher and the DGRM visualizer skin.
This commit is contained in:
parent
8fd51cd889
commit
a69b580778
5 changed files with 120 additions and 3 deletions
|
@ -71,6 +71,7 @@ import se.sics.cooja.Mote;
|
||||||
import se.sics.cooja.MotePlugin;
|
import se.sics.cooja.MotePlugin;
|
||||||
import se.sics.cooja.PluginType;
|
import se.sics.cooja.PluginType;
|
||||||
import se.sics.cooja.Simulation;
|
import se.sics.cooja.Simulation;
|
||||||
|
import se.sics.cooja.SupportedArguments;
|
||||||
import se.sics.cooja.VisPlugin;
|
import se.sics.cooja.VisPlugin;
|
||||||
import se.sics.cooja.Watchpoint;
|
import se.sics.cooja.Watchpoint;
|
||||||
import se.sics.cooja.WatchpointMote;
|
import se.sics.cooja.WatchpointMote;
|
||||||
|
@ -85,6 +86,7 @@ import se.sics.mspsim.util.ELFDebug;
|
||||||
|
|
||||||
@ClassDescription("Msp Code Watcher")
|
@ClassDescription("Msp Code Watcher")
|
||||||
@PluginType(PluginType.MOTE_PLUGIN)
|
@PluginType(PluginType.MOTE_PLUGIN)
|
||||||
|
@SupportedArguments(motes = {MspMote.class})
|
||||||
public class MspCodeWatcher extends VisPlugin implements MotePlugin {
|
public class MspCodeWatcher extends VisPlugin implements MotePlugin {
|
||||||
private static final long serialVersionUID = -8463196456352243367L;
|
private static final long serialVersionUID = -8463196456352243367L;
|
||||||
|
|
||||||
|
@ -314,7 +316,7 @@ public class MspCodeWatcher extends VisPlugin implements MotePlugin {
|
||||||
}
|
}
|
||||||
currentFileAction.setEnabled(true);
|
currentFileAction.setEnabled(true);
|
||||||
currentFileAction.putValue(Action.NAME, file.getName() + ":" + line);
|
currentFileAction.putValue(Action.NAME, file.getName() + ":" + line);
|
||||||
currentFileAction.putValue(Action.SHORT_DESCRIPTION, file.getAbsolutePath() + ":" + line);
|
currentFileAction.putValue(Action.SHORT_DESCRIPTION, file.getAbsolutePath() + ":" + line + ", PC:" + String.format("0x%04x", mspMote.getCPU().getPC()));
|
||||||
fileComboBox.setSelectedItem(file.getName());
|
fileComboBox.setSelectedItem(file.getName());
|
||||||
|
|
||||||
displaySourceFile(file, line, true);
|
displaySourceFile(file, line, true);
|
||||||
|
|
|
@ -1852,6 +1852,8 @@ public class GUI extends Observable {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TODO Check if plugin specifies supported arguments here */
|
||||||
|
|
||||||
/* Check if plugin was imported by a project directory */
|
/* Check if plugin was imported by a project directory */
|
||||||
File project =
|
File project =
|
||||||
getProjectConfig().getUserProjectDefining(GUI.class, "PLUGINS", newPluginClass.getName());
|
getProjectConfig().getUserProjectDefining(GUI.class, "PLUGINS", newPluginClass.getName());
|
||||||
|
@ -1934,6 +1936,34 @@ public class GUI extends Observable {
|
||||||
JMenuItem menuItem = new JMenuItem(guiAction);
|
JMenuItem menuItem = new JMenuItem(guiAction);
|
||||||
menuItem.putClientProperty("class", motePluginClass);
|
menuItem.putClientProperty("class", motePluginClass);
|
||||||
menuItem.putClientProperty("mote", mote);
|
menuItem.putClientProperty("mote", mote);
|
||||||
|
|
||||||
|
/* Check if mote plugin depends on any particular type of mote */
|
||||||
|
boolean enableMenuItem = true;
|
||||||
|
if (motePluginClass.getAnnotation(SupportedArguments.class) != null) {
|
||||||
|
enableMenuItem = false;
|
||||||
|
Class<? extends Mote>[] motes = motePluginClass.getAnnotation(SupportedArguments.class).motes();
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append(
|
||||||
|
"<html><pre>This plugin:\n" +
|
||||||
|
motePluginClass.getName() +
|
||||||
|
"\ndoes not support motes of type:\n" +
|
||||||
|
mote.getClass().getName() +
|
||||||
|
"\n\nIt only supports motes of types:\n"
|
||||||
|
);
|
||||||
|
for (Class<? extends Object> o: motes) {
|
||||||
|
sb.append(o.getName() + "\n");
|
||||||
|
if (o.isAssignableFrom(mote.getClass())) {
|
||||||
|
enableMenuItem = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sb.append("</html>");
|
||||||
|
if (!enableMenuItem) {
|
||||||
|
menuItem.setToolTipText(sb.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
menuItem.setEnabled(enableMenuItem);
|
||||||
menuMotePlugins.add(menuItem);
|
menuMotePlugins.add(menuItem);
|
||||||
}
|
}
|
||||||
return menuMotePlugins;
|
return menuMotePlugins;
|
||||||
|
|
64
tools/cooja/java/se/sics/cooja/SupportedArguments.java
Normal file
64
tools/cooja/java/se/sics/cooja/SupportedArguments.java
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2012, Swedish Institute of Computer Science. All rights
|
||||||
|
* reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer. 2. Redistributions in
|
||||||
|
* binary form must reproduce the above copyright notice, this list of
|
||||||
|
* conditions and the following disclaimer in the documentation and/or other
|
||||||
|
* materials provided with the distribution. 3. Neither the name of the
|
||||||
|
* Institute nor the names of its contributors may be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package se.sics.cooja;
|
||||||
|
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
|
||||||
|
import javax.swing.MenuElement;
|
||||||
|
|
||||||
|
import se.sics.cooja.plugins.Visualizer;
|
||||||
|
import se.sics.cooja.plugins.skins.DGRMVisualizerSkin;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* With this annotation, Cooja components (e.g. mote plugins) can be activated
|
||||||
|
* or deactivated depending on the given argument (e.g. mote). This may for
|
||||||
|
* example be used by a mote plugin that only accepts emulated motes, and that
|
||||||
|
* consequently should be hidden in other non-emulated motes' plugin menues.
|
||||||
|
*
|
||||||
|
* See below code usage examples.
|
||||||
|
*
|
||||||
|
* @see GUI#createMotePluginsSubmenu(Mote)
|
||||||
|
* @see Visualizer#populateSkinMenu(MenuElement)
|
||||||
|
* @see DGRMVisualizerSkin
|
||||||
|
*
|
||||||
|
* @author Fredrik Osterlind
|
||||||
|
*/
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface SupportedArguments {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return List of accepted mote classes.
|
||||||
|
*/
|
||||||
|
Class<? extends Mote>[] motes() default { Mote.class };
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return List of accepted radio medium classes.
|
||||||
|
*/
|
||||||
|
Class<? extends RadioMedium>[] radioMediums() default { RadioMedium.class };
|
||||||
|
}
|
|
@ -92,8 +92,10 @@ import se.sics.cooja.GUI.MoteRelation;
|
||||||
import se.sics.cooja.Mote;
|
import se.sics.cooja.Mote;
|
||||||
import se.sics.cooja.MoteInterface;
|
import se.sics.cooja.MoteInterface;
|
||||||
import se.sics.cooja.PluginType;
|
import se.sics.cooja.PluginType;
|
||||||
|
import se.sics.cooja.RadioMedium;
|
||||||
import se.sics.cooja.SimEventCentral.MoteCountListener;
|
import se.sics.cooja.SimEventCentral.MoteCountListener;
|
||||||
import se.sics.cooja.Simulation;
|
import se.sics.cooja.Simulation;
|
||||||
|
import se.sics.cooja.SupportedArguments;
|
||||||
import se.sics.cooja.VisPlugin;
|
import se.sics.cooja.VisPlugin;
|
||||||
import se.sics.cooja.interfaces.LED;
|
import se.sics.cooja.interfaces.LED;
|
||||||
import se.sics.cooja.interfaces.Position;
|
import se.sics.cooja.interfaces.Position;
|
||||||
|
@ -705,6 +707,23 @@ public class Visualizer extends VisPlugin {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
/* Check if skin depends on any particular radio medium */
|
||||||
|
boolean showMenuItem = true;
|
||||||
|
if (skinClass.getAnnotation(SupportedArguments.class) != null) {
|
||||||
|
showMenuItem = false;
|
||||||
|
Class<? extends RadioMedium>[] radioMediums = skinClass.getAnnotation(SupportedArguments.class).radioMediums();
|
||||||
|
for (Class<? extends Object> o: radioMediums) {
|
||||||
|
if (o.isAssignableFrom(simulation.getRadioMedium().getClass())) {
|
||||||
|
showMenuItem = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!showMenuItem) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (skinMenu instanceof JMenu) {
|
if (skinMenu instanceof JMenu) {
|
||||||
((JMenu)skinMenu).add(item);
|
((JMenu)skinMenu).add(item);
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,7 @@ import org.apache.log4j.Logger;
|
||||||
import se.sics.cooja.ClassDescription;
|
import se.sics.cooja.ClassDescription;
|
||||||
import se.sics.cooja.Mote;
|
import se.sics.cooja.Mote;
|
||||||
import se.sics.cooja.Simulation;
|
import se.sics.cooja.Simulation;
|
||||||
|
import se.sics.cooja.SupportedArguments;
|
||||||
import se.sics.cooja.interfaces.Position;
|
import se.sics.cooja.interfaces.Position;
|
||||||
import se.sics.cooja.interfaces.Radio;
|
import se.sics.cooja.interfaces.Radio;
|
||||||
import se.sics.cooja.plugins.Visualizer;
|
import se.sics.cooja.plugins.Visualizer;
|
||||||
|
@ -50,6 +51,7 @@ import se.sics.cooja.radiomediums.DestinationRadio;
|
||||||
import se.sics.cooja.radiomediums.DirectedGraphMedium;
|
import se.sics.cooja.radiomediums.DirectedGraphMedium;
|
||||||
|
|
||||||
@ClassDescription("Radio environment (DGRM)")
|
@ClassDescription("Radio environment (DGRM)")
|
||||||
|
@SupportedArguments(radioMediums = {DirectedGraphMedium.class})
|
||||||
public class DGRMVisualizerSkin implements VisualizerSkin {
|
public class DGRMVisualizerSkin implements VisualizerSkin {
|
||||||
private static Logger logger = Logger.getLogger(DGRMVisualizerSkin.class);
|
private static Logger logger = Logger.getLogger(DGRMVisualizerSkin.class);
|
||||||
|
|
||||||
|
@ -82,7 +84,7 @@ public class DGRMVisualizerSkin implements VisualizerSkin {
|
||||||
|
|
||||||
public void paintBeforeMotes(Graphics g) {
|
public void paintBeforeMotes(Graphics g) {
|
||||||
Mote selectedMote = visualizer.getSelectedMote();
|
Mote selectedMote = visualizer.getSelectedMote();
|
||||||
if (simulation == null
|
if (simulation == null
|
||||||
|| selectedMote == null
|
|| selectedMote == null
|
||||||
|| selectedMote.getInterfaces().getRadio() == null) {
|
|| selectedMote.getInterfaces().getRadio() == null) {
|
||||||
return;
|
return;
|
||||||
|
@ -100,7 +102,7 @@ public class DGRMVisualizerSkin implements VisualizerSkin {
|
||||||
g.setColor(Color.BLACK);
|
g.setColor(Color.BLACK);
|
||||||
|
|
||||||
DirectedGraphMedium radioMedium = (DirectedGraphMedium) simulation.getRadioMedium();
|
DirectedGraphMedium radioMedium = (DirectedGraphMedium) simulation.getRadioMedium();
|
||||||
|
|
||||||
/* Print transmission success probabilities */
|
/* Print transmission success probabilities */
|
||||||
DestinationRadio[] dests = radioMedium.getPotentialDestinations(selectedRadio);
|
DestinationRadio[] dests = radioMedium.getPotentialDestinations(selectedRadio);
|
||||||
if (dests == null || dests.length == 0) {
|
if (dests == null || dests.length == 0) {
|
||||||
|
|
Loading…
Reference in a new issue