com.threerings.media
Class FrameManager

java.lang.Object
  extended by com.threerings.media.FrameManager
Direct Known Subclasses:
BackFrameManager, FlipFrameManager

public abstract class FrameManager
extends Object

Provides a central point from which the computation for each "frame" or tick can be dispatched. This assumed that the application structures its activity around the rendering of each frame, which is a common architecture for games. The animation and sprite support provided by other classes in this package are structured for use in an application that uses a frame manager to tick everything once per frame.

The frame manager goes through a simple two part procedure every frame:

The ticking and rendering takes place on the AWT thread so as to avoid the need for complicated coordination between AWT event handler code and frame code. However, this means that all AWT (and Swing) event handlers must not perform any complicated processing. After each frame, control of the AWT thread is given back to the AWT which processes all pending AWT events before giving the frame manager an opportunity to process the next frame. Thus the convenience of everything running on the AWT thread comes with the price of requiring that AWT event handlers not block or perform any intensive processing. In general, this is a sensible structure for an application anyhow, so this organization tends to be preferable to an organization where the AWT and frame threads are separate and must tread lightly so as not to collide.

Note: the way that JScrollPane goes about improving performance when scrolling complicated contents cannot work with active rendering. If you use a JScrollPane in an application that uses the frame manager, you should either use the provided SafeScrollPane or set your scroll panes' viewports to SIMPLE_SCROLL_MODE.


Nested Class Summary
static interface FrameManager.ManagedRoot
          Provides a bridge between either ManagedJFrame or ManagedJApplet and the frame manager.
static interface FrameManager.SafeLayerComponent
          Normally, the frame manager will repaint any component in a JLayeredPane layer (popups, overlays, etc.) that overlaps a frame participant on every tick because the frame participant could have changed underneath the overlay which would require that the overlay be repainted.
protected  class FrameManager.Ticker
          Used to effect periodic calls to tick(long).
 
Field Summary
protected  boolean[] _clipped
          Used to lazily set the clip when painting popups and other "layered" components.
protected  float[] _fps
          Used to track and report frames per second.
protected  long _lastTickStamp
          Used to track big delays in calls to our tick method.
protected  TrailingAverage[] _metrics
          Used to track performance metrics.
protected  long _millisPerFrame
          The number of milliseconds per frame (14 by default, which gives an fps of ~71).
protected  MediaOverlay _overlay
          If active, an overlay that will be rendering sprites and animations on top of the frame.
protected  Object[] _participants
          The entities that are ticked each frame.
protected static RuntimeAdjust.BooleanAdjust _perfDebug
          A debug hook that toggles FPS rendering.
protected  ActiveRepaintManager _repainter
          Our custom repaint manager.
protected  FrameManager.ManagedRoot _root
          Provides access to our Swing bits.
protected static RuntimeAdjust.IntAdjust _sleepGranularity
          Allows us to tweak the sleep granularity.
protected  Rectangle _tbounds
          A temporary bounds rectangle used to avoid lots of object creation.
protected  FrameManager.Ticker _ticker
          The thread that dispatches our frame ticks.
protected  MediaTimer _timer
          Used to obtain timing measurements.
protected static RuntimeAdjust.BooleanAdjust _useFlip
          A debug hook that toggles debug rendering of sprite paths.
protected  Window _window
          The window into which we do our rendering.
protected static long BIG_GAP
          If we don't get ticked for 500ms, that's worth complaining about.
protected static boolean HANG_DEBUG
          Enable this to log warnings when ticking or painting takes too long.
protected static long HANG_GAP
          If we don't get ticked for 100ms and we're hang debugging, complain.
protected static String[] PERF_TIMERS
          The name of the high-performance timer class we attempt to load.
 
Constructor Summary
FrameManager()
           
 
Method Summary
 void clearMaxTimerDriftRatio()
          Clears out the maximum drift our timer remembers seeing.
 void clearMediaOverlay()
          Clears out any media overlay that is in use.
protected abstract  Graphics2D createGraphics()
          Returns a graphics context with which to layout its media objects.
