⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stumblerfunnel.java

📁 一个基于PlaceLab的室内和室外的智能导航系统
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
package org.placelab.stumbler;import java.util.Enumeration;import java.util.Hashtable;import java.util.Vector;import org.placelab.collections.HashtableSet;import org.placelab.core.Measurement;import org.placelab.core.ShutdownListener;import org.placelab.eventsystem.EventListener;import org.placelab.eventsystem.EventSystem;import org.placelab.spotter.PeriodicScannable;import org.placelab.spotter.Spotter;import org.placelab.spotter.SpotterException;import org.placelab.spotter.SpotterListener;/** * StumblerFunnel manages and collates Measurements from multiple Spotters.   *  * The StumblerFunnel, with the use of {@link SpotterExtension} objects, can be configured to  * allow for virtually any type of stumbling semantics.  Examples of real and * potential uses are given below. * <p> * <b>Trigger, Independent, and Dependent Spotters<b><br> * <ul> * <li><b>Trigger Spotters</b>: These are spotters that are run asynchronously * on the user or spotter defined scan interval * (see {@link PeriodicScannable#setPeriodicScanInterval(long)}).  When they update, they cause * all Dependent Spotters to be queried for their latest updates (whether this * triggers an actual scan of the environment or just gets the latest update * from the dependent spotter depends on the configuration of the Spotter Extension * for that dependent spotter). When the StumblerFunnel is started, all Trigger  * Spotters will have their startScanning() methods called, so they should not be * started prior to providing them to the StumblerFunnel. *  * <li><b>Independent Spotters</b>: These spotters also run asynchronously on the * user or spotter defined scan interval, but they do not trigger any other * spotters to update upon the StumblerFunnel's receipt of a Measurement from them. * When the StumblerFunnel is started, all Independent Spotters will have their  * startScanning() methods called. *  * <li><b>Dependent Spotters</b>: These spotters only have their Measurements * collected when Trigger Spotters return Measurements, or when the timeout fires  * (see below).  They can be either * synchronous or asynchronous since they will have their Measurements collected * with {@link SpotterExtension#getLatestMeasurement()} which should return quickly. * Note that the StumblerFunnel does not start Dependent Spotters, so if you intend * to have them run asynchronously you will have to use {@link SpotterExtension#startScanning()} * yourself. *  * </ul> * <br> * <b>Timeout</b><br> * If you specify a positive timeout, if the registered Trigger spotters do not produce * Measurements by the timeout period (or if there are no Trigger spotters) all Dependent * Spotters will have their latest Measurements collected and pushed through to * StumblerFunnelUpdateListeners at that time.  Negative timeouts will make it such * that a Trigger Spotter must update in order for Measurements to be collected from * any Dependent spotters. *  * <p> *  * <b>Examples of StumblerFunnel configurations</b><br> * "Straight-line stumbler": This type of Stumbler doesn't have any dependent spotters. * This is if you just want updates to come in as the spotters make them available. * <code> * StumblerFunnel f = new StumblerFunnel(-1); * WiFiSpotter wifi = new WiFiSpotter(250); // wifi will produce updates every 250 ms * NMEAGPSSpotter gps = SerialGPSSpotter.newSpotter(); // gps will produce updates as fast as the hardware allows * SpotterExtension wifiExt = new SpotterExtension(wifi, true, -1); * SpotterExtension gpsExt = new SpotterExtension(gps, false, SpotterExtension.GPS_STALE_TIME); * f.addIndependentSpotter(wifiExt); * f.addIndependentSpotter(gpsExt); * f.addUpdateListener(new LogWriter()); * f.start(); * </code> * <p> * "Place Lab Stumbler": This is (a simplification) of the default config used by PlacelabStumbler. * The idea is to place WiFi as accurately as possible, so WiFi should be collected when GPS Measurements * come in.  Running WiFi fast and independent of the GPS as above will probably see more APs, but * it won't produce logs that are as accurate as this method. * <code> * StumblerFunnel f = new StumblerFunnel(-1); // you might specify 2000 or something here to get something when GPS isn't active * WiFiSpotter wifi = new WiFiSpotter(); * NMEAGPSSpotter gps = SerialGPSSpotter.newSpotter(); * SpotterExtension wifiExt = new SpotterExtension(wifi, true, -1); * SpotterExtension gpsExt = new SpotterExtension(gps, false, SpotterExtension.GPS_STALE_TIME); * f.addDependentSpotter(wifiExt); * f.addTriggerSpotter(gpsExt); * f.addUpdateListener(new AudioNotifier()); * f.start(); * </code> * <br> *   * Listeners to StumblerFunnel will get notifications containing the measurements for * the StumblerSpotters as they are available according to the rules outlined above * The StumblerFunnel begins its funneling operations after start() is called and * runs these in a new thread.  This means that stumblerUpdated notifications will * not come back in the same thread as which start() was called.  If this won't work * for you, you can use start(EventSystem evs) and callbacks will be delivered by * the given EventSystem. *  * Finally, note that the update Hashtable is keyed by the Spotters, not the SpotterExtensions. */public class StumblerFunnel extends Thread implements SpotterListener {        protected HashtableSet dependentSpotters;    protected HashtableSet triggerSpotters;    protected HashtableSet independentSpotters;    protected HashtableSet shutdowns;    protected HashtableSet updateListeners;    protected boolean shuttingDown = false;    protected boolean suspend = false;    protected boolean doUpdate = false;        protected EventSystem eventSystem;    protected Timeout timeout;    protected volatile boolean timeoutFired = false;        // a queue of Spotters    protected Vector updateSenders = null;    // a queue of Measurements    protected Vector updateSenderMeasurements = null;        /** Create a StumblerFunnel with default timeout, as set     *  in placelab.StumblerFunnel.timeout system property or     *  2000 ms if not set     */    public StumblerFunnel() {        this(getDefaultTimeout());    }        private static long getDefaultTimeout() {        long timeout = 2000;        try {            timeout = Long.parseLong(                    System.getProperty("placelab.StumblerFunnel.timeout"));        } catch (Exception e) {                    }        return timeout;    }            /**     * Create a new StumblerFunnel.  If no trigger spotters have signaled that     * they have new Measurements available by timeout, then all dependent stumblers are polled     * for their Measurements.     */    public StumblerFunnel(long timeout) {        triggerSpotters = new HashtableSet();        independentSpotters = new HashtableSet();        dependentSpotters = new HashtableSet();        updateListeners = new HashtableSet();        updateSenderMeasurements = new Vector();        updateSenders = new Vector();        shutdowns = new HashtableSet();        this.timeout = new Timeout(this, timeout);    }        public void start(EventSystem evs) {        this.eventSystem = evs;        this.start();    }        public void run() {        this.startTriggerSpotters();        this.startIndependentSpotters();        timeout.start();		while (!shuttingDown) {			if (suspend) {				synchronized (this) {					try {						sleep(1000);					} catch (InterruptedException ie) {					}				}			} else {				if (doUpdate) {					doUpdate = false;					this.pulse();				}				synchronized (this) {					try {						this.wait();					} catch (InterruptedException ie) {					}				}			}		}	}            protected void startTriggerSpotters() {        Enumeration i = triggerSpotters.elements();        while(i.hasMoreElements()) {            Spotter sp = (Spotter)i.nextElement();            try {				sp.open();			} catch (SpotterException e1) {				e1.printStackTrace();			}            sp.startScanning();        }    }    protected void startIndependentSpotters() {        Enumeration i = independentSpotters.elements();        while(i.hasMoreElements()) {            Spotter sp = (Spotter)i.nextElement();            try {				sp.open();			} catch (SpotterException e1) {				e1.printStackTrace();			}            sp.startScanning();        }    }        /**     * Adds a spotter to be watched by the StumblerFunnel.  All SpotterExtensions are     * also ShutdownListeners, so they are automatically added to the shutdownListeners Vector too     * @param spotter to be added to the StumblerFunnel     */    public void addDependentSpotter(SpotterExtension spotter) {        checkRunning();        dependentSpotters.addElement(spotter);        shutdowns.addElement(spotter);    }        /**     * Adds a spotter to be watched by the StumblerFunnel.  All SpotterExtensions are     * also ShutdownListeners, so they are automatically added to the shutdownListeners Vector too.     * A Trigger Spotter is one that the StumblerFunnel will always fire an update in response     * to an update from.     * @param spotter to be added to the StumblerFunnel     */    public void addTriggerSpotter(SpotterExtension spotter) {        checkRunning();        triggerSpotters.addElement(spotter.getSpotter());        shutdowns.addElement(spotter);        spotter.addListener(this);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -