Remember last animation set by user and restart next time

This commit is contained in:
Thomas Kolb 2020-04-14 22:30:44 +02:00
parent 320268ca14
commit 2b72d6c95b
4 changed files with 90 additions and 12 deletions

View file

@ -22,6 +22,12 @@ class AnimationController
NUM_DEFAULT_ANIMATIONS
};
enum AnimationInitiator {
NONE,
INTERNAL,
USER
};
static const constexpr std::array<const char*, NUM_DEFAULT_ANIMATIONS> AnimationNames{
"Hot Fire",
"Cold Fire",
@ -33,8 +39,8 @@ class AnimationController
AnimationController(Fader *fader);
void changeAnimation(std::unique_ptr<Animation> anim, bool transition = true);
void changeAnimation(DefaultAnimation animation_id, bool transition = true);
void changeAnimation(std::unique_ptr<Animation> anim, bool transition = true, AnimationInitiator animInitiator = INTERNAL);
void changeAnimation(DefaultAnimation animation_id, bool transition = true, AnimationInitiator animInitiator = INTERNAL);
void loop(void);
@ -46,6 +52,10 @@ class AnimationController
return !m_animation || (m_animation->finished() && !m_nextAnimation);
}
uint32_t currentFrame(void) { return m_frame; }
AnimationInitiator animationInitiator(void) { return m_animationInitiator; }
DefaultAnimation lastDefaultAnimation(void) { return m_lastDefaultAnimation; }
private:
Fader *m_fader;
std::unique_ptr<Animation> m_animation;
@ -54,4 +64,7 @@ class AnimationController
SemaphoreHandle_t m_updateMutex;
uint64_t m_frame;
AnimationInitiator m_animationInitiator;
DefaultAnimation m_lastDefaultAnimation;
};

View file

@ -10,12 +10,13 @@ const constexpr
AnimationController::AnimationController(Fader *fader)
: m_fader(fader), m_animation(nullptr), m_frame(0)
: m_fader(fader), m_animation(nullptr), m_frame(0), m_animationInitiator(NONE), m_lastDefaultAnimation(FIRE_HOT)
{
m_updateMutex = xSemaphoreCreateMutex();
}
void AnimationController::changeAnimation(std::unique_ptr<Animation> anim, bool transition)
void AnimationController::changeAnimation(std::unique_ptr<Animation> anim, bool transition,
AnimationController::AnimationInitiator animInitiator)
{
xSemaphoreTake(m_updateMutex, portMAX_DELAY);
@ -32,29 +33,30 @@ void AnimationController::changeAnimation(std::unique_ptr<Animation> anim, bool
xSemaphoreGive(m_updateMutex);
}
void AnimationController::changeAnimation(AnimationController::DefaultAnimation animation_id, bool transition)
void AnimationController::changeAnimation(AnimationController::DefaultAnimation animation_id, bool transition,
AnimationController::AnimationInitiator animInitiator)
{
std::unique_ptr<Animation> anim(nullptr);
switch(animation_id) {
case FIRE_HOT:
changeAnimation(std::unique_ptr<Animation>(new FireAnimation(m_fader, false)), transition);
anim.reset(new FireAnimation(m_fader, false));
break;
case FIRE_COLD:
changeAnimation(std::unique_ptr<Animation>(new FireAnimation(m_fader, true)), transition);
anim.reset(new FireAnimation(m_fader, true));
break;
case SNOWFALL:
changeAnimation(std::unique_ptr<Animation>(new SnowfallAnimation(m_fader)), transition);
anim.reset(new SnowfallAnimation(m_fader));
break;
case MATRIX_CODE:
changeAnimation(std::unique_ptr<Animation>(new MatrixCodeAnimation(m_fader)), transition);
anim.reset(new MatrixCodeAnimation(m_fader));
break;
case FIREWORK:
changeAnimation(std::unique_ptr<Animation>(new FireworkAnimation(m_fader, 64, 1)), transition);
anim.reset(new FireworkAnimation(m_fader, 64, 1));
break;
case FONT_TEST:
@ -69,6 +71,12 @@ void AnimationController::changeAnimation(AnimationController::DefaultAnimation
default:
return; // unknown id, do nothing
}
m_lastDefaultAnimation = animation_id;
if(anim) {
changeAnimation(std::move(anim), transition, animInitiator);
}
}
void AnimationController::loop(void)

View file

@ -172,7 +172,8 @@ void WebServer::handleSetAnim(httpsserver::HTTPRequest *req, httpsserver::HTTPRe
WebServer::instance().m_animController->changeAnimation(
static_cast<AnimationController::DefaultAnimation>(anim_id),
true);
true,
AnimationController::USER);
}
void WebServer::handleListAnim(httpsserver::HTTPRequest *req, httpsserver::HTTPResponse *res)

View file

@ -105,6 +105,56 @@ enum LEDState {
TRANSITION_FADE2BLACK
};
static AnimationController::DefaultAnimation loadSavedAnimation(void)
{
size_t ret;
File f = SPIFFS.open("/dyn/last_anim");
if(!f) {
// error, but return something useful
goto readErr;
}
AnimationController::DefaultAnimation anim;
ret = f.readBytes(reinterpret_cast<char*>(&anim), sizeof(anim));
if(ret != sizeof(anim)) {
goto readErr;
}
f.close();
return anim;
readErr:
return AnimationController::FIRE_COLD;
}
static void updateSavedAnimation(AnimationController::DefaultAnimation newSavedAnim)
{
AnimationController::DefaultAnimation oldSavedAnim = loadSavedAnimation();
if(oldSavedAnim == newSavedAnim) {
return;
}
SPIFFS.mkdir("/dyn/");
File f = SPIFFS.open("/dyn/last_anim", "w");
if(!f) {
return;
}
size_t ret = f.write(reinterpret_cast<const uint8_t*>(&newSavedAnim), sizeof(newSavedAnim));
if(ret != sizeof(newSavedAnim)) {
// failed
}
f.close();
}
static void ledFSM(void)
{
static bool stateEntered = true;
@ -147,7 +197,8 @@ static void ledFSM(void)
// change to last used animation after some time
if((millis() - stateEnteredTime) > 60000) {
animController.changeAnimation(std::unique_ptr<Animation>(new FireAnimation(&ledFader, false)), true);
// FIXME: does not work with transition because of restart() call in ANIMATION state
animController.changeAnimation(loadSavedAnimation(), false);
ledState = ANIMATION;
}
break;
@ -165,6 +216,11 @@ static void ledFSM(void)
nextState = UDP;
ledState = TRANSITION;
}
if((animController.animationInitiator() == AnimationController::USER) &&
(animController.currentFrame() == 60*60)) { // FIXME: #define FPS and use everywhere
updateSavedAnimation(animController.lastDefaultAnimation());
}
break;
case UDP: