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}