added simulation reload functionality
tries to reload the current simulation by allocating new available corecomms, and replacing any references to the old ones warning: custom made simulation configs may not work with this functionality! this is a convenience method, and needs dynamic corecomms for reloading more than a constant number of times
This commit is contained in:
parent
cf96c89934
commit
ebf965bbb6
1 changed files with 181 additions and 8 deletions
|
@ -24,7 +24,7 @@
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Id: GUI.java,v 1.29 2007/03/22 23:01:11 fros4943 Exp $
|
* $Id: GUI.java,v 1.30 2007/03/23 11:25:19 fros4943 Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package se.sics.cooja;
|
package se.sics.cooja;
|
||||||
|
@ -353,6 +353,14 @@ public class GUI {
|
||||||
menuItem.addActionListener(guiEventHandler);
|
menuItem.addActionListener(guiEventHandler);
|
||||||
menu.add(menuItem);
|
menu.add(menuItem);
|
||||||
|
|
||||||
|
menuItem = new JMenuItem("Reload simulation");
|
||||||
|
menuItem.addActionListener(new ActionListener() {
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
reloadCurrentSimulation();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
menu.add(menuItem);
|
||||||
|
|
||||||
menuItem = new JMenuItem("Close simulation");
|
menuItem = new JMenuItem("Close simulation");
|
||||||
menuItem.setMnemonic(KeyEvent.VK_C);
|
menuItem.setMnemonic(KeyEvent.VK_C);
|
||||||
menuItem.setActionCommand("close sim");
|
menuItem.setActionCommand("close sim");
|
||||||
|
@ -1789,8 +1797,9 @@ public class GUI {
|
||||||
try {
|
try {
|
||||||
newSim = loadSimulationConfig(fileToLoad, quick);
|
newSim = loadSimulationConfig(fileToLoad, quick);
|
||||||
addToFileHistory(fileToLoad);
|
addToFileHistory(fileToLoad);
|
||||||
if (progressDialog != null)
|
if (progressDialog != null && progressDialog.isVisible()) {
|
||||||
progressDialog.dispose();
|
progressDialog.dispose();
|
||||||
|
}
|
||||||
} catch (UnsatisfiedLinkError e) {
|
} catch (UnsatisfiedLinkError e) {
|
||||||
logger.warn("Could not reopen libraries: " + e.getMessage());
|
logger.warn("Could not reopen libraries: " + e.getMessage());
|
||||||
if (progressDialog != null)
|
if (progressDialog != null)
|
||||||
|
@ -1819,7 +1828,9 @@ public class GUI {
|
||||||
loadThread.interrupt();
|
loadThread.interrupt();
|
||||||
doRemoveSimulation(false);
|
doRemoveSimulation(false);
|
||||||
}
|
}
|
||||||
progressDialog.dispose();
|
if (progressDialog != null && progressDialog.isVisible()) {
|
||||||
|
progressDialog.dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1839,6 +1850,142 @@ public class GUI {
|
||||||
progressDialog.setVisible(true);
|
progressDialog.setVisible(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reloads current simulation.
|
||||||
|
* This may include recompiling libraries and renaming mote type identifiers.
|
||||||
|
*/
|
||||||
|
private void reloadCurrentSimulation() {
|
||||||
|
final JDialog progressDialog = new JDialog(frame, "Reloading", true);
|
||||||
|
final Thread loadThread = new Thread(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
|
||||||
|
// Create mappings to new mote type identifiers
|
||||||
|
Properties moteTypeNames = new Properties();
|
||||||
|
for (MoteType moteType: getSimulation().getMoteTypes()) {
|
||||||
|
if (moteType.getClass().equals(ContikiMoteType.class)) {
|
||||||
|
// Suggest new identifier
|
||||||
|
int counter = 0;
|
||||||
|
String testIdentifier = "";
|
||||||
|
boolean identifierOK = false;
|
||||||
|
while (!identifierOK) {
|
||||||
|
counter++;
|
||||||
|
testIdentifier = ContikiMoteTypeDialog.ID_PREFIX + counter;
|
||||||
|
identifierOK = true;
|
||||||
|
|
||||||
|
// Check if identifier already reserved for some other type
|
||||||
|
if (moteTypeNames.containsValue(testIdentifier)) {
|
||||||
|
identifierOK = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if identifier is already used by some other type
|
||||||
|
for (MoteType existingMoteType : getSimulation().getMoteTypes()) {
|
||||||
|
if (existingMoteType != moteType
|
||||||
|
&& existingMoteType.getIdentifier().equals(testIdentifier)) {
|
||||||
|
identifierOK = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if library file with given identifier has already been loaded
|
||||||
|
if (identifierOK
|
||||||
|
&& CoreComm.hasLibraryFileBeenLoaded(new File(
|
||||||
|
ContikiMoteType.tempOutputDirectory,
|
||||||
|
testIdentifier
|
||||||
|
+ ContikiMoteType.librarySuffix))) {
|
||||||
|
identifierOK = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
moteTypeNames.setProperty(moteType.getIdentifier(), testIdentifier);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get current simulation configuration
|
||||||
|
Element simulationElement = new Element("simulation");
|
||||||
|
simulationElement.addContent(getSimulation().getConfigXML());
|
||||||
|
Collection<Element> pluginsConfig = getPluginsConfigXML();
|
||||||
|
|
||||||
|
// Scan and replace old configuration mote type names
|
||||||
|
Element root = new Element("simconf");
|
||||||
|
root.addContent(simulationElement);
|
||||||
|
|
||||||
|
if (pluginsConfig != null)
|
||||||
|
root.addContent(pluginsConfig);
|
||||||
|
|
||||||
|
Document doc = new Document(root);
|
||||||
|
XMLOutputter outputter = new XMLOutputter();
|
||||||
|
outputter.setFormat(Format.getPrettyFormat());
|
||||||
|
String configXML = outputter.outputString(doc);
|
||||||
|
|
||||||
|
Enumeration oldNames = moteTypeNames.keys();
|
||||||
|
while (oldNames.hasMoreElements()) {
|
||||||
|
String oldName = (String) oldNames.nextElement();
|
||||||
|
configXML = configXML.replaceAll(">" + oldName + "<", ">" + moteTypeNames.get(oldName) + "<");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove current simulation
|
||||||
|
doRemoveSimulation(false);
|
||||||
|
|
||||||
|
// Reload altered simulation config
|
||||||
|
Simulation newSim = null;
|
||||||
|
try {
|
||||||
|
newSim = loadSimulationConfig(new StringReader(configXML), true);
|
||||||
|
if (progressDialog != null && progressDialog.isVisible()) {
|
||||||
|
progressDialog.dispose();
|
||||||
|
}
|
||||||
|
} catch (UnsatisfiedLinkError e) {
|
||||||
|
logger.fatal("Could not reopen libraries: " + e.getMessage());
|
||||||
|
if (progressDialog != null && progressDialog.isVisible()) {
|
||||||
|
progressDialog.dispose();
|
||||||
|
}
|
||||||
|
newSim = null;
|
||||||
|
}
|
||||||
|
if (newSim != null) {
|
||||||
|
myGUI.setSimulation(newSim);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (progressDialog != null && progressDialog.isVisible()) {
|
||||||
|
progressDialog.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Display progress dialog while reloading
|
||||||
|
JProgressBar progressBar = new JProgressBar(0, 100);
|
||||||
|
progressBar.setValue(0);
|
||||||
|
progressBar.setIndeterminate(true);
|
||||||
|
|
||||||
|
JButton button = new JButton("Cancel");
|
||||||
|
button.addActionListener(new ActionListener() {
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
if (loadThread != null && loadThread.isAlive()) {
|
||||||
|
loadThread.interrupt();
|
||||||
|
doRemoveSimulation(false);
|
||||||
|
}
|
||||||
|
if (progressDialog != null && progressDialog.isVisible()) {
|
||||||
|
progressDialog.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
JPanel progressPanel = new JPanel(new BorderLayout());
|
||||||
|
progressPanel.add(BorderLayout.CENTER, progressBar);
|
||||||
|
progressPanel.add(BorderLayout.SOUTH, button);
|
||||||
|
progressPanel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
|
||||||
|
|
||||||
|
progressPanel.setVisible(true);
|
||||||
|
|
||||||
|
progressDialog.getContentPane().add(progressPanel);
|
||||||
|
progressDialog.pack();
|
||||||
|
|
||||||
|
progressDialog.getRootPane().setDefaultButton(button);
|
||||||
|
progressDialog.setLocationRelativeTo(frame);
|
||||||
|
progressDialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
|
||||||
|
|
||||||
|
loadThread.start();
|
||||||
|
progressDialog.setVisible(true);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save current simulation configuration to disk
|
* Save current simulation configuration to disk
|
||||||
*
|
*
|
||||||
|
@ -2465,16 +2612,42 @@ public class GUI {
|
||||||
* If associated libraries could not be loaded
|
* If associated libraries could not be loaded
|
||||||
*/
|
*/
|
||||||
public Simulation loadSimulationConfig(File file, boolean quick)
|
public Simulation loadSimulationConfig(File file, boolean quick)
|
||||||
throws UnsatisfiedLinkError {
|
throws UnsatisfiedLinkError {
|
||||||
|
|
||||||
Simulation newSim = null;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Open config file
|
|
||||||
SAXBuilder builder = new SAXBuilder();
|
SAXBuilder builder = new SAXBuilder();
|
||||||
Document doc = builder.build(file);
|
Document doc = builder.build(file);
|
||||||
Element root = doc.getRootElement();
|
Element root = doc.getRootElement();
|
||||||
|
|
||||||
|
return loadSimulationConfig(root, quick);
|
||||||
|
} catch (JDOMException e) {
|
||||||
|
logger.fatal("Config not wellformed: " + e.getMessage());
|
||||||
|
return null;
|
||||||
|
} catch (IOException e) {
|
||||||
|
logger.fatal("IOException: " + e.getMessage());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Simulation loadSimulationConfig(StringReader stringReader, boolean quick) {
|
||||||
|
try {
|
||||||
|
SAXBuilder builder = new SAXBuilder();
|
||||||
|
Document doc = builder.build(stringReader);
|
||||||
|
Element root = doc.getRootElement();
|
||||||
|
|
||||||
|
return loadSimulationConfig(root, quick);
|
||||||
|
} catch (JDOMException e) {
|
||||||
|
logger.fatal("Config not wellformed: " + e.getMessage());
|
||||||
|
return null;
|
||||||
|
} catch (IOException e) {
|
||||||
|
logger.fatal("IOException: " + e.getMessage());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Simulation loadSimulationConfig(Element root, boolean quick) {
|
||||||
|
Simulation newSim = null;
|
||||||
|
|
||||||
|
try {
|
||||||
// Check that config file version is correct
|
// Check that config file version is correct
|
||||||
if (!root.getName().equals("simconf")) {
|
if (!root.getName().equals("simconf")) {
|
||||||
logger.fatal("Not a valid COOJA simulation config!");
|
logger.fatal("Not a valid COOJA simulation config!");
|
||||||
|
|
Loading…
Reference in a new issue