Post any progress in terms of multitreading you may make here, if you like. I would appreciate it.
I will. The reason why this hasn't happen is not that I'm doing it in a secret underground facility, but rather since it has (once more) been difficult to allocate enough time to the project... And sorry for the delay in my answer.
- Interpolation schemes - I think you have talked about including such in Thor. Is this something we could expect in the short-term, or should we be looking elsewhere?
If I remember correctly, plans were related to animations, not functionality of a generic tweener library. But nothing in that direction is planned for the near future.
- Parallel animations - It doesn't look like a single animator can play animations in parallel (only in internal edge cases). Is the only way to do this to compose them manually? Would using two animators be reliable enough?
Depending on what you want to do, you can just use an animation that plays two other animations (if progress aligns):
auto anim = [=] (sf::Sprite& animated, float progress)
{
anim1(animated, progress);
anim2(animated, progress);
};
Using two animators should work too, but it's a bit overkill if the progress is changed in the same way for both.
Parallel animations have been on my list for ages, it's a shame I haven't done them yet
In the example in my post, I wished to ignore the keypress while the animation was playing; so this had to be tracked externally and updated with the callback mechanism. A lot of verbosity that would be eliminated by querying whether there's an active animationn. Meanwhile, internally this looks to be as simple as returning mPlayingAnimations.empty().
I realise the example is simple, however in a larger application one could keep distinct animators - according to the role - and thus still obtain useful information from this query.
Other animation APIs do offer such functionality. Could you clarify why you deem it best not to provide it? Do you have a better design in mind to achieve the intention in the example?
Yup, it's mainly the reason outlined in
the docs:
This class does not provide any methods to query the state and progress of the animations, by design. On one hand, there is not always an unambiguous animation playing – there may be none, or there may be multiple (when the delta time passed to update() has exceeded one). On the other hand, the intent of animators is to abstract such information from the user, and attempts to retrieve it nonetheless indicate a misunderstanding of Animator's capabilities (e.g. the need to know when an animation has finished, in order to start another). Sequential actions can be queued using play() and queue(); it's even possible to notify the user through callbacks.
The fact that your console example is simple can be important -- from my experience, things may look differently in bigger contexts. You want: "ignore keypress while animation is playing", but this is a short-cut that makes input directly dependent from graphics, a design that could be done differently. In a game, the actual condition might be: "when the guy presses the fire button (input), play the fire animation (graphics), launch a bullet (logic) and wait half a second before you accept further input (logic)". It would then rather be the logic that determines whether your input is processed, and graphics are only a result (you could say mapping/function) of the current game logic state. Wiring dependencies this way has many advantages: you can completely reconstruct a graphical scene from the current logic state, you can change graphics (fire animation duration) without affecting the cooldown time -- but still do it vice versa if you wanted, and so on.
By the way, thanks a lot for having a closer look at Thor and giving feedback based on usage in another project, this is very valuable. Thanks also for the blog post!