Jump to content
Search Community

TweenMax.killAll(true) doesn't complete tweens in order

moxol test
Moderator Tag

Recommended Posts

If I do TweenMax.kilAll(true) then TweenMax event listeners function doesn't end in order.

 

For example, if I have this code:

var timeline:TimelineMax = new TimelineMax();

  var tweenMax:TweenMax = new TweenMax(obj, 5, { x:200, y:200 } );
  tweenMax.addEventListener(TweenEvent.START, function():void
  {
trace("Start");
  });
  tweenMax.addEventListener(TweenEvent.UPDATE, function():void
  {
trace("Update");
  });
  tweenMax.addEventListener(TweenEvent.COMPLETE, function():void
  {
trace("Complete");
  });

  var tweenMax1:TweenMax = new TweenMax(obj, 5, { x:300, y:300 } );
  tweenMax1.addEventListener(TweenEvent.START, function():void
  {
trace("Start1");
  });
  tweenMax1.addEventListener(TweenEvent.UPDATE, function():void
  {
trace("Update1");
  });
  tweenMax1.addEventListener(TweenEvent.COMPLETE, function():void
  {
trace("Complete1");
  });

  timeline.append(tweenMax);
  timeline.append(tweenMax1);

 

If I do killAll(true) while tweenMax is playing then I get following order of event listneres triggered:

Start1

Update1

Complete1

Update

Complete

 

which means that tweenMax1 event listeners are triggered first and then tweenMax event listeners.

I thought that order of events would be:

Update

Complete

Start1

Update1

Complete1

 

because order of timeline appends is tweenMax and then tweenMax1.

Link to comment
Share on other sites

I have been looking at TweenMax.as code and I have found a reason for described behaviour.

 

Code for function TweenMax.killAll(true) is:

public static function killAll(complete:Boolean=false, tweens:Boolean=true, delayedCalls:Boolean=true, timelines:Boolean=true):void {
  var a:Array = getAllTweens(timelines),
i:int = a.length,
isDC:Boolean,
allTrue:Boolean = (tweens && delayedCalls && timelines),
tween:Animation;
  while (--i > -1) {
tween = a[i];
if (allTrue || (tween is SimpleTimeline) || ((isDC = (TweenLite(tween).target == TweenLite(tween).vars.onComplete)) && delayedCalls) || (tweens && !isDC)) {
 if (complete) {
  tween.totalTime(tween.totalDuration());
 } else {
  tween._enabled(false, false);
 }
}
  }
 }

 

Line 7 while (--i > -1) is iterating a:Array backwards causing tweens to be completed in reversed order from which they are added.

If I change line 3 i:int = a.length to i:int = 0 and line 7 while (--i > -1) to while (i < a.length) (and adding i++ to the end of loop) then tweens are completed in appended order and tween event listeners are triggered in appended order.

 

I want to know if this change is ok, will it have negative reflection on something?

 

Thanks.

Link to comment
Share on other sites

Its probably less a functional thing and more a way to eke out more performance.

 

For an iteration loop, you need two values; the number of iterations and a counter. In this style of 'reverse' loop you can combine these into one variable, and just countdown to 0. This saves on memory, however small, but when you're goal is extreme performance every tiny bit helps.

 

The other thing I would mention is that while (i < a.length) is something that is best avoided for non-trivial loops (its not going to make a difference if you are only looping a few times though). Essentially the reason is that, compared to a cached value in the loop, a.length is slower to access (the difference is getting pretty close to nothing in the latest javascript engines). In every iteration of the loop a.length is evaluated (it is a stored value of a though), which just means an extra step of looking at a for the value of length.

 

While it doesn't seem like much it can have an affect on low-level performance. If you want to iterate forward it's usually a good practice to cache the length, and compare i to that.

 

Here's a bunch of browser tests if you're interested.

 

I think you'll need to wait for Jack to answer on whether this really was done for performance, and what kind of side effects this change would have (if any).

  • Like 1
Link to comment
Share on other sites

I just wrote it in a quicker way to show what change I want.

Of course I will use variable instead of a.length in while.

 

I am more interested in functional repercussions of that change, will it affect in any way using GSAP platform.

Link to comment
Share on other sites

Yep, Jamie is correct in saying that it was a performance thing. Frankly, I hadn't considered the need to loop forward through the array because I figured everything is being killed anyway, so I prioritized performance. But you bring up a good point about the order of completion so that's fixed in the latest version (posted a few minutes ago).

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...