diff --git a/src/args.c b/src/args.c index bacfe46..e01d23b 100644 --- a/src/args.c +++ b/src/args.c @@ -49,6 +49,7 @@ static void print_help(int status_code) { "[--wayland] " "[--cocoa] " "[--win32] " + "[-as / -nas] " "[-oma=MAJOR] " "[-omi=MINOR] " "\n\n" @@ -87,6 +88,8 @@ static void print_help(int status_code) { " -nls, --no-load-state do not load saved state\n" " -ss, --save-state save state (default)\n" " -nss, --no-save-state do not save state\n" + " -as, --auto-save continuously save state (every ~10ms)\n" + " -nas, --no-auto-save do not continuously save state (default)\n" " -mr, --midi-reconnect auto-reconnect midi (default)\n" " -nmr, --no-midi-reconnect do not auto-reconnect midi\n" " -tm, --trace-midi print midi code and values\n" @@ -168,6 +171,7 @@ void args_parse(Parameters *params, int argc, char **argv) { params->internal_size = 720; params->load_state = true; params->save_state = true; + params->auto_save = false; params->midi_reconnect = true; params->trace_midi = false; params->trace_fps = false; @@ -234,6 +238,10 @@ void args_parse(Parameters *params, int argc, char **argv) { params->save_state = true; } else if (is_arg(arg, "-nss") || is_arg(arg, "--no-save-state")) { params->save_state = false; + } else if (is_arg(arg, "-as") || is_arg(arg, "--auto-save")) { + params->auto_save = true; + } else if (is_arg(arg, "-nas") || is_arg(arg, "--no-auto-save")) { + params->auto_save = false; } else if (is_arg(arg, "-mr") || is_arg(arg, "--midi-reconnect")) { params->midi_reconnect = true; } else if (is_arg(arg, "-nmr") || is_arg(arg, "--no-midi-reconnect")) { diff --git a/src/config.h b/src/config.h index 87489dd..2ea566c 100644 --- a/src/config.h +++ b/src/config.h @@ -87,6 +87,12 @@ #define MAX_TAP_VALUES 10 #endif +/* STATE */ + +#ifndef STATE_AUTO_SAVE_SECONDS +#define STATE_AUTO_SAVE_SECONDS 0.1 +#endif + /* OPENGL */ #ifndef OPENGL_MAJOR_VERSION @@ -98,6 +104,7 @@ #endif /* GLFW CONSTANTS */ + #ifndef GLFW_BACKENDS #define GLFW_BACKEND_ANY 0 #define GLFW_BACKEND_X11 1 diff --git a/src/file.c b/src/file.c index adb00dd..52c0b43 100644 --- a/src/file.c +++ b/src/file.c @@ -109,10 +109,12 @@ void file_dump(const char *path, const char *content) { fclose(file_pointer); } -void file_write(const char *path, const StringArray *lines) { +void file_write(const char *path, const StringArray *lines, const bool log) { FILE *file_pointer; - log_info("Writing %s...", path); + if (log) { + log_info("Writing %s...", path); + } // open file file_pointer = fopen(path, "w"); diff --git a/src/file.h b/src/file.h index c683e68..aa05e7b 100644 --- a/src/file.h +++ b/src/file.h @@ -9,7 +9,7 @@ bool file_should_update(const File *file); bool file_update(File *file); -void file_write(const char *path, const StringArray *lines); +void file_write(const char *path, const StringArray *lines, const bool log); void file_dump(const char *path, const char *content); diff --git a/src/forge.c b/src/forge.c index 7d3d3ad..7ea9b5f 100644 --- a/src/forge.c +++ b/src/forge.c @@ -207,6 +207,7 @@ static void start_state_background_write() { process_args->context = &context; process_args->state_config = project.state_config; process_args->midi = &midi; + process_args->auto_save = init_params.auto_save; if (pthread_create(&thread, NULL, state_background_write, process_args) == 0) { pthread_detach(thread); diff --git a/src/state.c b/src/state.c index 4549686..c7361d2 100644 --- a/src/state.c +++ b/src/state.c @@ -12,6 +12,7 @@ #include "rand.h" #include "state.h" #include "tempo.h" +#include "timer.h" static void safe_midi_write(MidiDevice midi, unsigned int code, unsigned char value) { @@ -179,10 +180,12 @@ static void load_from_index_file(Context *context, StateConfig state_config, } static void save_to_file(const Context *context, StateConfig state_config, - const char *state_file) { + const char *state_file, const bool log) { StringArray lines; - log_info("Saving state to '%s'...", state_file); + if (log) { + log_info("Saving state to '%s'...", state_file); + } lines.length = 0; @@ -278,16 +281,16 @@ static void save_to_file(const Context *context, StateConfig state_config, } } - file_write(state_file, &lines); + file_write(state_file, &lines, log); } static void save_to_default_file(const Context *context, - StateConfig state_config) { + StateConfig state_config, const bool log) { char state_file[STR_LEN]; snprintf(state_file, STR_LEN, "%s.txt", state_config.save_file_prefix); - save_to_file(context, state_config, state_file); + save_to_file(context, state_config, state_file, log); } static void save_to_index_file(const Context *context, StateConfig state_config, @@ -297,7 +300,7 @@ static void save_to_index_file(const Context *context, StateConfig state_config, snprintf(state_file, STR_LEN, "%s.%d.txt", state_config.save_file_prefix, index); - save_to_file(context, state_config, state_file); + save_to_file(context, state_config, state_file, true); } void state_parse_config(StateConfig *state_config, const ConfigFile *config) { @@ -756,16 +759,20 @@ void *state_background_write(void *args) { Context *context = process_args->context; StateConfig state_config = process_args->state_config; MidiDevice *midi = process_args->midi; + bool auto_save = process_args->auto_save; bool beat_active; bool last_active; bool change; bool last_change; + bool do_auto_save; + bool last_auto_save; log_info("(state) background writing started"); last_active = false; last_change = false; + last_auto_save = false; while (!context->stop) { beat_active = tempo_progress(&context->tempo, 1.0) < 0.5; @@ -791,6 +798,15 @@ void *state_background_write(void *args) { } last_change = change; + + do_auto_save = fmod(context->time, STATE_AUTO_SAVE_SECONDS) < + STATE_AUTO_SAVE_SECONDS * 0.5; + + if (auto_save && do_auto_save && !last_auto_save) { + save_to_default_file(context, state_config, false); + } + + last_auto_save = do_auto_save; } log_info("(state) background writing stopped by main thread"); @@ -831,5 +847,5 @@ void state_init(Context *context, StateConfig state_config, bool demo, } void state_save(const Context *context, StateConfig state_config) { - save_to_default_file(context, state_config); + save_to_default_file(context, state_config, true); } diff --git a/src/types.h b/src/types.h index 98a18cf..ad9afa8 100644 --- a/src/types.h +++ b/src/types.h @@ -55,6 +55,7 @@ typedef struct Parameters { unsigned int internal_size; bool load_state; bool save_state; + bool auto_save; bool midi_reconnect; bool trace_midi; bool trace_fps; @@ -279,6 +280,7 @@ typedef struct StateBackgroundWriteArgs { Context *context; StateConfig state_config; MidiDevice *midi; + bool auto_save; } StateBackgroundWriteArgs; // timer.c