Introduce StateManager to persist state between power cycles (#6)
- add reset state menu option to return all settings back to default values. - add reverse encoder menu option and save state - make saving to EEPROM safer by wrapping put calls with noInterrupts() - improve save state behavior by using a mutex flag and update check with debounce in main loop - refactor gravity.h global const definitions to be static and more readable. - improve usage of EncoderDir in ISR with pointer to instance and static isr() method. - reduce u8g2 memory usage by using single page buffer Reviewed-on: https://git.pinkduck.xyz/adam/libGravity/pulls/6 Co-authored-by: Adam Wonak <adam.wonak@gmail.com> Co-committed-by: Adam Wonak <adam.wonak@gmail.com>
This commit is contained in:
65
examples/Gravity/save_state.h
Normal file
65
examples/Gravity/save_state.h
Normal file
@ -0,0 +1,65 @@
|
||||
#ifndef SAVE_STATE_H
|
||||
#define SAVE_STATE_H
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <gravity.h>
|
||||
|
||||
// Forward-declare AppState to avoid circular dependencies.
|
||||
struct AppState;
|
||||
|
||||
// Define the constants for the current firmware.
|
||||
const char CURRENT_SKETCH_NAME[] = "Gravity";
|
||||
const float CURRENT_SKETCH_VERSION = 0.2f;
|
||||
|
||||
/**
|
||||
* @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
|
||||
Reference in New Issue
Block a user