This is tricky business; we need to be more careful about how we handle

animations triggered on the completion of previous animations so as not to
booch things if a triggered animation is queued up after all previous
animations have already been started.


git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@1916 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
Michael Bayne
2002-11-05 23:56:35 +00:00
parent 562111a95d
commit 10c2251bdb
@@ -1,5 +1,5 @@
// //
// $Id: AnimationSequencer.java,v 1.8 2002/11/05 21:53:56 mdb Exp $ // $Id: AnimationSequencer.java,v 1.9 2002/11/05 23:56:35 mdb Exp $
package com.threerings.media.animation; package com.threerings.media.animation;
@@ -32,7 +32,11 @@ public abstract class AnimationSequencer extends Animation
/** /**
* Adds the supplied animation to the sequence with the given * Adds the supplied animation to the sequence with the given
* parameters. Note that care should be taken if this is called after * parameters. Note that care should be taken if this is called after
* the animation sequence has begun firing animations. * the animation sequence has begun firing animations. Do not add new
* animations after the final animation in the sequence has been
* started or you run the risk of attempting to add an animation to
* the sequence after it thinks that it has finished (in which case
* this method will fail).
* *
* @param anim the animation to be sequenced, or null if the * @param anim the animation to be sequenced, or null if the
* completion action should be run immediately when this "animation" * completion action should be run immediately when this "animation"
@@ -54,17 +58,25 @@ public abstract class AnimationSequencer extends Animation
"Animation added to finished sequencer"); "Animation added to finished sequencer");
} }
AnimRecord arec = new AnimRecord(anim, delta, completionAction); // if this guy is triggering on a previous animation, grab that
// good fellow here
AnimRecord trigger = null;
if (delta == -1) { if (delta == -1) {
int size = _queued.size(); if (_queued.size() > 0) {
if (size == 0) { // if there are queued animations we want the most
// if there's no predecessor then this guy has nobody to // recently queued animation
// wait for, so we run him immediately trigger = (AnimRecord)_queued.get(_queued.size()-1);
arec.delta = 0; } else if (_running.size() > 0) {
} else { // otherwise, if there are running animations, we want the
((AnimRecord)_queued.get(size - 1)).dependent = arec; // last one in that list
trigger = (AnimRecord)_running.get(_running.size()-1);
} }
// otherwise we have no trigger, we'll just start ASAP
} }
AnimRecord arec = new AnimRecord(
anim, delta, trigger, completionAction);
// Log.info("Queued " + arec + ".");
_queued.add(arec); _queued.add(arec);
} }
@@ -138,28 +150,35 @@ public abstract class AnimationSequencer extends Animation
protected class AnimRecord protected class AnimRecord
implements AnimationObserver implements AnimationObserver
{ {
public long delta; public AnimRecord (Animation anim, long delta, AnimRecord trigger,
public AnimRecord dependent; Runnable completionAction)
public AnimRecord (
Animation anim, long delta, Runnable completionAction)
{ {
_anim = anim; _anim = anim;
this.delta = delta; _delta = delta;
_trigger = trigger;
_completionAction = completionAction; _completionAction = completionAction;
} }
public boolean readyToFire (long now, long lastStamp) public boolean readyToFire (long now, long lastStamp)
{ {
return (delta != -1) && (lastStamp + delta >= now); if (_delta == -1) {
// if we have no trigger, that means we should start
// immediately, otherwise we wait until our trigger is no
// longer running (they are guaranteed not to be still
// queued at this point because readyToFire is only called
// on an animation after all animations previous in the
// queue have been started)
return (_trigger == null) ?
true : !_running.contains(_trigger);
} else {
return (lastStamp + _delta >= now);
}
} }
public void fire (long when) public void fire (long when)
{ {
// String aclass = (_anim == null) ? "<none>" : // Log.info("Firing " + this + " at " + (when%100000) + ".");
// _anim.getClass().getName();
// Log.info("Firing animation " + aclass + " at " +
// (when%100000) + ".");
// if we have an animation, start it up and await its // if we have an animation, start it up and await its
// completion // completion
@@ -188,20 +207,11 @@ public abstract class AnimationSequencer extends Animation
// make a note that this animation is complete // make a note that this animation is complete
_running.remove(this); _running.remove(this);
// if the next animation is triggered on the completion of // kids, don't try this at home; we call tick() immediately so
// this animation... // that any animations triggered on the completion of previous
if (dependent != null) { // animations can trigger on the completion of this animation
// ...fiddle its delta so that it becomes immediately // rather than having to wait until the next tick to do so
// ready to fire tick(when);
dependent.delta = when - _lastStamp;
// kids, don't try this at home; we call tick()
// immediately so that this dependent animation and
// any simultaneous subsequent animations are fired
// immediately rather than waiting for the next call
// to tick
tick(when);
}
} }
public void handleEvent (AnimationEvent event) public void handleEvent (AnimationEvent event)
@@ -213,6 +223,8 @@ public abstract class AnimationSequencer extends Animation
protected Animation _anim; protected Animation _anim;
protected Runnable _completionAction; protected Runnable _completionAction;
protected long _delta;
protected AnimRecord _trigger;
} }
/** Animations that have not been fired. */ /** Animations that have not been fired. */