diff options
-rw-r--r-- | NEWS | 1 | ||||
-rw-r--r-- | src/output_command.c | 6 | ||||
-rw-r--r-- | src/output_state.c | 8 | ||||
-rw-r--r-- | src/output_state.h | 8 | ||||
-rw-r--r-- | src/playlist_state.c | 18 | ||||
-rw-r--r-- | src/playlist_state.h | 9 | ||||
-rw-r--r-- | src/state_file.c | 22 | ||||
-rw-r--r-- | src/volume.c | 6 | ||||
-rw-r--r-- | src/volume.h | 9 |
9 files changed, 87 insertions, 0 deletions
@@ -36,6 +36,7 @@ ver 0.16 (20??/??/??) * renamed option "--stdout" to "--stderr" * removed options --create-db and --no-create-db * automatically update the database with Linux inotify +* state_file: save only if something has changed * obey $(sysconfdir) for default mpd.conf location diff --git a/src/output_command.c b/src/output_command.c index 5da176dde..9d948c8cc 100644 --- a/src/output_command.c +++ b/src/output_command.c @@ -31,6 +31,8 @@ #include "mixer_control.h" #include "idle.h" +extern unsigned audio_output_state_version; + bool audio_output_enable_index(unsigned idx) { @@ -44,6 +46,8 @@ audio_output_enable_index(unsigned idx) ao->enabled = true; idle_add(IDLE_OUTPUT); + ++audio_output_state_version; + return true; } @@ -67,5 +71,7 @@ audio_output_disable_index(unsigned idx) idle_add(IDLE_MIXER); } + ++audio_output_state_version; + return true; } diff --git a/src/output_state.c b/src/output_state.c index 7fc60518c..be135f6d0 100644 --- a/src/output_state.c +++ b/src/output_state.c @@ -34,6 +34,8 @@ #define AUDIO_DEVICE_STATE "audio_device_state:" +unsigned audio_output_state_version; + void audio_output_state_save(FILE *fp) { @@ -80,3 +82,9 @@ audio_output_state_read(const char *line) ao->enabled = false; return true; } + +unsigned +audio_output_state_get_version(void) +{ + return audio_output_state_version; +} diff --git a/src/output_state.h b/src/output_state.h index 1efae94a1..3b865f5fe 100644 --- a/src/output_state.h +++ b/src/output_state.h @@ -34,4 +34,12 @@ audio_output_state_read(const char *line); void audio_output_state_save(FILE *fp); +/** + * Generates a version number for the current state of the audio + * outputs. This is used by timer_save_state_file() to determine + * whether the state has changed and the state file should be saved. + */ +unsigned +audio_output_state_get_version(void); + #endif diff --git a/src/playlist_state.c b/src/playlist_state.c index f288a5738..5d18cc339 100644 --- a/src/playlist_state.c +++ b/src/playlist_state.c @@ -200,3 +200,21 @@ playlist_state_restore(const char *line, FILE *fp, struct playlist *playlist) return true; } + +unsigned +playlist_state_get_hash(const struct playlist *playlist) +{ + return playlist->queue.version ^ + (getPlayerElapsedTime() << 8) ^ + (playlist->current >= 0 + ? (queue_order_to_position(&playlist->queue, + playlist->current) << 16) + : 0) ^ + ((int)getPlayerCrossFade() << 20) ^ + (getPlayerState() << 24) ^ + (playlist->queue.random << 27) ^ + (playlist->queue.repeat << 28) ^ + (playlist->queue.single << 29) ^ + (playlist->queue.consume << 30) ^ + (playlist->queue.random << 31); +} diff --git a/src/playlist_state.h b/src/playlist_state.h index 7ed7e8c8e..d116aaeb1 100644 --- a/src/playlist_state.h +++ b/src/playlist_state.h @@ -36,4 +36,13 @@ playlist_state_save(FILE *fp, const struct playlist *playlist); bool playlist_state_restore(const char *line, FILE *fp, struct playlist *playlist); +/** + * Generates a hash number for the current state of the playlist and + * the playback options. This is used by timer_save_state_file() to + * determine whether the state has changed and the state file should + * be saved. + */ +unsigned +playlist_state_get_hash(const struct playlist *playlist); + #endif diff --git a/src/state_file.c b/src/state_file.c index 14c76d739..4ba157b14 100644 --- a/src/state_file.c +++ b/src/state_file.c @@ -36,6 +36,13 @@ static char *state_file_path; /** the GLib source id for the save timer */ static guint save_state_source_id; +/** + * These version numbers determine whether we need to save the state + * file. If nothing has changed, we won't let the hard drive spin up. + */ +static unsigned prev_volume_version, prev_output_version, + prev_playlist_version; + static void state_file_write(void) { @@ -57,6 +64,10 @@ state_file_write(void) playlist_state_save(fp, &g_playlist); while(fclose(fp) && errno == EINTR) /* nothing */; + + prev_volume_version = sw_volume_state_get_hash(); + prev_output_version = audio_output_state_get_version(); + prev_playlist_version = playlist_state_get_hash(&g_playlist); } static void @@ -88,6 +99,10 @@ state_file_read(void) } while(fclose(fp) && errno == EINTR) /* nothing */; + + prev_volume_version = sw_volume_state_get_hash(); + prev_output_version = audio_output_state_get_version(); + prev_playlist_version = playlist_state_get_hash(&g_playlist); } /** @@ -97,6 +112,13 @@ state_file_read(void) static gboolean timer_save_state_file(G_GNUC_UNUSED gpointer data) { + if (prev_volume_version == sw_volume_state_get_hash() && + prev_output_version == audio_output_state_get_version() && + prev_playlist_version == playlist_state_get_hash(&g_playlist)) + /* nothing has changed - don't save the state file, + don't spin up the hard disk */ + return true; + state_file_write(); return true; } diff --git a/src/volume.c b/src/volume.c index 5f4a66837..8b33f592d 100644 --- a/src/volume.c +++ b/src/volume.c @@ -122,3 +122,9 @@ void save_sw_volume_state(FILE *fp) { fprintf(fp, SW_VOLUME_STATE "%u\n", volume_software_set); } + +unsigned +sw_volume_state_get_hash(void) +{ + return volume_software_set; +} diff --git a/src/volume.h b/src/volume.h index 0db231ef6..66e7c43f0 100644 --- a/src/volume.h +++ b/src/volume.h @@ -36,4 +36,13 @@ read_sw_volume_state(const char *line); void save_sw_volume_state(FILE *fp); +/** + * Generates a hash number for the current state of the software + * volume control. This is used by timer_save_state_file() to + * determine whether the state has changed and the state file should + * be saved. + */ +unsigned +sw_volume_state_get_hash(void); + #endif |