/* | 
|
 * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. | 
|
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | 
|
 * | 
|
 * This code is free software; you can redistribute it and/or modify it | 
|
 * under the terms of the GNU General Public License version 2 only, as | 
|
 * published by the Free Software Foundation.  Oracle designates this | 
|
 * particular file as subject to the "Classpath" exception as provided | 
|
 * by Oracle in the LICENSE file that accompanied this code. | 
|
 * | 
|
 * This code is distributed in the hope that it will be useful, but WITHOUT | 
|
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | 
|
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License | 
|
 * version 2 for more details (a copy is included in the LICENSE file that | 
|
 * accompanied this code). | 
|
 * | 
|
 * You should have received a copy of the GNU General Public License version | 
|
 * 2 along with this work; if not, write to the Free Software Foundation, | 
|
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | 
|
 * | 
|
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | 
|
 * or visit www.oracle.com if you need additional information or have any | 
|
 * questions. | 
|
*/  | 
|
package sun.java2d;  | 
|
/** | 
|
 * This interface is implemented by classes which contain complex state | 
|
 * so that other objects can track whether or not their state has changed | 
|
 * since earlier interactions with the object. | 
|
 * <p> | 
|
 * The suggested usage pattern for code that manages some trackable data | 
|
 * is as follows: | 
|
 * <pre> | 
|
 * class Trackable implements StateTrackable { | 
|
 *     TrackedInfo data; | 
|
 *     State curState = STABLE; | 
|
 *     StateTracker curTracker = null; | 
|
 *     // Hypothetical method to return a static piece of our tracked data. | 
|
 *     // Assume that Datum is either a copy of some piece of the tracked | 
|
 *     // data or that it is itself immutable. | 
|
 *     public Datum getSomeDatum(int key) { | 
|
 *         // No need to modify the state for this type of "get" call. | 
|
 *         return data.getDatum(key); | 
|
 *     } | 
|
 *     // Hypothetical method to return a raw reference to our tracked data. | 
|
 *     public TrackedInfo getRawHandleToInfo() { | 
|
 *         // Since we are returning a raw reference to our tracked | 
|
 *         // data and since we can not track what the caller will | 
|
 *         // do with that reference, we can no longer track the | 
|
 *         // state of this data. | 
|
 *         synchronized (this) { | 
|
 *             // Note: modifying both curState and curTracker requires | 
|
 *             // synchronization against the getStateTracker method. | 
|
 *             curState = UNTRACKABLE; | 
|
 *             curTracker = null; | 
|
 *         } | 
|
 *         return data; | 
|
 *     } | 
|
 *     // Hypothetical method to set a single piece of data to some | 
|
 *     // new static value. | 
|
 *     public void setSomeDatum(int key, Datum datum) { | 
|
 *         data.setDatum(key, datum); | 
|
 *         // We do not need to change state for this, we simply | 
|
 *         // invalidate the outstanding StateTracker objects. | 
|
 *         // Note: setting curTracker to null requires no synchronization. | 
|
 *         curTracker = null; | 
|
 *     } | 
|
 *     // getStateTracker must be synchronized against any code that | 
|
 *     // changes the State. | 
|
 *     public synchronized StateTracker getStateTracker() { | 
|
 *         StateTracker st = curTracker; | 
|
 *         if (st == null) { | 
|
 *             switch (curState) { | 
|
 *                 case IMMUTABLE:   st = StateTracker.ALWAYS_CURRENT; break; | 
|
 *                 case STABLE:      st = new Tracker(this); break; | 
|
 *                 case DYNAMIC:     st = StateTracker.NEVER_CURRENT; break; | 
|
 *                 case UNTRACKABLE: st = StateTracker.NEVER_CURRENT; break; | 
|
 *             } | 
|
 *             curTracker = st; | 
|
 *         } | 
|
 *         return st; | 
|
 *     } | 
|
 * | 
|
 *     static class Tracker implements StateTracker { | 
|
 *         Trackable theTrackable; | 
|
 *         public Tracker(Trackable t) { | 
|
 *             theTrackable = t; | 
|
 *         } | 
|
 *         public boolean isCurrent() { | 
|
 *             return (theTrackable.curTracker == this); | 
|
 *         } | 
|
 *     } | 
|
 * } | 
|
 * </pre> | 
|
 * Note that the mechanism shown above for invalidating outstanding | 
|
 * StateTracker objects is not the most theoretically conservative | 
|
 * way to implement state tracking in a "set" method. | 
|
 * There is a small window of opportunity after the data has changed | 
|
 * before the outstanding StateTracker objects are invalidated and | 
|
 * where they will indicate that the data is still the same as when | 
|
 * they were instantiated. | 
|
 * While this is technically inaccurate, it is acceptable since the more | 
|
 * conservative approaches to state management are much more complex and | 
|
 * cost much more in terms of performance for a very small gain in | 
|
 * correctness. | 
|
 * For example: | 
|
 * <p> | 
|
 * The most conservative approach would be to synchronize all accesses | 
|
 * and all modifications to the data, including its State. | 
|
 * This would require synchronized blocks around some potentially large | 
|
 * bodies of code which would impact the multi-threaded scalability of | 
|
 * the implementation. | 
|
 * Further, if data is to be coordinated or transferred between two | 
|
 * trackable objects then both would need to be synchronized raising | 
|
 * the possibility of deadlock unless some strict rules of priority | 
|
 * for the locking of the objects were established and followed | 
|
 * religiously. | 
|
 * Either or both of these drawbacks makes such an implementation | 
|
 * infeasible. | 
|
 * <p> | 
|
 * A less conservative approach would be to change the state of the | 
|
 * trackable object to DYNAMIC during all modifications of the data | 
|
 * and then to change it back to STABLE after those modifications | 
|
 * are complete. | 
|
 * While this state transition more accurately reflects the temporary | 
|
 * loss of tracking during the modification phase, in reality the | 
|
 * time period of the modifications would be small in most cases | 
|
 * and the 2 changes of state would each require synchronization. | 
|
 * <p> | 
|
 * In comparison the act of setting the <code>curTracker</code> | 
|
 * reference to null in the usage pattern above effectively invalidates | 
|
 * all outstanding <code>Tracker</code> objects as soon as possible | 
|
 * after the change to the data and requires very little code and no | 
|
 * synchronization to implement. | 
|
 * <p> | 
|
 * In the end it is up to the implementor of a StateTrackable object | 
|
 * how fine the granularity of State updates should be managed based | 
|
 * on the frequency and atomicity of the modifications and the | 
|
 * consequences of returning an inaccurate State for a particularly | 
|
 * small window of opportunity. | 
|
 * Most implementations are likely to follow the liberal, but efficient | 
|
 * guidelines found in the usage pattern proposed above. | 
|
 * | 
|
 * @since 1.7 | 
|
*/  | 
|
public interface StateTrackable { | 
|
    /** | 
|
     * An enumeration describing the current state of a trackable | 
|
     * object. | 
|
     * These values describe how often the complex data contained | 
|
     * in a trackable object can be changed and whether or not it | 
|
     * makes sense to try to track the data in its current state. | 
|
     * @see StateTrackable#getState | 
|
     * @since 1.7 | 
|
*/  | 
|
    public enum State { | 
|
        /** | 
|
         * The complex data will never change again. | 
|
         * Information related to the current contents of the complex | 
|
         * data can be calculated and cached indefinitely with no | 
|
         * further checks to see if the information is stale. | 
|
*/  | 
|
IMMUTABLE,  | 
|
        /** | 
|
         * The complex data is currently stable, but could change at | 
|
         * some point in the future. | 
|
         * Information related to the current contents of the complex | 
|
         * data can be calculated and cached, but a StateTracker should | 
|
         * be used to verify the freshness of such precalculated data | 
|
         * before each future use. | 
|
*/  | 
|
STABLE,  | 
|
        /** | 
|
         * The complex data is currently in flux and is frequently | 
|
         * changing. | 
|
         * While information related to the current contents of the | 
|
         * complex data could be calculated and cached, there is a | 
|
         * reasonably high probability that the cached information | 
|
         * would be found to be out of date by the next time it is | 
|
         * used. | 
|
         * It may also be the case that the current contents are | 
|
         * temporarily untrackable, but that they may become trackable | 
|
         * again in the future. | 
|
*/  | 
|
DYNAMIC,  | 
|
        /** | 
|
         * The complex data can currently be changed by external | 
|
         * references and agents in a way that cannot be tracked. | 
|
         * If any information about the current contents of the complex | 
|
         * data were to be cached, there would be no way to determine | 
|
         * whether or not that cached information was out of date. | 
|
*/  | 
|
UNTRACKABLE,  | 
|
};  | 
|
    /** | 
|
     * Returns the general state of the complex data held by this | 
|
     * object. | 
|
     * This return value can be used to determine if it makes | 
|
     * strategic sense to try and cache information about the current | 
|
     * contents of this object. | 
|
     * The StateTracker returned from the getStateTracker() method | 
|
     * will further aid in determining when the data has been | 
|
     * changed so that the caches can be verified upon future uses. | 
|
     * @return the current state of trackability of the complex | 
|
     * data stored in this object. | 
|
     * @see #getStateTracker | 
|
     * @since 1.7 | 
|
*/  | 
|
public State getState();  | 
|
    /** | 
|
     * Returns an object which can track future changes to the | 
|
     * complex data stored in this object. | 
|
     * If an external agent caches information about the complex | 
|
     * data of this object, it should first get a StateTracker | 
|
     * object from this method so that it can check if such | 
|
     * information is current upon future uses. | 
|
     * Note that a valid StateTracker will always be returned | 
|
     * regardless of the return value of getState(), but in some | 
|
     * cases the StateTracker may be a trivial implementation | 
|
     * which always returns the same value from its | 
|
     * {@link StateTracker#isCurrent isCurrent} method. | 
|
     * <ul> | 
|
     * <li>If the current state is {@link State#IMMUTABLE IMMUTABLE}, | 
|
     * this StateTracker and any future StateTracker objects | 
|
     * returned from this method will always indicate that | 
|
     * the state has not changed.</li> | 
|
     * <li>If the current state is {@link State#UNTRACKABLE UNTRACKABLE}, | 
|
     * this StateTracker and any future StateTracker objects | 
|
     * returned from this method will always indicate that | 
|
     * the state has changed.</li> | 
|
     * <li>If the current state is {@link State#DYNAMIC DYNAMIC}, | 
|
     * this StateTracker may always indicate that the current | 
|
     * state has changed, but another StateTracker returned | 
|
     * from this method in the future when the state has changed | 
|
     * to {@link State#STABLE STABLE} will correctly track changes.</li> | 
|
     * <li>Otherwise the current state is {@link State#STABLE STABLE} | 
|
     * and this StateTracker will indicate whether or not the | 
|
     * data has changed since the time at which it was fetched | 
|
     * from the object.</li> | 
|
     * </ul> | 
|
     * @return an object implementing the StateTracker interface | 
|
     * that tracks whether changes have been made to the complex | 
|
     * contents of this object since it was returned. | 
|
     * @see State | 
|
     * @see #getState | 
|
     * @since 1.7 | 
|
*/  | 
|
public StateTracker getStateTracker();  | 
|
}  |