QWiiLoad (previously named WiiTCPLoad) Nintendo Wii homebrew executable uploader is now fully rewritten and it’s working with recent versions of Wii homebrew channel. First version was released 12 years ago 🙂 it was my first (public) Qt project.
Tag: c++20
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
CppCon 2018: Louis Dionne “Compile-time programming and reflection in C++20 and beyond”
Overview on upcoming features in C++20. Video covers extended constexpr functionality, upcoming reflection and code injection.
Introducing concepts in ledboard project
In near feature we’ll able to write nifty constrains for template arguments using concepts (C++20). I’m currently researching common use cases and trying to adopt them in my ledboard project. With GCC >= 8.1 you can enable concepts using `-fconcepts` instrumentation compile flag, but this feature is not standardized yet. The current implementation and specification on concepts might change, keep this in mind. With recent talk at CppCon by Bjarne Stroustrup we get a pretty bold picture that this feature is essential and simplify things (see Bjarne Stroustrup “Concepts: The Future of Generic Programming (the future is here)”). From my perspective them main advantage is to write zero-cost abstraction with better constrains and maintainability and get rid of template error novel.
Below there is code that I’m currently using for as static interface for my animation classes, take a look:
template<typename type> concept bool animation_interface = requires(type a) { { a.value() } -> rgb // animation_interface must have method value() that returns rgb type { a.r() } -> u8 // requires a.r() method with integer return type { a.g() } -> u8 // ... { a.b() } -> u8 // ... { a.step() } -> void // requires callable a.step() method without return type }; // without constrains template <typename type> constexpr auto doSomething(type &&v) { return v.value(); } doSomething(100) // deduction from arguments to doSomething<int>(100) // will fail with error we cannot call value() on 100 (prvalue) // but error is hard to understand and situation is a post factum // with constrains template <animation_interface type> constexpr auto doSomething(type &&v) { return v.value(); } doSomething(100) // does not fulfilled requirements for animation_interface (nice error) // example class white_color_forever { public: auto value() -> rgb { return {r(), g(), b()}; } auto r() { return 0xff; } auto g() { return 0xff; } auto b() { return 0xff; } auto step() -> void {} } doSomething(white_color_forever{}); // fine, this is acceptable because // all exceptations are meet
There are requirements that must be fulfilled. Code does not compile if template parameter do not fulfill requirements. If you’re interested there is one of my use cases: a palette_converter_wrapper. Where I’m wrapping animation inside method forwarding class and overloading value() method. This code will play nice with any type that fulfill abstraction_interface requirements 🙂 So this is a static interface, that is what we’re waiting for.