Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  //
  // Nenya library - tools for developing networked games
  // Copyright (C) 2002-2012 Three Rings Design, Inc., All Rights Reserved
  // https://github.com/threerings/nenya
  //
  // This library is free software; you can redistribute it and/or modify it
  // under the terms of the GNU Lesser General Public License as published
  // by the Free Software Foundation; either version 2.1 of the License, or
  // (at your option) any later version.
 //
 // This library 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
 // Lesser General Public License for more details.
 //
 // You should have received a copy of the GNU Lesser General Public
 // License along with this library; if not, write to the Free Software
 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
 package com.threerings.media.animation;
 
 
 
 
 
 import static com.threerings.media.Log.log;

An animation that provides facilities for adding a sequence of animations that are fired after a fixed time interval has elapsed or after previous animations in the sequence have completed. Facilities are also provided for running code upon the completion of animations in the sequence.
 
 public class AnimationSequencer extends Animation
 {
    
Constructs an animation sequencer with the expectation that animations will be added via subsequent calls to addAnimation(com.threerings.media.animation.Animation).

Parameters:
animmgr the animation manager to which to add our animations when they are ready to start.
 
     public AnimationSequencer (AnimationManager animmgr)
     {
         super(new Rectangle());
          = animmgr;
     }

    
Adds the supplied animation to the sequence with the given parameters. Note that care should be taken if this is called after 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).

Parameters:
anim the animation to be sequenced, or null if the completion action should be run immediately when this "animation" is ready to fired.
delta the number of milliseconds following the start of the previous animation in the queue that this animation should be started; 0 if it should be started simultaneously with its predecessor in the queue; -1 if it should be started when its predecessor has completed.
completionAction a runnable to be executed when this animation completes.
 
     public void addAnimation (Animation animlong deltaRunnable completionAction)
     {
         // sanity check
         if () {
             throw new IllegalStateException("Animation added to finished sequencer");
         }
 
         // if this guy is triggering on a previous animation, grab that
         // good fellow here
         AnimRecord trigger = null;
         if (delta == -1) {
             if (.size() > 0) {
                 // if there are queued animations we want the most
                 // recently queued animation
                 trigger = .get(.size()-1);
             } else if (.size() > 0) {
                 // otherwise, if there are running animations, we want the
                 // last one in that list
                 trigger = .get(.size()-1);
             }
             // otherwise we have no trigger, we'll just start ASAP
         }
 
         AnimRecord arec = new AnimRecord(animdeltatriggercompletionAction);
 //         Log.info("Queued " + arec + ".");
         .add(arec);
     }

    
Convenience wrapper to add an animation to run at the same time as the previous one.
 
    public void addAnimation (Animation anim)
    {
        addAnimation(anim, 0, null);
    }

    
Convenience wrapper to add an animation to run after the previous one.
    public void appendAnimation (Animation anim)
    {
        addAnimation(anim, -1, null);
    }

    
Clears out the animations being managed by this sequencer.
    public void clear ()
    {
        .clear();
         = 0;
    }
    @Override
    public void tick (long tickStamp)
    {
        if ( == 0) {
             = tickStamp;
        }
        // add all animations whose time has come
        while (.size() > 0) {
            AnimRecord arec = .get(0);
            if (!arec.readyToFire(tickStamp)) {
                // if it's not time to add this animation, all subsequent
                // animations must surely wait as well
                break;
            }
            // remove it from queued and put it on the running list
            .remove(0);
            .add(arec);
            // note that we've advanced to the next animation
             = tickStamp;
            // fire in the hole!
            arec.fire(tickStamp);
        }
        // we're done when both lists are empty
//         boolean finished = _finished;
         = ((.size() + .size()) == 0);
//         if (!finished && _finished) {
//             Log.info("Finishing sequence at " + (tickStamp%10000) + ".");
//         }
    }
    @Override
    public void paint (Graphics2D gfx)
    {
        // don't care
    }
    @Override
    public void fastForward (long timeDelta)
    {
         += timeDelta;
    }
    @Override
    public void viewLocationDidChange (int dxint dy)
    {
        super.viewLocationDidChange(dxdy);
        // track cumulative view location changes so that we can adjust our
        // animations before we start them
         += dx;
         += dy;
    }

    
Called when the time comes to start an animation. Derived classes may override this method and pass the animation on to their animation manager and do whatever else they need to do with operating animations. The default implementation simply adds them to the media panel supplied when we were constructed.

Parameters:
anim the animation to be displayed.
tickStamp the timestamp at which this animation was fired.
    protected void startAnimation (Animation animlong tickStamp)
    {
        // account for any view scrolling that happened before this animation
        // was actually added to the view
        if ( != 0 ||  != 0) {
            anim.viewLocationDidChange();
        }
        .registerAnimation(anim);
    }
    protected class AnimRecord extends AnimationAdapter
    {
        public AnimRecord (
            Animation animlong deltaAnimRecord triggerRunnable completionAction) {
             = anim;
             = delta;
             = trigger;
             = completionAction;
        }
        public boolean readyToFire (long nowlong lastStamp) {
            if ( == -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 ( == null) ? true : !.contains();
            } else {
                return (lastStamp +  <= now);
            }
        }
        public void fire (long when) {
//             Log.info("Firing " + this + " at " + (when%10000) + ".");
            // if we have an animation, start it up and await its completion
            if ( != null) {
                startAnimation(when);
                .addAnimationObserver(this);
            } else {
                // since there's no animation, we need to fire our
                // completion routine immediately
                fireCompletion(when);
            }
        }
        public void fireCompletion (long when) {
//             Log.info("Completing " + this + " at " + (when%10000) + ".");
            // call the completion action, if there is one
            if ( != null) {
                try {
                    .run();
                } catch (Throwable t) {
                    .warning(t);
                }
            }
            // make a note that this animation is complete
            .remove(this);
            // kids, don't try this at home; we call tick() immediately so that any animations
            // triggered on the completion of previous animations can trigger on the completion of
            // this animation rather than having to wait until the next tick to do so
            tick(when);
        }
        @Override
        public void animationCompleted (Animation animlong when) {
            fireCompletion(when);
        }
        @Override
        public String toString () {
            return "[anim=" + StringUtil.shortClassName() +
                (( == null) ? "" : ("/" + .hashCode())) +
                ", action=" +  +
                ", delta=" +  + ", trig=" + ( != null) + "]";
        }
        protected Animation _anim;
        protected Runnable _completionAction;
        protected long _delta;
        protected AnimRecord _trigger;
    }

    
The animation manager in which we run animations.
    protected AnimationManager _animmgr;

    
Animations that have not been fired.
    protected ArrayList<AnimRecord_queued = Lists.newArrayList();

    
Animations that are currently running.
    protected ArrayList<AnimRecord_running = Lists.newArrayList();

    
The timestamp at which we fired the last animation.
    protected long _lastStamp;

    
Used to track view scrolling while animations are in limbo.
    protected int _vdx_vdy;
New to GrepCode? Check out our FAQ X