int main() {
initialize();
for (;;) {
sequential_animation<animation_loop,
repeat<speed<to_grb888<rainbow_animation>, 8>, 8>,
repeat<speed<to_grb888<rainbow_animation>, 4>, 4>,
repeat<speed<to_grb888<rainbow_animation>, 2>, 2>>();
}
return 0;
}
I’m working on animation framework that’s semi-type driven. If you’re not sure how it works I’ll try to explain.
Let’s examine the rainbow_animation, this is an animation object that storing current animation progress. It has three methods:
- value(), that’s storing current rgb value of animation
- step(), after call step, animation will do one iteration
- is_finished(), hold state of end condition
Basic use of rainbow_animation will be looking like this:
rainbow_animation animation;
while (!animation.is_finished())
{
const auto current_color = animation.value();
doSomethingWithColor(current_color);
animation.step();
}
To hide details about animation loop, we can create a templated function like this:
run_animation<doSomethingWithColorFunction, rainbow_animation>()
But if we want to run multiple animations we will end with:
run_animation<doSomethingWithColorFunction, rainbow_animation>(); run_animation<doSomethingWithColorFunction, custom_color_animation>(); run_animation<doSomethingWithColorFunction, other_color_animation>();
Until we’ll take advantage of variadic template that will call run_annimation multiple times, for every type that we’ll pass.
sequential_animation<doSomethingWithColorFunction, rainbow_animation, custom_color_animation, other_color_animation>();
But what if we want repeat a custom_color_animation 5 times?
sequential_animation<doSomethingWithColorFunction, rainbow_animation, custom_color_animation, custom_color_animation, custom_color_animation, custom_color_animation, custom_color_animation, other_color_animation>();
Is this a little ugly? To fix this problem we can create a class wrapper that will call custom_color_animation as many times as we declare.
template <animation_interface animation_type, auto times>
class repeat {
static_assert(times > 0);
public:
constexpr auto value() const noexcept {
return m_animation.value();
}
void step() {
m_animation.step();
if (m_animation.is_finished()) {
m_finished = (--m_steps) == 0;
m_animation = decltype(m_animation){};
}
}
constexpr bool is_finished() const noexcept {
return m_finished;
}
private:
int m_steps = times;
animation_type m_animation;
bool m_finished{false};
};
And now we can fix code using repeat wrapper:
sequential_animation<doSomethingWithColorFunction, rainbow_animation, repeat<custom_color_animation, 5>, other_color_animation>();
For palette conversion and animation speed, we can do similar wrappers. You can find more code there: https://github.com/dev-0x7C6/ledboard/tree/master/src/animation