From 1b3971cafa407f93b48634d065392050a477a6a1 Mon Sep 17 00:00:00 2001 From: Not Zed Date: Wed, 20 Dec 2023 19:27:15 +1030 Subject: [PATCH] Implement state as multi-entry. Implement 'play now' state so it returns to the list afterwards as expected. --- dbindex.c | 21 +++++++++++++++++---- dbindex.h | 4 ++-- http-monitor.c | 2 +- music-player.c | 29 ++++++++++++++++++++++++++--- 4 files changed, 46 insertions(+), 10 deletions(-) diff --git a/dbindex.c b/dbindex.c index 89eeaf1..1f0745b 100644 --- a/dbindex.c +++ b/dbindex.c @@ -264,8 +264,8 @@ void dbindex_abort(MDB_txn *tx) { mdb_txn_abort(tx); } -int dbstate_get(MDB_txn *tx, dbindex *db, dbstate *s) { - MDB_val key = { .mv_data = "state", .mv_size = strlen("state") }; +int dbstate_get(MDB_txn *tx, dbindex *db, const char *id, dbstate *s) { + MDB_val key = { .mv_data = (char *)id, .mv_size = strlen(id) }; MDB_val data; db->res = mdb_get(tx, db->meta, &key, &data); @@ -275,6 +275,13 @@ int dbstate_get(MDB_txn *tx, dbindex *db, dbstate *s) { if (p->size != sizeof(dbstate)) return MDB_NOTFOUND; *s = *p; + + printf("dbstate get '%s'\n", id); + printf(" state: %08x\n", s->state); + printf(" listd: %d\n", s->listid); + printf(" seq: %d\n", s->seq); + printf(" filed: %d\n", s->fileid); + return 0; } else { printf("dbstate get: %s\n", mdb_strerror(db->res)); @@ -283,12 +290,18 @@ int dbstate_get(MDB_txn *tx, dbindex *db, dbstate *s) { return db->res; } -int dbstate_put(MDB_txn *tx, dbindex *db, dbstate *s) { - MDB_val key = { .mv_data = "state", .mv_size = strlen("state") }; +int dbstate_put(MDB_txn *tx, dbindex *db, const char *id, dbstate *s) { + MDB_val key = { .mv_data = (char *)id, .mv_size = strlen(id) }; MDB_val data = { .mv_data = s, .mv_size = sizeof(*s) }; s->size = sizeof(dbstate); + printf("dbstate put '%s'\n", id); + printf(" state: %08x\n", s->state); + printf(" listd: %d\n", s->listid); + printf(" seq: %d\n", s->seq); + printf(" filed: %d\n", s->fileid); + return mdb_put(tx, db->meta, &key, &data, 0); } diff --git a/dbindex.h b/dbindex.h index 5de544c..f74acf0 100644 --- a/dbindex.h +++ b/dbindex.h @@ -93,8 +93,8 @@ dbtxn *dbindex_begin(dbindex *db, dbtxn *txn, int readonly); int dbindex_commit(dbtxn *tx); void dbindex_abort(dbtxn *tx); -int dbstate_get(dbtxn *tx, dbindex *db, dbstate *s); -int dbstate_put(dbtxn *tx, dbindex *db, dbstate *s); +int dbstate_get(dbtxn *tx, dbindex *db, const char *id, dbstate *s); +int dbstate_put(dbtxn *tx, dbindex *db, const char *id, dbstate *s); dbdisk *dbdisk_get(dbtxn *tx, dbindex *db, int diskid); dbdisk *dbdisk_get_uuid(dbtxn *tx, dbindex *db, const char *uuid); diff --git a/http-monitor.c b/http-monitor.c index 1c47834..aa52d1a 100644 --- a/http-monitor.c +++ b/http-monitor.c @@ -162,7 +162,7 @@ static void write_file_json(struct obstack *os, dbfile *file) { static void write_state_json(dbindex *db, struct obstack *os) { dbtxn *tx = dbindex_begin(db, NULL, 1); dbstate state; - int res = dbstate_get(tx, db, &state); + int res = dbstate_get(tx, db, "state", &state); dbfile *file = NULL; printf("state.fileid = %d\n", state.fileid); diff --git a/music-player.c b/music-player.c index d4429ec..11917a6 100644 --- a/music-player.c +++ b/music-player.c @@ -622,7 +622,7 @@ int audio_checkpoint_state(struct audio_player *ap) { printf("checkpoint state=%d file=%d pos=%zd poss=%f '%s'\n", ap->playing_state.state, ap->playing_state.fileid, ap->playing_state.pos, ap->playing_state.poss, ap->playing ? ap->playing->full_path : ""); //printf("Checkpoint state, = %d\n", ap->playing_state.state); - if ((res = dbstate_put(tx, ap->index, &ap->playing_state)) == 0) { + if ((res = dbstate_put(tx, ap->index, "state", &ap->playing_state)) == 0) { dbindex_commit(tx); } else { printf("checkpoint failed: %s\n", mdb_strerror(res)); @@ -647,11 +647,20 @@ static int audio_advance_file(struct audio_player *ap, dbfile *(*advance)(dbscan dbfile_free(ap->playing); ap->playing = NULL; + if (ap->playing_state.listid == 0) { + printf("advance: play-now back to list\n"); + res = dbstate_get(tx, ap->index, "state:list", &ap->playing_state); + if (res != 0) { + printf("No list state, fallback to lid=1\n"); + ap->playing_state.listid = 1; + } + } + do { printf("loop: %d\n", retry); file = dbscan_list_entry(tx, &scan, ap->index, ap->playing_state.listid, ap->playing_state.seq, ap->playing_state.fileid); if (file) { - printf("entry: %s\n", file->path); + printf("entry: lid=%d seq=%d path=%s\n", ap->playing_state.listid, ap->playing_state.seq, file->path); dbfile_free(file); file = advance(&scan); printf("next: %s\n", file ? file->path : ""); @@ -774,6 +783,20 @@ int audio_goto_file(struct audio_player *ap, int fileid) { if (file) { dbfile_full_path(tx, ap->index, file); + if (ap->playing_state.listid != 0) { + dbtxn *tw = dbindex_begin(ap->index, NULL, 0); + ap->playing_state.stamp = time(NULL); + printf("save list: lid=%d seq=%d path=%s\n", ap->playing_state.listid, ap->playing_state.seq, file->path); + res = dbstate_put(tw, ap->index, "state:list", &ap->playing_state); + if (res == 0) + dbindex_commit(tw); + else + printf("checkpoint failed %s\n", mdb_strerror(res)); + } + ap->playing_state.listid = 0; + ap->playing_state.seq = 0; + ap->playing_state.fileid = file->id; + ap->playing = file; res = audio_init_media(ap, file->full_path); @@ -794,7 +817,7 @@ int audio_restore_state(struct audio_player *ap) { // FIXME: playlist stuff? - if ((res = dbstate_get(tx, ap->index, &ap->playing_state)) == 0 && ap->playing_state.state == 1) { + if ((res = dbstate_get(tx, ap->index, "state", &ap->playing_state)) == 0 && ap->playing_state.state == 1) { dbfile *file = dbfile_get(tx, ap->index, ap->playing_state.fileid); printf("restoring file %s\n", file->path); -- 2.39.5