001/* Interface for objects that support deferrable change requests.
002
003 Copyright (c) 2003-2013 The Regents of the University of California.
004 All rights reserved.
005 Permission is hereby granted, without written agreement and without
006 license or royalty fees, to use, copy, modify, and distribute this
007 software and its documentation for any purpose, provided that the above
008 copyright notice and the following two paragraphs appear in all copies
009 of this software.
010
011 IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
012 FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
013 ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
014 THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
015 SUCH DAMAGE.
016
017 THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
018 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
019 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
020 PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
021 CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
022 ENHANCEMENTS, OR MODIFICATIONS.
023
024 PT_COPYRIGHT_VERSION_2
025 COPYRIGHTENDKEY
026 */
027package ptolemy.kernel.util;
028
029///////////////////////////////////////////////////////////////////
030//// Changeable
031
032/**
033 This is an interface for objects that support change requests that can
034 be deferred.  A change request is any
035 modification to a model that might be performed during execution of the
036 model, but where there might only be certain phases of execution during
037 which it is safe to make the modification.  Such changes are also called
038 <i>mutations</i>.
039 <p>
040 A change request is typically made by instantiating a subclass of
041 ChangeRequest (possibly using an anonymous inner class) and then passing
042 it to the requestChange() method of an object implementing this interface.
043 That object may delegate the request (for example, it might consolidate
044 all such requests at the top level of the hierarchy by passing the
045 request to its container).  If it does delegate, then it is expected
046 to consistently delegate all commands to the same object.
047 <p>
048 When a change request is made, if it is safe to do so, then an
049 implementor of this interface is free to immediately execute
050 the request, unless setDeferringChangeRequests(true) has been called.
051 It is never safe to execute a change request if the implementor
052 is already in the middle of executing a change request (that
053 execution may have triggered the request).
054
055 @author Edward A. Lee
056 @version $Id$
057 @since Ptolemy II 4.0
058 @Pt.ProposedRating Green (eal)
059 @Pt.AcceptedRating Green (neuendor)
060 @see ChangeRequest
061 */
062public interface Changeable {
063    ///////////////////////////////////////////////////////////////////
064    ////                         public methods                    ////
065
066    /** Add a change listener. Each listener
067     *  will be notified of the execution (or failure) of each
068     *  change request that is executed via the requestChange() method.
069     *  Implementors are free to delegate both the request and the
070     *  listener to other objects (e.g. the container), so the listener
071     *  may be notified of more changes than those requested through
072     *  the requestChange() method of this object. Implementors are
073     *  required to not add a listener that is already on the list
074     *  of listeners (i.e., objects should not appear more than once
075     *  on the list).
076     *  @param listener The listener to add.
077     *  @see #removeChangeListener(ChangeListener)
078     *  @see #requestChange(ChangeRequest)
079     */
080    public void addChangeListener(ChangeListener listener);
081
082    /** Execute requested changes. An implementor is free to delegate
083     *  this to another implementor of Changeable. An implementor
084     *  is expected to execute all pending change requests (even
085     *  if setDeferringChangeRequests() has been
086     *  called with a true argument).  Listeners will be notified
087     *  of success or failure.
088     *  @see #addChangeListener(ChangeListener)
089     *  @see #requestChange(ChangeRequest)
090     *  @see #setDeferringChangeRequests(boolean)
091     */
092    public void executeChangeRequests();
093
094    /** Return true if setDeferringChangeRequests(true) has been called
095     *  to specify that change requests should be deferred.
096     *  @return True if change requests are being deferred.
097     *  @see #setDeferringChangeRequests(boolean)
098     */
099    public boolean isDeferringChangeRequests();
100
101    /** Remove a change listener, if it is present, and otherwise
102     *  do nothing.
103     *  @param listener The listener to remove.
104     *  @see #addChangeListener(ChangeListener)
105     */
106    public void removeChangeListener(ChangeListener listener);
107
108    /** Request that the given change be executed. An implementor is free
109     *  to delegate this request to another object (e.g. the container).
110     *  It may also execute the request immediately,
111     *  unless this object is deferring change requests. If
112     *  setDeferChangeRequests() has been called with a true argument,
113     *  then an implementor is expected to queue the request until
114     *  either setDeferChangeRequests() is called with a false
115     *  argument or executeChangeRequests() is called.
116     *  If an implementor is already in the middle of executing a change
117     *  request, then the implementor is expected to finish that
118     *  execution before executing this one.
119     *  Change listeners will be notified of success (or failure) of the
120     *  request when it is executed.
121     *  @param change The requested change.
122     *  @see #executeChangeRequests()
123     *  @see #setDeferringChangeRequests(boolean)
124     */
125    public void requestChange(ChangeRequest change);
126
127    /** Specify whether change requests made by calls to requestChange()
128     *  should be executed immediately. An implementor is free to delegate
129     *  this to another object implementing Changeable (e.g. the container).
130     *  If the argument is true, then an implementor is expected to
131     *  queue requests until either this method is called again
132     *  with argument false, or until executeChangeRequests() is called.
133     *  If the argument is false, then execute any pending change requests
134     *  and set a flag requesting that future requests be executed
135     *  immediately.
136     *  @param isDeferring If true, defer change requests.
137     *  @see #addChangeListener(ChangeListener)
138     *  @see #executeChangeRequests()
139     *  @see #isDeferringChangeRequests()
140     *  @see #requestChange(ChangeRequest)
141     */
142    public void setDeferringChangeRequests(boolean isDeferring);
143}