com.hdcookbook.grin.animator
Class ClockBasedEngine

java.lang.Object
  extended by com.hdcookbook.grin.animator.AnimationEngine
      extended by com.hdcookbook.grin.animator.ClockBasedEngine
All Implemented Interfaces:
java.lang.Runnable
Direct Known Subclasses:
DirectDrawEngine, RepaintDrawEngine, ScalingDirectDrawEngine

public abstract class ClockBasedEngine
extends AnimationEngine

Abstract base class for a clock-based animation engine. A clock-based engine uses System.currentTimeMillis and Object.wait() to pace the animation to real time.


Field Summary
 
Fields inherited from class com.hdcookbook.grin.animator.AnimationEngine
modelTimeSkipped, renderContext, repaintBounds, targetsCanOverlap, transparent
 
Constructor Summary
protected ClockBasedEngine()
          Create a new ClockBasedEngine
 
Method Summary
 int getFps()
          Get the current framerate, in 1001ths of a second.
 void pause()
          Pause the currently running animations.
protected  void runAnimationLoop()
          The inner loop for the animation thread.
 void setFps(int fps)
          Set the frame rate of the animation, in 1001sts of a second.
 void skipFrames(int num)
          Skip ahead the given number of frames.
 void start()
          Start the current animations.
 
Methods inherited from class com.hdcookbook.grin.animator.AnimationEngine
advanceModel, callPaintTargets, checkDestroy, checkNewClients, clearArea, destroy, destroyRequested, finishedFrame, getAnimationClients, getComponent, getDrawTargets, getEraseTargets, getHeight, getModelTimeSkipped, getNumDrawTargets, getNumEraseTargets, getWidth, initClients, initContainer, initialize, needsFullRedrawInAnimationLoop, paintFrame, paintNextFrameFully, paintTargets, repaintFrame, resetAnimationClients, run, setAllowOverlappingTargets, setDrawTargetCollapseThreshold, setThreadPriority, showFrame, terminatingEraseScreen
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

ClockBasedEngine

protected ClockBasedEngine()
Create a new ClockBasedEngine

Method Detail

start

public void start()
Start the current animations. The animation will start animating sometime after this method is called. This can be called while initialization is still underway in the animation thread.

By default, the manager will assume that the contents of the framebuffer wasn't changed while the manager was paused. If it might have been, it's advisable to call paintNextFrameFully().

The animation manager starts in the paused state, so this method will normally need to be called at least once.

Specified by:
start in class AnimationEngine
See Also:
AnimationEngine.paintNextFrameFully()

pause

public void pause()
Pause the currently running animations. The animation thread will go into a wait state, until start() or destroy() are called.

This method will return immediately, even if the animation hasn't reached the paused state yet.

When the animation framework is paused, no effort is made to output one last frame with the current state of the model.

Specified by:
pause in class AnimationEngine

setFps

public void setFps(int fps)
Set the frame rate of the animation, in 1001sts of a second. In other words, the following table applies:

     Desired framerate    fps value
     =================    =========
           23.976                 24,000
           24.000           24,024
           29.970                 30,000
           30.000                 30,030
           59.940           60,000
           60.000           60,060
 
 
If you find yourself asking "why 1001," read the HD Handbook starting from page 2-2 (ISBN 978-0-07-149585-1). Long story short: NTSC video's frame rate is 30*1000/1001 frames/second, due to issues around the transition from B&W to color. Fun fact: 1001 isn't prime, it's 7*11*13

The frame rate must be greater than 0 fps. To stop the animation, call pause().

If the animation is paused when this method is called, it will stay paused.

Throws:
java.lang.IllegalArgumentException - if fps < 0.
See Also:
skipFrames(int)

getFps

public int getFps()
Get the current framerate, in 1001ths of a second. The returned value might be 0, e.g. if animation is paused, or if a skipFrames() request is currently being processed.

Returns:
the current fps value in 1001ths of a second, or 0 if the value is unknown.
See Also:
setFps(int), skipFrames(int)

skipFrames

public void skipFrames(int num)
                throws java.lang.InterruptedException
Skip ahead the given number of frames. After skipping ahead, the framerate will be restored. If the animation is paused, the current state of the model will be output as a frame. If two threads call this method concurrently on the same instance, one will bail out early. A concurrent call to setFps() will cause this method to bail out as well.

This method is probably only useful for debugging.

Parameters:
num - The number of frames to skip
Throws:
java.lang.InterruptedException

runAnimationLoop

protected void runAnimationLoop()
                         throws java.lang.InterruptedException
The inner loop for the animation thread. This implementation uses System.currentTimeMillis() and wait() to keep a steady frame rate. This method can be overridden for animation styles that have a different synch mechanism, like SFAA. If this is done, be sure to look inside this method, and obey the same semantic contract.

This method must call checkNewClients() outside of any synchronized block at least once per frame. This should be done at the beginning of the frame before any model updates or animation work is done.

This method must check destroyRequested() at least once per frame, and if it's true, bail out of the loop. To advance the model by one frame, it should call advanceModel(). When it wants to show a frame (and not skip it), it should call showFrame(), which will cause callPaintTargets() to be called.

Of course, the animation loop should also check Thread.interrupted() regularly.

Specified by:
runAnimationLoop in class AnimationEngine
Throws:
java.lang.InterruptedException
See Also:
AnimationEngine.destroyRequested(), AnimationEngine.advanceModel(), AnimationEngine.showFrame(), AnimationEngine.callPaintTargets()