001/* An actor that outputs the previous event when it receives an event. 002 003 Copyright (c) 1998-2018 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 java.util.Set; 031 032import ptolemy.data.Token; 033import ptolemy.data.expr.Parameter; 034import ptolemy.graph.Inequality; 035import ptolemy.kernel.CompositeEntity; 036import ptolemy.kernel.util.IllegalActionException; 037import ptolemy.kernel.util.InternalErrorException; 038import ptolemy.kernel.util.NameDuplicationException; 039 040/////////////////////////////////////////////////////////////////// 041//// Previous 042 043/** 044 On each iteration, this actor produces the token received on the previous 045 iteration. On the first iteration, it produces the token given by the 046 <i>initialValue</i> parameter, if such a value has been set. 047 <p> 048 Although it might be tempting to try, this actor is not very useful 049 for breaking precedences in a feedback loop in DE, the way the 050 TimedDelay actor in DE or the SampleDelay actor in SDF do. 051 Since it does not trigger until there is an input, it will not 052 actually break the precedences in a feedback loop. 053 <p> 054 The output data type is constrained to be at least as general 055 as both the input and the <i>initialValue</i> parameter. 056 057 @see ptolemy.domains.de.lib.TimedDelay 058 @see ptolemy.domains.sdf.lib.SampleDelay 059 060 @author Edward A. Lee 061 @version $Id$ 062 @since Ptolemy II 2.0 063 @Pt.ProposedRating Red (eal) 064 @Pt.AcceptedRating Red (cxh) 065 */ 066public class Previous extends DETransformer { 067 /** Construct an actor with the specified container and name. 068 * @param container The composite actor to contain this one. 069 * @param name The name of this actor. 070 * @exception IllegalActionException If the entity cannot be contained 071 * by the proposed container. 072 * @exception NameDuplicationException If the container already has an 073 * actor with this name. 074 */ 075 public Previous(CompositeEntity container, String name) 076 throws NameDuplicationException, IllegalActionException { 077 super(container, name); 078 initialValue = new Parameter(this, "initialValue"); 079 } 080 081 /////////////////////////////////////////////////////////////////// 082 //// ports and parameters //// 083 084 /** The initial output value. If this is set, it specifies the 085 * first output value produced when the first input arrives. 086 * If it is not set, then no output is produced on the first 087 * firing. 088 */ 089 public Parameter initialValue; 090 091 /////////////////////////////////////////////////////////////////// 092 //// public methods //// 093 094 /** If there is a previous token, then produce it on the output, 095 * and then read the input and record it for the next firing. 096 * @exception IllegalActionException If getting token from input or 097 * sending token to output throws it. 098 */ 099 @Override 100 public void fire() throws IllegalActionException { 101 super.fire(); 102 103 if (_previous != null) { 104 output.send(0, _previous); 105 } 106 107 if (input.hasToken(0)) { 108 _tempPrevious = input.get(0); 109 } 110 } 111 112 /** Initialize so that the initial token will be produced. 113 * @exception IllegalActionException If the super class throws it 114 * or can not get a valid token from the initializeValue parameter. 115 */ 116 @Override 117 public void initialize() throws IllegalActionException { 118 super.initialize(); 119 120 // Note that this might be null, if it has not been set. 121 _previous = initialValue.getToken(); 122 _tempPrevious = null; 123 } 124 125 /** Update the state of the actor. 126 * @exception IllegalActionException If the base class throws it. 127 */ 128 @Override 129 public boolean postfire() throws IllegalActionException { 130 _previous = _tempPrevious; 131 _tempPrevious = null; 132 return super.postfire(); 133 } 134 135 /** Override the method in the base class so that the type 136 * constraint for the <i>initialValue</i> parameter will be set 137 * if it contains a value. 138 * @return a list of Inequality objects. 139 * @see ptolemy.graph.Inequality 140 */ 141 /* public Set<Inequality> typeConstraints() { 142 Set<Inequality> typeConstraints = super.typeConstraints(); 143 144 try { 145 if (initialValue.getToken() != null) { 146 Inequality ineq = new Inequality(initialValue.getTypeTerm(), 147 output.getTypeTerm()); 148 typeConstraints.add(ineq); 149 } 150 151 Inequality ineq2 = new Inequality(input.getTypeTerm(), 152 output.getTypeTerm()); 153 typeConstraints.add(ineq2); 154 } catch (IllegalActionException ex) { 155 // Errors in the initialValue parameter should 156 // already have been caught in getAttribute() method 157 // of the base class. 158 throw new InternalErrorException("Bad initialValue value!"); 159 } 160 161 return typeConstraints; 162 } 163 */ 164 165 /** 166 * Adds to the set of inequalities returned by the overridden method 167 * a constraint that requires the initial value to be less than or 168 * equal to the type of the output. 169 */ 170 @Override 171 public Set<Inequality> _containedTypeConstraints() { 172 Set<Inequality> result = super._containedTypeConstraints(); 173 try { 174 // type of initialValue <= type of output 175 if (initialValue.getToken() != null) { 176 result.add(new Inequality(initialValue.getTypeTerm(), 177 output.getTypeTerm())); 178 } 179 } catch (IllegalActionException ex) { 180 // Errors in the initialValue parameter should already 181 // have been caught in getAttribute() method of the base 182 // class. 183 throw new InternalErrorException("Bad initialValue value!"); 184 } 185 186 return result; 187 } 188 189 /** Reset the state variables. 190 * @exception IllegalActionException If the base class throws it. 191 */ 192 @Override 193 public void wrapup() throws IllegalActionException { 194 super.wrapup(); 195 _tempPrevious = null; 196 _previous = null; 197 } 198 199 /////////////////////////////////////////////////////////////////// 200 //// private variables //// 201 // Previous input. 202 private Token _previous; 203 204 // Temporary previous input. 205 private Token _tempPrevious; 206}