//********************************************************************** // //<copyright> // //BBN Technologies //10 Moulton Street //Cambridge, MA 02138 //(617) 873-8000 // //Copyright (C) BBNT Solutions LLC. All rights reserved. // //</copyright> //********************************************************************** // //$Source: ///cvs/darwars/ambush/aar/src/com/bbn/ambush/mission/MissionHandler.java,v //$ //$RCSfile: MissionHandler.java,v $ //$Revision: 1.10 $ //$Date: 2004/10/21 20:08:31 $ //$Author: dietrick $ // //********************************************************************** package com.bbn.openmap.omGraphics.time; import java.util.Iterator; import java.util.TreeSet; import java.util.logging.Level; import java.util.logging.Logger; /** * The TemporalSupport object is intended to provide rudimentary support for * choosing the right temporal status for a given time. A list of TemporalRecord * objects are managed by this support object and given a time, it will return * the applicable TemporalRecord for that time. The updateForTemporalRecord * method allows this object to be extended to keep track of what happens to an * object from the start of time, so that an object's status can be observed and * calculated based on everything that might have changed in the TemporalRecord * list before a given time. */ public abstract class TemporalSupport { public static Logger logger = Logger.getLogger("com.bbn.openmap.omGraphics.time.TemporalSupport"); protected TreeSet<? extends TemporalRecord> temporals; /** * * @param time in milliseconds * @param interpolate flag to signal that the returned Temporal object * should be interpolated (in whatever way needed) if the time falls * between Temporal objects. */ public <T extends TemporalRecord> T getPosition(long time, boolean interpolate) { T previous = null; T next = null; // Find out where the timestamp is in relation to the reported // positions synchronized (temporals) { Iterator<T> it = iterator(); while (it.hasNext()) { T temporal = it.next(); long recTimeStamp = temporal.getTime(); if (logger.isLoggable(Level.FINER)) { logger.finer("evaluating: " + temporal + " vs " + time); } if (recTimeStamp < time) { previous = temporal; updateForTemporal(time, temporal); } else if (recTimeStamp > time) { next = temporal; break; } else { // Hit a time right at a position. updateForTemporal(time, temporal); return temporal; } } } T pos = null; // OK, now's the opportunity to leave if // interpolation is not wanted. if (previous != null && !interpolate) { return previous; } else if (previous == null) { // time is before MissionFeature is placed. // Don't want to set pos here, should be null to set // visibility properly. if (next != null) { // Just for fun, put location where it will be. We // still want to get here if interpolation is not // wanted if the current time is before the first // position report. if (logger.isLoggable(Level.FINER)) { logger.finer("premature time, invisible: " + next.toString()); } // We're displaying this position before we're // supposed to know it's there. // pos = createPosition(time, next); } else { // no timestamps // Returning null Position } } else if (next == null) { // time is after last temporal // We're displaying this position after the last position // report, assuming that the object is just going to sit // there. pos = previous; } else { // Need to interpolate between the two, previous and next. // This may not be exact, but it's close. pos = (T) interpolate(time, previous, next); } return pos; } /** * Override this method to use the TemporalRecord's contents to affect the * status of whatever you like. * * @param time milliseconds reflecting the current time. * @param temporal record that reflects something that has happened. */ protected void updateForTemporal(long time, TemporalRecord temporal) { } /** * Just returns the TemporalRecord that is closes to the current time. * Assumes neither previous or next are null. * * @param time the current time. * @param previous TemporalRecord that occurred before current time. * @param next TemporalRecord that occurred after current time. * @return closest one. */ protected TemporalRecord interpolate(long time, TemporalRecord previous, TemporalRecord next) { long midTime = previous.getTime() + (next.getTime() - previous.getTime()) / 2l; if (time < midTime) { return previous; } return next; } public <T extends TemporalRecord> TreeSet<T> getTemporals() { if (temporals == null) { temporals = createTemporalSet(); } return (TreeSet<T>) temporals; } public <T extends TemporalRecord> void setTemporals(TreeSet<T> temporals) { this.temporals = temporals; } public abstract <T extends TemporalRecord> TreeSet<T> createTemporalSet(); public abstract <T extends TemporalRecord> Iterator<T> iterator(); public void add(TemporalRecord tr) { getTemporals().add(tr); } /** * Return true if the TemporalRecord was contained in the list. * * @param tr * @return true if removal was successful. */ public boolean remove(TemporalRecord tr) { return getTemporals().remove(tr); } public void clear() { temporals.clear(); } }