new experimental feature: possibility to change mote types when loading a simulation
made compile dialogs only select mote interfaces specified in the loaded configuration
This commit is contained in:
parent
c651604a4f
commit
50caa3650c
7 changed files with 170 additions and 97 deletions
|
@ -37,6 +37,8 @@ import java.util.Observer;
|
|||
import java.util.Random;
|
||||
import java.util.Vector;
|
||||
|
||||
import javax.swing.JOptionPane;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.jdom.Element;
|
||||
|
||||
|
@ -56,7 +58,7 @@ public class Simulation extends Observable implements Runnable {
|
|||
public static final long MILLISECOND = 1000*MICROSECOND;
|
||||
|
||||
/*private static long EVENT_COUNTER = 0;*/
|
||||
|
||||
|
||||
private Vector<Mote> motes = new Vector<Mote>();
|
||||
|
||||
private Vector<MoteType> moteTypes = new Vector<MoteType>();
|
||||
|
@ -109,7 +111,7 @@ public class Simulation extends Observable implements Runnable {
|
|||
* Request poll from simulation thread.
|
||||
* Poll requests are prioritized over simulation events, and are
|
||||
* executed between each simulation event.
|
||||
*
|
||||
*
|
||||
* @param r Simulation thread action
|
||||
*/
|
||||
public void invokeSimulationThread(Runnable r) {
|
||||
|
@ -127,7 +129,7 @@ public class Simulation extends Observable implements Runnable {
|
|||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add millisecond observer.
|
||||
* This observer is notified once every simulated millisecond.
|
||||
|
@ -143,7 +145,7 @@ public class Simulation extends Observable implements Runnable {
|
|||
public void run() {
|
||||
if (!millisecondEvent.isScheduled()) {
|
||||
scheduleEvent(
|
||||
millisecondEvent,
|
||||
millisecondEvent,
|
||||
currentSimulationTime - (currentSimulationTime % MILLISECOND) + MILLISECOND);
|
||||
}
|
||||
}
|
||||
|
@ -173,7 +175,7 @@ public class Simulation extends Observable implements Runnable {
|
|||
* Already scheduled events must be removed before they are rescheduled.
|
||||
*
|
||||
* If the simulation is running, this method may only be called from the simulation thread.
|
||||
*
|
||||
*
|
||||
* @see #invokeSimulationThread(Runnable)
|
||||
*
|
||||
* @param e Event
|
||||
|
@ -237,12 +239,12 @@ public class Simulation extends Observable implements Runnable {
|
|||
return "MILLISECOND: " + millisecondObservable.countObservers();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
public void clearEvents() {
|
||||
eventQueue.removeAll();
|
||||
pollRequests.clear();
|
||||
}
|
||||
|
||||
|
||||
public void run() {
|
||||
long lastStartTime = System.currentTimeMillis();
|
||||
logger.info("Simulation main loop started, system time: " + lastStartTime);
|
||||
|
@ -261,7 +263,7 @@ public class Simulation extends Observable implements Runnable {
|
|||
while (hasPollRequests) {
|
||||
popSimulationInvokes().run();
|
||||
}
|
||||
|
||||
|
||||
/* Handle one simulation event, and update simulation time */
|
||||
nextEvent = eventQueue.popFirst();
|
||||
if (nextEvent == null) {
|
||||
|
@ -303,7 +305,7 @@ public class Simulation extends Observable implements Runnable {
|
|||
|
||||
this.setChanged();
|
||||
this.notifyObservers(this);
|
||||
logger.info("Simulation main loop stopped, system time: " + System.currentTimeMillis() +
|
||||
logger.info("Simulation main loop stopped, system time: " + System.currentTimeMillis() +
|
||||
"\tDuration: " + (System.currentTimeMillis() - lastStartTime) +
|
||||
" ms" +
|
||||
"\tSimulated time " + getSimulationTimeMillis() +
|
||||
|
@ -333,9 +335,9 @@ public class Simulation extends Observable implements Runnable {
|
|||
|
||||
/**
|
||||
* Stop simulation
|
||||
*
|
||||
*
|
||||
* @param block Block until simulation has stopped, with timeout (100ms)
|
||||
*
|
||||
*
|
||||
* @see #stopSimulation()
|
||||
*/
|
||||
public void stopSimulation(boolean block) {
|
||||
|
@ -363,7 +365,7 @@ public class Simulation extends Observable implements Runnable {
|
|||
/**
|
||||
* Stop simulation (blocks).
|
||||
* Calls stopSimulation(true).
|
||||
*
|
||||
*
|
||||
* @see #stopSimulation(boolean)
|
||||
*/
|
||||
public void stopSimulation() {
|
||||
|
@ -454,7 +456,7 @@ public class Simulation extends Observable implements Runnable {
|
|||
public SimEventCentral getEventCentral() {
|
||||
return eventCentral;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the current simulation config represented by XML elements. This
|
||||
* config also includes the current radio medium, all mote types and motes.
|
||||
|
@ -525,12 +527,12 @@ public class Simulation extends Observable implements Runnable {
|
|||
if (moteConfig == null) {
|
||||
moteConfig = new ArrayList<Element>();
|
||||
}
|
||||
|
||||
|
||||
/* Add mote type identifier */
|
||||
Element typeIdentifier = new Element("motetype_identifier");
|
||||
typeIdentifier.setText(mote.getType().getIdentifier());
|
||||
moteConfig.add(typeIdentifier);
|
||||
|
||||
|
||||
element.addContent(moteConfig);
|
||||
config.add(element);
|
||||
}
|
||||
|
@ -540,7 +542,7 @@ public class Simulation extends Observable implements Runnable {
|
|||
|
||||
/**
|
||||
* Sets the current simulation config depending on the given configuration.
|
||||
*
|
||||
*
|
||||
* @param configXML Simulation configuration
|
||||
* @param visAvailable True if simulation is allowed to show visualizers
|
||||
* @param manualRandomSeed Simulation random seed. May be null, in which case the configuration is used
|
||||
|
@ -566,7 +568,7 @@ public class Simulation extends Observable implements Runnable {
|
|||
// Random seed
|
||||
if (element.getName().equals("randomseed")) {
|
||||
long newSeed;
|
||||
|
||||
|
||||
if (element.getText().equals("generated")) {
|
||||
randomSeedGenerated = true;
|
||||
newSeed = new Random().nextLong();
|
||||
|
@ -634,6 +636,25 @@ public class Simulation extends Observable implements Runnable {
|
|||
if (element.getName().equals("motetype")) {
|
||||
String moteTypeClassName = element.getText().trim();
|
||||
|
||||
/* Try to recreate simulation using a different mote type */
|
||||
if (visAvailable) {
|
||||
String[] availableMoteTypes = getGUI().getProjectConfig().getStringArrayValue("se.sics.cooja.GUI.MOTETYPES");
|
||||
String newClass = (String) JOptionPane.showInputDialog(
|
||||
GUI.getTopParentContainer(),
|
||||
"The simulation is about to load '" + moteTypeClassName + "'\n" +
|
||||
"You may try to load the simulation using a different mote type.\n",
|
||||
"Loading mote type",
|
||||
JOptionPane.QUESTION_MESSAGE,
|
||||
null,
|
||||
availableMoteTypes,
|
||||
moteTypeClassName
|
||||
);
|
||||
if (newClass != null && !newClass.equals(moteTypeClassName)) {
|
||||
logger.warn("Changing mote type class: " + moteTypeClassName + " -> " + newClass);
|
||||
moteTypeClassName = newClass;
|
||||
}
|
||||
}
|
||||
|
||||
Class<? extends MoteType> moteTypeClass = myGUI.tryLoadClass(this,
|
||||
MoteType.class, moteTypeClassName);
|
||||
|
||||
|
@ -672,7 +693,7 @@ public class Simulation extends Observable implements Runnable {
|
|||
if (moteType == null) {
|
||||
throw new Exception("No mote type specified for mote");
|
||||
}
|
||||
|
||||
|
||||
/* Create mote using mote type */
|
||||
Mote mote = moteType.generateMote(this);
|
||||
if (mote.setConfigXML(this, element.getChildren(), visAvailable)) {
|
||||
|
@ -694,12 +715,12 @@ public class Simulation extends Observable implements Runnable {
|
|||
|
||||
setChanged();
|
||||
notifyObservers(this);
|
||||
|
||||
|
||||
/* Execute simulation thread events now, before simulation starts */
|
||||
while (hasPollRequests) {
|
||||
popSimulationInvokes().run();
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -716,7 +737,7 @@ public class Simulation extends Observable implements Runnable {
|
|||
public void run() {
|
||||
motes.remove(mote);
|
||||
currentRadioMedium.unregisterMote(mote, Simulation.this);
|
||||
|
||||
|
||||
/* Dispose mote interface resources */
|
||||
mote.removed();
|
||||
for (MoteInterface i: mote.getInterfaces().getInterfaces()) {
|
||||
|
@ -747,7 +768,7 @@ public class Simulation extends Observable implements Runnable {
|
|||
/* Remove mote from simulation thread */
|
||||
invokeSimulationThread(removeMote);
|
||||
}
|
||||
|
||||
|
||||
getGUI().closeMotePlugins(mote);
|
||||
}
|
||||
|
||||
|
@ -760,14 +781,14 @@ public class Simulation extends Observable implements Runnable {
|
|||
if (currentRadioMedium != null) {
|
||||
currentRadioMedium.removed();
|
||||
}
|
||||
|
||||
|
||||
/* Remove all motes */
|
||||
Mote[] motes = getMotes();
|
||||
for (Mote m: motes) {
|
||||
removeMote(m);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds a mote to this simulation
|
||||
*
|
||||
|
@ -787,7 +808,7 @@ public class Simulation extends Observable implements Runnable {
|
|||
mote.getInterfaces().getClock().setDrift(-getSimulationTime());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
motes.add(mote);
|
||||
currentRadioMedium.registerMote(mote, Simulation.this);
|
||||
|
||||
|
@ -795,12 +816,12 @@ public class Simulation extends Observable implements Runnable {
|
|||
for (MoteInterface i: mote.getInterfaces().getInterfaces()) {
|
||||
i.added();
|
||||
}
|
||||
|
||||
|
||||
setChanged();
|
||||
notifyObservers(mote);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
if (!isRunning()) {
|
||||
/* Simulation is stopped, add mote immediately */
|
||||
addMote.run();
|
||||
|
@ -821,10 +842,10 @@ public class Simulation extends Observable implements Runnable {
|
|||
public Mote getMote(int pos) {
|
||||
return motes.get(pos);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns simulation with with given ID.
|
||||
*
|
||||
*
|
||||
* @param id ID
|
||||
* @return Mote or null
|
||||
* @see Mote#getID()
|
||||
|
@ -899,7 +920,7 @@ public class Simulation extends Observable implements Runnable {
|
|||
|
||||
/**
|
||||
* Remove given mote type from simulation.
|
||||
*
|
||||
*
|
||||
* @param type Mote type
|
||||
*/
|
||||
public void removeMoteType(MoteType type) {
|
||||
|
@ -907,7 +928,7 @@ public class Simulation extends Observable implements Runnable {
|
|||
logger.fatal("Mote type is not registered: " + type);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Remove motes */
|
||||
for (Mote m: getMotes()) {
|
||||
if (m.getType() == type) {
|
||||
|
@ -925,15 +946,15 @@ public class Simulation extends Observable implements Runnable {
|
|||
* The simulation loop delays given value every simulated millisecond.
|
||||
* If the value is zero there is no delay.
|
||||
* If the value is negative, the simulation loop delays 1ms every (-time) simulated milliseconds.
|
||||
*
|
||||
*
|
||||
* Examples:
|
||||
* time=0: no sleeping (simulation runs as fast as possible).
|
||||
* time=10: simulation delays 10ms every simulated millisecond.
|
||||
* time=-5: simulation delays 1ms every 5 simulated milliseconds.
|
||||
*
|
||||
*
|
||||
* Special case:
|
||||
* time=Integer.MIN_VALUE: simulation tries to execute at real time.
|
||||
*
|
||||
*
|
||||
* @param time New delay time value
|
||||
*/
|
||||
public void setDelayTime(int time) {
|
||||
|
@ -949,12 +970,12 @@ public class Simulation extends Observable implements Runnable {
|
|||
delayTime = time;
|
||||
delayPeriod = 1; /* minimum */
|
||||
}
|
||||
|
||||
|
||||
invokeSimulationThread(new Runnable() {
|
||||
public void run() {
|
||||
if (!delayEvent.isScheduled()) {
|
||||
scheduleEvent(
|
||||
delayEvent,
|
||||
delayEvent,
|
||||
currentSimulationTime - (currentSimulationTime % MILLISECOND) + MILLISECOND);
|
||||
}
|
||||
Simulation.this.setChanged();
|
||||
|
@ -975,7 +996,7 @@ public class Simulation extends Observable implements Runnable {
|
|||
if (delayPeriod == Integer.MIN_VALUE) {
|
||||
return Integer.MIN_VALUE;
|
||||
}
|
||||
|
||||
|
||||
if (delayPeriod > 1) {
|
||||
return -delayPeriod;
|
||||
}
|
||||
|
@ -1007,7 +1028,7 @@ public class Simulation extends Observable implements Runnable {
|
|||
|
||||
/**
|
||||
* Returns current simulation time rounded to milliseconds.
|
||||
*
|
||||
*
|
||||
* @see #getSimulationTime()
|
||||
* @return Time rounded to milliseconds
|
||||
*/
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue