Remember last animation set by user and restart next time
This commit is contained in:
parent
320268ca14
commit
2b72d6c95b
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
58
src/main.cpp
58
src/main.cpp
|
@ -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:
|
||||
|
|
Loading…
Reference in a new issue