Animation framework for my skateboard slowly taking shape

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

Leave a Reply

Your email address will not be published.