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

View file

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

View file

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

View file

@ -105,6 +105,56 @@ enum LEDState {
TRANSITION_FADE2BLACK 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 void ledFSM(void)
{ {
static bool stateEntered = true; static bool stateEntered = true;
@ -147,7 +197,8 @@ static void ledFSM(void)
// change to last used animation after some time // change to last used animation after some time
if((millis() - stateEnteredTime) > 60000) { 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; ledState = ANIMATION;
} }
break; break;
@ -165,6 +216,11 @@ static void ledFSM(void)
nextState = UDP; nextState = UDP;
ledState = TRANSITION; ledState = TRANSITION;
} }
if((animController.animationInitiator() == AnimationController::USER) &&
(animController.currentFrame() == 60*60)) { // FIXME: #define FPS and use everywhere
updateSavedAnimation(animController.lastDefaultAnimation());
}
break; break;
case UDP: case UDP: