feat(state): auto-save
This commit is contained in:
@@ -49,6 +49,7 @@ static void print_help(int status_code) {
|
|||||||
"[--wayland] "
|
"[--wayland] "
|
||||||
"[--cocoa] "
|
"[--cocoa] "
|
||||||
"[--win32] "
|
"[--win32] "
|
||||||
|
"[-as / -nas] "
|
||||||
"[-oma=MAJOR] "
|
"[-oma=MAJOR] "
|
||||||
"[-omi=MINOR] "
|
"[-omi=MINOR] "
|
||||||
"\n\n"
|
"\n\n"
|
||||||
@@ -87,6 +88,8 @@ static void print_help(int status_code) {
|
|||||||
" -nls, --no-load-state do not load saved state\n"
|
" -nls, --no-load-state do not load saved state\n"
|
||||||
" -ss, --save-state save state (default)\n"
|
" -ss, --save-state save state (default)\n"
|
||||||
" -nss, --no-save-state do not save state\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"
|
" -mr, --midi-reconnect auto-reconnect midi (default)\n"
|
||||||
" -nmr, --no-midi-reconnect do not auto-reconnect midi\n"
|
" -nmr, --no-midi-reconnect do not auto-reconnect midi\n"
|
||||||
" -tm, --trace-midi print midi code and values\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->internal_size = 720;
|
||||||
params->load_state = true;
|
params->load_state = true;
|
||||||
params->save_state = true;
|
params->save_state = true;
|
||||||
|
params->auto_save = false;
|
||||||
params->midi_reconnect = true;
|
params->midi_reconnect = true;
|
||||||
params->trace_midi = false;
|
params->trace_midi = false;
|
||||||
params->trace_fps = false;
|
params->trace_fps = false;
|
||||||
@@ -234,6 +238,10 @@ void args_parse(Parameters *params, int argc, char **argv) {
|
|||||||
params->save_state = true;
|
params->save_state = true;
|
||||||
} else if (is_arg(arg, "-nss") || is_arg(arg, "--no-save-state")) {
|
} else if (is_arg(arg, "-nss") || is_arg(arg, "--no-save-state")) {
|
||||||
params->save_state = false;
|
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")) {
|
} else if (is_arg(arg, "-mr") || is_arg(arg, "--midi-reconnect")) {
|
||||||
params->midi_reconnect = true;
|
params->midi_reconnect = true;
|
||||||
} else if (is_arg(arg, "-nmr") || is_arg(arg, "--no-midi-reconnect")) {
|
} else if (is_arg(arg, "-nmr") || is_arg(arg, "--no-midi-reconnect")) {
|
||||||
|
|||||||
@@ -87,6 +87,12 @@
|
|||||||
#define MAX_TAP_VALUES 10
|
#define MAX_TAP_VALUES 10
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* STATE */
|
||||||
|
|
||||||
|
#ifndef STATE_AUTO_SAVE_SECONDS
|
||||||
|
#define STATE_AUTO_SAVE_SECONDS 0.1
|
||||||
|
#endif
|
||||||
|
|
||||||
/* OPENGL */
|
/* OPENGL */
|
||||||
|
|
||||||
#ifndef OPENGL_MAJOR_VERSION
|
#ifndef OPENGL_MAJOR_VERSION
|
||||||
@@ -98,6 +104,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* GLFW CONSTANTS */
|
/* GLFW CONSTANTS */
|
||||||
|
|
||||||
#ifndef GLFW_BACKENDS
|
#ifndef GLFW_BACKENDS
|
||||||
#define GLFW_BACKEND_ANY 0
|
#define GLFW_BACKEND_ANY 0
|
||||||
#define GLFW_BACKEND_X11 1
|
#define GLFW_BACKEND_X11 1
|
||||||
|
|||||||
+4
-2
@@ -109,10 +109,12 @@ void file_dump(const char *path, const char *content) {
|
|||||||
fclose(file_pointer);
|
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;
|
FILE *file_pointer;
|
||||||
|
|
||||||
log_info("Writing %s...", path);
|
if (log) {
|
||||||
|
log_info("Writing %s...", path);
|
||||||
|
}
|
||||||
|
|
||||||
// open file
|
// open file
|
||||||
file_pointer = fopen(path, "w");
|
file_pointer = fopen(path, "w");
|
||||||
|
|||||||
+1
-1
@@ -9,7 +9,7 @@ bool file_should_update(const File *file);
|
|||||||
|
|
||||||
bool file_update(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);
|
void file_dump(const char *path, const char *content);
|
||||||
|
|
||||||
|
|||||||
@@ -207,6 +207,7 @@ static void start_state_background_write() {
|
|||||||
process_args->context = &context;
|
process_args->context = &context;
|
||||||
process_args->state_config = project.state_config;
|
process_args->state_config = project.state_config;
|
||||||
process_args->midi = &midi;
|
process_args->midi = &midi;
|
||||||
|
process_args->auto_save = init_params.auto_save;
|
||||||
if (pthread_create(&thread, NULL, state_background_write, process_args) ==
|
if (pthread_create(&thread, NULL, state_background_write, process_args) ==
|
||||||
0) {
|
0) {
|
||||||
pthread_detach(thread);
|
pthread_detach(thread);
|
||||||
|
|||||||
+23
-7
@@ -12,6 +12,7 @@
|
|||||||
#include "rand.h"
|
#include "rand.h"
|
||||||
#include "state.h"
|
#include "state.h"
|
||||||
#include "tempo.h"
|
#include "tempo.h"
|
||||||
|
#include "timer.h"
|
||||||
|
|
||||||
static void safe_midi_write(MidiDevice midi, unsigned int code,
|
static void safe_midi_write(MidiDevice midi, unsigned int code,
|
||||||
unsigned char value) {
|
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,
|
static void save_to_file(const Context *context, StateConfig state_config,
|
||||||
const char *state_file) {
|
const char *state_file, const bool log) {
|
||||||
StringArray lines;
|
StringArray lines;
|
||||||
|
|
||||||
log_info("Saving state to '%s'...", state_file);
|
if (log) {
|
||||||
|
log_info("Saving state to '%s'...", state_file);
|
||||||
|
}
|
||||||
|
|
||||||
lines.length = 0;
|
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,
|
static void save_to_default_file(const Context *context,
|
||||||
StateConfig state_config) {
|
StateConfig state_config, const bool log) {
|
||||||
char state_file[STR_LEN];
|
char state_file[STR_LEN];
|
||||||
|
|
||||||
snprintf(state_file, STR_LEN, "%s.txt", state_config.save_file_prefix);
|
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,
|
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,
|
snprintf(state_file, STR_LEN, "%s.%d.txt", state_config.save_file_prefix,
|
||||||
index);
|
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) {
|
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;
|
Context *context = process_args->context;
|
||||||
StateConfig state_config = process_args->state_config;
|
StateConfig state_config = process_args->state_config;
|
||||||
MidiDevice *midi = process_args->midi;
|
MidiDevice *midi = process_args->midi;
|
||||||
|
bool auto_save = process_args->auto_save;
|
||||||
|
|
||||||
bool beat_active;
|
bool beat_active;
|
||||||
bool last_active;
|
bool last_active;
|
||||||
bool change;
|
bool change;
|
||||||
bool last_change;
|
bool last_change;
|
||||||
|
bool do_auto_save;
|
||||||
|
bool last_auto_save;
|
||||||
|
|
||||||
log_info("(state) background writing started");
|
log_info("(state) background writing started");
|
||||||
|
|
||||||
last_active = false;
|
last_active = false;
|
||||||
last_change = false;
|
last_change = false;
|
||||||
|
last_auto_save = false;
|
||||||
|
|
||||||
while (!context->stop) {
|
while (!context->stop) {
|
||||||
beat_active = tempo_progress(&context->tempo, 1.0) < 0.5;
|
beat_active = tempo_progress(&context->tempo, 1.0) < 0.5;
|
||||||
@@ -791,6 +798,15 @@ void *state_background_write(void *args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
last_change = change;
|
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");
|
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) {
|
void state_save(const Context *context, StateConfig state_config) {
|
||||||
save_to_default_file(context, state_config);
|
save_to_default_file(context, state_config, true);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ typedef struct Parameters {
|
|||||||
unsigned int internal_size;
|
unsigned int internal_size;
|
||||||
bool load_state;
|
bool load_state;
|
||||||
bool save_state;
|
bool save_state;
|
||||||
|
bool auto_save;
|
||||||
bool midi_reconnect;
|
bool midi_reconnect;
|
||||||
bool trace_midi;
|
bool trace_midi;
|
||||||
bool trace_fps;
|
bool trace_fps;
|
||||||
@@ -279,6 +280,7 @@ typedef struct StateBackgroundWriteArgs {
|
|||||||
Context *context;
|
Context *context;
|
||||||
StateConfig state_config;
|
StateConfig state_config;
|
||||||
MidiDevice *midi;
|
MidiDevice *midi;
|
||||||
|
bool auto_save;
|
||||||
} StateBackgroundWriteArgs;
|
} StateBackgroundWriteArgs;
|
||||||
|
|
||||||
// timer.c
|
// timer.c
|
||||||
|
|||||||
Reference in New Issue
Block a user