PrimaryFeather / Sparrow-Framework

The Open Source Game Engine for iOS
http://www.sparrow-framework.org
Other
538 stars 173 forks source link

Fixed juggler "juggling out-of-order" problem. #1029

Closed Odie closed 13 years ago

Odie commented 13 years ago

Hi there!

Here's the fix of a bug I was bit by yesterday.

Bug summary: Two items placed under the care of the juggler at the same time, a tween and a delayed invokation in this case, with the same time-delay might finish "out-of-order".

Expected behavior: The juggler always processes the items under it's care in the order they were added, so the order in which they are finished, even if they finish on the same tick/frame, is deterministic.

Long winded description: The setup here is that there is a game object, which controls a progress bar an other components via some state machine logic. As the game object gets to work, it sets up a tween for the juggler to animate the progress bar (SXGauge!). At the same time, a delayed invokation is setup to progress the game object to the next state, with the same time delay as the progress bar animation. The expectation is that these two objects would complete their task in the exact same game tick. The problem arises because...

The next state of the game object restart the exact same state, and makes use of the same progress bar instance.

This means that the order in which the tween and the delayed invokation is completed is important. When they are completed out of order, we run into this situation:

And here is the problem. By the time the [Second generation] tween comes around to being processed, the ratio/value of the progress bar is already 1. So then it does nothing for the duration of the animation.

The fix: The reason why the juggler might be running these object out-of-order is because the juggler is storing and iterating over all SPAnimatable objects using an NSSet right now. As element ordering makes no difference in a set, NSSet also does not guarantee the order in which it stores the items it stores. Iterating over the items in the NSSet is naturally out-of-order. It is natural, then, that the juggler processes the Animatables out-of-order as well.

The fix here is to move from using NSSet to NSArray to perserve the order in which the items are added and processed.

I don't know if there might be any potential performance problems with element removal. But I think having the order of execution be ordered and predictable is very important.

PrimaryFeather commented 13 years ago

Thanks a lot for the detailed description, Odie! That makes perfect sense. I will change the NSSet to an NSArray, as you recommended!

Odie commented 13 years ago

Awesome! Thanks for reading the crazy long writeup. =)