001/* Base class for source actors that will only a fire a limited number of times. 002 003 Copyright (c) 2007-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.actor.lib; 029 030import ptolemy.data.IntToken; 031import ptolemy.data.expr.Parameter; 032import ptolemy.data.type.BaseType; 033import ptolemy.kernel.CompositeEntity; 034import ptolemy.kernel.util.Attribute; 035import ptolemy.kernel.util.IllegalActionException; 036import ptolemy.kernel.util.NameDuplicationException; 037import ptolemy.kernel.util.Settable; 038 039/////////////////////////////////////////////////////////////////// 040//// LimitedFiringSource 041 042/** 043 Base class for source actors that will only fire a limited number of 044 times. This actor has a parameter, 045 <i>firingCountLimit</i>, that optionally limits the number of iterations 046 for which the actor is fired. If this number is <i>n</i> > 0, then 047 the <i>n</i>-th invocation of postfire() returns false, which indicates 048 to the scheduler that it should stop invocations of this actor. 049 The default value of <i>firingCountLimit</i> 050 is NONE, which results in postfire always returning 051 true. Derived classes must call super.postfire() for this mechanism to 052 work. 053 054 @author Edward A. Lee 055 @version $Id$ 056 @since Ptolemy II 6.1 057 @Pt.ProposedRating Green (eal) 058 @Pt.AcceptedRating Green (bilung) 059 */ 060public class LimitedFiringSource extends Source { 061 /** Construct an actor with the given container and name. 062 * The <i>firingCountLimit</i> parameter is also constructed. 063 * @param container The container. 064 * @param name The name of this actor. 065 * @exception IllegalActionException If the actor cannot be contained 066 * by the proposed container. 067 * @exception NameDuplicationException If the container already has an 068 * actor with this name. 069 */ 070 public LimitedFiringSource(CompositeEntity container, String name) 071 throws NameDuplicationException, IllegalActionException { 072 super(container, name); 073 074 firingCountLimit = new Parameter(this, "firingCountLimit"); 075 firingCountLimit.setExpression("NONE"); 076 firingCountLimit.setTypeEquals(BaseType.INT); 077 078 Parameter NONE = new Parameter(this, "NONE"); 079 080 // Don't setExpression here, it breaks Copernicus, use setToken(). 081 // NONE.setExpression("0"); 082 NONE.setToken(IntToken.ZERO); 083 084 // Don't setTypeEquals here, it breaks Copernicus. 085 //NONE.setTypeEquals(BaseType.INT); 086 NONE.setVisibility(Settable.EXPERT); 087 } 088 089 /////////////////////////////////////////////////////////////////// 090 //// ports and parameters //// 091 092 /** If a positive integer, then the number of iterations before the 093 * actor indicates to the scheduler that it is finished by returning 094 * false in its postfire() method. 095 */ 096 public Parameter firingCountLimit; 097 098 /////////////////////////////////////////////////////////////////// 099 //// public methods //// 100 101 /** Override the base class to determine which attribute is being 102 * specified. 103 * @param attribute The attribute that changed. 104 * @exception IllegalActionException If the function is not recognized. 105 */ 106 @Override 107 public void attributeChanged(Attribute attribute) 108 throws IllegalActionException { 109 if (attribute == firingCountLimit) { 110 _firingCountLimit = ((IntToken) firingCountLimit.getToken()) 111 .intValue(); 112 } 113 } 114 115 /** Initialize the iteration counter. A derived class must call 116 * this method in its initialize() method or the <i>firingCountLimit</i> 117 * feature will not work. 118 * @exception IllegalActionException If the parent class throws it, 119 * which could occur if, for example, the director will not accept 120 * sequence actors. 121 */ 122 @Override 123 public void initialize() throws IllegalActionException { 124 super.initialize(); 125 _iterationCount = 0; 126 } 127 128 /** Increment the iteration counter, and if it equals the 129 * value of the <i>firingCountLimit</i> parameter, return false. 130 * Otherwise, return true. Derived classes should call this 131 * at the end of their postfire() method and return its returned 132 * value. 133 * @exception IllegalActionException If firingCountLimit has 134 * an invalid expression. 135 */ 136 @Override 137 public boolean postfire() throws IllegalActionException { 138 if (_firingCountLimit != 0) { 139 _iterationCount++; 140 141 if (_iterationCount == _firingCountLimit) { 142 return false; 143 } 144 } 145 146 return super.postfire(); 147 } 148 149 /////////////////////////////////////////////////////////////////// 150 //// protected variables //// 151 152 /** This is the value in parameter 153 * firingCountLimit. 154 * It may be convenient for derived classes to read this 155 * variable in the iterate() method. 156 */ 157 protected int _firingCountLimit; 158 159 /** The current number of elapsed iterations. 160 * It may be convenient for derived classes to read/set this 161 * variable in the iterate() method. 162 */ 163 protected int _iterationCount = 0; 164}