/** * @file EffectStateMachine.h * @author Gustice * @brief Effect-State-Machine-Class for processing Effect Macros * @version 0.6 * @date 2019-10-01 * * @copyright Copyright (c) 2019 * */ #pragma once #include "Color.hpp" #include "Macro.hpp" #include #include "ExactIndex.hpp" namespace Effect { /** * @brief Effect State Machine Class * @details Processes Effect macro array Macro entry subsequently * Processing is executed in following manner: * \li Index-incrementing each Tick * \li ticks until duration \ref EffMacro is finished * \li each tick the index incremented by templateLength/duration * \li Repeats-processing * \li Each repeat the tick and the index are set back to start * \li Switches to next Macro enty * \li Next entry is given by 'next' index * \li Color changes can be executed optionally */ class StateMachine { public: /// @brief Collection of object configuration at startup struct Parameter { /// @brief Idle intensity as background color uint8_t idleIntens; /// @brief dynamic range as variation around background color uint8_t dynamicRange; /// @brief Fade steps for color changes uint8_t fadeSteps; /// @brief Count of target LEDs uint8_t targetCount; }; ///@brief Construct a new Effect State Machine object ///@param templateLength Length of waveforms that are used to display StateMachine(Parameter ¶meter); ///@brief Sets the effect state machine to process given effect macro ///@param sequence reference to sequence ///@param startColor Start color. Use noColor to invoke with default color ///@param initialDelay Number of steps that are waited before effect is started void setEffect(const Macro &sequence, Color const *startColor = noColor, uint8_t initialDelay = 0); /// @brief Sets the effect state machine to process given effect macro /// @param sequence reference to sequence /// @param startColor Start color. Use noColor to invoke with default color /// @param intens Idle intensity for effect. Use nullptr to start with default intensity /// @param delayedStart Number of steps that are waited before effect is started void setEffect(const Macro &sequence, Color const *startColor, const uint8_t *intens, const uint8_t delayedStart); /// @brief Execute step of state machine /// @details Each tick the tick variable is decremented. After the limit is reached, /// the current macro line is either repeated or the next macro line is started (with /// an optional color change).\n /// @note Tick must be called regularly. For standard light applications all 40 ms seems to be /// a convenient values. /// @return Color const* Reference to color result virtual Color tick(void); /// Black out lights static Color UpdateBlank(StepProcessVars &pcsParam); /// Continuous illumination in idle intensity static Color UpdateIdle(StepProcessVars &pcsParam); /// Keep latest state on hold static Color UpdateFreeze(StepProcessVars &pcsParam); /// Step through a defined waveform static Color UpdateWave(StepProcessVars &pcsParam); /// Step through a defined waveform backwards static Color UpdateRevWave(StepProcessVars &pcsParam); /// Show flicker effect with idle intensity as static part with dynamic flicker-range static Color UpdateFlicker(StepProcessVars &pcsParam); protected: /// Collection of process values to maintain processing state machine struct ProcessValues { /// Decrementing tick, counting duration uint8_t tick; /// Decrementing repeats of current Effect-part uint8_t repeats; /// Index to macro element uint8_t macroIdx; /// Current index to waveform uint16_t waveIdx; /// Index step each tick according to duration and template length. uint16_t waveStep; }; /// @brief Concentrated parameter values of instance Parameter &_params; Color const * _curentColor; ProcessValues _prcValues; void SetIndexes(void); Macro const *_p_effSeq; Macro_t const *_p_effMac; ExactIndex _idx; // Color& (*apF_Effects)(StateMachine * SM); typedef Color const *pEffPrc(StateMachine *); }; } // namespace Effect