001/* 002 @Copyright (c) 1998-2014 The Regents of the University of California. 003 All rights reserved. 004 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 008 above copyright notice and the following two paragraphs appear in all 009 copies 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.sdf.kernel.test; 029 030import ptolemy.actor.TypedAtomicActor; 031import ptolemy.actor.TypedIOPort; 032import ptolemy.data.IntToken; 033import ptolemy.data.expr.Parameter; 034import ptolemy.data.type.BaseType; 035import ptolemy.kernel.CompositeEntity; 036import ptolemy.kernel.util.IllegalActionException; 037import ptolemy.kernel.util.NameDuplicationException; 038 039/** 040 * This actor copies one token from its input to its output when fired. 041 * 042 * @author Steve Neuendorffer 043 * @version $Id$ 044 * @since Ptolemy II 0.4 045 * @Pt.ProposedRating Red 046 * @Pt.AcceptedRating Red 047 */ 048public class SDFTestDelay extends TypedAtomicActor { 049 /* 050 * Object constructor. This creates an object of class SDFTestDelay. 051 * The object will have a name given by the 'name' argument and will 052 * be contained within the composite actor given by the 'container' 053 * argument. This method throws two exceptions, which are error 054 * conditions that the method (or one of the methods it calls) has 055 * detected (notice the @exception tag). 056 */ 057 058 /** 059 * Create an SDFTestDelay actor in the given container with the given name. 060 * This actor copies one token from the input port named "input" to the 061 * output port named "output" when fired. 062 * @exception IllegalActionException If the contained methods throw it 063 * @exception NameDuplicationException If the contained methods throw it 064 */ 065 public SDFTestDelay(CompositeEntity container, String name) 066 throws IllegalActionException, NameDuplicationException { 067 /* This starts out by calling TypedAtomicActor's constructor. 068 * allows us to add some extra code specific to this actor, in 069 * addition to the regular initializer in TypedAtomicActor. 070 */ 071 super(container, name); 072 073 /* This construct is called a "try-catch block". It is used to 074 * detect exceptions that occurred during the execution of some 075 * other code. In this case, we detect IllegalActionException and 076 * print a reasonable error message. This is convenient under 077 * some environments which can destroy the debugging information from 078 * java 079 */ 080 /* Create a new input port */ 081 input = new TypedIOPort(this, "input", true, false); 082 083 /* Set the Consumption rate on the port. A good way to think of 084 * this is that you are making a contract with the Ptolemy system. 085 * If you always consume one token from this port when fired, 086 * then Ptolemy will always guarantee that there will be a token 087 * ready when you are fired. 088 */ 089 input_tokenConsumptionRate = new Parameter(input, 090 "tokenConsumptionRate", new IntToken(1)); 091 092 /* The getPort method (in ptolemy.kernel.Entity) finds a port by 093 * name. It returns a Port object, but all the ports in the 094 * actor package are of type TypedIOPort, 095 * which extends Port. So, we 096 * have to upcast the return value to the appropriate type. 097 * The setDeclaredType calls use the type system to define what 098 * types of tokens are valid for this actor. 099 */ 100 input.setTypeEquals(BaseType.INT); 101 102 /* Similarly for the output port */ 103 output = new TypedIOPort(this, "output", false, true); 104 output_tokenProductionRate = new Parameter(output, 105 "tokenProductionRate", new IntToken(1)); 106 107 output.setTypeEquals(BaseType.INT); 108 } 109 110 public TypedIOPort input; 111 112 public TypedIOPort output; 113 114 public Parameter input_tokenConsumptionRate; 115 116 public Parameter output_tokenProductionRate; 117 118 /* Notice that constructors start the file. Public methods should follow, 119 * in alphabetical order, followed by protected and private methods. 120 * Instance variables come at the end of the class. 121 */ 122 /* The fire method is where the bulk of the action takes place. In 123 * SDF, fire will be called exactly once between prefire and postfire. 124 * In this class, we get an input port, print its value, and put the 125 * same token back on the output port. 126 */ 127 128 /** This fires an actor and may be invoked several times between 129 * invocations of prefire() and postfire(). It may produce output 130 * data. Typically, the fire() method performs the computation associated 131 * with an actor. 132 * 133 * @exception IllegalActionException If firing is not permitted. 134 */ 135 @Override 136 public void fire() throws IllegalActionException { 137 /* First we declare a variable that is a Token that can carry 138 * integer data (ptolemy.data.IntToken). 139 */ 140 IntToken message; 141 142 /* Figure out how many tokens should be copied from the input to the 143 * output. 144 */ 145 int tokens = ((IntToken) input_tokenConsumptionRate.getToken()) 146 .intValue(); 147 148 if (((IntToken) output_tokenProductionRate.getToken()) 149 .intValue() != tokens) { 150 throw new IllegalActionException( 151 "SDFTestDelay: Rates on input port and output port " 152 + "must match!"); 153 } 154 155 int i; 156 157 for (i = 0; i < tokens; i++) { 158 /* now that we have the port, we can get a token from it. 159 * The argument to get is known as the channel. 160 * The channel must be 161 * zero, since there can only be one IORelation connected to this 162 * input. Multiple channels are useful with Multiports, which 163 * allow more than one relation to be connected to a port. 164 */ 165 message = (IntToken) input.get(0); 166 167 /* After looking at the token, pass it along to the next actor 168 */ 169 output.send(0, message); 170 } 171 } 172 173 /* Postfire is the last step in an iteration. This actor returns 174 * true, since it places no limit on how execution may proceed. In 175 * practice this method can be used to define a stopping condition, 176 * where execution will stop once some condition has been met. 177 */ 178 179 /** This method should be invoked once per iteration, after the last 180 * invocation of fire() in that iteration. It may produce output data. 181 * It returns true if the execution can proceed into the next iteration. 182 * This method typically wraps up an iteration, which may involve 183 * updating local state. In an opaque, non-atomic entity, it may also 184 * transfer output data. 185 * 186 * @return True if the execution can continue. 187 * @exception IllegalActionException If postfiring is not permitted. 188 */ 189 @Override 190 public boolean postfire() throws IllegalActionException { 191 return true; 192 } 193 194 /* Prefire is the first step in every iteration. This method returns 195 * true if the actor can perform useful work by being fired. For 196 * example, an actor could return false if it was waiting for a certain 197 * amount of data for a calculation, but that amount of data was not 198 * yet present. Most actors under SDF will just return true, since they 199 * have made a contract with the SDF domain to be fired when enough data 200 * is present. 201 */ 202 203 /** This method should be invoked once per iteration, before the first 204 * invocation of fire() in that iteration. It returns true if the 205 * iteration can proceed (the fire() method can be invoked). Thus 206 * this method will typically check preconditions for an iteration, if 207 * there are any. In an opaque, non-atomic entity, 208 * it may move data into an inner subsystem. 209 * 210 * @return True if the iteration can proceed. 211 * @exception IllegalActionException If prefiring is not permitted. 212 */ 213 @Override 214 public boolean prefire() throws IllegalActionException { 215 return true; 216 } 217 218 /* When this method is called, the actor must do everything in its power 219 * to immediately stop whatever it is doing. This is primarily 220 * called under 221 * two circumstances. The first is a user initiated break, such as 222 * via CTRL-C. The second is if an error occurs during wrapup() that 223 * cannot be recovered from. 224 */ 225 226 /** This method is invoked to immediately terminate any execution 227 * within an actor. 228 */ 229 @Override 230 public void terminate() { 231 return; 232 } 233 234 /* This method is called at the end of an execution, to allow the 235 * actor to cleanup after itself. Often this will involve destroying 236 * graphical windows, flushing buffers, etc. This method will also get 237 * called under most abnormal termination conditions. 238 * This actor has nothing to do here. 239 */ 240 241 /** This method should be invoked exactly once per execution 242 * of an application. None of the other action methods should be 243 * be invoked after it. It finalizes an execution, typically closing 244 * files, displaying final results, etc. 245 * 246 * @exception IllegalActionException If wrapup is not permitted. 247 */ 248 @Override 249 public void wrapup() throws IllegalActionException { 250 return; 251 } 252}