001/* An abstract base class for a schedule element.
002
003 Copyright (c) 1998-2013 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.sched;
029
030import java.util.Iterator;
031
032///////////////////////////////////////////////////////////////////
033//// ScheduleElement
034
035/**
036 This is an abstract base class for a schedule element. Instances of the
037 Schedule and Firing subclasses are used to construct a static schedule.
038 A schedule can be thought of as a structure that consists of an iteration
039 count and a list of schedule elements. A schedule element can contain
040 an actor, or it can contain another schedule. It is usually required that,
041 all of the lowest-level schedule elements must contain an actor. It is
042 up to the scheduler to enforce this, however. The Schedule class is a
043 schedule element that contains a schedule. The Firing class is a schedule
044 element that contains an actor. Therefore,
045 the top-level schedule element must be an instance of Schedule, and all
046 of the lowest-level elements must each be an instance of Firing.
047 <p>
048 This base class implements the getIterationCount() and setIterationCount()
049 methods, which return and set the iteration count for this schedule element.
050 A default value of 1 is used for the iteration count.
051
052 @author Brian K. Vogel
053 @version $Id$
054 @since Ptolemy II 1.0
055 @Pt.ProposedRating Green (vogel)
056 @Pt.AcceptedRating Yellow (chf)
057 @see ptolemy.actor.sched.Firing
058 @see ptolemy.actor.sched.Schedule
059 */
060public abstract class ScheduleElement {
061    /** Construct a schedule element with an iteration count of 1 and
062     *  with no parent schedule element. The constructor that takes
063     *  a parameter should be used when constructing a schedule
064     *  element that is contained by another schedule element.
065     */
066    public ScheduleElement() {
067        super();
068        _scheduleVersion = 0;
069    }
070
071    ///////////////////////////////////////////////////////////////////
072    ////                         public methods                    ////
073
074    // What is the key difference between the following methods?
075    // From Steve:
076    // Basically, in some cases (debugging? testing?) it seemed
077    // more worthwhile to have a flat view of the schedule (actorIterator)
078    // rather than a tree view... providing this method also meant that
079    // it was temporarily easy to muck about with the schedule
080    // representation, without breaking the execution mechanism.
081    // ScheduleElement contains an iteration count, which multiplies the number
082    // of times that an actor is fired or a Schedule is executed.
083
084    /** Return the actor invocation sequence of the schedule in the
085     *  form of a sequence of actors. All of the lowest-level nodes
086     *  should be an instance of Actor. Otherwise, the returned
087     *  iterator will contain null elements.
088     *
089     *  @return An iterator over a sequence of actors.
090     */
091    public abstract Iterator actorIterator();
092
093    /** Return the actor invocation sequence in the form
094     *  of a sequence of firings. All of the lowest-level nodes
095     *  should be an instance of Firing, which references an
096     *  actor and an iteration count. Otherwise, the returned
097     *  iterator will contain null elements.
098     *
099     *  @return An iterator over a sequence of firings.
100     */
101    public abstract Iterator firingIterator();
102
103    /** Return the iteration count for this schedule. This method
104     *  returns the iteration count that was set by
105     *  setIterationCount(). If setIterationCount() was never invoked,
106     *  then a value of one is returned.
107     *
108     *  @return The iteration count for this schedule.
109     *  @see #setIterationCount(int)
110     */
111    public int getIterationCount() {
112        return _iterationCount;
113    }
114
115    /** Set the iteration count for this schedule. The
116     *  getIterationCount() method will return the value set
117     *  by this method. If this method is not invoked, a default
118     *  value of one will be used.
119     *
120     *  @param count The iteration count for this schedule.
121     *  @see #getIterationCount()
122     */
123    public void setIterationCount(int count) {
124        _incrementVersion();
125        _iterationCount = count;
126    }
127
128    /** Set the parent schedule element of this schedule element to
129     *  the specified schedule element. If this schedule element is
130     *  added to another schedule element (the parent), then the
131     *  add() method of the parent will invoke this method.
132     *  This association is used to notify the parent schedule
133     *  element when changes are made to this schedule element.
134     *
135     *  @param parent The parent schedule element of this schedule
136     *   element.
137     */
138    public void setParent(ScheduleElement parent) {
139        _parent = parent;
140    }
141
142    ///////////////////////////////////////////////////////////////////
143    ////                         protected methods                 ////
144
145    /** Return the current version of this schedule element. The
146     *  version changes whenever a structural change is made to
147     *  this schedule element.
148     *
149     *  @return The current version of this schedule element.
150     */
151    protected long _getVersion() {
152        return _scheduleVersion;
153    }
154
155    /** Increment the version of this schedule element and if this schedule
156     *  element has a parent schedule, increment the version of the parent
157     *  schedule as well. This method will therefore cause a version update
158     *  to propagate up to all parent schedule elements. This method is
159     *  called when a structure change is made to this schedule element, and
160     *  is also called by the immediate children of this schedule element
161     *  when they are modified.
162     */
163    protected void _incrementVersion() {
164        _scheduleVersion++;
165
166        if (_parent != null) {
167            _parent._incrementVersion();
168        }
169    }
170
171    ///////////////////////////////////////////////////////////////////
172    ////                         private variables                 ////
173
174    /** The parent schedule of this schedule. Null means this schedule
175     *  has no parent.
176     */
177    protected ScheduleElement _parent = null;
178
179    ///////////////////////////////////////////////////////////////////
180    ////                         private variables                 ////
181    // The iteration count for this schedule element.
182    private int _iterationCount = 1;
183
184    // The current version of this schedule.
185    private long _scheduleVersion;
186}