static MediaTimer createTimer()
          Attempts to create a high resolution timer, but if that isn't possible, uses a System.currentTimeMillis based timer.
 FrameManager.ManagedRoot getManagedRoot()
          Returns the managed root on which this frame manager is operating.
 float getMaxTimerDriftRatio()
          Returns the highest drift ratio our timer has seen. 1.0 means no drift (and is what we return if we're not using a CalibratingTimer)
 MediaOverlay getMediaOverlay()
          Returns an overlay that can be used to render sprites and animations on top of the entire frame.
 TrailingAverage[] getPerfMetrics()
          Returns debug performance metrics.
 int getPerfTicks()
          Returns the number of ticks executed in the last second.
 int getPerfTries()
          Returns the number of ticks requested in the last second.
static Component getRoot(Component comp, Rectangle rect)
          Returns the root component for the supplied component or null if it is not part of a rooted hierarchy or if any parent along the way is found to be hidden or without a peer.
 long getTimeStamp()
          Returns a millisecond granularity time stamp using the MediaTimer with which this frame manager was configured.
protected  void init(FrameManager.ManagedRoot root, MediaTimer timer)
          Initializes this frame manager and prepares it for operation.
 boolean isRegisteredFrameParticipant(FrameParticipant participant)
          Returns true if the specified participant is registered.
 boolean isRunning()
          Returns true if the tick interval is be running (not necessarily at that instant, but in general).
static FrameManager newInstance(FrameManager.ManagedRoot root)
          Creates a frame manager that will try to use a high resolution timer for timing but will fall back to MillisTimer, which is available on every platform, but returns inaccurate time stamps on many platforms.
static FrameManager newInstance(FrameManager.ManagedRoot root, MediaTimer timer)
          Constructs a frame manager that will do its rendering to the supplied root and use the supplied media timer for timing information.
protected  boolean paint(Graphics2D gfx)
          Paints our frame participants and any dirty components via the repaint manager.
protected abstract  void paint(long tickStamp)
          Called once per frame to invoke paint(long) on all of our frame participants' components and all dirty components managed by our ActiveRepaintManager.
 void registerFrameParticipant(FrameParticipant participant)
          Registers a frame participant.
 void removeFrameParticipant(FrameParticipant participant)
          Removes a frame participant.
protected  void renderLayer(Graphics2D g, Rectangle bounds, JLayeredPane pane, boolean[] clipped, Integer layer)
          Renders all components in the specified layer of the supplied layered pane that intersect the supplied bounds.
protected  void renderLayers(Graphics2D g, Component pcomp, Rectangle bounds, boolean[] clipped, Rectangle dirty)
          Renders all components in all JLayeredPane layers that intersect the supplied bounds.
protected abstract  void restoreFromBack(Rectangle dirty)
          Called by the ManagedJFrame when our window was hidden and reexposed.
 void setTargetFrameRate(int fps)
          Instructs the frame manager to target the specified number of frames per second.
 void start()
          Starts up the per-frame tick
 void stop()
          Stops the per-frame tick.
protected  void tick(long tickStamp)
          Called to perform the frame processing and rendering.
protected  void tickParticipants(long tickStamp)
          Called once per frame to invoke FrameParticipant.tick(long) on all of our frame participants.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

_window

protected Window _window
The window into which we do our rendering.


_root

protected FrameManager.ManagedRoot _root
Provides access to our Swing bits.


_timer

protected MediaTimer _timer
Used to obtain timing measurements.


_repainter

protected ActiveRepaintManager _repainter
Our custom repaint manager.


_overlay

protected MediaOverlay _overlay
If active, an overlay that will be rendering sprites and animations on top of the frame.


_millisPerFrame

protected long _millisPerFrame
The number of milliseconds per frame (14 by default, which gives an fps of ~71).


_lastTickStamp

protected long _lastTickStamp
Used to track big delays in calls to our tick method.


_ticker

protected FrameManager.Ticker _ticker
The thread that dispatches our frame ticks.


_fps

protected float[] _fps
Used to track and report frames per second.


_metrics

protected TrailingAverage[] _metrics
Used to track performance metrics.


_tbounds

protected Rectangle _tbounds
A temporary bounds rectangle used to avoid lots of object creation.


_clipped

protected boolean[] _clipped
Used to lazily set the clip when painting popups and other "layered" components.


_participants

protected Object[] _participants
The entities that are ticked each frame.


BIG_GAP

protected static final long BIG_GAP
If we don't get ticked for 500ms, that's worth complaining about.

See Also:
Constant Field Values

HANG_GAP

protected static final long HANG_GAP
If we don't get ticked for 100ms and we're hang debugging, complain.

See Also:
Constant Field Values

HANG_DEBUG

protected static final boolean HANG_DEBUG
Enable this to log warnings when ticking or painting takes too long.

See Also:
Constant Field Values

_useFlip

protected static RuntimeAdjust.BooleanAdjust _useFlip
A debug hook that toggles debug rendering of sprite paths.


_sleepGranularity

protected static RuntimeAdjust.IntAdjust _sleepGranularity
Allows us to tweak the sleep granularity.


_perfDebug

protected static RuntimeAdjust.BooleanAdjust _perfDebug
A debug hook that toggles FPS rendering.


PERF_TIMERS

protected static final String[] PERF_TIMERS
The name of the high-performance timer class we attempt to load.

Constructor Detail

FrameManager

public FrameManager()
Method Detail

newInstance

public static FrameManager newInstance(FrameManager.ManagedRoot root)
Creates a frame manager that will try to use a high resolution timer for timing but will fall back to MillisTimer, which is available on every platform, but returns inaccurate time stamps on many platforms.

See Also:
newInstance(ManagedRoot, MediaTimer)

createTimer

public static MediaTimer createTimer()
Attempts to create a high resolution timer, but if that isn't possible, uses a System.currentTimeMillis based timer.


newInstance

public static FrameManager newInstance(FrameManager.ManagedRoot root,
                                       MediaTimer timer)
Constructs a frame manager that will do its rendering to the supplied root and use the supplied media timer for timing information.


setTargetFrameRate

public void setTargetFrameRate(int fps)
Instructs the frame manager to target the specified number of frames per second. If the computation and rendering for a frame are completed with time to spare, the frame manager will wait until the proper time to begin processing for the next frame. If a frame takes longer than its allotted time, the frame manager will immediately begin processing on the next frame.


registerFrameParticipant

public void registerFrameParticipant(FrameParticipant participant)
Registers a frame participant. The participant will be given the opportunity to do processing and rendering on each frame.


isRegisteredFrameParticipant

public boolean isRegisteredFrameParticipant(FrameParticipant participant)
Returns true if the specified participant is registered.


removeFrameParticipant

public void removeFrameParticipant(FrameParticipant participant)
Removes a frame participant.


getTimeStamp

public long getTimeStamp()
Returns a millisecond granularity time stamp using the MediaTimer with which this frame manager was configured. Note: this should only be called from the AWT thread.


getMaxTimerDriftRatio

public float getMaxTimerDriftRatio()
Returns the highest drift ratio our timer has seen. 1.0 means no drift (and is what we return if we're not using a CalibratingTimer)


clearMaxTimerDriftRatio

public void clearMaxTimerDriftRatio()
Clears out the maximum drift our timer remembers seeing.


getMediaOverlay

public MediaOverlay getMediaOverlay()
Returns an overlay that can be used to render sprites and animations on top of the entire frame. This is lazily created the first time this method is called and the overlay will remain a frame participant until clearMediaOverlay() is called. Be sure to coordinate access to the overlay in your application as there is only one overlay in existence at any time, and attempts to use an overlay after it has been cleared will fail.


getManagedRoot

public FrameManager.ManagedRoot getManagedRoot()
Returns the managed root on which this frame manager is operating.


clearMediaOverlay

public void clearMediaOverlay()
Clears out any media overlay that is in use.


start

public void start()
Starts up the per-frame tick


stop

public void stop()
Stops the per-frame tick.


isRunning

public boolean isRunning()
Returns true if the tick interval is be running (not necessarily at that instant, but in general).


getPerfTicks

public int getPerfTicks()
Returns the number of ticks executed in the last second.


getPerfTries

public int getPerfTries()
Returns the number of ticks requested in the last second.


getPerfMetrics

public TrailingAverage[] getPerfMetrics()
Returns debug performance metrics.


getRoot

public static Component getRoot(Component comp,
                                Rectangle rect)
Returns the root component for the supplied component or null if it is not part of a rooted hierarchy or if any parent along the way is found to be hidden or without a peer. Along the way, it adjusts the supplied component-relative rectangle to be relative to the returned root component.


init

protected void init(FrameManager.ManagedRoot root,
                    MediaTimer timer)
Initializes this frame manager and prepares it for operation.


tick

protected void tick(long tickStamp)
Called to perform the frame processing and rendering.


tickParticipants

protected void tickParticipants(long tickStamp)
Called once per frame to invoke FrameParticipant.tick(long) on all of our frame participants.


paint

protected abstract void paint(long tickStamp)
Called once per frame to invoke paint(long) on all of our frame participants' components and all dirty components managed by our ActiveRepaintManager.


createGraphics

protected abstract Graphics2D createGraphics()
Returns a graphics context with which to layout its media objects. The returned context must be disposed when layout is complete and must not be retained across frame ticks. Used by the MediaOverlay.


paint

protected boolean paint(Graphics2D gfx)
Paints our frame participants and any dirty components via the repaint manager.

Returns:
true if anything was painted, false if not.

restoreFromBack

protected abstract void restoreFromBack(Rectangle dirty)
Called by the ManagedJFrame when our window was hidden and reexposed.


renderLayers

protected void renderLayers(Graphics2D g,
                            Component pcomp,
                            Rectangle bounds,
                            boolean[] clipped,
                            Rectangle dirty)
Renders all components in all JLayeredPane layers that intersect the supplied bounds.


renderLayer

protected void renderLayer(Graphics2D g,
                           Rectangle bounds,
                           JLayeredPane pane,
                           boolean[] clipped,
                           Integer layer)
Renders all components in the specified layer of the supplied layered pane that intersect the supplied bounds.