001/* Record an initial token and then output that initial token during initialize(), then pass through.
002
003 @Copyright (c) 2011-2014 The Regents of the University of California.
004 All rights reserved.
005
006 Permission is hereby granted, without written agreement and without
007 license or royalty fees, to use, copy, modify, and distribute this
008 software and its documentation for any purpose, provided that the
009 above copyright notice and the following two paragraphs appear in all
010 copies of this software.
011
012 IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
013 FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
014 ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
015 THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
016 SUCH DAMAGE.
017
018 THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
019 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
020 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
021 PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
022 CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
023 ENHANCEMENTS, OR MODIFICATIONS.
024
025 PT_COPYRIGHT_VERSION 2
026 COPYRIGHTENDKEY
027 */
028
029package ptolemy.domains.sdf.lib;
030
031import ptolemy.data.Token;
032import ptolemy.kernel.CompositeEntity;
033import ptolemy.kernel.util.IllegalActionException;
034import ptolemy.kernel.util.NameDuplicationException;
035
036/**
037 *
038 * Record an initial token and then output that initial token during
039 * initialize(), then pass through.
040 *
041 * <p>The BootstrapSampleDelay works in the same way as a regular
042 * sample delay actor, but with the added feature that it records the
043 * initial value passed into it and will send that value out as the
044 * initial value on the next run.</p>
045 *
046 * <p>Frequently, sample delays are placed as dependency loop-breakers
047 * so that a model can run, but their default value of {0} is
048 * undesirable. This is commonly fixed by examining the first value
049 * passed into the sample delay and either setting the sample delay's
050 * starting value to this value; or recording that value in a
051 * parameter within the same container as the sample delay and setting
052 * the sample delay's starting value to reference the parameter.</p>
053 *
054 * <p>The Bootstrap sample delay internalizes the above solutions and
055 * furthermore needs no additional manual upkeep should starting
056 * values change.
057 *
058 * @author Jason Smith, Christopher Brooks
059 * @version $Id$
060 * @since Ptolemy II 10.0
061 * @Pt.ProposedRating Red (cxh)
062 * @Pt.AcceptedRating Red (cxh)
063 *
064 */
065public class BootstrapSampleDelay extends SampleDelay {
066    /** Construct an actor with the given container and name.
067     *  @param container The container.
068     *  @param name The name of this actor.
069     *  @exception IllegalActionException If the actor cannot be contained
070     *   by the proposed container.
071     *  @exception NameDuplicationException If the container already has an
072     *   actor with this name.
073     */
074    public BootstrapSampleDelay(final CompositeEntity container,
075            final String name)
076            throws IllegalActionException, NameDuplicationException {
077        super(container, name);
078    }
079
080    /** During the first iteration, read exactly one input token, update
081     *  the initialOutputs for a future run and send the token to the output.
082     *  @exception IllegalActionException If the get() or send() methods
083     *   of the ports throw it.
084     */
085    @Override
086    public void fire() throws IllegalActionException {
087        if (once) {
088            final Token message = input.get(0);
089            output.send(0, message);
090            initialOutputs.setExpression("{" + message.toString() + "}");
091            initialOutputs.setPersistent(true);
092            once = false;
093        } else {
094            super.fire();
095        }
096    }
097
098    /**
099     * Reset the state for the next run.
100     * @exception IllegalActionException If thrown by a base class.
101     */
102    @Override
103    public void wrapup() throws IllegalActionException {
104        super.wrapup();
105        once = true;
106    }
107
108    ///////////////////////////////////////////////////////////////////
109    ////                         private variables                 ////
110
111    private boolean once = true;
112}