Implement state as multi-entry.
authorNot Zed <notzed@gmail.com>
Wed, 20 Dec 2023 08:57:15 +0000 (19:27 +1030)
committerNot Zed <notzed@gmail.com>
Wed, 20 Dec 2023 08:57:15 +0000 (19:27 +1030)
Implement 'play now' state so it returns to the list afterwards as expected.

dbindex.c
dbindex.h
http-monitor.c
music-player.c

index 89eeaf1..1f0745b 100644 (file)
--- 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);
 }
 
index 5de544c..f74acf0 100644 (file)
--- 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);
index 1c47834..aa52d1a 100644 (file)
@@ -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);
index d4429ec..11917a6 100644 (file)
@@ -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 : "<nil>");
@@ -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);