esp32-sk6812/src/Animation/AnimationController.cpp

106 lines
2.6 KiB
C++

#include "Animation/AnimationController.h"
#include "Animation/AllAnimations.h"
#include "Font.h"
const constexpr
std::array<const char*, AnimationController::NUM_DEFAULT_ANIMATIONS>
AnimationController::AnimationNames;
AnimationController::AnimationController(Fader *fader)
: m_fader(fader), m_animation(nullptr), m_frame(0)
{
m_updateMutex = xSemaphoreCreateMutex();
}
void AnimationController::changeAnimation(std::unique_ptr<Animation> anim, bool transition)
{
xSemaphoreTake(m_updateMutex, portMAX_DELAY);
if(transition && m_animation) {
m_nextAnimation = std::move(anim);
m_animation->stop();
} else {
m_frame = 0;
m_animation = std::move(anim);
m_nextAnimation.reset(nullptr);
}
xSemaphoreGive(m_updateMutex);
}
void AnimationController::changeAnimation(AnimationController::DefaultAnimation animation_id, bool transition)
{
std::unique_ptr<Animation> anim(nullptr);
switch(animation_id) {
case FIRE_HOT:
changeAnimation(std::unique_ptr<Animation>(new FireAnimation(m_fader, false)), transition);
break;
case FIRE_COLD:
changeAnimation(std::unique_ptr<Animation>(new FireAnimation(m_fader, true)), transition);
break;
case SNOWFALL:
changeAnimation(std::unique_ptr<Animation>(new SnowfallAnimation(m_fader)), transition);
break;
case MATRIX_CODE:
changeAnimation(std::unique_ptr<Animation>(new MatrixCodeAnimation(m_fader)), transition);
break;
case FONT_TEST:
{
Bitmap bmp(0, 0);
Font::textToBitmap("Hello World! ABCDEFGHIJKLMNOPQRSTUVWXYZ", &bmp, Fader::Color{0, 0, 32, 32});
changeAnimation(std::unique_ptr<Animation>(new ImageScrollerAnimation(m_fader, &bmp, 5)), transition);
}
break;
default:
return; // unknown id, do nothing
}
}
void AnimationController::loop(void)
{
xSemaphoreTake(m_updateMutex, portMAX_DELAY);
if(m_animation && !m_animation->finished()) {
m_animation->loop(m_frame);
}
m_frame++;
if(m_nextAnimation &&
(!m_animation || m_animation->finished())) {
// old animation has finished or is unset -> start the new one
m_frame = 0;
m_animation.swap(m_nextAnimation);
m_nextAnimation.reset(nullptr);
}
xSemaphoreGive(m_updateMutex);
}
void AnimationController::stop(void)
{
if(m_animation) {
m_animation->stop();
}
}
void AnimationController::restart(void)
{
if(m_animation) {
m_animation->reset();
}
m_frame = 0;
}