Animation framework for my skateboard slowly taking shape

int main() {

	for (;;) {
			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();

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);

	constexpr auto value() const noexcept {
		return m_animation.value();

	void 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;

	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: