Package simtools.data

Source Code of simtools.data.DataSourceCollectionAnimator

/* ==============================================
* 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: DataSourceCollectionAnimator.java,v 1.7 2007/10/05 09:37:49 ogor Exp $
*
* Changes
* -------
* 25-Sep-2003 : Initial public release (NB);
*
*/
package simtools.data;

import java.util.Collection;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Timer;
import java.util.TimerTask;

/**
* This class adds dynamical features to a DataSourceCollection. This is useful
* to replay time series, for example. It will use the underlying collection 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 also redirected, including vector.
* Collective data sources are also redirect to us. So, this wrapper should
* really be transparent. This is especially important to understand the code
* behind buffer functions also works without overloading base functions.
*
* @author Nicolas Brodu
*/
public class DataSourceCollectionAnimator extends DynamicDataSourceCollection implements DataSourceCollectionListener {
    static public final String MARKER = "AnimatedCollection:";

    protected DataSourceCollection 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 DataSourceCollectionAnimator(DataSourceCollection dsc) {
        if (dsc instanceof DataSourceCollectionAnimator) {
            target = ((DataSourceCollectionAnimator) dsc).target;
        }
        target = dsc;
        sourceInfo = new SourceInfo[target.size()];
        for (int i = 0; i < target.size(); ++i) {
            CollectiveDataSource cds = (CollectiveDataSource) target.get(i);
            sourceInfo[i] = new SourceInfo();
            sourceInfo[i].info = target.getInformation(i);
            sourceInfo[i].kind = target.getKind(i);
            cds.collection = this; // redirect to us, especially important for
            // buffers
        }
        target.addListener(this);
    }

    /*
     * (non-Javadoc)
     *
     * @see simtools.data.DynamicDataSourceCollection#getInformation()
     */
    public DataInfo getInformation() {
        ourInfo = DataInfo.clone(target.getInformation());
        ourInfo.id = MARKER + ourInfo.id;
        return ourInfo;
    }

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

    /**
     * @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
                    }
                }
            }
        }, 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 (buffers != null) {
                for (int i = 0; i < buffers.length; ++i) {
                    if (buffers[i] != null) {
                        buffers[i].clear();
                    }
                }
            }
            this.lastIndex = -1;
            finished = false;
        }
        for (int i = 0; i < size(); ++i) {
            DataSource ds = (DataSource) get(i);
            ds.notifyListenersForIndexRangeChange(getStartIndex(i), getLastIndex(i));
        }
    }

    /**
     * @return Returns the autoStop.
     */
    public boolean isAutoStop() {
        return autoStop;
    }

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

    protected DataSource createDataSource(DataInfo info, int kind) {
        throw new java.lang.UnsupportedOperationException();
    }

    protected DataSource createDataSource(DataInfo info) {
        throw new java.lang.UnsupportedOperationException();
    }

    // We listen to our target
    // And propagate the changes together with our own listeners
    public void DataSourceCollectionInfoChanged(DataSourceCollection dsc, DataInfo newInfo) {
        notifyListenersForInfoChange(newInfo);
    }

    public void DataSourceCollectionDataSourceAdded(DataSourceCollection dsc, DataSource ds) {
        // Ouch, quite Bad!!!
        throw new java.lang.UnsupportedOperationException();
    }

    public void DataSourceCollectionDataSourceRemoved(DataSourceCollection dsc, DataSource ds) {
        // Ouch, quite Bad!!!
        throw new java.lang.UnsupportedOperationException();
    }

    public void DataSourceCollectionRemoved(DataSourceCollection dsc) {
    }

    // Keep this one, not necessary but very slighly more performant like that
    // (Vector API extension)
    public DataSource get(String id) {
        return target.get(id);
    }

    // Vector overload
    public synchronized void copyInto(Object[] anArray) {
        target.copyInto(anArray);
    }

    public synchronized void trimToSize() {
        target.trimToSize();
    }

    public synchronized void ensureCapacity(int minCapacity) {
        target.ensureCapacity(minCapacity);
    }

    public synchronized void setSize(int newSize) {
        target.setSize(newSize);
    }

    public synchronized int capacity() {
        return target.capacity();
    }

    public synchronized int size() {
        return target.size();
    }

    public synchronized boolean isEmpty() {
        return target.isEmpty();
    }

    public Enumeration elements() {
        return target.elements();
    }

    public boolean contains(Object elem) {
        return target.contains(elem);
    }

    public int indexOf(Object elem) {
        return target.indexOf(elem);
    }

    public synchronized int indexOf(Object elem, int index) {
        return target.indexOf(elem, index);
    }

    public synchronized int lastIndexOf(Object elem) {
        return target.lastIndexOf(elem);
    }

    public synchronized int lastIndexOf(Object elem, int index) {
        return target.lastIndexOf(elem, index);
    }

    public synchronized Object elementAt(int index) {
        return target.elementAt(index);
    }

    public synchronized Object firstElement() {
        return target.firstElement();
    }

    public synchronized Object lastElement() {
        return target.lastElement();
    }

    public synchronized void setElementAt(Object obj, int index) {
        target.setElementAt(obj, index);
    }

    public synchronized void removeElementAt(int index) {
        target.removeElementAt(index);
    }

    public synchronized void insertElementAt(Object obj, int index) {
        target.insertElementAt(obj, index);
    }

    public synchronized void addElement(Object obj) {
        target.addElement(obj);
    }

    public synchronized boolean removeElement(Object obj) {
        return target.removeElement(obj);
    }

    public synchronized void removeAllElements() {
        target.removeAllElements();
    }

    public synchronized Object clone() {
        return target.clone();
    }

    public synchronized Object[] toArray() {
        return target.toArray();
    }

    public synchronized Object[] toArray(Object[] a) {
        return target.toArray(a);
    }

    public synchronized Object get(int index) {
        return target.get(index);
    }

    public synchronized Object set(int index, Object element) {
        return target.set(index, element);
    }

    public synchronized boolean add(Object o) {
        return target.add(o);
    }

    public boolean remove(Object o) {
        return target.remove(o);
    }

    public void add(int index, Object element) {
        target.add(index, element);
    }

    public synchronized Object remove(int index) {
        return target.remove(index);
    }

    public void clear() {
        target.clear();
    }

    public synchronized boolean containsAll(Collection c) {
        return target.containsAll(c);
    }

    public synchronized boolean addAll(Collection c) {
        return target.addAll(c);
    }

    public synchronized boolean removeAll(Collection c) {
        return target.removeAll(c);
    }

    public synchronized boolean retainAll(Collection c) {
        return target.retainAll(c);
    }

    public synchronized boolean addAll(int index, Collection c) {
        return target.addAll(index, c);
    }

    public synchronized boolean equals(Object o) {
        return target.equals(o);
    }

    public synchronized int hashCode() {
        return target.hashCode();
    }

    public synchronized String toString() {
        return target.toString();
    }

    public synchronized List subList(int fromIndex, int toIndex) {
        return target.subList(fromIndex, toIndex);
    }

    public Iterator iterator() {
        return target.iterator();
    }

    public ListIterator listIterator() {
        return target.listIterator();
    }

    public ListIterator listIterator(int index) {
        return target.listIterator(index);
    }

    /**
     * @return
     */
    public DataSourceCollection getTargetCollection() {
        return target;
    }
}
TOP

Related Classes of simtools.data.DataSourceCollectionAnimator

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.