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:
Game object gets to work. It initializes the progress bar, setting the ration/value to 0, then sets up [First generation] tween and delayed invokation.
Time elapses...
Juggler's advanceTime: runs
Juggler advances time on [First generation] delayed invokation and causes the game object to setup the next game state
Game object setups up the progress bar again, setting current ratio/value to 0, then sets up [Second generation] tween and delayed invokation.
Control is returned to juggler. [First generation] delayed invokation is disposed of.
Juggler advances time on [First generation] tween, causing the progress bar ratio/value to be set to 1.
Control is returned to the juggler. [First generation] tween is disposed of.
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.
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.