diff --git a/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/plugins/MspCodeWatcher.java b/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/plugins/MspCodeWatcher.java index 4221035f8..0358720f4 100644 --- a/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/plugins/MspCodeWatcher.java +++ b/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/plugins/MspCodeWatcher.java @@ -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); diff --git a/tools/cooja/java/se/sics/cooja/GUI.java b/tools/cooja/java/se/sics/cooja/GUI.java index c35492fb0..a14d5d184 100644 --- a/tools/cooja/java/se/sics/cooja/GUI.java +++ b/tools/cooja/java/se/sics/cooja/GUI.java @@ -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( + "
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(""); + if (!enableMenuItem) { + menuItem.setToolTipText(sb.toString()); + } + } + + menuItem.setEnabled(enableMenuItem); menuMotePlugins.add(menuItem); } return menuMotePlugins; diff --git a/tools/cooja/java/se/sics/cooja/SupportedArguments.java b/tools/cooja/java/se/sics/cooja/SupportedArguments.java new file mode 100644 index 000000000..fa09710cb --- /dev/null +++ b/tools/cooja/java/se/sics/cooja/SupportedArguments.java @@ -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 }; +} diff --git a/tools/cooja/java/se/sics/cooja/plugins/Visualizer.java b/tools/cooja/java/se/sics/cooja/plugins/Visualizer.java index 00b3d1ade..bc5769381 100644 --- a/tools/cooja/java/se/sics/cooja/plugins/Visualizer.java +++ b/tools/cooja/java/se/sics/cooja/plugins/Visualizer.java @@ -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); } diff --git a/tools/cooja/java/se/sics/cooja/plugins/skins/DGRMVisualizerSkin.java b/tools/cooja/java/se/sics/cooja/plugins/skins/DGRMVisualizerSkin.java index ae4f69a20..df2d86900 100644 --- a/tools/cooja/java/se/sics/cooja/plugins/skins/DGRMVisualizerSkin.java +++ b/tools/cooja/java/se/sics/cooja/plugins/skins/DGRMVisualizerSkin.java @@ -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) {