001/* An event that represents an actor activation.
002
003 Copyright (c) 2000-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;
029
030import ptolemy.kernel.util.DebugEvent;
031import ptolemy.kernel.util.NamedObj;
032
033///////////////////////////////////////////////////////////////////
034//// FiringEvent
035
036/**
037 An event that is published by directors whenever an actor is activated.
038 An activation occurs whenever an actor is prefired, fired, or
039 postfired.  The appropriate event should be published just before
040 or after the associated method of the executable interface is
041 called.  The iterate event is published by those directors which
042 vectorize firings of a particular actor.  This event may be
043 published instead of many individual prefire, fire and postfire
044 events.  As an example of how to implement a director that
045 publishes these events, see the SDF Director.
046 One way in which these events are used is to trace the firings of
047 different actors.  A user interface can also implement a breakpoint
048 mechanism by pausing execution of the executing thread in response
049 to one of these events.
050
051 <p>
052 Note that since most directors work with a constant set of actors, and fire
053 them repeatedly, it may improve efficiency dramatically to use a
054 flyweight design pattern with firing events.  This can result in greatly
055 reducing the load on the garbage collector.
056
057 @author  Steve Neuendorffer
058 @version $Id$
059 @since Ptolemy II 1.0
060 @Pt.ProposedRating Green (neuendor)
061 @Pt.AcceptedRating Yellow (neuendor)
062 @see ptolemy.kernel.util.DebugListener
063 */
064public class FiringEvent implements DebugEvent {
065    /** Create a new firing event with the given source, actor, and type.
066     *  @param source The director invoking the firing.
067     *  @param actor The actor being fired.
068     *  @param type An identifier for the method being invoked, which is
069     *   one of AFTER_PREFIRE, AFTER_FIRE, AFTER_POSTFIRE, AFTER_ITERATE,
070     *   BEFORE_PREFIRE, BEFORE_FIRE, BEFORE_POSTFIRE, or BEFORE_ITERATE.
071     */
072    public FiringEvent(Director source, Actor actor, FiringEventType type) {
073        _director = source;
074        _actor = actor;
075        _type = type;
076    }
077
078    /** Create a new firing event with the given source, actor, type,
079     *  and multiplicity.
080     *  @param source The director invoking the firing.
081     *  @param actor The actor being fired.
082     *  @param type An identifier for the method being invoked, which is
083     *   one of AFTER_PREFIRE, AFTER_FIRE, AFTER_POSTFIRE, AFTER_ITERATE,
084     *   BEFORE_PREFIRE, BEFORE_FIRE, BEFORE_POSTFIRE, or BEFORE_ITERATE.
085     *  @param multiplicity The multiplicity of the firing.
086     *
087     */
088    public FiringEvent(Director source, Actor actor, FiringEventType type,
089            int multiplicity) {
090        _director = source;
091        _actor = actor;
092        _type = type;
093        _multiplicity = multiplicity;
094    }
095
096    ///////////////////////////////////////////////////////////////////
097    ////                         public methods                    ////
098
099    /** Return the actor that is being activated.
100     *  @return The actor that is being activated.
101     */
102    public Actor getActor() {
103        return _actor;
104    }
105
106    /** Return the director that activated the actor.
107     *  @return The director that activated the actor.
108     */
109    public Director getDirector() {
110        return _director;
111    }
112
113    /** Return the source of the event.  This class returns the director
114     *  that activated the actor.
115     *  @return An instance of Director.
116     */
117    @Override
118    public NamedObj getSource() {
119        return _director;
120    }
121
122    /** Return the type of activation that this event represents.
123     *  @return the type of activation that this event represents.
124     */
125    public FiringEventType getType() {
126        return _type;
127    }
128
129    /** Return a string representation of this event.
130     *  @return A user-readable string describing the event.
131     */
132    @Override
133    public String toString() {
134        // Note that a string buffer is used to reduce the overhead.
135        // Additionally it may be useful to cache this string, but since
136        // in current cases we only ever call this method once, lets
137        // not bother.
138        StringBuffer buffer = new StringBuffer();
139        buffer.append("The actor ");
140        buffer.append(((NamedObj) _actor).getFullName());
141        buffer.append(" ");
142        buffer.append(_type.getName());
143
144        if (_multiplicity > 1) {
145            buffer.append(" ");
146            buffer.append(_multiplicity);
147            buffer.append(" times");
148        }
149
150        buffer.append(".");
151        return buffer.toString();
152    }
153
154    ///////////////////////////////////////////////////////////////////
155    ////                         public variables                  ////
156
157    /** This type of event is published after a prefire method is called. */
158    public static final FiringEventType AFTER_PREFIRE = new FiringEventType(
159            "prefired", false);
160
161    /** This type of event is published after a fire method is called. */
162    public static final FiringEventType AFTER_FIRE = new FiringEventType(
163            "fired", false);
164
165    /** This type of event is published after a postfire method is called. */
166    public static final FiringEventType AFTER_POSTFIRE = new FiringEventType(
167            "postfired", false);
168
169    /** This type of event is published after an iterate method is called. */
170    public static final FiringEventType AFTER_ITERATE = new FiringEventType(
171            "iterated", false);
172
173    /** This type of event is published before a prefire method is called. */
174    public static final FiringEventType BEFORE_PREFIRE = new FiringEventType(
175            "prefired", true);
176
177    /** This type of event is published before a fire method is called. */
178    public static final FiringEventType BEFORE_FIRE = new FiringEventType(
179            "fired", true);
180
181    /** This type of event is published before a postfire method is called. */
182    public static final FiringEventType BEFORE_POSTFIRE = new FiringEventType(
183            "postfired", true);
184
185    /** This type of event is published before an iterate method is called. */
186    public static final FiringEventType BEFORE_ITERATE = new FiringEventType(
187            "iterated", true);
188
189    // FIXME: Kepler should be fixed so that these are not necessary.
190
191    /** The type of event published as part of the Kepler sql actor. */
192    public static final FiringEventType BEFORE_RW_FIRE = new FiringEventType(
193            "rw fired", true);
194
195    /** The type of event published as part of the Kepler sql actor. */
196    public static final FiringEventType AFTER_RW_FIRE = new FiringEventType(
197            "rw fired", false);
198
199    ///////////////////////////////////////////////////////////////////
200    ////                         private variables                 ////
201    // The actor that was activated.
202    private Actor _actor;
203
204    // The director that activated the actor.
205    private Director _director;
206
207    // The multiplicity.
208    private int _multiplicity = 1;
209
210    // The type of activation.
211    private FiringEventType _type;
212
213    ///////////////////////////////////////////////////////////////////
214    ////                         inner classes                     ////
215
216    /** A type of firing event that can be published.  This class implements
217     *  a type-safe enumeration.  The constructor is private so that the
218     *  only admissible event types are the static members of the
219     *  FiringEvent class.
220     */
221    public static class FiringEventType {
222        /** Create a new event type with the given name.
223         *  @param name The name of this event type.
224         *  @param isStart true if this event type is a start event,
225         *  false if it is an end event.
226         */
227        private FiringEventType(String name, boolean isStart) {
228            _isStart = isStart;
229            _name = name;
230        }
231
232        /** Return the string name of this event type.
233         *  @return the string name of this event type.
234         */
235        public String getName() {
236            if (_isStart) {
237                return "will be " + _name;
238            } else {
239                return "was " + _name;
240            }
241        }
242
243        /** Return a string description of this event type.
244         *  @return a string description of this event type.
245         */
246        @Override
247        public String toString() {
248            return "FiringEventType(" + getName() + ")";
249        }
250
251        /** Return true if this event corresponds with a start event.
252         *  @return true if this event corresponds with a start event.
253         */
254        public boolean isStart() {
255            return _isStart;
256        }
257
258        /** Return the name of this event type.
259         *  @return the name of this event type.
260         */
261        public String getTypeName() {
262            return _name;
263        }
264
265        // The name of this event type.
266        private String _name;
267
268        // True if start of this event type.
269        private boolean _isStart;
270    }
271}