|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object com.hdcookbook.grin.animator.AnimationEngine
public abstract class AnimationEngine
Abstract base class for an animation engine.
An animation engine runs the main animation loop, and manages display of a set of animation clients to a component.
Field Summary | |
---|---|
protected int |
modelTimeSkipped
|
protected com.hdcookbook.grin.animator.RenderContextBase |
renderContext
The list of erase and drawing areas that were updated in the current frame of animation, and records of what happened in the last. |
protected java.awt.Rectangle |
repaintBounds
The area that has been damaged and need to be repainted in the next cycle. |
protected boolean |
targetsCanOverlap
|
static java.awt.Color |
transparent
A useful constant that's used extensively by engines |
Constructor Summary | |
---|---|
protected |
AnimationEngine()
Initialize a new AnimationEngine. |
Method Summary | |
---|---|
protected void |
advanceModel()
|
protected abstract void |
callPaintTargets()
Paint the current frame into the right graphics buffer. |
void |
checkDestroy()
Throw an InterruptedException if we should bail out. |
protected void |
checkNewClients()
Check to see if we have new animation clients. |
protected abstract void |
clearArea(int x,
int y,
int width,
int height)
Called from showFrame() to cause an area to be cleared in the current frame. |
void |
destroy()
Destroy this animation manager, by terminating the animation thread. |
boolean |
destroyRequested()
Tells us if there has been a request to destroy this animation manager. |
protected abstract void |
finishedFrame()
Called when the engine is finished drawing the current frame. |
AnimationClient[] |
getAnimationClients()
Return a copy of the list of animation clients that were last set for this animation engine. |
abstract java.awt.Component |
getComponent()
Get the component that this animation engine renders into. |
protected java.awt.Rectangle[] |
getDrawTargets()
|
protected java.awt.Rectangle[] |
getEraseTargets()
|
abstract int |
getHeight()
Get the height of the area we display over |
int |
getModelTimeSkipped()
Return the number of ms skipped before the next model update. |
protected int |
getNumDrawTargets()
|
protected int |
getNumEraseTargets()
|
abstract int |
getWidth()
Get the width of the area we display over |
void |
initClients(AnimationClient[] clients)
Initialize this engine with the animation clients it will be managing. |
abstract void |
initContainer(java.awt.Container container,
java.awt.Rectangle bounds)
Initialize this engine with its parent container and the position and size of the engine within the container. |
void |
initialize(AnimationContext context)
Initialize this animation manager. |
protected abstract boolean |
needsFullRedrawInAnimationLoop()
Tell us whether or not this style of animation requires a full redraw of everything on the screen in each pass through the animation loop. |
protected void |
paintFrame(java.awt.Graphics2D g)
Paint the current frame into the given graphics object. |
void |
paintNextFrameFully()
Sets this engine so that the next frame will be painted in its entirety, with no redraw optimization. |
protected void |
paintTargets(java.awt.Graphics2D g)
Paint the current set of target areas in our RenderContext for the current frame into the given graphics object. |
abstract void |
pause()
Pause the currently running animations. |
void |
repaintFrame(java.awt.Graphics2D g)
Repaint the current frame. |
void |
resetAnimationClients(AnimationClient[] clients)
Reset the set of clients being rendered by a running animation engine. |
void |
run()
This is the main loop for animation. |
protected abstract void |
runAnimationLoop()
The inner loop for the animation thread. |
void |
setAllowOverlappingTargets(boolean v)
Sets whether or not overlapping draw targets are allowed. |
void |
setDrawTargetCollapseThreshold(int t)
Sets the threshold of the number of pixels of increased drawing the engine is willing to tolerate in order to collapse two draw targets into one. |
void |
setThreadPriority(int priority)
Set the priority of the thread that runs the animation loop. |
protected void |
showFrame()
Tell the model we're caught up, and show the current frame. |
abstract void |
start()
Start the current animations. |
protected abstract void |
terminatingEraseScreen()
Erase the screen because the AnimationManager is terminating. |
Methods inherited from class java.lang.Object |
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
Field Detail |
---|
public static final java.awt.Color transparent
protected com.hdcookbook.grin.animator.RenderContextBase renderContext
protected java.awt.Rectangle repaintBounds
protected int modelTimeSkipped
protected boolean targetsCanOverlap
Constructor Detail |
---|
protected AnimationEngine()
Method Detail |
---|
public void initClients(AnimationClient[] clients)
Note that the algorithm used to collapse render area targets is cubic with the number of targets, so this number should be kept low. Between one and three would be reasonable, and five is perhaps a workable maximum.
clients
- The animation clients we'll supportAnimationContext.animationInitialize()
public void setDrawTargetCollapseThreshold(int t)
This value may be set to 0, or even a negative number. This might be valuable to disable the collapse optimization, for clients that want a predictable and consistent render time.
public void setAllowOverlappingTargets(boolean v)
This method must only be called during the model update.
The default value of this parameter is false.
public void resetAnimationClients(AnimationClient[] clients)
The framework takes ownership of the array that's passed in, so the caller should not modify that array after calling this method.
public AnimationClient[] getAnimationClients()
Note that the old animation clients are destroyed, and not put into a quiescent state. In the case of a GRIN show, this means that if you want to later add the show back, you'll need to re-read it from the .grin file.
public void setThreadPriority(int priority)
public abstract void initContainer(java.awt.Container container, java.awt.Rectangle bounds)
The Component will be set to the specified bounds, and an internal double buffer may be created to these bounds. The container is expected to have a null layout; if it doesn't, this might change the widget's size to be different than the bounds passed in (and therefore the double buffer). The container must be visible when this is called.
initialize(com.hdcookbook.grin.animator.AnimationContext)
,
AnimationContext.animationInitialize()
public abstract int getWidth()
public abstract int getHeight()
protected int getNumEraseTargets()
protected java.awt.Rectangle[] getEraseTargets()
protected int getNumDrawTargets()
protected java.awt.Rectangle[] getDrawTargets()
public boolean destroyRequested()
public void checkDestroy() throws java.lang.InterruptedException
java.lang.InterruptedException
public abstract java.awt.Component getComponent()
initialize(com.hdcookbook.grin.animator.AnimationContext)
,
AnimationContext.animationInitialize()
public void paintNextFrameFully()
public void initialize(AnimationContext context)
context.animationInitialize(); // a good time to set up the HScene and Player for each client c c.initialize() context.animationFinishInitialization(); // perhaps set UI state for (frame = 0 to infinity) { wait until it's time for next frame for each client call nextFrame if animation isn't behind for each client call setCaughtUp call addDisplayAreas for each client call paintFrame as many times as needed for each client call paintDone }
This method returns immediately after starting the thread, so that
an Xlet can quickly return from the xlet lifecycle method
Xlet.initXlet(). Any code that depends on animation clients being
initialized should be put in the body of the
AnimationContext.animationFinishInitialization()
method.
For example, if you're using a GRIN show,
animationFinishInitialization() is where you should put
the call to
Show.activateSegment()
on the show's
initial segument.
context
- The context that the animation manager is running in.
This can be used for initialization that the client
wants to do in the animation thread. The context might
use this to create an HScene, load a GRIN show,
synchronously
start video playing, or do other time-consuming
operations.AnimationContext.animationFinishInitialization()
,
Show.activateSegment(com.hdcookbook.grin.Segment)
public abstract void start()
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.
paintNextFrameFully()
public abstract void pause()
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.
public void destroy()
This method will not return until the animation thread has terminated.
protected abstract void clearArea(int x, int y, int width, int height)
showFrame()
protected abstract boolean needsFullRedrawInAnimationLoop()
protected abstract void callPaintTargets() throws java.lang.InterruptedException
java.lang.InterruptedException
paintFrame(java.awt.Graphics2D)
protected abstract void finishedFrame()
protected abstract void terminatingEraseScreen()
public void run()
run
in interface java.lang.Runnable
protected abstract void runAnimationLoop() throws java.lang.InterruptedException
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.
java.lang.InterruptedException
destroyRequested()
,
advanceModel()
,
showFrame()
,
callPaintTargets()
protected final void checkNewClients() throws java.lang.InterruptedException
java.lang.InterruptedException
public final int getModelTimeSkipped()
Typically, model updates should be very much faster than the time between frames, so this method should almost always return 0, unless the animation clients are doing some atypically complex calculations.
This can be queried from within AnimationClient.nextFrame() to see how much time to add to the normal frame time, if code wishes to keep time-based animations synchronized in time, even in the face of CPU-intensive model updates.
AnimationClient.nextFrame()
protected final void advanceModel() throws java.lang.InterruptedException
java.lang.InterruptedException
protected final void showFrame() throws java.lang.InterruptedException
java.lang.InterruptedException
callPaintTargets()
protected final void paintTargets(java.awt.Graphics2D g) throws java.lang.InterruptedException
The Graphics2D instance must have a clip area that is set to the extent of the area being managed by this animation manager. The instance will have an unmodified clip area after this method is called, but other attributes, like the drawing mode and the foreground color, might be changed. However, the Graphics2D instance will be suitable for re-use in a subsequent paintFrame operation.
g
- A graphics context with a clip area covering
the full extent of the screen area under the
control of this animation manager.
java.lang.InterruptedException
callPaintTargets()
protected final void paintFrame(java.awt.Graphics2D g) throws java.lang.InterruptedException
g
- A graphics context with a clip area covering the
area that needs to be painted to
java.lang.InterruptedException
paintTargets(java.awt.Graphics2D)
public void repaintFrame(java.awt.Graphics2D g) throws java.lang.InterruptedException
This can also be used for things like capturing a screenshot to a buffered image.
java.lang.InterruptedException
|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |