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:
Fredrik Osterlind 2012-05-09 13:47:03 +02:00
parent 8fd51cd889
commit a69b580778
5 changed files with 120 additions and 3 deletions

View File

@ -71,6 +71,7 @@ import se.sics.cooja.Mote;
import se.sics.cooja.MotePlugin;
import se.sics.cooja.PluginType;
import se.sics.cooja.Simulation;
import se.sics.cooja.SupportedArguments;
import se.sics.cooja.VisPlugin;
import se.sics.cooja.Watchpoint;
import se.sics.cooja.WatchpointMote;
@ -85,6 +86,7 @@ import se.sics.mspsim.util.ELFDebug;
@ClassDescription("Msp Code Watcher")
@PluginType(PluginType.MOTE_PLUGIN)
@SupportedArguments(motes = {MspMote.class})
public class MspCodeWatcher extends VisPlugin implements MotePlugin {
private static final long serialVersionUID = -8463196456352243367L;
@ -314,7 +316,7 @@ public class MspCodeWatcher extends VisPlugin implements MotePlugin {
}
currentFileAction.setEnabled(true);
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());
displaySourceFile(file, line, true);

View File

@ -1852,6 +1852,8 @@ public class GUI extends Observable {
return false;
}
/* TODO Check if plugin specifies supported arguments here */
/* Check if plugin was imported by a project directory */
File project =
getProjectConfig().getUserProjectDefining(GUI.class, "PLUGINS", newPluginClass.getName());
@ -1934,6 +1936,34 @@ public class GUI extends Observable {
JMenuItem menuItem = new JMenuItem(guiAction);
menuItem.putClientProperty("class", motePluginClass);
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);
}
return menuMotePlugins;

View 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 };
}

View File

@ -92,8 +92,10 @@ import se.sics.cooja.GUI.MoteRelation;
import se.sics.cooja.Mote;
import se.sics.cooja.MoteInterface;
import se.sics.cooja.PluginType;
import se.sics.cooja.RadioMedium;
import se.sics.cooja.SimEventCentral.MoteCountListener;
import se.sics.cooja.Simulation;
import se.sics.cooja.SupportedArguments;
import se.sics.cooja.VisPlugin;
import se.sics.cooja.interfaces.LED;
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) {
((JMenu)skinMenu).add(item);
}

View File

@ -41,6 +41,7 @@ import org.apache.log4j.Logger;
import se.sics.cooja.ClassDescription;
import se.sics.cooja.Mote;
import se.sics.cooja.Simulation;
import se.sics.cooja.SupportedArguments;
import se.sics.cooja.interfaces.Position;
import se.sics.cooja.interfaces.Radio;
import se.sics.cooja.plugins.Visualizer;
@ -50,6 +51,7 @@ import se.sics.cooja.radiomediums.DestinationRadio;
import se.sics.cooja.radiomediums.DirectedGraphMedium;
@ClassDescription("Radio environment (DGRM)")
@SupportedArguments(radioMediums = {DirectedGraphMedium.class})
public class DGRMVisualizerSkin implements VisualizerSkin {
private static Logger logger = Logger.getLogger(DGRMVisualizerSkin.class);
@ -82,7 +84,7 @@ public class DGRMVisualizerSkin implements VisualizerSkin {
public void paintBeforeMotes(Graphics g) {
Mote selectedMote = visualizer.getSelectedMote();
if (simulation == null
if (simulation == null
|| selectedMote == null
|| selectedMote.getInterfaces().getRadio() == null) {
return;
@ -100,7 +102,7 @@ public class DGRMVisualizerSkin implements VisualizerSkin {
g.setColor(Color.BLACK);
DirectedGraphMedium radioMedium = (DirectedGraphMedium) simulation.getRadioMedium();
/* Print transmission success probabilities */
DestinationRadio[] dests = radioMedium.getPotentialDestinations(selectedRadio);
if (dests == null || dests.length == 0) {