001/* 002 * Copyright (c) 2005-2010 The Regents of the University of California. 003 * All rights reserved. 004 * 005 * '$Author: welker $' 006 * '$Date: 2010-05-06 05:21:26 +0000 (Thu, 06 May 2010) $' 007 * '$Revision: 24234 $' 008 * 009 * Permission is hereby granted, without written agreement and without 010 * license or royalty fees, to use, copy, modify, and distribute this 011 * software and its documentation for any purpose, provided that the above 012 * copyright notice and the following two paragraphs appear in all copies 013 * of this software. 014 * 015 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 016 * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 017 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 018 * THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 019 * SUCH DAMAGE. 020 * 021 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 022 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 023 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 024 * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 025 * CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 026 * ENHANCEMENTS, OR MODIFICATIONS. 027 * 028 */ 029 030package org.resurgence.actor; 031 032import ptolemy.actor.TypedAtomicActor; 033import ptolemy.actor.TypedIOPort; 034import ptolemy.actor.parameters.PortParameter; 035import ptolemy.data.BooleanToken; 036import ptolemy.data.IntToken; 037import ptolemy.data.Token; 038import ptolemy.data.expr.StringParameter; 039import ptolemy.data.type.BaseType; 040import ptolemy.kernel.CompositeEntity; 041import ptolemy.kernel.util.Attribute; 042import ptolemy.kernel.util.IllegalActionException; 043import ptolemy.kernel.util.NameDuplicationException; 044 045////////////////////////////////////////////////////////////////////////// 046//// BooleanAccumulator 047 048/** 049 * This actor reads a sequence of boolean values and writes one boolean value 050 * from their combination. 051 * 052 * @author Wibke Sudholt, University and ETH Zurich, November 2004 053 * @version $Id: BooleanAccumulator.java 24234 2010-05-06 05:21:26Z welker $ 054 */ 055public class BooleanAccumulator extends TypedAtomicActor { 056 057 /** 058 * Construct a BooleanAccumulator with the given container and name. 059 * 060 * @param container 061 * The container. 062 * @param name 063 * The name of this actor. 064 * @exception IllegalActionException 065 * If the entity cannot be contained by the proposed 066 * container. 067 * @exception NameDuplicationException 068 * If the container already has an actor with this name. 069 */ 070 public BooleanAccumulator(CompositeEntity container, String name) 071 throws NameDuplicationException, IllegalActionException { 072 super(container, name); 073 074 booleans = new TypedIOPort(this, "booleans", true, false); 075 booleans.setTypeEquals(BaseType.BOOLEAN); 076 077 combination = new TypedIOPort(this, "combination", false, true); 078 combination.setTypeEquals(BaseType.BOOLEAN); 079 080 operation = new StringParameter(this, "Logical operator"); 081 operation.addChoice("and"); 082 operation.addChoice("or"); 083 operation.setExpression("and"); 084 085 number = new PortParameter(this, "number"); 086 number.setExpression("1"); 087 } 088 089 // ///////////////////////////////////////////////////////////////// 090 // // ports and parameters //// 091 092 /** 093 * The input port, which contains the booleans. 094 */ 095 public TypedIOPort booleans = null; 096 /** 097 * The output port, which contains their combination. 098 */ 099 public TypedIOPort combination = null; 100 /** 101 * The parameter, which specifies the logical operator. 102 */ 103 public StringParameter operation = null; 104 /** 105 * The port parameter, which specifies the number of booleans in the 106 * sequence and defaults to 1. 107 */ 108 public PortParameter number = null; 109 110 // ///////////////////////////////////////////////////////////////// 111 // // public methods //// 112 113 /** 114 * Check the validity of the <i>number</i> parameter value, set the 115 * consumption rate of the input port, and, if necessary, invalidate the 116 * current schedule of the director. 117 * 118 * @param attribute 119 * The attribute that has changed. 120 * @exception IllegalActionException 121 * If the parameter is out of range. 122 */ 123 public void attributeChanged(Attribute attribute) 124 throws IllegalActionException { 125 if (attribute == number) { 126 _length = ((IntToken) number.getToken()).intValue(); 127 if (_length < 0) { 128 throw new IllegalActionException(this, "Invalid number: " 129 + _length); 130 } 131 } else { 132 super.attributeChanged(attribute); 133 } 134 } 135 136 /** 137 * Take the booleans and combine them. 138 * 139 * @exception IllegalActionException 140 * If there's no director or if the operation is wrong. 141 */ 142 public void fire() throws IllegalActionException { 143 super.fire(); 144 number.update(); 145 _length = ((IntToken) number.getToken()).intValue(); 146 _array = booleans.get(0, _length); 147 _logic = operation.stringValue(); 148 _sum = (BooleanToken) _array[0]; 149 if (_logic.equalsIgnoreCase("and")) { 150 for (int i = 1; i < _length; i++) { 151 _sum = _sum.and((BooleanToken) _array[i]); 152 } 153 } else if (_logic.equalsIgnoreCase("or")) { 154 for (int i = 1; i < _length; i++) { 155 _sum = _sum.or((BooleanToken) _array[i]); 156 } 157 } else { 158 _sum = null; 159 throw new IllegalActionException(this, "Invalid operation: " 160 + _logic); 161 } 162 combination.send(0, _sum); 163 } 164 165 /** 166 * Post fire the actor. Return false to indicate that the process has 167 * finished. If it returns true, the process will continue indefinitely. 168 */ 169 public boolean postfire() { 170 return false; 171 } 172 173 /** 174 * Prefire the actor. Return true if the input port has enough tokens for 175 * this actor to fire. The number of tokens required is determined by the 176 * value of the <i>number</i> parameter. 177 * 178 * @return boolean True if there are enough tokens at the input port for 179 * this actor to fire. 180 * @exception IllegalActionException 181 * If the hasToken() query to the input port throws it. 182 */ 183 public boolean prefire() throws IllegalActionException { 184 _length = ((IntToken) number.getToken()).intValue(); 185 if (!booleans.hasToken(0, _length)) { 186 if (_debugging) { 187 _debug("Called prefire(), which returns false."); 188 } 189 return false; 190 } else { 191 return super.prefire(); 192 } 193 } 194 195 // ///////////////////////////////////////////////////////////////// 196 // // protected members //// 197 198 // ///////////////////////////////////////////////////////////////// 199 // // private methods //// 200 201 // ///////////////////////////////////////////////////////////////// 202 // // private members //// 203 204 private int _length; 205 private Token[] _array; 206 private String _logic; 207 private BooleanToken _sum; 208}