001/* Output an initial token during initialize(), then pass through. 002 003 @Copyright (c) 1998-2015 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 */ 028package ptolemy.domains.sdf.lib; 029 030import java.util.HashSet; 031import java.util.Set; 032 033import ptolemy.data.ArrayToken; 034import ptolemy.data.Token; 035import ptolemy.data.expr.Parameter; 036import ptolemy.data.type.ArrayType; 037import ptolemy.graph.Inequality; 038import ptolemy.kernel.CompositeEntity; 039import ptolemy.kernel.util.Attribute; 040import ptolemy.kernel.util.IllegalActionException; 041import ptolemy.kernel.util.InternalErrorException; 042import ptolemy.kernel.util.NameDuplicationException; 043import ptolemy.kernel.util.Workspace; 044 045/////////////////////////////////////////////////////////////////// 046//// SampleDelay 047 048/** 049 This actor outputs a set of initial tokens during the initialize() 050 method, and subsequently passes the input tokens to the output. 051 It is used to break dependency cycles in directed loops of SDF models. 052 This actor declares an initial production parameter in its output port 053 that is used by the SDF scheduler to properly schedule the model, and 054 the initial outputs permit the computation to get started. The 055 default value for the <i>initialOutputs</i> parameter causes a 056 single integer token with value zero to be produced in 057 initialize(). 058 059 @author Steve Neuendorffer, Edward A. Lee 060 @version $Id$ 061 @since Ptolemy II 1.0 062 @Pt.ProposedRating Yellow (eal) 063 @Pt.AcceptedRating Yellow (neuendor) 064 */ 065public class SampleDelay extends SDFTransformer { 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 SampleDelay(CompositeEntity container, String name) 075 throws IllegalActionException, NameDuplicationException { 076 super(container, name); 077 078 initialOutputs = new Parameter(this, "initialOutputs"); 079 initialOutputs.setExpression("{0}"); 080 initialOutputs.setTypeAtLeast(ArrayType.ARRAY_BOTTOM); 081 082 output_tokenInitProduction.setExpression("initialOutputs.length()"); 083 084 // set type constraints. 085 output.setTypeAtLeast(ArrayType.elementType(initialOutputs)); 086 output.setTypeAtLeast(input); 087 } 088 089 /////////////////////////////////////////////////////////////////// 090 //// ports and parameters //// 091 092 /** The values that will be produced in the initialize method. 093 * This parameter must contain an ArrayToken. 094 * It defaults to contain a single zero-valued integer token. 095 * Changes to this parameter after initialize() has been invoked 096 * are ignored until the next execution of the model. 097 */ 098 public Parameter initialOutputs; 099 100 /////////////////////////////////////////////////////////////////// 101 //// public methods //// 102 103 /** Override the base class to allow type changes on 104 * <i>initialOutputs</i>. 105 * @exception IllegalActionException If type changes are not 106 * allowed on the specified attribute. 107 */ 108 @Override 109 public void attributeTypeChanged(Attribute attribute) 110 throws IllegalActionException { 111 if (attribute != initialOutputs) { 112 super.attributeTypeChanged(attribute); 113 } else { 114 _typesValid = false; // Set flag to invalidate cached type constraints 115 } 116 } 117 118 /** Clone the actor into the specified workspace. This calls the 119 * base class and then resets the type constraints. 120 * @param workspace The workspace for the new object. 121 * @return A new actor. 122 * @exception CloneNotSupportedException If a derived class contains 123 * an attribute that cannot be cloned. 124 */ 125 @Override 126 public Object clone(Workspace workspace) throws CloneNotSupportedException { 127 SampleDelay newObject = (SampleDelay) super.clone(workspace); 128 129 // set the type constraints 130 try { 131 newObject.output.setTypeAtLeast( 132 ArrayType.elementType(newObject.initialOutputs)); 133 } catch (IllegalActionException e) { 134 throw new InternalErrorException(e); 135 } 136 newObject.output.setTypeAtLeast(newObject.input); 137 138 return newObject; 139 } 140 141 /** Read exactly one input token and send it to the output. 142 * @exception IllegalActionException If the get() or send() methods 143 * of the ports throw it. 144 */ 145 @Override 146 public void fire() throws IllegalActionException { 147 super.fire(); 148 149 Token message = input.get(0); 150 output.send(0, message); 151 } 152 153 /** Produce on the output a sequence tokens, one for each element 154 * of the <i>initialOutputs</i> parameter (which is an array). 155 * @exception IllegalActionException If the send() method 156 * of the output port throws it. 157 */ 158 @Override 159 public void initialize() throws IllegalActionException { 160 super.initialize(); 161 output.send(0, _outputsArray.arrayValue(), _outputsArray.length()); 162 } 163 164 /** Check that the <i>initialOutputs</i> parameter contains an 165 * array token. Set the <i>tokenInitProduction</i> parameter of 166 * the output port to the length of the value of <i>initialOutputs</i> 167 * Note that the value and type <i>initialOutputs</i> are observed 168 * only here. If the value or type change during execution 169 * of the model, the change will not take effect until the next 170 * execution. 171 * 172 * @exception IllegalActionException If <i>initialOutputs</i> parameter 173 * is invalid, or if the base class throws it. 174 */ 175 @Override 176 public void preinitialize() throws IllegalActionException { 177 super.preinitialize(); 178 179 Token contents = initialOutputs.getToken(); 180 181 if (!(contents instanceof ArrayToken)) { 182 throw new IllegalActionException(this, "InitialOutputs was " 183 + contents + " which is not an" + " array token."); 184 } 185 186 _outputsArray = (ArrayToken) contents; 187 188 getDirector().invalidateResolvedTypes(); 189 } 190 191 /** Sets up backward type constraint that sets output ≤ input 192 * if backward type inference is enabled. 193 * @return A set of Inequalities. 194 */ 195 @Override 196 protected Set<Inequality> _customTypeConstraints() { 197 Set<Inequality> result = new HashSet<Inequality>(); 198 if (isBackwardTypeInferenceEnabled()) { 199 result.add( 200 new Inequality(output.getTypeTerm(), input.getTypeTerm())); 201 } 202 return result; 203 } 204 205 /////////////////////////////////////////////////////////////////// 206 //// private variables //// 207 // The outputs to be produced in the initialize method. 208 private ArrayToken _outputsArray; 209}