Package simtools.data

Source Code of simtools.data.DataSourceAnimator

/* ==============================================
* Simtools : The tools library used in JSynoptic
* ==============================================
*
* Project Info:  http://jsynoptic.sourceforge.net/index.html
*
* This library is free software; you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Foundation;
* either version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*
* (C) Copyright 2003, by :
*     Corporate:
*         Astrium SAS
*         EADS CRC
*     Individual:
*         Nicolas Brodu
*
* $Id: DataSourceAnimator.java,v 1.4 2006/02/15 18:29:07 cazenave Exp $
*
* Changes
* -------
* 21-Jan-2004: made initial version from collection animator (NB)
*
*/

package simtools.data;

import java.util.Timer;
import java.util.TimerTask;

/**
* This class adds dynamical features to a DataSource. This is useful to replay time series,
* for example.
* It will use the underlying source to provide the values, and has its own API to control
* how to advance the index : step by step, or with a timer.
*
* Note: All APIs from superclasses are redirected. So, this wrapper should really be transparent.
*  
* @author Nicolas Brodu
*/
public class DataSourceAnimator extends DynamicDataSource implements DataSourceListener {

  static public final String MARKER = "AnimatedSource:";

  protected DataSource target;
  protected long period = 1000;
  protected Timer timer;
  protected boolean finished;
  protected boolean autoStop;
 
  /**
   * @return true iff the underlying data source has no more values
   */
  public boolean isFinished() {
    return finished;
  }

  public DataSourceAnimator(DataSource ds) {
      this(ds,0);
  }
 
  public DataSourceAnimator(DataSource ds, int delay) {
      this(ds,delay,1000);
  }
 
  public DataSourceAnimator(DataSource ds, int delay, long period) {
      super(ds.getInformation(), ds.getKind(), delay);
      this.period = period;
    if (ds instanceof DataSourceAnimator) target = ((DataSourceAnimator)ds).target;
    target = ds;
    info.id = MARKER + info.id;
    this.autoRegister = false; // let's control things more finely
    target.addListener(this);
  }

  /** Increase current index */
  public void step() throws DataException {
    try {
      switch (kind) {
///        case ValueProvider.TypeProvider: super.setTypeValue(target.getTypeValue(lastIndex+1));
// ------ START of perl-generated corresponding code --------
        case ValueProvider.ByteProvider: super.setByteValue(target.getByteValue(lastIndex+1));
        case ValueProvider.ShortProvider: super.setShortValue(target.getShortValue(lastIndex+1));
        case ValueProvider.IntegerProvider: super.setIntegerValue(target.getIntegerValue(lastIndex+1));
        case ValueProvider.LongProvider: super.setLongValue(target.getLongValue(lastIndex+1));
        case ValueProvider.FloatProvider: super.setFloatValue(target.getFloatValue(lastIndex+1));
        case ValueProvider.DoubleProvider: super.setDoubleValue(target.getDoubleValue(lastIndex+1));
// -------- END of perl-generated corresponding code --------
          case ValueProvider.ObjectProvider: super.setObjectValue(target.getValue(lastIndex+1));
      }
      finished = false;
    } catch (DataException de) {
      if (autoStop && (de instanceof NoSuchIndex)) {
        finished=true;
      }
      throw de;
    }
    super.registerNewValue();
  }



  /**
   * @return The current period, in milliseconds
   */
  public long getPeriod() {
    return period;
  }

  /** Sets a period for cyclic execution
   * @param period, in milliseconds
   */
  public void setPeriod(long period) {
    if (isRunning()) {
      stop();
      this.period = period;
      start();
    }
    else this.period = period;
  }

  /**
   * @return true is the values are beeing updated cyclically.
   */
  public boolean isRunning() {
    return timer != null;
  }

  /**
   * Starts to update the values with the given period.
   */
  public void start(long period) {
    if (isRunning()) return;
    this.period=period;
    start();
  }

  /**
   * Starts to update the values with the previously set period. Default is 1 second.
   */
  public void start() {
    if (isRunning()) return;
    timer = new Timer(true); // do not block the application on exit
    timer.scheduleAtFixedRate(new TimerTask() {
      public void run() {
        try {
          step();
        } catch (DataException e) {
          if (autoStop && (e instanceof NoSuchIndex)) {
            stop(); // Exits gracefully when there is no more data
          }
        } catch(Exception e){
          // need some feed back in case of error
          // TimerTask/finally hide exceptions
          e.printStackTrace();
          stop();
        }
      }
    }
    ,0,period);
  }

