001/* Append arrays together to form a larger array. 002 003 Copyright (c) 1998-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.ArrayToken; 031import ptolemy.data.type.ArrayType; 032import ptolemy.data.type.Type; 033import ptolemy.kernel.CompositeEntity; 034import ptolemy.kernel.util.IllegalActionException; 035import ptolemy.kernel.util.NameDuplicationException; 036import ptolemy.kernel.util.Workspace; 037 038/////////////////////////////////////////////////////////////////// 039//// ArrayAccumulate 040 041/** 042 An actor that accumulates input arrays into a growing array that 043 includes the contents of all input arrays. Upon firing, this actor reads 044 an input array, appends it to the accumulating array, and outputs 045 the new array. The length of the output array grows by the size 046 of the input array on each firing. 047 048 @author Edward A. Lee 049 @version $Id$ 050 @since Ptolemy II 10.0 051 @Pt.ProposedRating Yellow (cxh) 052 @Pt.AcceptedRating Red (eal) 053 */ 054public class ArrayAccumulate extends Transformer { 055 /** Construct an actor with the given container and name. 056 * @param container The container. 057 * @param name The name of this actor. 058 * @exception IllegalActionException If the actor cannot be contained 059 * by the proposed container. 060 * @exception NameDuplicationException If the container already has an 061 * actor with this name. 062 */ 063 public ArrayAccumulate(CompositeEntity container, String name) 064 throws NameDuplicationException, IllegalActionException { 065 super(container, name); 066 // Set type constraints. 067 input.setTypeAtLeast(ArrayType.ARRAY_BOTTOM); 068 output.setTypeAtLeast(input); 069 output.setTypeAtLeast(ArrayType.ARRAY_UNSIZED_BOTTOM); 070 } 071 072 /////////////////////////////////////////////////////////////////// 073 //// public methods //// 074 075 /** Clone the actor into the specified workspace. This calls the 076 * base class and then creates new ports and parameters. 077 * @param workspace The workspace for the new object. 078 * @return A new actor. 079 * @exception CloneNotSupportedException If a derived class contains 080 * an attribute that cannot be cloned. 081 */ 082 @Override 083 public Object clone(Workspace workspace) throws CloneNotSupportedException { 084 ArrayAccumulate newObject = (ArrayAccumulate) super.clone(workspace); 085 086 // Set the type constraints. 087 newObject.input.setTypeAtLeast(ArrayType.ARRAY_BOTTOM); 088 newObject.output.setTypeAtLeast(newObject.input); 089 newObject.output.setTypeAtLeast(ArrayType.ARRAY_UNSIZED_BOTTOM); 090 newObject._arrays = new ArrayToken[2]; 091 return newObject; 092 } 093 094 /** Consume at most one ArrayToken from the input, append it 095 * to the accumulating token, and produce the accumulated result 096 * on the output. 097 * @exception IllegalActionException If a runtime type conflict occurs, 098 * or if there are no input channels. 099 */ 100 @Override 101 public void fire() throws IllegalActionException { 102 super.fire(); 103 // NOTE: Do not use System.arraycopy here because the 104 // arrays being appended may be subclasses of ArrayToken, 105 // so values have to be accessed via the getElement() method, 106 // which is overridden in the subclasses. Use the append() 107 // method of ArrayToken instead. 108 if (input.hasToken(0)) { 109 ArrayToken token = (ArrayToken) input.get(0); 110 if (_accumulating == null) { 111 _tentativeAccumulating = token; 112 output.send(0, token); 113 } else { 114 _arrays[0] = _accumulating; 115 _arrays[1] = token; 116 _tentativeAccumulating = ArrayToken.append(_arrays); 117 output.send(0, ArrayToken.append(_arrays)); 118 } 119 } else { 120 Type elementType = ((ArrayType) output.getType()).getElementType(); 121 output.send(0, new ArrayToken(elementType)); 122 } 123 } 124 125 /** Initialize this actor to have an empty accumulating array. 126 * @exception IllegalActionException If the superclass throws it. 127 */ 128 @Override 129 public void initialize() throws IllegalActionException { 130 super.initialize(); 131 _accumulating = null; 132 _tentativeAccumulating = null; 133 } 134 135 /** Record the accumulating array and return true. 136 * @return True. 137 * @exception IllegalActionException If the superclass throws it. 138 */ 139 @Override 140 public boolean postfire() throws IllegalActionException { 141 boolean result = super.postfire(); 142 _accumulating = _tentativeAccumulating; 143 return result; 144 } 145 146 /////////////////////////////////////////////////////////////////// 147 //// private variables //// 148 149 /** The accumulating array. */ 150 private ArrayToken _accumulating; 151 152 /** An array to use (repeatedly) to append arrays. */ 153 private ArrayToken[] _arrays = new ArrayToken[2]; 154 155 /** The tentative accumulating array. */ 156 private ArrayToken _tentativeAccumulating; 157}