Thanks a lot for your suggestions (and thanks for the compliments)!
I am happy about any ideas on that topic, and I totally understand what you mean.
Basically, there are 2 ways to handle chaining events; one way to do it is what you're describing (having a method that takes all tweens and plays them one after the other), the other way is the approach Sparrow is currently taking (having a "delay" property to allow doing it manually).
Of course, each way has its advantages and disadvantages. I chose the latter method because I felt it would be the simpler way to do it (and whatever felt simpler to understand, I almost always chose to implement -- I'm a lazy guy! *g*).
But having an alternative would be great, and I think this is a great idea for an extension!
What follows are just my ideas on how we could integrate similar functionality into Sparrow, without changing the whole architecture altogether.
Sparrow's juggler object can already be used to group animations together, because you can add a juggler to a juggler. So you could say:
SPTween *tween1 = ...;
SPTween *tween2 = ...;
tween2.delay = tween1.time;
SPJuggler *animation = [SPJuggler juggler];
[animation addObject:tween1];
[animation addObject:tween2];
[self.stage.juggler addObject:animation];
So you've already got a way to group several tweens together in one object, though it does not make a lot of sense yet. But we could build on that.
Side-note: the problem with this approach is that currently, the "isComplete" method of the juggler always returns "NO". I should change this to the following implementation:
- (BOOL)isComplete
{
return mObjects.count == 0;
}
Because then it would work as we want it to: as soon as all sub-animations are finished, the juggler will be removed from its parent juggler.
With that in place, we could add methods like these:
// let animations run after each other (sets 'delay' internally)
[mJuggler chainTweens:tween1, tween2, nil];
// group animations together to run at the same time
[mJuggler addObjects:tween1, tween2, nil];
So, 2 use-cases are already done, and we did not change much code. We're still missing the callback at the end, though.
One way to do it: let the methods from above return the total duration.
double totalTime = [mJuggler chainObjects:...];
[[mJuggler delayInvocationAtTarget:self byTime:totalTime] cleanUp];
Agreed, not very nice to look at. Another, probably nicer alternative would be to add a block that's called when it's finished.
[mJuggler chainObjects:...];
[mJuggler onComplete:^() { [self cleanUp]; }]
That, however, would be limited to iOS 4, so it could only be added to Sparrow 2.0. (Yes, I'm using blocks already, but this only works through a trick on iOS 3. Here, it wouldn't.)
So, I'm not saying that this is the best way of doing it -- but it might be a very simple way to get closer to what you're looking for.
As for the loop stuff: you're right, for some reason I never noticed that! I suppose it's because the 2 looping parts were developed with a lot of time in-between. I might correct this in Sparrow 2.0.