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
|
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;
|
||||||
};
|
};
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
58
src/main.cpp
58
src/main.cpp
|
@ -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:
|
||||||
|
|
Loading…
Reference in a new issue