001/* A Director governs the execution of a CompositeActor.
002
003 Copyright (c) 1997-2015 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 java.util.ArrayList;
031import java.util.HashMap;
032import java.util.HashSet;
033import java.util.Iterator;
034import java.util.LinkedHashSet;
035import java.util.LinkedList;
036import java.util.List;
037import java.util.Set;
038
039import ptolemy.actor.util.BooleanDependency;
040import ptolemy.actor.util.CausalityInterface;
041import ptolemy.actor.util.CausalityInterfaceForComposites;
042import ptolemy.actor.util.Dependency;
043import ptolemy.actor.util.Time;
044import ptolemy.data.BooleanToken;
045import ptolemy.data.DoubleToken;
046import ptolemy.data.Token;
047import ptolemy.data.expr.Parameter;
048import ptolemy.data.type.BaseType;
049import ptolemy.kernel.CompositeEntity;
050import ptolemy.kernel.util.Attribute;
051import ptolemy.kernel.util.IllegalActionException;
052import ptolemy.kernel.util.InternalErrorException;
053import ptolemy.kernel.util.LazyComposite;
054import ptolemy.kernel.util.NameDuplicationException;
055import ptolemy.kernel.util.Nameable;
056import ptolemy.kernel.util.NamedObj;
057import ptolemy.kernel.util.Settable;
058import ptolemy.kernel.util.Workspace;
059
060///////////////////////////////////////////////////////////////////
061//// Director
062
063/**
064 A Director governs the execution within a CompositeActor.  A composite actor
065 that contains a director is said to be <i>opaque</i>, and the execution model
066 within the composite actor is determined by the contained director.   This
067 director is called the <i>local director</i> of a composite actor.
068 A composite actor is also aware of the director of its container,
069 which is referred to as its <i>executive director</i>.
070 A director may also be contained by a CompositeEntity that is not a
071 CompositeActor, in which case it acts like any other entity within
072 that composite.
073 <p>
074 A top-level composite actor is generally associated with a <i>manager</i>
075 as well as a local director.  The Manager has overall responsibility for
076 executing the application, and is often associated with a GUI.   Top-level
077 composite actors have no executive director and getExecutiveDirector() will
078 return null.
079 <p>
080 A local director is responsible for invoking the actors contained by the
081 composite.  If there is no local director, then the executive director
082 is given the responsibility.  The getDirector() method of CompositeActor,
083 therefore, returns the local director, if there is one, and otherwise
084 returns the executive director.  Thus, it returns whichever director
085 is responsible for executing the contained actors, or null if there is none.
086 Whatever it returns is called simply the <i>director</i> (vs. local
087 director or executive director).
088 <p>
089 A director implements the action methods (preinitialize(),
090 initialize(), prefire(), fire(), postfire(), iterate(),
091 and wrapup()).  In this base class, default implementations
092 are provided that may or may not be useful in specific domains.   In general,
093 these methods will perform domain-dependent actions, and then call the
094 respective methods in all contained actors.
095 <p>
096 The director also provides methods to optimize the iteration portion of an
097 execution. This is done by setting the workspace to be read-only during
098 an iteration. In this base class, the default implementation results in
099 a read/write workspace. Derived classes (e.g. domain specific
100 directors) should override the _writeAccessRequired() method to report
101 that write access is not required. If none of the directors in a simulation
102 require write access, then it is safe to set the workspace to be read-only,
103 which will result in faster execution.
104 <p>
105 @author Mudit Goel, Edward A. Lee, Lukito Muliadi, Steve Neuendorffer, John Reekie
106 @version $Id$
107 @since Ptolemy II 0.2
108
109 @Pt.ProposedRating Green (eal)
110 @Pt.AcceptedRating Yellow (neuendor)
111 */
112public class Director extends Attribute implements Executable {
113    /** Construct a director in the default workspace with an empty string
114     *  as its name. The director is added to the list of objects in
115     *  the workspace. Increment the version number of the workspace.
116     *  @exception NameDuplicationException If construction of Time objects fails.
117     *  @exception IllegalActionException If construction of Time objects fails.
118     */
119    public Director() throws IllegalActionException, NameDuplicationException {
120        super();
121        _addIcon();
122        _initializeParameters();
123    }
124
125    /** Construct a director in the given container with the given name.
126     *  The container argument must not be null, or a
127     *  NullPointerException will be thrown.
128     *  If the name argument is null, then the name is set to the
129     *  empty string. Increment the version number of the workspace.
130     *
131     *  @param container The container.
132     *  @param name The name of this director.
133     *  @exception IllegalActionException If the name has a period in it, or
134     *   the director is not compatible with the specified container, or if
135     *   the time resolution parameter is malformed.
136     *  @exception NameDuplicationException If the container already contains
137     *   an entity with the specified name.
138     */
139    public Director(CompositeEntity container, String name)
140            throws IllegalActionException, NameDuplicationException {
141        super(container, name);
142        _addIcon();
143        _initializeParameters();
144    }
145
146    /** Construct a director in the workspace with an empty name.
147     *  The director is added to the list of objects in the workspace.
148     *  Increment the version number of the workspace.
149     *  @param workspace The workspace of this object.
150     *  @exception NameDuplicationException If construction of Time objects fails.
151     *  @exception IllegalActionException If construction of Time objects fails.
152     */
153    public Director(Workspace workspace)
154            throws IllegalActionException, NameDuplicationException {
155        super(workspace);
156        _addIcon();
157        _initializeParameters();
158    }
159
160    ///////////////////////////////////////////////////////////////////
161    ////                         public parameters                 ////
162
163    /** The clock that keeps track of current time of the model. */
164    public LocalClock localClock;
165
166    /** The local time of model when this director is initialized.
167     *  By default, this is blank, which
168     *  indicates that the start time is the current time of the enclosing
169     *  director when initialize() is invoked, or 0.0 if there is no
170     *  enclosing director. This can be set to a double value to explicitly
171     *  specify a start time.
172     *  Note that if <i>startTime</i> is given a value
173     *  that is different from the start time of the enclosing
174     *  director, then local time may be ahead of or behind
175     *  environment time during execution.
176     *  Also note that some directors do not advance time (including
177     *  PN and Rendezvous, for example), in which case, local time remains
178     *  at the start time value throughout the execution.
179     */
180    public Parameter startTime;
181
182    /** The stop time of the model. By default, this is blank, which
183     *  means that no stop time is specified. If a stop time is specified,
184     *  it must be a double, and when local time meets or exceeds the
185     *  stop time, then {@link #postfire()} returns false.
186     */
187    public Parameter stopTime;
188
189    ///////////////////////////////////////////////////////////////////
190    ////                         public methods                    ////
191
192    /** Add the specified object to the set of objects whose
193     *  preinitialize(), initialize(), and wrapup()
194     *  methods should be invoked upon invocation of the corresponding
195     *  methods of this object.
196     *  @param initializable The object whose methods should be invoked.
197     *  @see #removeInitializable(Initializable)
198     *  @see ptolemy.actor.CompositeActor#addPiggyback(Executable)
199     */
200    @Override
201    public void addInitializable(Initializable initializable) {
202        if (_initializables == null) {
203            _initializables = new LinkedHashSet<Initializable>();
204        }
205        _initializables.add(initializable);
206    }
207
208    /** Override the base class to update local variables.
209     *  @param attribute The attribute that changed.
210     *  @exception IllegalActionException If timeResolution is
211     *   being changed and the model is executing (and not in
212     *   preinitialize()).
213     */
214    @Override
215    public void attributeChanged(Attribute attribute)
216            throws IllegalActionException {
217        if (attribute == startTime) {
218            DoubleToken startTimeValue = (DoubleToken) startTime.getToken();
219            if (startTimeValue == null) {
220                _startTime = null;
221            } else {
222                _startTime = new Time(this, startTimeValue.doubleValue());
223            }
224            localClock.resetLocalTime(getModelStartTime());
225        } else if (attribute == stopTime) {
226            DoubleToken stopTimeValue = (DoubleToken) stopTime.getToken();
227            if (stopTimeValue != null) {
228                _stopTime = new Time(this, stopTimeValue.doubleValue());
229            } else {
230                _stopTime = null;
231            }
232        }
233
234        super.attributeChanged(attribute);
235    }
236
237    /** Clone the object into the specified workspace. The new object is
238     *  <i>not</i> added to the directory of that workspace (you must do this
239     *  yourself if you want it there).
240     *  @param workspace The workspace for the cloned object.
241     *  @exception CloneNotSupportedException Not thrown in this base class
242     *  @return The new Attribute.
243     */
244    @Override
245    public Object clone(Workspace workspace) throws CloneNotSupportedException {
246        Director newObject = (Director) super.clone(workspace);
247        newObject._actorsFinishedExecution = null;
248        newObject._initializables = null;
249        newObject._startTime = null;
250        newObject._stopTime = null;
251        newObject._zeroTime = new Time(newObject);
252        newObject._executionAspects = null;
253        newObject._aspectForActor = null;
254        newObject._nextScheduleTime = null;
255        return newObject;
256    }
257
258    /** Create the schedule for this director, if necessary.
259     *  In this base class nothing is done.
260     *  @exception IllegalActionException If the schedule can't be created.
261     */
262    public void createSchedule() throws IllegalActionException {
263    }
264
265    /** Return a default dependency to use between input
266     *  ports and output ports.
267     *  Director subclasses may override this if
268     *  need specialized dependency. This base class
269     *  returns {@link BooleanDependency}.OTIMES_IDENTITY.
270     *  @see Dependency
271     *  @see CausalityInterface
272     *  @see Actor#getCausalityInterface()
273     *  @return A default dependency between input ports
274     *   and output ports.
275     */
276    public Dependency defaultDependency() {
277        if (isEmbedded()) {
278            return ((CompositeActor) getContainer()).getExecutiveDirector()
279                    .defaultDependency();
280        } else {
281            return BooleanDependency.OTIMES_IDENTITY;
282        }
283    }
284
285    /** Return a boolean dependency representing a model-time delay
286     *  of the specified amount. This base clear returns
287     *  BooleanDependency.OTIMES_IDENTITY, which indicates a delay
288     *  but does not quantify the delay.
289     *  @param delay A non-negative delay.
290     *  @return A boolean dependency representing a delay.
291     */
292    public Dependency delayDependency(double delay) {
293        return BooleanDependency.OTIMES_IDENTITY;
294    }
295
296    /** Return the elapsed time (in milliseconds) since the start of execution
297     *  of the model. The start of execution is defined to be the time after
298     *  preinitialize() and initialize() has been called for all components,
299     *  and before any component has been iterated. This method delegates to
300     *  the manager so that the start time is consistent among all directors
301     *  in a model.
302     *  @return The time in milliseconds since the start of execution of the model.
303     */
304    public long elapsedTimeSinceStart() {
305        Manager manager = ((CompositeActor) getContainer()).getManager();
306        return manager.elapsedTimeSinceStart();
307    }
308
309    /** Request that after the current iteration finishes postfire() returns
310     *  false, indicating to the environment that no more iterations should
311     *  be invoked. To support domains where actor firings do not necessarily
312     *  terminate, such as PN, you may wish to call stopFire() as well to request
313     *  that those actors complete their firings.
314     */
315    public void finish() {
316        _finishRequested = true;
317    }
318
319    /** Iterate all the deeply contained actors of the
320     *  container of this director exactly once. This method is not functional,
321     *  since an iteration of the deeply contained actors may change
322     *  state in their postfire() method. The actors are iterated
323     *  in the order that they appear on the list returned by deepEntityList(),
324     *  which is normally the order in which they were created.
325     *  <p>
326     *  This method is <i>not</i> synchronized on the workspace, so the
327     *  caller should be.
328     *  <p>
329     *  In this base class, an attempt is made to fire each actor exactly
330     *  once, in the order they were created.  Prefire is called once, and
331     *  if prefire returns true, then fire is called once, followed by
332     *  postfire.  The return value from postfire is ignored. If the
333     *  container is not an instance of CompositeActor, however, then
334     *  this method does nothing.
335     *
336     *  @exception IllegalActionException If any called method of one
337     *  of the associated actors throws it.
338     */
339    @Override
340    public void fire() throws IllegalActionException {
341        if (_debugging) {
342            _debug("Director: Called fire().");
343        }
344
345        Nameable container = getContainer();
346
347        if (container instanceof CompositeActor) {
348            Iterator<?> actors = ((CompositeActor) container).deepEntityList()
349                    .iterator();
350            int iterationCount = 1;
351
352            while (actors.hasNext() && !_stopRequested) {
353                Actor actor = (Actor) actors.next();
354
355                if (_debugging) {
356                    _debug(new FiringEvent(this, actor,
357                            FiringEvent.BEFORE_ITERATE, iterationCount));
358                }
359
360                if (actor.iterate(1) == Executable.STOP_ITERATING) {
361                    if (_debugging) {
362                        _debug("Actor requests halt: "
363                                + ((Nameable) actor).getFullName());
364                    }
365
366                    break;
367                }
368
369                if (_debugging) {
370                    _debug(new FiringEvent(this, actor,
371                            FiringEvent.AFTER_ITERATE, iterationCount));
372                }
373            }
374        }
375    }
376
377    /** Request a firing of the given actor at the given absolute
378     *  time.  This method is only intended to be called from within
379     *  main simulation thread.  Actors that create their own
380     *  asynchronous threads should used the fireAtCurrentTime()
381     *  method to schedule firings.
382     *
383     *  This method calls {@link #fireAt(Actor, Time)} method.
384     *
385     *  @param actor The actor scheduled to be fired.
386     *  @param time The scheduled time.
387     *  @exception IllegalActionException If the operation is not
388     *    permissible (e.g. the given time is in the past).
389     *  @deprecated Instead of using double as time argument, use a
390     *  time object instead. As of Ptolemy 4.1, replaced by
391     *  {@link #fireAt(Actor, Time)}
392     */
393    @Deprecated
394    public void fireAt(Actor actor, double time) throws IllegalActionException {
395        fireAt(actor, new Time(this, time));
396    }
397
398    /** Request a firing of the given actor at the given model
399     *  time.  This base class ignores the request and returns a Time
400     *  with value equal to the current time, unless this director
401     *  is embedded within a model (and has an executive director),
402     *  in which case, this base class requests that the executive
403     *  director fire the container of this director at the requested
404     *  time, adjusted by the current offset and drift of the local clock.
405     *  It does this by delegating to {@link #fireContainerAt(Time, int)}
406     *  with the microstep argument set to 1.
407     *  <p>
408     *  The intent of this method is to request a firing of the actor
409     *  at the specified time, but this implementation does not assure
410     *  that. In particular, if there is no executive director, it
411     *  completely ignores the request. If there is an executive director,
412     *  then it is not required to do the firing at the specified time.
413     *  In particular, derived classes may override this method
414     *  and modify the time of the firing, for example to prevent
415     *  attempts to fire an actor in the past.
416     *  <p>
417     *  Derived classes should override this method to return the time at which
418     *  they expect to fire the specified actor. It is up to the actor
419     *  to throw an exception if it is not acceptable for the time
420     *  to differ from the requested time.
421     *  <p>
422     *  Note that it is not correct behavior for a director to override
423     *  this method to simply fire the specified actor. The actor needs
424     *  to be fired as part of the regular execution cycle of that director,
425     *  and that needs to occur after this method has returned.
426     *  <p>
427     *  <b>Note to authors of subclasses:</b> Usually you should not
428     *  override this method, but rather override
429     *  {@link #fireAt(Actor, Time, int)}. However, we cannot make
430     *  this method final because occasionally a domain will change the
431     *  default starting microstep. E.g., DE does this.
432     *  @param actor The actor scheduled to be fired.
433     *  @param time The requested time.
434     *  @return An instance of Time with the current time value, or
435     *   if there is an executive director, the time at which the
436     *   container of this director will next be fired
437     *   in response to this request.
438     *  @see #fireAtCurrentTime(Actor)
439     *  @exception IllegalActionException If there is an executive director
440     *   and it throws it. Derived classes may choose to throw this
441     *   exception for other reasons.
442     */
443    public Time fireAt(Actor actor, Time time) throws IllegalActionException {
444        // Unless the actor specifically requests a particular microstep,
445        // we assume it knows nothing about microsteps. We use microstep 1
446        // as the default, since this is the default for discrete events.
447        // The Continuous domain will specifically request a firing at
448        // microstep 0.
449        return fireAt(actor, time, 1);
450    }
451
452    /** Request a firing of the given actor at the given model
453     *  time with the given microstep. This method behaves exactly
454     *  like {@link #fireAt(Actor, Time)}, except that it also
455     *  passes up to the executive director the microstep, if there
456     *  is one.
457     *  This default implementation just delegates to
458     *  {@link #fireContainerAt(Time, int)}
459     *  @param actor The actor scheduled to be fired.
460     *  @param time The requested time.
461     *  @param microstep The requested microstep.
462     *  @return An instance of Time with the current time value, or
463     *   if there is an executive director, the time at which the
464     *   container of this director will next be fired
465     *   in response to this request.
466     *  @see #fireAtCurrentTime(Actor)
467     *  @see #fireContainerAt(Time)
468     *  @exception IllegalActionException If there is an executive director
469     *   and it throws it. Derived classes may choose to throw this
470     *   exception for other reasons.
471     */
472    public Time fireAt(Actor actor, Time time, int microstep)
473            throws IllegalActionException {
474        return fireContainerAt(time, microstep);
475    }
476
477    /** Request a firing of the given actor at the current model time or later.
478     *  This base class simply calls fireAt(actor, getModelTime())
479     *  and returns whatever that returns. Note that fireAt() will modify
480     *  the requested time if it happens to be in the past by the time
481     *  it is to be posted on the event queue, which is exactly what we
482     *  want. Note that the returned time may not match the value
483     *  returned by getModelTime() prior to this call.
484     *  <p>
485     *  Note that it is not correct behavior for a director to override
486     *  this method to simply fire the specified actor. The actor needs
487     *  to be fired as part of the regular execution cycle of that director,
488     *  and that needs to occur after this method has returned.
489     *  @param actor The actor to be fired.
490     *  @return The time at which the specified actor will be fired,
491     *   which in this case is whatever fireAt() returns.
492     *  @see #fireAt(Actor, Time)
493     *  @exception IllegalActionException If this method is called
494     *  before the model is running.
495     */
496    public Time fireAtCurrentTime(Actor actor) throws IllegalActionException {
497        return fireAt(actor, getModelTime());
498    }
499
500    /** Request a firing of the container of this director at the specified time
501     *  and throw an exception if the executive director does not agree to
502     *  do it at the requested time. If there is no executive director (this
503     *  director is at the top level), then ignore the request.
504     *  This is a convenience method provided because several directors need it.
505     *  The requested microstep will be zero.
506     *  @param time The requested time.
507     *  @return The time that the executive director indicates it will fire this
508     *   director, or an instance of Time with value equal to current time
509     *   if there is no executive director.
510     *  @exception IllegalActionException If the director does not
511     *   agree to fire the actor at the specified time, or if there
512     *   is no director.
513     */
514    public Time fireContainerAt(Time time) throws IllegalActionException {
515        return fireContainerAt(time, _defaultMicrostep);
516    }
517
518    /** Request a firing of the container of this director at the specified time,
519     *  adjusted by the current offset and drift of the local clock,
520     *  and the specified microstep.
521     *  Throw an exception if the executive director does not agree to
522     *  do it at the requested time. If there is no executive director (this
523     *  director is at the top level), then ignore the request and return
524     *  a Time with value equal to the current time.
525     *  The microstep argument is used by directors that implement
526     *  {@link SuperdenseTimeDirector}.
527     *  @param time The requested time.
528     *  @param microstep The requested microstep.
529     *  @return The time that the executive director indicates it will fire this
530     *   director, or an instance of Time with value equal to current time
531     *   if there is no executive director.
532     *  @exception IllegalActionException If the director does not
533     *   agree to fire the actor at the specified time, or if there
534     *   is no director.
535     */
536    public Time fireContainerAt(Time time, int microstep)
537            throws IllegalActionException {
538        Actor container = (Actor) getContainer();
539        // Some composites, such as RunCompositeActor want to be treated
540        // as if they are at the top level even though they have an executive
541        // director, so be sure to check _isTopLevel().
542        if (container != null && !_isTopLevel()) {
543            Director director = container.getExecutiveDirector();
544            if (director != null) {
545                if (_debugging) {
546                    _debug("**** Requesting that enclosing director refire me at "
547                            + time + " with microstep " + microstep);
548                }
549                // Translate the local time into an environment time.
550                Time environmentTime = localClock
551                        .getEnvironmentTimeForLocalTime(time);
552                Time result = director.fireAt(container, environmentTime,
553                        microstep);
554                if (!result.equals(environmentTime)) {
555                    throw new IllegalActionException(this,
556                            "Timing incompatibility error: "
557                                    + director.getName() + " is unable to fire "
558                                    + container.getName()
559                                    + " at the requested time: " + time
560                                    + ". It responds it will fire it at: "
561                                    + result + ".");
562                }
563                // Translate the response from the environment into a local time.
564                return localClock.getLocalTimeForEnvironmentTime(result);
565            }
566        }
567        return localClock.getLocalTime();
568    }
569
570    /** Return true if the next actor in the model governed by this director
571     *  can be scheduled. The base class always returns true, but derived
572     *  classes might override this.
573     * @return True if next actor to be fired can be scheduled.
574     * @exception IllegalActionException not thrown here.
575     */
576    public boolean scheduleContainedActors() throws IllegalActionException {
577        return true;
578    }
579
580    /** Return a causality interface for the composite actor that
581     *  contains this director. This base class returns an
582     *  instance of {@link CausalityInterfaceForComposites}, but
583     *  subclasses may override this to return a domain-specific
584     *  causality interface.
585     *  @return A representation of the dependencies between input ports
586     *   and output ports of the container.
587     */
588    public CausalityInterface getCausalityInterface() {
589        return new CausalityInterfaceForComposites((Actor) getContainer(),
590                defaultDependency());
591    }
592
593    /** Return the current time value of the model being executed by this
594     *  director. This time can be set with the setCurrentTime method.
595     *  In this base class, time never increases, and there are no restrictions
596     *  on valid times.
597     *
598     *  @return The current time value.
599     *  @deprecated As of Ptolemy II 4.1, replaced by
600     *  {@link #getModelTime()}
601     *  @see #setCurrentTime(double)
602     */
603    @Deprecated
604    public double getCurrentTime() {
605        return getModelTime().getDoubleValue();
606    }
607
608    /** Compute the deadline for an actor firing. In this base class, the deadline
609     *  is set to the maximum value.
610     * @param actor The actor.
611     * @param timestamp The timestamp of the event that triggered the firing.
612     * @return The deadline.
613     * @exception IllegalActionException Thrown in subclasses.
614     */
615    public Time getDeadline(NamedObj actor, Time timestamp)
616            throws IllegalActionException {
617        return Time.POSITIVE_INFINITY;
618    }
619
620    /** Get current environment time.
621     *  This is the current time of the enclosing executive
622     *  director, if there is one, and null otherwise.
623     *  @return Environment time or null if the associated director is the top level director.
624     */
625    public Time getEnvironmentTime() {
626        if (getContainer() instanceof Actor) {
627            Actor container = (Actor) getContainer();
628            if (container != null && container.getContainer() != null) {
629                Director executiveDirector = container.getExecutiveDirector();
630                // Some composites, such as RunCompositeActor want to be treated
631                // as if they are at the top level even though they have an executive
632                // director, so be sure to check _isTopLevel().
633                if (executiveDirector != null && !_isTopLevel()) {
634                    return executiveDirector.getModelTime();
635                }
636            }
637        }
638        return localClock.getLocalTime();
639    }
640
641    /** Return the global time for this model. The global time is
642     *  defined to be the value returned by the @link{#getModelTime()}
643     *  method of the top-level director in the model.
644     *  @return The time of the top-level director in the model.
645     * @exception IllegalActionException If the top level is not an Actor.
646     */
647    public Time getGlobalTime() throws IllegalActionException {
648        NamedObj toplevel = toplevel();
649        if (!(toplevel instanceof Actor)) {
650            throw new IllegalActionException(this,
651                    "Cannot get a global time because the top level is not an actor."
652                            + " It is " + toplevel);
653        }
654        return ((Actor) toplevel).getDirector().getModelTime();
655    }
656
657    /** Return the next time of interest in the model being executed by
658     *  this director or the director of any enclosing model up the
659     *  hierarchy. If this director is at the top level, then this
660     *  default implementation simply returns the current time, since
661     *  this director does not advance time. If this director is not
662     *  at the top level, then return whatever the enclosing director
663     *  returns.
664     *  <p>
665     *  This method is useful for domains that perform
666     *  speculative execution (such as CT).  Such a domain in a hierarchical
667     *  model (i.e. CT inside DE) uses this method to determine how far
668     *  into the future to execute.
669     *  <p>
670     *  Derived classes should override this method to provide an appropriate
671     *  value, if possible. For example, the DEDirector class returns the
672     *  time value of the next event in the event queue.
673     *  @return The time of the next iteration.
674     *  @exception IllegalActionException If time objects cannot be created.
675     *  @see #getModelTime()
676     */
677    public Time getModelNextIterationTime() throws IllegalActionException {
678        NamedObj container = getContainer();
679        // NOTE: the container may not be a composite actor.
680        // For example, the container may be an entity as a library,
681        // where the director is already at the top level.
682        if (container instanceof CompositeActor) {
683            Director executiveDirector = ((CompositeActor) container)
684                    .getExecutiveDirector();
685            // Some composites, such as RunCompositeActor want to be treated
686            // as if they are at the top level even though they have an executive
687            // director, so be sure to check _isTopLevel().
688            if (executiveDirector != null && !_isTopLevel()) {
689                return executiveDirector.getModelNextIterationTime();
690            }
691        }
692        return getModelTime();
693    }
694
695    /** Return the start time parameter value, if it has been explicitly
696     *  set. Otherwise, return the current time of the enclosing director,
697     *  if there is one, and return a Time with value 0.0 otherwise.
698     *  @return the start time parameter value.
699     *  @exception IllegalActionException If the executive director throws it.
700     */
701    public final Time getModelStartTime() throws IllegalActionException {
702
703        // This method is final for performance reason.
704        if (_startTime == null) {
705            if (isEmbedded() && getContainer() instanceof Actor) {
706                // The previous implementation assumes this method is only called
707                // during initialize. This is not a valid assumption.
708                // It is called when attributeChanged() on startTime, and also
709                // when cloning.
710                Director executiveDirector = ((Actor) getContainer())
711                        .getExecutiveDirector();
712                // Some composites, such as RunCompositeActor want to be treated
713                // as if they are at the top level even though they have an executive
714                // director, so be sure to check _isTopLevel().
715                if (executiveDirector != null && !_isTopLevel()) {
716                    return executiveDirector.getModelTime();
717                } else {
718                    return _zeroTime;
719                }
720            } else {
721                return _zeroTime;
722            }
723        }
724        return _startTime;
725    }
726
727    /** Return the stop time parameter value, if it has been set,
728     *  and otherwise, return a time with value Double.POSITIVE_INFINITY.
729     *  @return the stop time parameter value.
730     */
731    public final Time getModelStopTime() {
732        if (_stopTime != null) {
733            return _stopTime;
734        }
735        return Time.POSITIVE_INFINITY;
736    }
737
738    /** Return the current time object of the model being executed by this
739     *  director.
740     *  This time can be set with the setModelTime method. In this base
741     *  class, time never increases, and there are no restrictions on valid
742     *  times.
743     *
744     *  @return The current time.
745     *  @see #setModelTime(Time)
746     */
747    public Time getModelTime() {
748        return localClock.getLocalTime();
749    }
750
751    /** Return the next time of interest in the model being executed by
752     *  this director. This method is useful for domains that perform
753     *  speculative execution (such as CT).  Such a domain in a hierarchical
754     *  model (i.e. CT inside DE) uses this method to determine how far
755     *  into the future to execute.
756     *  <p>
757     *  In this base class, we return the current time.
758     *  Derived classes should override this method to provide an appropriate
759     *  value, if possible.
760     *  <p>
761     *  Note that this method is not made abstract to facilitate the use
762     *  of the test suite.
763     *  @return The time of the next iteration.
764     *  @exception IllegalActionException If Time objects cannot be created.
765     *  @deprecated As of Ptolemy II 4.1, replaced by
766     *  {@link #getModelNextIterationTime}
767     */
768    @Deprecated
769    public double getNextIterationTime() throws IllegalActionException {
770        return getModelNextIterationTime().getDoubleValue();
771    }
772
773    /** Get the start time of the model. This base class returns
774     *  a Time object with 0.0 as the value of the start time.
775     *  Subclasses need to override this method to get a different
776     *  start time.
777     *  For example, CT director and DE director use the value of
778     *  the startTime parameter to specify the real start time.
779     *  @return The start time of the model.
780     *  @deprecated As of Ptolemy II 4.1, replaced by
781     *  {@link #getModelStartTime}
782     *  @exception IllegalActionException If the specified start time
783     *   is invalid.
784     */
785    @Deprecated
786    public double getStartTime() throws IllegalActionException {
787        return 0.0;
788    }
789
790    /** Get the stop time of the model. This base class returns
791     *  a new Time object with Double.MAX_VALUE as the value of the
792     *  stop time.
793     *  Subclasses need to override this method to get a different
794     *  stop time.
795     *  For example, CT director and DE director use the value of
796     *  the stopTime parameter to specify the real stop time.
797     *  @return The stop time of the model.
798     *  @deprecated As of Ptolemy II 4.1, replaced by
799     *  {@link #getModelStopTime}
800     *  @exception IllegalActionException If the specified stop time
801     *   is invalid.
802     */
803    @Deprecated
804    public double getStopTime() throws IllegalActionException {
805        return getModelStopTime().getDoubleValue();
806    }
807
808    /** Get the time resolution of the model. The time resolution is
809     *  the value of the <i>timeResolution</i> parameter. This is the
810     *  smallest time unit for the model.
811     *  @return The time resolution of the model.
812     *  @see #setTimeResolution(double)
813     */
814    public final double getTimeResolution() {
815        // This method is final for performance reason.
816        return localClock.getTimeResolution();
817    }
818
819    /** Return true if this director assumes and exports
820     *  the strict actor semantics, as described in this paper:
821     *  <p>
822     *  A. Goderis, C. Brooks, I. Altintas, E. A. Lee, and C. Goble,
823     *  "Heterogeneous Composition of Models of Computation,"
824     *  EECS Department, University of California, Berkeley,
825     *  Tech. Rep. UCB/EECS-2007-139, Nov. 2007.
826     *  http://www.eecs.berkeley.edu/Pubs/TechRpts/2007/EECS-2007-139.html
827     *  <p>
828     *  In particular, a director that implements this interface guarantees
829     *  that it will not invoke the postfire() method of an actor until all
830     *  its inputs are known at the current tag.  Moreover, it it will only
831     *  do so in its own postfire() method, and in its prefire() and fire()
832     *  methods, it does not change its own state.  Thus, such a director
833     *  can be used within a model of computation that has a fixed-point
834     *  semantics, such as SRDirector and ContinuousDirector.
835     *  This base class returns false.
836     *  @return True if the director assumes and exports strict actor semantics.
837     */
838    public boolean implementsStrictActorSemantics() {
839        return false;
840    }
841
842    /** Initialize the model controlled by this director.  Set the
843     *  current time to the start time or the current time of the
844     *  executive director, and then invoke the initialize() method
845     *  of this director on each actor that is controlled by this director.
846     *  If the container is not an instance of CompositeActor, do nothing.
847     *
848     *  This method should typically be invoked once per execution, after the
849     *  preinitialization phase, but before any iteration.  It may be
850     *  invoked in the middle of an execution, if reinitialization is
851     *  desired.  Since type resolution has been completed and the
852     *  current time is set, the initialize() method of a contained
853     *  actor may produce output or schedule events.  If stop() is
854     *  called during this methods execution, then stop initializing
855     *  actors immediately.
856     *
857     *  This method is <i>not</i> synchronized on the workspace,
858     *  so the caller should be.
859     *
860     *  @exception IllegalActionException If the initialize() method of
861     *   one of the associated actors throws it.
862     */
863    @Override
864    public void initialize() throws IllegalActionException {
865        // Note that the inner director in gt.TransformationRule
866        // does not call super.initialize(), so changes made to this
867        // method may apply there.
868
869        if (_debugging) {
870            _debug("Called initialize().");
871        }
872
873        // First invoke initializable methods.
874        if (_initializables != null) {
875            for (Initializable initializable : _initializables) {
876                initializable.initialize();
877            }
878        }
879
880        _actorsFinishedExecution = new HashSet();
881
882        // Reset the flag that causes postfire() to return false.
883        _finishRequested = false;
884
885        localClock.resetLocalTime(getModelStartTime());
886        localClock.start();
887
888        if (_nextScheduleTime != null) {
889            _nextScheduleTime.clear();
890        }
891        _tokenSentToCommunicationAspect = false;
892
893        // Initialize the contained actors.
894        Nameable container = getContainer();
895        if (container instanceof CompositeActor) {
896            Iterator<?> actors = ((CompositeActor) container).deepEntityList()
897                    .iterator();
898
899            while (actors.hasNext() && !_stopRequested) {
900                Actor actor = (Actor) actors.next();
901
902                if (_debugging) {
903                    _debug("Invoking initialize(): ",
904                            ((NamedObj) actor).getFullName());
905                }
906
907                initialize(actor);
908            }
909        }
910    }
911
912    /** Initialize the given actor.  This method is generally called
913     *  by the initialize() method of the director, and by the manager
914     *  whenever an actor is added to an executing model as a
915     *  mutation.  This method will generally perform domain-specific
916     *  initialization on the specified actor and call its
917     *  initialize() method.  In this base class, only the actor's
918     *  initialize() method of the actor is called and no
919     *  domain-specific initialization is performed.  Typical actions
920     *  a director might perform include starting threads to execute
921     *  the actor or checking to see whether the actor can be managed
922     *  by this director.  For example, a time-based domain (such as
923     *  CT) might reject sequence based actors.
924     *  @param actor The actor that is to be initialized.
925     *  @exception IllegalActionException If the actor is not
926     *  acceptable to the domain.  Not thrown in this base class.
927     */
928    public void initialize(Actor actor) throws IllegalActionException {
929        // FIXME: Note that ProcessDirector does *not* invoke this
930        // method, so changes made here might apply to
931        // ProcessDirector.initialize(Actor).
932
933        if (_debugging) {
934            _debug("Initializing actor: " + ((Nameable) actor).getFullName()
935                    + ".");
936        }
937
938        actor.initialize();
939        if (getExecutionAspect((NamedObj) actor) != null) {
940            _aspectsPresent = true;
941        }
942    }
943
944    /** Resume the execution of an actor that was previously blocked because
945     *  it didn't have all the resources it needed for execution. This method
946     *  is called by {@link ActorExecutionAspect} actors.
947     *
948     *  In this base class, the implementation is empty. Derived directors
949     *  should override this method to handle resuming of actor execution.
950     *  @param actor The actor that resumes execution.
951     *  @exception IllegalActionException Not thrown here but in derived classes.
952     */
953    public void resumeActor(NamedObj actor) throws IllegalActionException {
954    }
955
956    /** Indicate that resolved types in the model may no longer be valid.
957     *  This will force type resolution to be redone on the next iteration.
958     *  This method simply defers to the manager, notifying it.  If there
959     *  is no container, or the container is not an instance of
960     *  CompositeActor, or if it has no manager, do nothing.
961     */
962    public void invalidateResolvedTypes() {
963        Nameable container = getContainer();
964
965        if (container instanceof CompositeActor) {
966            Manager manager = ((CompositeActor) container).getManager();
967
968            if (manager != null) {
969                manager.invalidateResolvedTypes();
970            }
971        }
972    }
973
974    /** Indicate that a schedule for the model may no longer be valid, if
975     *  there is a schedule.  This method should be called when topology
976     *  changes are made, or for that matter when any change that may
977     *  invalidate the schedule is made.  In this base class, the method
978     *  does nothing. In derived classes, it will cause any static
979     *  schedule information to be recalculated in the prefire method
980     *  of the director.
981     */
982    public void invalidateSchedule() {
983    }
984
985    /** Return true if this director is embedded inside an opaque composite
986     *  actor contained by another composite actor. Note that some classes,
987     *  such as RunCompositeActor, may return false even if they are actually
988     *  embedded, but they want to be treated as if they were not.
989     *  @return True if this directory is embedded inside an opaque composite
990     *   actor contained by another composite actor.
991     *  @see #setEmbedded(boolean)
992     */
993    public final boolean isEmbedded() {
994        return !_isTopLevel();
995    }
996
997    /** Return false. This director iterates actors in its fire()
998     *  method, which includes an invocation of their postfire()
999     *  methods, so its fire method changes the state of the model.
1000     *
1001     *  @return False.
1002     */
1003    @Override
1004    public boolean isFireFunctional() {
1005        return false;
1006    }
1007
1008    /** Return true. The transferInputs() method does not check whether
1009     *  the inputs are known before calling hasToken(), and consequently
1010     *  will throw an exception if inputs are not known. Thus, this
1011     *  director requires that inputs be known in order to be able to
1012     *  iterate.  Derived classes that can tolerate unknown inputs
1013     *  should override this method to return false.
1014     *
1015     *  @return True.
1016     *  @exception IllegalActionException Thrown by subclass.
1017     */
1018    @Override
1019    public boolean isStrict() throws IllegalActionException {
1020        return true;
1021    }
1022
1023    /** Return true if stop has been requested.
1024     *  @return True if stop() has been called.
1025     *  @see #stop()
1026     */
1027    public boolean isStopRequested() {
1028        return _stopRequested;
1029    }
1030
1031    /** Invoke a specified number of iterations of this director. An
1032     *  iteration is equivalent to invoking prefire(), fire(), and
1033     *  postfire(), in that order. In an iteration, if prefire()
1034     *  returns true, then fire() will be called once, followed by
1035     *  postfire(). Otherwise, if prefire() returns false, fire()
1036     *  and postfire() are not invoked, and this method returns
1037     *  NOT_READY. If postfire() returns false, then no more
1038     *  iterations are invoked, and this method returns STOP_ITERATING.
1039     *  Otherwise, it returns COMPLETED.  Also, if the stop() is
1040     *  called during this execution, then immediately stop iterating
1041     *  and return STOP_ITERATING.
1042     *  <p>
1043     *  This base class method actually invokes prefire(), fire(),
1044     *  and postfire(), as described above, but a derived class
1045     *  may override the method to execute more efficient code.
1046     *
1047     *  @param count The number of iterations to perform.
1048     *  @return NOT_READY, STOP_ITERATING, or COMPLETED.
1049     *  @exception IllegalActionException If iterating is not
1050     *   permitted, or if prefire(), fire(), or postfire() throw it.
1051     */
1052    @Override
1053    public int iterate(int count) throws IllegalActionException {
1054        int n = 0;
1055
1056        while (n++ < count && !_stopRequested) {
1057            if (prefire()) {
1058                fire();
1059
1060                if (!postfire()) {
1061                    return Executable.STOP_ITERATING;
1062                }
1063            } else {
1064                return Executable.NOT_READY;
1065            }
1066        }
1067
1068        if (_stopRequested) {
1069            return Executable.STOP_ITERATING;
1070        } else {
1071            return Executable.COMPLETED;
1072        }
1073    }
1074
1075    /** Return the object to use to obtain a mutex lock on this director.
1076     *  This base class returns this director itself, but subclasses may
1077     *  return something else.
1078     *  @return An object to use to obtain a lock on this director.
1079     */
1080    public Object mutexLockObject() {
1081        return this;
1082    }
1083
1084    /** Return a new receiver of a type compatible with this director.
1085     *  In this base class, this returns an instance of Mailbox.
1086     *  @return A new Mailbox.
1087     */
1088    public Receiver newReceiver() {
1089        return new Mailbox();
1090    }
1091
1092    /** Notify this director that a token was sent to a communication
1093     *  aspect. Some directors need to perform specific actions but the
1094     *  base class just sets a boolean flag.
1095     */
1096    public void notifyTokenSentToCommunicationAspect() {
1097        _tokenSentToCommunicationAspect = true;
1098    }
1099
1100    /** Return true if the director wishes to be scheduled for another
1101     *  iteration.  This method is called by the container of
1102     *  this director to see whether the director wishes to execute anymore.
1103     *  It should <i>not</i>, in general, call postfire() on the contained
1104     *  actors.
1105     *  <p>
1106     *  In this base class, return the false if stop() has been called
1107     *  since preinitialize(), and true otherwise. Derived classes that
1108     *  override this method need to respect this semantics. The
1109     *  protected variable _stopRequested indicates whether stop()
1110     *  has been called.
1111     *
1112     *  @return True to continue execution, and false otherwise.
1113     *  @exception IllegalActionException Not thrown in this base class.
1114     */
1115    @Override
1116    public boolean postfire() throws IllegalActionException {
1117        if (_debugging) {
1118            _debug("Director: Called postfire().");
1119        }
1120        return !_stopRequested && !_finishRequested;
1121    }
1122
1123    /** Return true if the director is ready to fire. This method is
1124     *  called by the container of this director to determine whether the
1125     *  director is ready to execute. It does <i>not</i>
1126     *  call prefire() on the contained actors.
1127     *  If this director is not at the top level of the hierarchy,
1128     *  then this base class synchronizes to environment time, making
1129     *  any necessary adjustments for drift or offset of the local clock.
1130     *  <p>
1131     *  In this base class, assume that the director is always ready to
1132     *  be fired, and so return true. Domain directors should probably
1133     *  override this method to provide domain-specific behavior.
1134     *  However, they should call super.prefire() if they
1135     *  wish to propagate time as done here.
1136     *
1137     *  @return True.
1138     *  @exception IllegalActionException Not thrown in this base class.
1139     */
1140    @Override
1141    public boolean prefire() throws IllegalActionException {
1142        // FIXME: Note that ProcessDirector does *not*
1143        // invoke this method, so changes made here might
1144        // apply to ProcessDirector.prefire().
1145
1146        if (_debugging) {
1147            _debug("Director: Called prefire().");
1148        }
1149
1150        Time modifiedTime = _consultTimeRegulators(
1151                localClock.getLocalTimeForCurrentEnvironmentTime());
1152
1153        setModelTime(modifiedTime);
1154        boolean noNewActors = true;
1155        List<TimeRegulator> regulators = getContainer()
1156                .attributeList(TimeRegulator.class);
1157        for (TimeRegulator regulator : regulators) {
1158            noNewActors = noNewActors && regulator.noNewActors();
1159        }
1160        if (_debugging) {
1161            _debug("-- Setting current time to " + getModelTime());
1162        }
1163
1164        return true && noNewActors;
1165    }
1166
1167    /** Validate the attributes and then invoke the preinitialize()
1168     *  methods of all its deeply contained actors.
1169     *  This method is invoked once per execution, before any
1170     *  iteration, and before the initialize() method.
1171     *  Time is not set during this stage. So preinitialize() method
1172     *  of actors should not make use of time. They should wait
1173     *  until the initialize phase of the execution.
1174     *  <p>This method also resets the protected variable _stopRequested
1175     *  to false, so if a derived class overrides this method, then it
1176     *  should also do that.
1177     *  <p>This method is <i>not</i> synchronized on the workspace, so the
1178     *  caller should be.
1179     *
1180     *  @exception IllegalActionException If the preinitialize() method of
1181     *   one of the associated actors throws it.
1182     */
1183    @Override
1184    public void preinitialize() throws IllegalActionException {
1185        // Note that the inner director in gt.TransformationRule
1186        // does not call super.preinitialize(), so changes made to this
1187        // method may apply there.
1188
1189        if (_debugging) {
1190            _debug(getFullName(), "Preinitializing ...");
1191        }
1192
1193        // Support old models that set time resolution in director.
1194        Attribute timeResolution = getAttribute("timeResolution");
1195        if (timeResolution != null) {
1196            double timeResolutionDouble = ((DoubleToken) ((Parameter) timeResolution)
1197                    .getToken()).doubleValue();
1198            try {
1199                timeResolution.setContainer(null);
1200            } catch (NameDuplicationException e) {
1201                // Can't happen.
1202                e.printStackTrace();
1203            }
1204            localClock.globalTimeResolution.setToken("" + timeResolutionDouble);
1205        }
1206        _zeroTime = new Time(this, 0.0);
1207        localClock.initialize();
1208
1209        // First invoke initializable methods.
1210        if (_initializables != null) {
1211            for (Initializable initializable : _initializables) {
1212                initializable.preinitialize();
1213            }
1214        }
1215
1216        // validate all settable attributes.
1217        Iterator<?> attributes = attributeList(Settable.class).iterator();
1218        while (attributes.hasNext()) {
1219            Settable attribute = (Settable) attributes.next();
1220            attribute.validate();
1221        }
1222        // In case the preinitialize() method of any actor
1223        // access current time, set the start time. This is required
1224        // for instance in DDF.
1225        // The following will be repeated in initialize().
1226        localClock.resetLocalTime(getModelStartTime());
1227        localClock.start();
1228
1229        // preinitialize protected variables.
1230        _stopRequested = false;
1231        _finishRequested = false;
1232
1233        Nameable container = getContainer();
1234        // Preinitialize all the contained actors.
1235        if (container instanceof CompositeActor) {
1236            // Populate any LazyTypedComposites.
1237            // Needed by $PTII/ptolemy/cg/lib/test/auto/ModularCodeGen4.xml
1238            Iterator entities = ((CompositeActor) toplevel())
1239                    .entityList(LazyComposite.class).iterator();
1240            while (entities.hasNext()) {
1241                // LazyTypedCompositeActor implements ptolemy.kernel.util.LazyComposite,
1242                // which has a populate() method.  We refer to the interface so
1243                // as to avoid a dependency between Director and LazyTypedCompositeActor.
1244                LazyComposite lazyComposite = (LazyComposite) entities.next();
1245                lazyComposite.populate();
1246            }
1247
1248            // Preinitialize all the contained actors.
1249            Iterator<?> actors = ((CompositeActor) container).deepEntityList()
1250                    .iterator();
1251            while (actors.hasNext()) {
1252                Actor actor = (Actor) actors.next();
1253                if (_debugging) {
1254                    _debug("Invoking preinitialize(): ",
1255                            ((NamedObj) actor).getFullName());
1256                }
1257                preinitialize(actor);
1258            }
1259
1260            // Don't need to create receivers if the workspace hasn't changed since the last run.
1261            // Note that we have to use the version recorded by the Manager on the last
1262            // completion of preinitializeAndResolveTypes() because otherwise, if there
1263            // are multiple directors, then the workspace version will always have changed
1264            // since the last run, since creatingReceivers itself changes it.
1265            Manager manager = ((Actor) container).getManager();
1266            if (manager == null || manager
1267                    .getPreinitializeVersion() != workspace().getVersion()) {
1268                // This increments the workspace version.
1269                _createReceivers();
1270            }
1271        }
1272
1273        _aspectsPresent = false;
1274
1275        _executionAspects = new ArrayList<ActorExecutionAspect>();
1276        _aspectForActor = new HashMap<NamedObj, ActorExecutionAspect>();
1277        if (getContainer() instanceof CompositeActor) {
1278            for (Object entity : ((CompositeActor) getContainer())
1279                    .entityList(ActorExecutionAspect.class)) {
1280                ActorExecutionAspect aspect = (ActorExecutionAspect) entity;
1281                _executionAspects.add(aspect);
1282            }
1283            _aspectsPresent = ((CompositeActor) getContainer())
1284                    .entityList(CommunicationAspect.class).size() > 0;
1285        }
1286
1287        if (_debugging) {
1288            _debug(getFullName(), "Finished preinitialize().");
1289        }
1290    }
1291
1292    /**
1293     * Preinitialize the actor.
1294     * This method is used by directors that want to instrument calls to
1295     * preinitialize. {@link #preinitialize()} calls this method.
1296     * @param actor The actor to be preinitialized.
1297     * @exception IllegalActionException If thrown while the actor is being
1298     * preinitialized.
1299     * @see #preinitialize()
1300     */
1301    public void preinitialize(Actor actor) throws IllegalActionException {
1302        actor.preinitialize();
1303    }
1304
1305    /** Remove the specified object from the list of objects whose
1306     *  preinitialize(), initialize(), and wrapup()
1307     *  methods should be invoked upon invocation of the corresponding
1308     *  methods of this object. If the specified object is not
1309     *  on the list, do nothing.
1310     *  @param initializable The object whose methods should no longer be invoked.
1311     *  @see #addInitializable(Initializable)
1312     *  @see ptolemy.actor.CompositeActor#removePiggyback(Executable)
1313     */
1314    @Override
1315    public void removeInitializable(Initializable initializable) {
1316        if (_initializables != null) {
1317            _initializables.remove(initializable);
1318            if (_initializables.size() == 0) {
1319                _initializables = null;
1320            }
1321        }
1322    }
1323
1324    /** Queue an initialization request with the manager.
1325     *  The specified actor will be initialized at an appropriate time,
1326     *  between iterations, by calling its preinitialize() and initialize()
1327     *  methods. This method is called by CompositeActor when an actor
1328     *  sets its container to that composite actor.  Typically, that
1329     *  will occur when a model is first constructed, and during the
1330     *  execute() method of a ChangeRequest.
1331     *  In this base class, the request is delegated
1332     *  to the manager. If there is no manager, or if the container
1333     *  is not an instance of CompositeActor, then do nothing.
1334     *  @param actor The actor to initialize.
1335     */
1336    public void requestInitialization(Actor actor) {
1337        Nameable container = getContainer();
1338
1339        if (container instanceof CompositeActor) {
1340            Manager manager = ((CompositeActor) container).getManager();
1341
1342            if (manager != null) {
1343                manager.requestInitialization(actor);
1344            }
1345        }
1346    }
1347
1348    /** Start or resume the actor, which means (re)start the local clock.
1349     *  If the clock is not stopped then this has no effect.
1350     *  @exception IllegalActionException If the fireAt() request throws it.
1351     */
1352    public void resume() throws IllegalActionException {
1353        localClock.start();
1354    }
1355
1356    /** Specify the container.  If the specified container is an instance
1357     *  of CompositeActor, then this becomes the active director for
1358     *  that composite.  Otherwise, this is an attribute like any other within
1359     *  the container. If the container is not in the same
1360     *  workspace as this director, throw an exception.
1361     *  If this director is already an attribute of the container,
1362     *  then this has the effect only of making it the active director.
1363     *  If this director already has a container, remove it
1364     *  from that container first.  Otherwise, remove it from
1365     *  the directory of the workspace, if it is present.
1366     *  If the argument is null, then remove it from its container.
1367     *  This director is not added to the workspace directory, so calling
1368     *  this method with a null argument could result in
1369     *  this director being garbage collected.
1370     *  <p>
1371     *  If this method results in removing this director from a container
1372     *  that is a CompositeActor, then this director ceases to be the active
1373     *  director for that CompositeActor.  Moreover, if the composite actor
1374     *  contains any other directors, then the most recently added of those
1375     *  directors becomes the active director.
1376     *  <p>
1377     *  This method is write-synchronized
1378     *  to the workspace and increments its version number.
1379     *  @param container The proposed container.
1380     *  @exception IllegalActionException If the action would result in a
1381     *   recursive containment structure, or if
1382     *   this director and container are not in the same workspace, or
1383     *   if the protected method _checkContainer() throws it.
1384     *  @exception NameDuplicationException If the name of this director
1385     *   collides with a name already in the container.  This will not
1386     *   be thrown if the container argument is an instance of
1387     *   CompositeActor.
1388     */
1389    @Override
1390    public void setContainer(NamedObj container)
1391            throws IllegalActionException, NameDuplicationException {
1392        try {
1393            _workspace.getWriteAccess();
1394
1395            Nameable oldContainer = getContainer();
1396
1397            if (oldContainer instanceof CompositeActor
1398                    && oldContainer != container) {
1399                // Need to remove this director as the active one of the
1400                // old container. Search for another director contained
1401                // by the composite.  If it contains more than one,
1402                // use the most recently added one.
1403                Director previous = null;
1404                CompositeActor castContainer = (CompositeActor) oldContainer;
1405                Iterator<?> directors = castContainer
1406                        .attributeList(Director.class).iterator();
1407
1408                while (directors.hasNext()) {
1409                    Director altDirector = (Director) directors.next();
1410
1411                    // Since we haven't yet removed this director, we have
1412                    // to be sure to not just set it to the active
1413                    // director again.
1414                    if (altDirector != this) {
1415                        previous = altDirector;
1416                    }
1417                }
1418
1419                castContainer._setDirector(previous);
1420            }
1421
1422            super.setContainer(container);
1423
1424            if (container instanceof CompositeActor) {
1425                // Set cached value in composite actor.
1426                ((CompositeActor) container)._setDirector(this);
1427            }
1428        } finally {
1429            _workspace.doneWriting();
1430        }
1431    }
1432
1433    /** Set a new value to the current time of the model, where
1434     *  the new time must be no earlier than the current time.
1435     *  Derived classes will likely override this method to ensure that
1436     *  the time is valid.
1437     *
1438     *  @param newTime The new current simulation time.
1439     *  @exception IllegalActionException If the new time is less than
1440     *  the current time returned by getCurrentTime().
1441     *  @deprecated As of Ptolemy 4.1, replaced by
1442     *  {@link #setModelTime}
1443     *  @see #getCurrentTime()
1444     */
1445    @Deprecated
1446    public void setCurrentTime(double newTime) throws IllegalActionException {
1447        setModelTime(new Time(this, newTime));
1448    }
1449
1450    /** With a false argument, force this director to behave as if it is
1451     *  a top-level director even if it is not. This is used by composite
1452     *  actors such as RunCompositeActor that need for the inside director
1453     *  to behave as if it is running at the top level.
1454     *  @param force False to force this director to behave as if it were
1455     *   not embedded.
1456     *  @see #isEmbedded()
1457     */
1458    public final void setEmbedded(boolean force) {
1459        if (!force) {
1460            _notEmbeddedForced = true;
1461        }
1462    }
1463
1464    /** Set a new value to the current time of the model.
1465     *  @param newTime The new current simulation time.
1466     *  @exception IllegalActionException If the new time is less than
1467     *  the current time returned by getCurrentTime().
1468     *  @see #getModelTime()
1469     */
1470    public void setModelTime(Time newTime) throws IllegalActionException {
1471        localClock.setLocalTime(newTime);
1472    }
1473
1474    /** Set time resolution.
1475     *  @param timeResolution The new time resolution.
1476     *  @see #getTimeResolution()
1477     */
1478    public void setTimeResolution(double timeResolution) {
1479        localClock.setTimeResolution(timeResolution);
1480    }
1481
1482    /** Request that the director cease execution altogether.
1483     *  This causes a call to stop() on all actors contained by
1484     *  the container of this director, and sets a flag
1485     *  so that the next call to postfire() returns false.
1486     *
1487     *  <p> The stop() method requests immediate stopping.  To give
1488     *  determinate stopping, call finish() so that the
1489     *  current iteration is completed.</p>
1490     *
1491     *  <p>In multithreaded domains, Director.stopFire() is called
1492     *  to request that all actors conclude ongoing firings.</p>
1493     *
1494     */
1495    @Override
1496    public void stop() {
1497        // Set _stopRequested first before looping through actors below
1498        // so isStopRequested() more useful while we are still looping
1499        // below.  Kepler's EML2000DataSource needed this.
1500        _stopRequested = true;
1501
1502        Nameable container = getContainer();
1503
1504        if (container instanceof CompositeActor) {
1505            Iterator<?> actors = ((CompositeActor) container).deepEntityList()
1506                    .iterator();
1507
1508            while (actors.hasNext()) {
1509                Actor actor = (Actor) actors.next();
1510                actor.stop();
1511            }
1512        }
1513    }
1514
1515    /** Request that execution of the current iteration stop.
1516     *  In this base class, the request is simply passed on to all actors
1517     *  that are deeply contained by the container of this director.
1518     *  For most domains, an iteration is a finite computation, so nothing
1519     *  further needs to be done here.  However, for some process-oriented
1520     *  domains, the fire() method of the director is an unbounded computation.
1521     *  Those domains should override this method so that when it is called,
1522     *  it does whatever it needs to do to get the fire() method to return.
1523     *  Typically, it will set flags that will cause all executing threads
1524     *  to suspend.  These domains should suspend execution in such a way
1525     *  that if the fire() method is called again, execution will
1526     *  resume at the point where it was suspended.  However, they should
1527     *  not assume the fire() method will be called again.  It is possible
1528     *  that the wrapup() method will be called next.
1529     *  If the container is not an instance of CompositeActor, then this
1530     *  method does nothing.
1531     */
1532    @Override
1533    public void stopFire() {
1534        Nameable container = getContainer();
1535
1536        if (container instanceof CompositeActor) {
1537            Iterator<?> actors = ((CompositeActor) container).deepEntityList()
1538                    .iterator();
1539
1540            while (actors.hasNext()) {
1541                Actor actor = (Actor) actors.next();
1542                actor.stopFire();
1543            }
1544        }
1545    }
1546
1547    /** Return an array of suggested directors to be used with
1548     *  ModalModel. Each director is specified by its full class
1549     *  name.  The first director in the array will be the default
1550     *  director used by a modal model. This base class delegates
1551     *  to the executive director, if there is one, and otherwise
1552     *  returns an array with only one element,
1553     *  "ptolemy.domains.modal.kernel.FSMDirector".
1554     *  @return An array of suggested directors to be used with ModalModel.
1555     */
1556    public String[] suggestedModalModelDirectors() {
1557        NamedObj container = getContainer();
1558        if (container instanceof Actor) {
1559            Director executiveDirector = ((Actor) container)
1560                    .getExecutiveDirector();
1561            // Some composites, such as RunCompositeActor want to be treated
1562            // as if they are at the top level even though they have an executive
1563            // director, so be sure to check _isTopLevel().
1564            if (executiveDirector != null && !_isTopLevel()) {
1565                return executiveDirector.suggestedModalModelDirectors();
1566            }
1567        }
1568        // Default is just one suggestion.
1569        String[] defaultSuggestions = {
1570                "ptolemy.domains.modal.kernel.FSMDirector" };
1571        return defaultSuggestions;
1572    }
1573
1574    /** Return a boolean to indicate whether a ModalModel under control
1575     *  of this director supports multirate firing. In this class, false
1576     *  is always returned. Subclasses may override this method to return true.
1577     *  @return False indicating a ModalModel under control of this director
1578     *  does not support multirate firing.
1579     */
1580    public boolean supportMultirateFiring() {
1581        return false;
1582    }
1583
1584    /** Suspend the actor at the specified time. This will stop the local
1585     *  clock.
1586     */
1587    public void suspend() {
1588        localClock.stop();
1589    }
1590
1591    /** Terminate any currently executing model with extreme prejudice.
1592     *  This method is not intended to be used as a normal route of
1593     *  stopping execution. To normally stop execution, call the finish()
1594     *  method instead. This method should be called only
1595     *  when execution fails to terminate by normal means due to certain
1596     *  kinds of programming errors (infinite loops, threading errors, etc.).
1597     *  There is no assurance that the topology will be in a consistent
1598     *  state after this method returns.  The
1599     *  topology should probably be recreated before attempting any
1600     *  further operations.
1601     *  <p>
1602     *  This base class recursively calls terminate() on all actors deeply
1603     *  contained by the container of this director. Derived classes should
1604     *  override this method to release all resources in use and kill
1605     *  any sub-threads.  Derived classes should not synchronize this
1606     *  method because it should execute as soon as possible.
1607     *  If the container is not an instance of CompositeActor, then
1608     *  this method does nothing.</p>
1609     */
1610    @Override
1611    public void terminate() {
1612        Nameable container = getContainer();
1613
1614        if (container instanceof CompositeActor) {
1615            Iterator<?> actors = ((CompositeActor) container).deepEntityList()
1616                    .iterator();
1617
1618            while (actors.hasNext()) {
1619                Actor actor = (Actor) actors.next();
1620                actor.terminate();
1621            }
1622        }
1623    }
1624
1625    /** Transfer data from an input port of the container to the ports
1626     *  it is connected to on the inside.  The implementation in this
1627     *  base class transfers at most one token.  Derived classes may override
1628     *  this method to transfer a domain-specific number of tokens.
1629     *
1630     *  @param port The port to transfer tokens from.
1631     *  @return True if at least one data token is transferred.
1632     *  @exception IllegalActionException If the port is not an opaque
1633     *  input port.
1634     */
1635    public boolean transferInputs(IOPort port) throws IllegalActionException {
1636        // Use a strategy pattern here so that the code that transfers
1637        // at most one token is available to any derived class.
1638        return _transferInputs(port);
1639    }
1640
1641    /** Transfer data from all output ports of the container to the
1642     *  ports they are connected to on the outside. This base class
1643     *  iterates over the ports in their natural order and delegates to
1644     *  {@link #transferOutputs(IOPort)} to actually do the transfer.
1645     *  Override this method if you need to change the order in which
1646     *  the transfers occur.
1647     *  @exception IllegalActionException Not thrown in this base class.
1648     */
1649    public void transferOutputs() throws IllegalActionException {
1650        NamedObj container = getContainer();
1651        if (container instanceof Actor) {
1652            List<IOPort> outports = ((Actor) container).outputPortList();
1653            for (IOPort port : outports) {
1654                transferOutputs(port);
1655            }
1656        }
1657    }
1658
1659    /** Transfer data from an output port of the container to the
1660     *  ports it is connected to on the outside.  The implementation
1661     *  in this base class transfers at most
1662     *  one token, but derived classes may transfer more than one
1663     *  token.
1664     *  @param port The port to transfer tokens from.
1665     *  @return True if at least one data token is transferred.
1666     *  @exception IllegalActionException If the port is not an opaque
1667     *  output port.
1668     */
1669    public boolean transferOutputs(IOPort port) throws IllegalActionException {
1670        // Use a strategy pattern here so that the code that transfers
1671        // at most one token is available to any derived class.
1672        return _transferOutputs(port);
1673    }
1674
1675    /** Invoke the wrapup() method of all the actors contained in the
1676     *  director's container.   In this base class wrapup() is called on the
1677     *  associated actors in the order of their creation.  If the container
1678     *  is not an instance of CompositeActor, then this method does nothing.
1679     *  <p>
1680     *  This method should be invoked once per execution.  None of the other
1681     *  action methods should be invoked after it in the execution.
1682     *  This method is <i>not</i> synchronized on the workspace, so the
1683     *  caller should be.
1684     *
1685     *  @exception IllegalActionException If the wrapup() method of
1686     *   one of the associated actors throws it.
1687     */
1688    @Override
1689    public void wrapup() throws IllegalActionException {
1690        // FIXME: Note that ProcessDirector and the inner director in
1691        // gt TransformationRule do not invoke this method, so changes
1692        // made here might apply to ProcessDirector.wrapup().
1693
1694        if (_debugging) {
1695            _debug("Director: Called wrapup().");
1696        }
1697
1698        // Collect all the exception messages that occur, but ensure that each
1699        // wrapup method is called.
1700        List<Throwable> exceptions = new LinkedList<Throwable>();
1701
1702        // First invoke initializable methods.
1703        if (_initializables != null) {
1704            for (Initializable initializable : _initializables) {
1705                try {
1706                    initializable.wrapup();
1707                } catch (Throwable ex) {
1708                    exceptions.add(ex);
1709                }
1710            }
1711        }
1712
1713        Nameable container = getContainer();
1714
1715        if (container instanceof CompositeActor) {
1716            Iterator<?> actors = ((CompositeActor) container).deepEntityList()
1717                    .iterator();
1718
1719            while (actors.hasNext()) {
1720                Actor actor = (Actor) actors.next();
1721                try {
1722                    actor.wrapup();
1723                } catch (Throwable ex) {
1724                    exceptions.add(ex);
1725                }
1726            }
1727        }
1728        if (exceptions.size() > 0) {
1729            StringBuffer message = new StringBuffer(
1730                    "Exceptions occurred during wrapup:\n");
1731            for (Throwable ex : exceptions) {
1732                message.append(ex);
1733                message.append("\n");
1734            }
1735            throw new IllegalActionException(this, exceptions.get(0),
1736                    message.toString());
1737        }
1738    }
1739
1740    ///////////////////////////////////////////////////////////////////
1741    ////                         protected methods                 ////
1742
1743    /** Return true if the actor finished execution.
1744     *  @param actor The actor.
1745     *  @return True if the actor finished execution.
1746     */
1747    protected boolean _actorFinished(NamedObj actor) {
1748        return _aspectForActor.get(actor) != null
1749                && _aspectForActor.get(actor).lastScheduledActorFinished();
1750    }
1751
1752    /** Consult all attributes contained by the container of this director
1753     *  that implement the {@link TimeRegulator} interface, if any, and return the
1754     *  smallest time returned by those regulators. If there are no such
1755     *  attributes, return the proposedTime argument.
1756     *  @param proposedTime The time proposed.
1757     *  @return The smallest time returned by a TimeRegulator, or the
1758     *   proposedTime if none.
1759     *  @exception IllegalActionException If a time regulator throws it.
1760     */
1761    protected Time _consultTimeRegulators(Time proposedTime)
1762            throws IllegalActionException {
1763        Time returnValue = proposedTime;
1764        List<TimeRegulator> regulators = getContainer()
1765                .attributeList(TimeRegulator.class);
1766        for (TimeRegulator regulator : regulators) {
1767            Time modifiedTime = regulator.proposeTime(returnValue);
1768            if (modifiedTime.compareTo(returnValue) < 0) {
1769                returnValue = modifiedTime;
1770            }
1771        }
1772        return returnValue;
1773    }
1774
1775    /** Return a description of the object.  The level of detail depends
1776     *  on the argument, which is an or-ing of the static final constants
1777     *  defined in the NamedObj class.  Lines are indented according to
1778     *  to the level argument using the protected method _getIndentPrefix().
1779     *  Zero, one or two brackets can be specified to surround the returned
1780     *  description.  If one is specified it is the the leading bracket.
1781     *  This is used by derived classes that will append to the description.
1782     *  Those derived classes are responsible for the closing bracket.
1783     *  An argument other than 0, 1, or 2 is taken to be equivalent to 0.
1784     *  This method is read-synchronized on the workspace.
1785     *  @param detail The level of detail.
1786     *  @param indent The amount of indenting.
1787     *  @param bracket The number of surrounding brackets (0, 1, or 2).
1788     *  @return A description of the object.
1789     *  @exception IllegalActionException If thrown while getting the
1790     *  description of subcomponents.
1791     */
1792    @Override
1793    protected String _description(int detail, int indent, int bracket)
1794            throws IllegalActionException {
1795        try {
1796            _workspace.getReadAccess();
1797
1798            String result;
1799
1800            if (bracket == 1 || bracket == 2) {
1801                result = super._description(detail, indent, 1);
1802            } else {
1803                result = super._description(detail, indent, 0);
1804            }
1805
1806            // FIXME: Add director-specific information here, like
1807            // what is the state of the director.
1808            // if ((detail & FIXME) != 0 ) {
1809            //  if (result.trim().length() > 0) {
1810            //      result += " ";
1811            //  }
1812            //  result += "FIXME {\n";
1813            //  result += _getIndentPrefix(indent) + "}";
1814            // }
1815            if (bracket == 2) {
1816                result += "}";
1817            }
1818
1819            return result;
1820        } finally {
1821            _workspace.doneReading();
1822        }
1823    }
1824
1825    /** Return true if this director is embedded inside an opaque composite
1826     *  actor contained by another composite actor.
1827     *  @return True if this directory is embedded inside an opaque composite
1828     *  actor contained by another composite actor.
1829     * @deprecated Use {@link #isEmbedded()} instead
1830     */
1831    @Deprecated
1832    protected boolean _isEmbedded() {
1833        return isEmbedded();
1834    }
1835
1836    /** Return true if this is a top-level director, or if it should
1837     *  always be handled as if it were a top-level director.
1838     *  Parts of this method is read synchronized on the workspace.
1839     * @return True if this director is at the top-level.
1840     */
1841    protected boolean _isTopLevel() {
1842        if (_notEmbeddedForced) {
1843            return true;
1844        }
1845        NamedObj container = getContainer();
1846
1847        // NOTE: the container may not be a composite actor.
1848        // For example, the container may be an entity as a library,
1849        // where the director is already at the top level.
1850        if (container instanceof CompositeActor) {
1851            if (((CompositeActor) container).getExecutiveDirector() == null) {
1852                return true;
1853            } else {
1854                return false;
1855            }
1856        }
1857
1858        return true;
1859    }
1860
1861    /** Find the ExecutionAspect for the actor. Only one ExecutionAspect
1862     *  is returned at this point.
1863     *  @param actor The actor to be scheduled.
1864     *  @return The aspect.
1865     *  @exception IllegalActionException If thrown while getting the
1866     *  enable token or the decorator.
1867     */
1868    public ActorExecutionAspect getExecutionAspect(NamedObj actor)
1869            throws IllegalActionException {
1870        if (_aspectForActor == null) {
1871            _aspectForActor = new HashMap<NamedObj, ActorExecutionAspect>();
1872        }
1873        ActorExecutionAspect result = _aspectForActor.get(actor);
1874        if (result == null) {
1875            for (ExecutionAttributes executionAttributes : actor
1876                    .attributeList(ExecutionAttributes.class)) {
1877                if (((BooleanToken) executionAttributes.enable.getToken())
1878                        .booleanValue()) {
1879                    result = (ActorExecutionAspect) executionAttributes
1880                            .getDecorator();
1881                    _aspectForActor.put(actor, result);
1882                    break;
1883                }
1884            }
1885        }
1886        return result;
1887    }
1888
1889    /** Transfer at most one data token from the given input port of
1890     *  the container to the ports it is connected to on the inside.
1891     *  This method delegates the operation to the IOPort, so that the
1892     *  subclass of IOPort, TypedIOPort, can override this method to
1893     *  perform run-time type conversion.
1894     *
1895     *  @param port The port to transfer tokens from.
1896     *  @return True if at least one data token is transferred.
1897     *  @exception IllegalActionException If the port is not an opaque
1898     *  input port.
1899     *  @see IOPort#transferInputs
1900     */
1901    protected boolean _transferInputs(IOPort port)
1902            throws IllegalActionException {
1903        if (_debugging) {
1904            _debug("Calling transferInputs on port: " + port.getFullName());
1905        }
1906
1907        if (!port.isInput() || !port.isOpaque()) {
1908            throw new IllegalActionException(this, port,
1909                    "Attempted to transferInputs on a port is not an opaque"
1910                            + "input port.");
1911        }
1912
1913        boolean wasTransferred = false;
1914
1915        for (int i = 0; i < port.getWidth(); i++) {
1916            try {
1917                if (i < port.getWidthInside()) {
1918                    if (port.hasToken(i)) {
1919                        Token t = port.get(i);
1920
1921                        if (_debugging) {
1922                            _debug("Transferring input " + t + " from "
1923                                    + port.getName());
1924                        }
1925
1926                        port.sendInside(i, t);
1927                        wasTransferred = true;
1928                    }
1929                } else {
1930                    // No inside connection to transfer tokens to.
1931                    // In this case, consume one input token if there is one.
1932                    if (_debugging) {
1933                        _debug(getName(),
1934                                "Dropping single input from " + port.getName());
1935                    }
1936
1937                    if (port.isKnown() && port.hasToken(i)) {
1938                        port.get(i);
1939                    }
1940                }
1941            } catch (NoTokenException ex) {
1942                // this shouldn't happen.
1943                throw new InternalErrorException(this, ex, null);
1944            }
1945        }
1946
1947        return wasTransferred;
1948    }
1949
1950    /** Transfer at most one data token from the given output port of
1951     *  the container to the ports it is connected to on the outside..
1952     *  @param port The port to transfer tokens from.
1953     *  @return True if the port has an inside token that was successfully
1954     *  transferred.  Otherwise return false (or throw an exception).
1955     *  @exception IllegalActionException If the port is not an opaque
1956     *  output port
1957     *
1958     */
1959    protected boolean _transferOutputs(IOPort port)
1960            throws IllegalActionException {
1961        boolean result = false;
1962        if (_debugging) {
1963            _debug("Calling transferOutputs on port: " + port.getFullName());
1964        }
1965
1966        if (!port.isOutput() || !port.isOpaque()) {
1967            throw new IllegalActionException(this, port,
1968                    "Attempted to transferOutputs on a port that "
1969                            + "is not an opaque input port.");
1970        }
1971
1972        for (int i = 0; i < port.getWidthInside(); i++) {
1973            try {
1974                if (port.hasTokenInside(i)) {
1975                    Token t = port.getInside(i);
1976
1977                    if (_debugging) {
1978                        _debug(getName(), "transferring output " + t + " from "
1979                                + port.getName());
1980                    }
1981
1982                    port.send(i, t);
1983                    result = true;
1984                }
1985            } catch (NoTokenException ex) {
1986                // this shouldn't happen.
1987                throw new InternalErrorException(this, ex, null);
1988            }
1989        }
1990        return result;
1991    }
1992
1993    /** Schedule an actor for execution on a ExecutionAspect. If the actor can
1994     *  execute this method returns true. If resources are not available this
1995     *  method returns false.
1996     *  @param actor The actor.
1997     *  @param timestamp The time the actor requests to be scheduled.
1998     *  @return True if actor was scheduled and can be fired.
1999     *  @exception IllegalActionException Thrown if parameters cannot be read, actor cannot be
2000     *   scheduled or container cannot be fired at future time.
2001     */
2002    protected boolean _schedule(NamedObj actor, Time timestamp)
2003            throws IllegalActionException {
2004        ActorExecutionAspect aspect = getExecutionAspect(actor);
2005        Time time = null;
2006        Boolean finished = true;
2007        if (timestamp == null) {
2008            timestamp = getModelTime();
2009        }
2010        if (aspect != null) {
2011            Time environmentTime = ((CompositeActor) aspect.getContainer())
2012                    .getDirector().getEnvironmentTime();
2013            time = ExecutionAspectHelper.schedule(aspect, actor,
2014                    environmentTime, getDeadline(actor, timestamp));
2015            if (_nextScheduleTime == null) {
2016                _nextScheduleTime = new HashMap<ActorExecutionAspect, Time>();
2017            }
2018            _nextScheduleTime.put(aspect, time);
2019            finished = _actorFinished(actor);
2020            if (time != null && time.getDoubleValue() > 0.0) {
2021                CompositeActor container = (CompositeActor) aspect
2022                        .getContainer();
2023                Time fireAtTime = environmentTime;
2024                if (!time.equals(Time.POSITIVE_INFINITY)) {
2025                    fireAtTime = fireAtTime.add(time);
2026                    container.getDirector().fireContainerAt(fireAtTime);
2027                }
2028            }
2029        }
2030        return time == null || finished;
2031    }
2032
2033    /** Set of actors that have returned false from  postfire(),
2034     *  indicating that they do not wish to be iterated again.
2035     */
2036    protected Set _actorsFinishedExecution;
2037
2038    /** Contains a map of actors and the ExecutionAspect that is specified for the actor. */
2039    protected HashMap<NamedObj, ActorExecutionAspect> _aspectForActor;
2040
2041    /** True if any of the directed actors specifies a ExecutionAspect
2042     *  in the parameters and this ExecutionAspect exists on this or
2043     *  a hierarchy level above (i.e. has not been deleted).
2044     */
2045    protected boolean _aspectsPresent;
2046
2047    /** The director's default microstep. */
2048    protected int _defaultMicrostep;
2049
2050    /** ExecutionAspects in the container of this director.
2051     */
2052    protected List<ActorExecutionAspect> _executionAspects;
2053
2054    /** Indicator that finish() has been called. */
2055    protected boolean _finishRequested;
2056
2057    /** Set of objects whose (pre)initialize() and wrapup() methods
2058     *  should be slaved to these.
2059     */
2060    protected transient Set<Initializable> _initializables;
2061
2062    /** Next time the aspect wants to be executed. */
2063    protected HashMap<ActorExecutionAspect, Time> _nextScheduleTime;
2064
2065    /** Flag set to true if a token has been sent to a communication aspect
2066     *  by any port/receiver where the aspect is enabled.
2067     */
2068    protected boolean _tokenSentToCommunicationAspect;
2069
2070    /** Indicator that a stop has been requested by a call to stop(). */
2071    protected boolean _stopRequested = false;
2072
2073    /** Time with value 0.0. */
2074    protected Time _zeroTime;
2075
2076    ///////////////////////////////////////////////////////////////////
2077    ////                         private methods                   ////
2078    // Add an XML graphic as a hint to UIs for rendering the director.
2079    private void _addIcon() {
2080        _attachText("_iconDescription",
2081                "<svg>\n" + "<rect x=\"-50\" y=\"-15\" "
2082                        + "width=\"100\" height=\"30\" "
2083                        + "style=\"fill:green\"/>\n" + "</svg>\n");
2084    }
2085
2086    /** Create receivers for all contained actors.
2087     *  @exception IllegalActionException If any port of a contained
2088     *  actor throws it when its receivers are created.
2089     *  @see Actor#createReceivers
2090     */
2091    private void _createReceivers() throws IllegalActionException {
2092        Nameable container = getContainer();
2093        if (container instanceof CompositeActor) {
2094            for (Object actor : ((CompositeActor) container).deepEntityList()) {
2095                ((Actor) actor).createReceivers();
2096            }
2097        }
2098    }
2099
2100    /** Initialize parameters. This is called by the constructor.
2101     *  @exception IllegalActionException
2102     *  @exception NameDuplicationException
2103     */
2104    private void _initializeParameters()
2105            throws IllegalActionException, NameDuplicationException {
2106        localClock = new LocalClock(this, "localClock");
2107
2108        startTime = new Parameter(this, "startTime");
2109        startTime.setTypeEquals(BaseType.DOUBLE);
2110
2111        stopTime = new Parameter(this, "stopTime");
2112        stopTime.setTypeEquals(BaseType.DOUBLE);
2113
2114        _defaultMicrostep = 0;
2115
2116    }
2117
2118    ///////////////////////////////////////////////////////////////////
2119    ////                         private variables                 ////
2120
2121    /** Flag indicating that this director has been forced to behave
2122     *  as if it were at the top level.
2123     */
2124    private transient boolean _notEmbeddedForced = false;
2125
2126    /** Start time. */
2127    private transient Time _startTime;
2128
2129    /** Stop time. */
2130    private transient Time _stopTime;
2131
2132}