  /**
   * Stop to update the values. This method is automatically called when there is no more
   * data in the underlying data source, if this option is chosen.
   */
  public void stop() {
    if (!isRunning()) return;
    timer.cancel();
    timer = null;
  }

  /**
   * Resets the source. Next call to step will show the first source element.
   */
  public void reset() {
    synchronized (this) {
      if (buffer!=null) buffer.clear();
      this.lastIndex = -1;
      finished = false;
    }
   
    notifyListenersForIndexRangeChange(getStartIndex(), getLastIndex());
  }

  /**
   * @return Returns the autoStop.
   */
  public boolean isAutoStop() {
    return autoStop;
  }
  /**
   * @param autoStop The autoStop to set.
   */
  public void setAutoStop(boolean autoStop) {
    this.autoStop = autoStop;
  }


// We listen to our target
// And propagate the changes together with our own listeners

  /* (non-Javadoc)
     * @see simtools.data.DataSourceListener#DataSourceValueChanged(simtools.data.DataSource, long, long)
     */
    public void DataSourceValueChanged(DataSource ds, long minIndex, long maxIndex) {
        if (buffer==null) {
            if ((lastIndex>=minIndex) && (lastIndex <= maxIndex))
                this.notifyListenersForValueChange(lastIndex, lastIndex);
        } else {
            long idxmin = Math.max(minIndex, buffer.getStartIndex());
            long idxmax = Math.min(maxIndex, buffer.getEndIndex());
            if (idxmin<=idxmax) // intersection not empty
                this.notifyListenersForValueChange(idxmin, idxmax);
        }
    }

    /* (non-Javadoc)
     * @see simtools.data.DataSourceListener#DataSourceIndexRangeChanged(simtools.data.DataSource, long, long)
     */
    public void DataSourceIndexRangeChanged(DataSource ds, long startIndex, long lastIndex) {
        if (buffer==null) {
            if ((this.lastIndex>=startIndex) && (this.lastIndex <= lastIndex))
                this.notifyListenersForIndexRangeChange(this.lastIndex, this.lastIndex);
        } else {
            long idxmin = Math.max(startIndex, buffer.getStartIndex());
            long idxmax = Math.min(lastIndex, buffer.getEndIndex());
            if (idxmin<=idxmax) // intersection not empty
                this.notifyListenersForIndexRangeChange(idxmin, idxmax);
        }
    }

    /* (non-Javadoc)
     * @see simtools.data.DataSourceListener#DataSourceInfoChanged(simtools.data.DataSource, simtools.data.DataInfo)
     */
    public void DataSourceInfoChanged(DataSource ds, DataInfo newInfo) {
        info = newInfo;
        notifyListenersForInfoChange(newInfo);
    }

    /* (non-Javadoc)
     * @see simtools.data.DataSourceListener#DataSourceValueRangeChanged(simtools.data.DataSource)
     */
    public void DataSourceValueRangeChanged(DataSource ds) {
        this.notifyListenersForValueRangeChange();
    }

    /* (non-Javadoc)
     * @see simtools.data.DataSourceListener#DataSourceOrderChanged(simtools.data.DataSource, int)
     */
    public void DataSourceOrderChanged(DataSource ds, int newOrder) {
        this.notifyListenersForOrderChange(newOrder);
    }
   
  /* (non-Javadoc)
   * @see simtools.data.DataSourceListener#DataSourceReplaced(simtools.data.DataSource, simtools.data.DataSource)
   */
  public void DataSourceReplaced(DataSource oldData, DataSource newData) {
    this.notifyListenersForDataReplaced(oldData,newData);
  }



// Delegate methods

    /* (non-Javadoc)
     * @see simtools.data.DataSource#sortedOrder()
     */
    public int sortedOrder() {
        return target.sortedOrder();
    }
   
    /* (non-Javadoc)
     * @see simtools.data.DynamicDataSource#valueClass()
     */
    public Class valueClass() {
        return target.valueClass();
    }
}
TOP

Related Classes of simtools.data.DataSourceAnimator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.