001/* An actor to display 10x10 LEDs 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 OR RESEARCH IN MOTION 012 LIMITED BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, 013 INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS 014 SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA 015 OR RESEARCH IN MOTION LIMITED HAVE BEEN ADVISED OF THE POSSIBILITY OF 016 SUCH DAMAGE. 017 018 THE UNIVERSITY OF CALIFORNIA AND RESEARCH IN MOTION LIMITED 019 SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 020 THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 021 PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" 022 BASIS, AND THE UNIVERSITY OF CALIFORNIA AND RESEARCH IN MOTION 023 LIMITED HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 024 ENHANCEMENTS, OR MODIFICATIONS. 025 026 PT_COPYRIGHT_VERSION_2 027 COPYRIGHTENDKEY 028 029 */ 030package ptolemy.vergil.actor.lib; 031 032import ptolemy.actor.TypedAtomicActor; 033import ptolemy.actor.TypedIOPort; 034import ptolemy.data.BooleanToken; 035import ptolemy.data.IntToken; 036import ptolemy.data.expr.Parameter; 037import ptolemy.data.type.BaseType; 038import ptolemy.kernel.CompositeEntity; 039import ptolemy.kernel.util.Attribute; 040import ptolemy.kernel.util.IllegalActionException; 041import ptolemy.kernel.util.Location; 042import ptolemy.kernel.util.NameDuplicationException; 043import ptolemy.kernel.util.Workspace; 044import ptolemy.vergil.icon.EditorIcon; 045import ptolemy.vergil.kernel.attributes.RectangleAttribute; 046 047/////////////////////////////////////////////////////////////////// 048//// LEDMatrix 049 050/** An actor that displays an array of LEDs. The array display only 051 one color, red. This actor has two inputs, row and column which 052 are integers that identify the row and column of the LED to possibly be 053 illuminated and a control input which determines whether the 054 LED is illuminated or not. 055 056 @author Christopher Brooks, Based on MicaLeds byElaine Cheong 057 @version $Id$ 058 @since Ptolemy II 8.0 059 @Pt.ProposedRating Red (celaine) 060 @Pt.AcceptedRating Red (celaine) 061 */ 062public class LEDMatrix extends TypedAtomicActor { 063 064 /** Construct an actor with the given container and name. 065 * @param container The container. 066 * @param name The name of this actor. 067 * @exception IllegalActionException If the actor cannot be contained 068 * by the proposed container. 069 * @exception NameDuplicationException If the container already has an 070 * actor with this name. 071 */ 072 public LEDMatrix(CompositeEntity container, String name) 073 throws NameDuplicationException, IllegalActionException { 074 super(container, name); 075 076 // Create the input ports. 077 column = new TypedIOPort(this, "column", true, false); 078 column.setTypeEquals(BaseType.INT); 079 row = new TypedIOPort(this, "row", true, false); 080 row.setTypeEquals(BaseType.INT); 081 082 control = new TypedIOPort(this, "control", true, false); 083 control.setTypeEquals(BaseType.BOOLEAN); 084 085 // The number of columns 086 columns = new Parameter(this, "columns"); 087 columns.setExpression("10"); 088 rows = new Parameter(this, "rows"); 089 rows.setExpression("10"); 090 091 // Create the LED Array icon. 092 _ledArray_icon = new EditorIcon(this, "_icon"); 093 _init(); 094 } 095 096 /////////////////////////////////////////////////////////////////// 097 //// ports and parameters //// 098 099 /** The column of the LED to be illuminated. The columns are 0-based, 100 * to address the first column, the value of this port should be 0. 101 * The token type is integer. 102 */ 103 public TypedIOPort column; 104 105 /** True if the LED is to be illuminated. The token type is Boolean. 106 */ 107 public TypedIOPort control; 108 109 /** The row of the LED to be illuminated. The columns are 0-based, 110 * to address the first row, the value of this port should be 0. 111 * The token type is integer. 112 */ 113 public TypedIOPort row; 114 115 /** The number of columns. The number must be a positive integer, 116 * the initial default value is 10. 117 */ 118 public Parameter columns; 119 120 /** The number of rows. The number must be a positive integer, 121 * the initial default value is 10. 122 */ 123 public Parameter rows; 124 125 /////////////////////////////////////////////////////////////////// 126 //// public methods //// 127 128 /** Clone this actor into the specified workspace. 129 * Override the base class to ensure that private variables are 130 * reset. 131 * @param workspace The workspace for the cloned object. 132 * @return A new instance of VisualModelReference. 133 * @exception CloneNotSupportedException If a derived class contains 134 * an attribute that cannot be cloned. 135 */ 136 @Override 137 public Object clone(Workspace workspace) throws CloneNotSupportedException { 138 LEDMatrix newActor = (LEDMatrix) super.clone(workspace); 139 try { 140 int columnsValue = ((IntToken) newActor.columns.getToken()) 141 .intValue(); 142 int rowsValue = ((IntToken) newActor.rows.getToken()).intValue(); 143 newActor._leds = new RectangleAttribute[rowsValue][columnsValue]; 144 Attribute attribute = newActor.getAttribute("_icon"); 145 if (attribute != null) { 146 attribute.setContainer(null); 147 } 148 newActor._ledArray_icon = new EditorIcon(newActor, "_icon"); 149 } catch (Throwable ex) { 150 throw new CloneNotSupportedException( 151 getFullName() + ": Failed to get rows or columns: " + ex); 152 } 153 return newActor; 154 } 155 156 /** If the argument is <i>rows</i> or <i>columns</i>, then update 157 * the size of the array. 158 * @param attribute The attribute that changed. 159 * @exception IllegalActionException If the offsets array is not 160 * nondecreasing and nonnegative. 161 */ 162 // FIXME: get attribute changed working by moving init() to initialize()? 163 // public void attributeChanged(Attribute attribute) 164 // throws IllegalActionException { 165 // if (attribute == rows || attribute == columns) { 166 // try { 167 // _init(); 168 // } catch (NameDuplicationException ex) { 169 // throw new IllegalActionException(this, ex, "Failed to initialize."); 170 // } 171 // } else { 172 // super.attributeChanged(attribute); 173 // } 174 // } 175 /** Read a token from the row and column ports and illuminate that 176 * led until the next fire. 177 * @exception IllegalActionException If the row or column ports 178 * cannot be read. 179 */ 180 @Override 181 public void fire() throws IllegalActionException { 182 super.fire(); 183 if (row.hasToken(0) && column.hasToken(0) && control.hasToken(0)) { 184 int rowValue = ((IntToken) row.get(0)).intValue(); 185 int columnValue = ((IntToken) column.get(0)).intValue(); 186 boolean controlValue = ((BooleanToken) control.get(0)) 187 .booleanValue(); 188 if (controlValue) { 189 _leds[rowValue][columnValue].fillColor 190 .setToken("{1.0, 0.0, 0.0, 1.0}"); 191 } else { 192 _leds[rowValue][columnValue].fillColor 193 .setToken("{0.0, 0.0, 0.0, 1.0}"); 194 } 195 } 196 } 197 198 @Override 199 public void preinitialize() throws IllegalActionException { 200 super.preinitialize(); 201 202 int columnsValue = ((IntToken) columns.getToken()).intValue(); 203 int rowsValue = ((IntToken) rows.getToken()).intValue(); 204 for (int x = 0; x < rowsValue; x++) { 205 for (int y = 0; y < columnsValue; y++) { 206 _leds[x][y].fillColor.setToken("{0.0, 0.0, 0.0, 1.0}"); 207 } 208 } 209 } 210 211 /////////////////////////////////////////////////////////////////// 212 //// private methods //// 213 214 /** Create the LED Array. */ 215 private void _init() 216 throws IllegalActionException, NameDuplicationException { 217 218 int columnsValue = ((IntToken) columns.getToken()).intValue(); 219 int rowsValue = ((IntToken) rows.getToken()).intValue(); 220 _leds = new RectangleAttribute[rowsValue][columnsValue]; 221 for (int x = 0; x < rowsValue; x++) { 222 for (int y = 0; y < columnsValue; y++) { 223 RectangleAttribute rectangle = new RectangleAttribute( 224 _ledArray_icon, "_led_" + x + "_" + y); 225 Location location = new Location(rectangle, "_location"); 226 double[] ledLocationValue = { x * 20, y * 20 }; 227 location.setLocation(ledLocationValue); 228 rectangle.width.setToken("20.0"); 229 rectangle.height.setToken("39.0"); 230 rectangle.centered.setToken("true"); 231 rectangle.fillColor.setToken("{0.0, 0.0, 0.0, 1.0}"); 232 _leds[x][y] = rectangle; 233 } 234 } 235 } 236 237 /////////////////////////////////////////////////////////////////// 238 //// private variables //// 239 240 /** Graphical icons for LED Array; */ 241 private RectangleAttribute[][] _leds; 242 243 /** The icon. */ 244 EditorIcon _ledArray_icon; 245}