📄 simulation.java
字号:
/* * Copyright (c) 2006, 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. * * $Id: Simulation.java,v 1.18 2007/10/03 14:20:57 fros4943 Exp $ */package se.sics.cooja;import java.util.*;import org.apache.log4j.Logger;import org.jdom.*;import se.sics.cooja.dialogs.*;/** * A simulation consists of a number of motes and mote types. * * The motes in the simulation are ticked one by one in a simulation loop. When * all motes have been ticked once, the simulation time is updated and then the * simulation sleeps for some specified delay time. Any tick observers are also * notified at this time. * * When observing the simulation itself, the simulation state, added or deleted * motes etc. are observed, as opposed to individual mote changes. Changes of * individual motes should instead be observed via corresponding mote * interfaces. * * @author Fredrik Osterlind */public class Simulation extends Observable implements Runnable { private Vector<Mote> motes = new Vector<Mote>(); private Vector<MoteType> moteTypes = new Vector<MoteType>(); private int delayTime = 5; private int currentSimulationTime = 0; private int tickTime = 1; private String title = null; private RadioMedium currentRadioMedium = null; private static Logger logger = Logger.getLogger(Simulation.class); private boolean isRunning = false; private boolean stopSimulation = false; private Thread thread = null; private GUI myGUI = null; private long randomSeed = 123456; private int currentTickListIndex = 0; private int nrTickLists = 1; private int maxMoteStartupDelay = 0; private Random tickListRandom = new Random(); private Random delayMotesRandom = new Random(); // Tick observable private class TickObservable extends Observable { private void allTicksPerformed() { setChanged(); notifyObservers(); } } private TickObservable tickObservable = new TickObservable(); /** * Add tick observer. This observer is notified once every tick loop, that is, * when all motes have been ticked. * * @see #deleteTickObserver(Observer) * @param newObserver * New observer */ public void addTickObserver(Observer newObserver) { tickObservable.addObserver(newObserver); } /** * Delete an existing tick observer. * * @see #addTickObserver(Observer) * @param observer * Observer to delete */ public void deleteTickObserver(Observer observer) { tickObservable.deleteObserver(observer); } public void run() { long lastStartTime = System.currentTimeMillis(); logger.info("Simulation main loop started, system time: " + lastStartTime); isRunning = true; // Notify observers simulation is starting this.setChanged(); this.notifyObservers(this); // Distribute motes in tick lists according to random seed // TODO Timeconsuming approach (but only performed once) int motesToDistribute = motes.size(); Mote[][] allLists = new Mote[nrTickLists][]; for (int i=0; i < nrTickLists; i++) { allLists[i] = new Mote[(int) Math.ceil((double)motesToDistribute/(double)(nrTickLists - i))]; motesToDistribute -= allLists[i].length; } // Distribute motes according to seed tickListRandom.setSeed(randomSeed); Vector<Mote> motesClone = (Vector<Mote>) motes.clone(); for (int i=0; i < allLists.length; i++) { for (int j=0; j < allLists[i].length; j++) { int moteNr = tickListRandom.nextInt(motesClone.size()); allLists[i][j] = motesClone.remove(moteNr); } } while (isRunning) { try { // Tick current mote subset for (Mote moteToTick : allLists[currentTickListIndex]) { moteToTick.tick(currentSimulationTime); } // Select next mote subset (persistent) currentTickListIndex++; if (currentTickListIndex >= nrTickLists) { currentTickListIndex = 0; } // Increase simulation time currentSimulationTime += tickTime; // Notify tick observers tickObservable.allTicksPerformed(); // Sleep if (delayTime > 0) { Thread.sleep(delayTime); } if (stopSimulation) { // We should only tick once (and we just did), so abort now stopSimulation = false; isRunning = false; thread = null; } } catch (InterruptedException e) { isRunning = false; thread = null; break; } catch (IllegalArgumentException e) { logger.warn("llegalArgumentException:" + e); isRunning = false; thread = null; break; } catch (IllegalMonitorStateException e) { logger.warn("IllegalMonitorStateException:" + e); isRunning = false; thread = null; break; } } isRunning = false; thread = null; stopSimulation = false; // Notify observers simulation has stopped this.setChanged(); this.notifyObservers(this); logger.info("Simulation main loop stopped, system time: " + System.currentTimeMillis() + "\tDuration: " + (System.currentTimeMillis() - lastStartTime) + " ms"); } /** * Creates a new simulation with a delay time of 100 ms. */ public Simulation(GUI gui) { myGUI = gui; delayMotesRandom.setSeed(randomSeed); } /** * Starts this simulation (notifies observers). */ public void startSimulation() { if (!isRunning()) { isRunning = true; thread = new Thread(this); thread.start(); } } /** * Stops this simulation (notifies observers). */ public void stopSimulation() { if (isRunning()) { stopSimulation = true; thread.interrupt(); // Wait until simulation stops if (Thread.currentThread() != thread) { while (thread != null && thread.isAlive()) { try { Thread.sleep(10); } catch (InterruptedException e) { } } } } } /** * Starts simulation if stopped, ticks all motes once, and finally stops * simulation again. */ public void tickSimulation() { stopSimulation = true; if (!isRunning()) { thread = new Thread(this); thread.start(); } // Wait until simulation stops while (thread != null && thread.isAlive()) { try { Thread.sleep(10); } catch (InterruptedException e) { } } } /** * @return GUI holding this simulation */ public GUI getGUI() { return myGUI; } /** * @return Random seed */ public long getRandomSeed() { return randomSeed; } /** * @param randomSeed Random seed */ public void setRandomSeed(long randomSeed) { this.randomSeed = randomSeed; } /** * @return Number of tick lists */ public int getNrTickLists() { return nrTickLists; } /** * @param nrTickLists Number of tick lists */ public void setNrTickLists(int nrTickLists) { this.nrTickLists = Math.max(1, nrTickLists); } /** * @return Maximum mote startup delay */ public int getDelayedMoteStartupTime() { return maxMoteStartupDelay; } /** * @param nrTickLists Maximum mote startup delay */ public void setDelayedMoteStartupTime(int maxMoteStartupDelay) { this.maxMoteStartupDelay = Math.max(0, maxMoteStartupDelay); } /** * Returns the current simulation config represented by XML elements. This * config also includes the current radio medium, all mote types and motes. * * @return Current simulation config */ public Collection<Element> getConfigXML() { Vector<Element> config = new Vector<Element>(); Element element; // Title element = new Element("title"); element.setText(title); config.add(element); // Delay time element = new Element("delaytime"); element.setText(Integer.toString(delayTime)); config.add(element); // Tick time element = new Element("ticktime"); element.setText(Integer.toString(tickTime)); config.add(element); // Random seed element = new Element("randomseed"); element.setText(Long.toString(randomSeed)); config.add(element); // Number of tick lists element = new Element("nrticklists"); element.setText(Integer.toString(nrTickLists)); config.add(element); // Max mote startup delay element = new Element("motedelay"); element.setText(Integer.toString(maxMoteStartupDelay)); config.add(element); // Radio Medium element = new Element("radiomedium"); element.setText(currentRadioMedium.getClass().getName()); Collection radioMediumXML = currentRadioMedium.getConfigXML(); if (radioMediumXML != null) { element.addContent(radioMediumXML); } config.add(element); // Mote types for (MoteType moteType : getMoteTypes()) { element = new Element("motetype"); element.setText(moteType.getClass().getName()); Collection moteTypeXML = moteType.getConfigXML(); if (moteTypeXML != null) { element.addContent(moteTypeXML); } config.add(element); } // Motes for (Mote mote : motes) { element = new Element("mote"); element.setText(mote.getClass().getName()); Collection moteXML = mote.getConfigXML(); if (moteXML != null) { element.addContent(moteXML);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -