#ifndef SAVE_STATE_H #define SAVE_STATE_H #include #include // Forward-declare AppState to avoid circular dependencies. struct AppState; // Define the constants for the current firmware. const char CURRENT_SKETCH_NAME[] = "Gravity"; const byte CURRENT_SKETCH_VERSION = 3; /** * @brief Manages saving and loading of the application state to and from EEPROM. */ class StateManager { public: StateManager(); // Populate the AppState instance with values from EEPROM if they exist. bool initialize(AppState& app); // Reset AppState instance back to default values. void reset(AppState& app); // Call from main loop, check if state has changed and needs to be saved. void update(const AppState& app); // Indicate that state has changed and we should save. void markDirty(); private: // This struct holds the data that identifies the firmware version. struct Metadata { char sketchName[16]; byte version; }; struct ChannelState { byte base_clock_mod_index; byte base_probability; byte base_duty_cycle; byte base_offset; byte cv_source; // Cast the CvSource enum to a byte for storage byte cv_destination; // Cast the CvDestination enum as a byte for storage }; // This struct holds all the parameters we want to save. struct EepromData { int tempo; bool encoder_reversed; byte selected_param; byte selected_channel; byte selected_source; ChannelState channel_data[Gravity::OUTPUT_COUNT]; }; void save(const AppState& app); bool isDataValid(); void _save_worker(const AppState& app); void _metadata_worker(); bool _isDirty; unsigned long _lastChangeTime; static const unsigned long SAVE_DELAY_MS = 2000; }; #endif // SAVE_STATE_H