001/* Measure the time interval between input events.
002
003 Copyright (c) 1998-2014 The Regents of the University of California.
004 All rights reserved.
005 Permission is hereby granted, without written agreement and without
006 license or royalty fees, to use, copy, modify, and distribute this
007 software and its documentation for any purpose, provided that the above
008 copyright notice and the following two paragraphs appear in all copies
009 of this software.
010
011 IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
012 FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
013 ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
014 THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
015 SUCH DAMAGE.
016
017 THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
018 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
019 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
020 PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
021 CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
022 ENHANCEMENTS, OR MODIFICATIONS.
023
024 PT_COPYRIGHT_VERSION_2
025 COPYRIGHTENDKEY
026
027 */
028package ptolemy.domains.de.lib;
029
030import ptolemy.actor.util.Time;
031import ptolemy.data.DoubleToken;
032import ptolemy.data.type.BaseType;
033import ptolemy.kernel.CompositeEntity;
034import ptolemy.kernel.util.IllegalActionException;
035import ptolemy.kernel.util.NameDuplicationException;
036
037///////////////////////////////////////////////////////////////////
038//// TimeGap
039
040/**
041 This actor measures the time interval between arrivals of successive
042 input tokens.
043 Beginning with the second input arrival, the measurement is produced
044 at the output.  The output is always a DoubleToken.
045 @see WaitingTime
046
047 @author Jie Liu, Edward A Lee, Haiyang Zheng
048 @version $Id$
049 @since Ptolemy II 1.0
050 @Pt.ProposedRating Yellow (hyzheng)
051 @Pt.AcceptedRating Red (hyzheng)
052 */
053public class TimeGap extends DETransformer {
054    /** Construct an actor with the specified container and name.
055     *  @param container The container.
056     *  @param name The name.
057     *  @exception IllegalActionException If the entity cannot be contained
058     *   by the proposed container.
059     *  @exception NameDuplicationException If the container already has an
060     *   actor with this name.
061     */
062    public TimeGap(CompositeEntity container, String name)
063            throws NameDuplicationException, IllegalActionException {
064        super(container, name);
065        output.setTypeEquals(BaseType.DOUBLE);
066    }
067
068    ///////////////////////////////////////////////////////////////////
069    ////                         public methods                    ////
070
071    /** Beginning with the second input, produce an output that is
072     *  the elapsed time since the previous input is received.  When the
073     *  first input is received, nothing is produced.  This method
074     *  consumes at most one token from the input each time it is fired.
075     *  @exception IllegalActionException If get() or send() throws it.
076     */
077    @Override
078    public void fire() throws IllegalActionException {
079        super.fire();
080        // Consume an input.
081        if (input.hasToken(0)) {
082            _hadInput = true;
083            input.get(0);
084            // Produce an output only when an input has arrived.
085            Time currentTime = getDirector().getModelTime();
086
087            if (_previousTime.compareTo(Time.NEGATIVE_INFINITY) != 0) {
088                DoubleToken outToken = new DoubleToken(
089                        currentTime.subtract(_previousTime).getDoubleValue());
090                output.send(0, outToken);
091            }
092        } else {
093            _hadInput = false;
094        }
095    }
096
097    /** Set the previous event time to negative infinity.
098     */
099    @Override
100    public void initialize() throws IllegalActionException {
101        _previousTime = Time.NEGATIVE_INFINITY;
102        _hadInput = false;
103        super.initialize();
104    }
105
106    /** Record the time when the current input arrives.
107     *  @return True to continue firing.
108     *  @exception IllegalActionException If there is no director or thrown
109     *  in the super class.
110     */
111    @Override
112    public boolean postfire() throws IllegalActionException {
113        if (_hadInput) {
114            _previousTime = getDirector().getModelTime();
115            _hadInput = false;
116        }
117        return super.postfire();
118    }
119
120    ///////////////////////////////////////////////////////////////////
121    ////                         private variables                 ////
122    // The time when the previous input arrives.
123    private Time _previousTime;
124    // Indicator that a non-absent input was seen in fire().
125    private boolean _hadInput;
126}