diff --git a/core/playlists/artist.c b/core/playlists/artist.c index 8ab8b83b..88b690bc 100644 --- a/core/playlists/artist.c +++ b/core/playlists/artist.c @@ -71,13 +71,10 @@ static bool __artist_pl_load(void *data) for (i = 0; i < n; i++) { name = file_readl(&artist_file); playlist = __artist_pl_lookup(name); + if (playlist) + playlist_generic_load(playlist, &artist_file, + PL_SAVE_METADATA); g_free(name); - - if (!playlist) - continue; - queue_load_flags(&playlist->pl_queue, &artist_file, true); - queue_iter_set(&playlist->pl_queue, &playlist->pl_queue.q_cur, - playlist->pl_queue.q_cur.it_pos); } file_close(&artist_file); diff --git a/core/playlists/generic.c b/core/playlists/generic.c index 9647201e..1151c8b0 100644 --- a/core/playlists/generic.c +++ b/core/playlists/generic.c @@ -22,6 +22,50 @@ void playlist_generic_init(struct playlist *playlist, unsigned int flags, playlist->pl_private = NULL; } +void playlist_generic_load(struct playlist *playlist, struct file *file, + unsigned int flags) +{ + unsigned int f, n, i, t, it = 0; + int field, ascending; + GSList *sort = NULL; + gchar *line; + + if (!playlist) + return; + + if (flags & PL_SAVE_ITER) + file_readf(file, "%u", &it); + + if (flags & PL_SAVE_FLAGS) { + file_readf(file, "%u %u", &f, &n); + for (i = 0; i < n; i++) { + file_readf(file, "%u %d", &field, &ascending); + field += 1; + if (!ascending) + field = -field; + sort = g_slist_append(sort, GINT_TO_POINTER(field)); + } + playlist->pl_queue.q_sort = sort; + queue_resort(&playlist->pl_queue); + + if (file_readf(file, "%m\n", &line)) + g_free(line); + } + + if (flags & PL_SAVE_TRACKS) { + file_readf(file, "%u ", &n); + for (i = 0; i < n; i++) { + file_readf(file, "%u", &t); + queue_add(&playlist->pl_queue, track_get(t)); + } + if (file_readf(file, "%m\n", &line)) + g_free(line); + } + + playlist->pl_queue.q_flags |= (f & Q_VALID_FLAGS); + queue_iter_set(&playlist->pl_queue, &playlist->pl_queue.q_cur, it); +} + bool playlist_generic_can_select(struct playlist *playlist) { return queue_size(&playlist->pl_queue) > 0; diff --git a/core/playlists/library.c b/core/playlists/library.c index e66161a8..bbdf76e9 100644 --- a/core/playlists/library.c +++ b/core/playlists/library.c @@ -75,13 +75,10 @@ static bool __lib_pl_load(void *data) for (i = 0; i < n; i++) { name = file_readl(&lib_file); playlist = __lib_pl_lookup(name); + if (playlist) + playlist_generic_load(playlist, &lib_file, + PL_SAVE_METADATA); g_free(name); - - if (!playlist) - continue; - queue_load_flags(&playlist->pl_queue, &lib_file, true); - queue_iter_set(&playlist->pl_queue, &playlist->pl_queue.q_cur, - playlist->pl_queue.q_cur.it_pos); } file_close(&lib_file); diff --git a/core/playlists/system.c b/core/playlists/system.c index a744b567..adf99cc4 100644 --- a/core/playlists/system.c +++ b/core/playlists/system.c @@ -154,7 +154,8 @@ static bool sys_pl_queued_load() flags &= Q_VALID_FLAGS; if (i == 0) queue->q_flags |= flags; - queue_load_tracks(queue, &sys_deck_f); + playlist_generic_load(pl_system_get(SYS_PL_QUEUED), + &sys_deck_f, PL_SAVE_TRACKS); } file_close(&sys_deck_f); @@ -191,7 +192,7 @@ static bool sys_pl_collection_load() struct playlist *playlist = pl_system_get(SYS_PL_COLLECTION); if (file_open(&sys_collection_f, OPEN_READ)) { - queue_load_flags(&playlist->pl_queue, &sys_collection_f, false); + playlist_generic_load(playlist, &sys_collection_f, PL_SAVE_FLAGS); file_close(&sys_collection_f); file_remove(&sys_collection_f); } @@ -275,7 +276,7 @@ static bool __sys_pl_load() g_free(name); if (playlist) - queue_load_tracks(&playlist->pl_queue, &sys_file); + playlist_generic_load(playlist, &sys_file, PL_SAVE_TRACKS); } file_close(&sys_file); @@ -286,7 +287,7 @@ static bool __sys_pl_load() static bool __sys_pl_load_new() { struct playlist *playlist; - unsigned int i, n; + unsigned int i, n, load; gchar *name; if (!file_open(&sys_pl_file, OPEN_READ)) { @@ -299,19 +300,25 @@ static bool __sys_pl_load_new() file_readf(&sys_pl_file, "%u\n", &n); for (i = 0; i < n; i++) { - name = file_readl(&sys_pl_file); + load = PL_SAVE_METADATA; + name = file_readl(&sys_pl_file); + + if (string_match(name, "Banned")) { + g_free(name); + name = g_strdup("Hidden"); + } + playlist = pl_system_lookup(name); g_free(name); - queue_load_flags(&playlist->pl_queue, &sys_pl_file, true); switch (i) { case SYS_PL_FAVORITES: case SYS_PL_HIDDEN: case SYS_PL_QUEUED: - queue_load_tracks(&playlist->pl_queue, &sys_pl_file); - default: - break; + load = PL_SAVE_ALL; } + + playlist_generic_load(playlist, &sys_pl_file, load); } file_close(&sys_pl_file); diff --git a/core/playlists/user.c b/core/playlists/user.c index aaabe43c..fe1f4c39 100644 --- a/core/playlists/user.c +++ b/core/playlists/user.c @@ -43,12 +43,7 @@ static struct db_entry *user_db_read(struct file *file, unsigned int index) gchar *name = file_readl(file); struct user_playlist *playlist = __user_db_alloc(name, index); - queue_load_flags(&playlist->pl_playlist.pl_queue, file, true); - queue_load_tracks(&playlist->pl_playlist.pl_queue, file); - queue_iter_set(&playlist->pl_playlist.pl_queue, - &playlist->pl_playlist.pl_queue.q_cur, - playlist->pl_playlist.pl_queue.q_cur.it_pos); - + playlist_generic_load(&playlist->pl_playlist, file, PL_SAVE_ALL); return &playlist->pl_dbe; } diff --git a/core/queue.c b/core/queue.c index a3112300..f49660ea 100644 --- a/core/queue.c +++ b/core/queue.c @@ -163,47 +163,6 @@ void queue_save_tracks(struct queue *queue, struct file *file) file_writef(file, "\n"); } -void queue_load_flags(struct queue *queue, struct file *file, bool iter) -{ - unsigned int flags, n, i; - int field, ascending; - unsigned int it = 0; - gchar *line; - - if (iter) - file_readf(file, "%u", &it); - - file_readf(file, "%u %u", &flags, &n); - for (i = 0; i < n; i++) { - file_readf(file, "%u %d", &field, &ascending); - queue_sort(queue, field + 1, (i == 0) ? true : false); - if (ascending == false) - queue_sort(queue, field + 1, false); - } - - flags &= Q_VALID_FLAGS; - queue->q_flags |= flags; - queue->q_cur.it_pos = it; - - if (file_readf(file, "%m\n", &line)) - g_free(line); -} - -void queue_load_tracks(struct queue *queue, struct file *file) -{ - unsigned int i, n, t; - gchar *line; - - file_readf(file, "%u ", &n); - for (i = 0; i < n; i++) { - file_readf(file, "%u", &t); - queue_add(queue, track_get(t)); - } - - if (file_readf(file, "%m\n", &line)) - g_free(line); -} - void queue_set_flag(struct queue *queue, enum queue_flags flag) { queue->q_flags |= flag; diff --git a/include/core/playlists/generic.h b/include/core/playlists/generic.h index cf5b08ae..1c8a2549 100644 --- a/include/core/playlists/generic.h +++ b/include/core/playlists/generic.h @@ -5,6 +5,14 @@ #define OCARINA_CORE_PLAYLISTS_GENERIC_H #include +enum playlist_save_flags { + PL_SAVE_FLAGS = (1 << 0), /* Save playlist random and sort data. */ + PL_SAVE_ITER = (1 << 1), /* Save playlist iterator position. */ + PL_SAVE_TRACKS = (1 << 2), /* Save playlist tracks. */ +}; +#define PL_SAVE_METADATA (PL_SAVE_FLAGS | PL_SAVE_ITER) +#define PL_SAVE_ALL (PL_SAVE_TRACKS | PL_SAVE_METADATA) + struct playlist_callbacks { }; @@ -15,6 +23,9 @@ void playlist_generic_set_callbacks(struct playlist_callbacks *); /* Generic playlist init function. */ void playlist_generic_init(struct playlist *, unsigned int, struct queue_ops *); +/* Generic playlist load function. */ +void playlist_generic_load(struct playlist *, struct file *, unsigned int); + /* Generic playlist can-select function. */ bool playlist_generic_can_select(struct playlist *); diff --git a/include/core/queue.h b/include/core/queue.h index 729fb92d..d176c8cf 100644 --- a/include/core/queue.h +++ b/include/core/queue.h @@ -120,12 +120,6 @@ void queue_save_flags(struct queue *, struct file *, bool); /* Called to save the list of queued tracks. */ void queue_save_tracks(struct queue *, struct file *); -/* Called to load flags, sort order, and (optionally) iterator pos from file. */ -void queue_load_flags(struct queue *, struct file *, bool); - -/* Called to load queued tracks from file. */ -void queue_load_tracks(struct queue *, struct file *); - /* Called to set a queue flag. */ void queue_set_flag(struct queue *, enum queue_flags); diff --git a/tests/core/playlist.c b/tests/core/playlist.c index e6ac647f..a41d9790 100644 --- a/tests/core/playlist.c +++ b/tests/core/playlist.c @@ -34,6 +34,52 @@ static void test_null() g_assert_false(playlist_sort(NULL, COMPARE_TRACK, true)); g_assert_false(playlist_sort(NULL, COMPARE_TRACK, false)); + + playlist_generic_load(NULL, NULL, PL_SAVE_ALL); +} + +static void test_save_load() +{ + struct playlist p = DEFINE_PLAYLIST(PL_MAX_TYPE, "Test", 0, NULL); + struct playlist q = DEFINE_PLAYLIST(PL_MAX_TYPE, "Test 2", 0, NULL); + struct playlist r = DEFINE_PLAYLIST(PL_MAX_TYPE, "Test", 0, NULL); + struct playlist s = DEFINE_PLAYLIST(PL_MAX_TYPE, "Test 2", 0, NULL); + struct file f = FILE_INIT("test.playlist", 0); + unsigned int i; + + for (i = 0; i < 13; i++) { + queue_add(&p.pl_queue, track_get(i)); + queue_add(&q.pl_queue, track_get(i)); + } + queue_set_flag(&p.pl_queue, Q_RANDOM); + queue_sort(&p.pl_queue, COMPARE_TRACK, true); + p.pl_queue.q_cur.it_pos = 3; + q.pl_queue.q_cur.it_pos = 4; + + g_assert_false(file_exists(&f)); + g_assert_true( file_open(&f, OPEN_WRITE)); + queue_save_flags(&p.pl_queue, &f, true); + queue_save_flags(&q.pl_queue, &f, true); + queue_save_tracks(&q.pl_queue, &f); + file_close(&f); + + g_assert_true(file_open(&f, OPEN_READ)); + playlist_generic_load(&r, &f, PL_SAVE_METADATA); + playlist_generic_load(&s, &f, PL_SAVE_ALL); + file_close(&f); + + g_assert_true(queue_has_flag(&r.pl_queue, Q_RANDOM)); + g_assert_cmpuint(r.pl_queue.q_cur.it_pos, ==, 3); + g_assert_cmpuint(g_slist_length(r.pl_queue.q_sort), ==, 1); + g_assert_cmpuint(GPOINTER_TO_UINT(r.pl_queue.q_sort->data), + ==, COMPARE_TRACK); + g_assert_cmpuint(g_queue_get_length(&r.pl_queue.q_tracks), ==, 0); + + g_assert_false(queue_has_flag(&s.pl_queue, Q_RANDOM)); + g_assert_cmpuint(s.pl_queue.q_cur.it_pos, ==, 4); + g_assert(queue_iter_val(&s.pl_queue.q_cur) == queue_at(&q.pl_queue, 4)); + g_assert_cmpuint(g_slist_length(s.pl_queue.q_sort), ==, 0); + g_assert_cmpuint(g_queue_get_length(&s.pl_queue.q_tracks), ==, 13); } int main(int argc, char **argv) @@ -49,9 +95,23 @@ int main(int argc, char **argv) library = library_find("tests/Music"); track_add(library, "tests/Music/Hyrule Symphony/01 - Title Theme.ogg"); + track_add(library, "tests/Music/Hyrule Symphony/02 - Kokiri Forest.ogg"); + track_add(library, "tests/Music/Hyrule Symphony/03 - Hyrule Field.ogg"); + track_add(library, "tests/Music/Hyrule Symphony/04 - Hyrule Castle.ogg"); + track_add(library, "tests/Music/Hyrule Symphony/05 - Lon Lon Ranch.ogg"); + track_add(library, "tests/Music/Hyrule Symphony/06 - Kakariko Village.ogg"); + track_add(library, "tests/Music/Hyrule Symphony/07 - Death Mountain.ogg"); + track_add(library, "tests/Music/Hyrule Symphony/08 - Zora's Domain.ogg"); + track_add(library, "tests/Music/Hyrule Symphony/09 - Gerudo Valley.ogg"); + track_add(library, "tests/Music/Hyrule Symphony/10 - Ganondorf.ogg"); + track_add(library, "tests/Music/Hyrule Symphony/11 - Princess Zelda.ogg"); + track_add(library, "tests/Music/Hyrule Symphony/12 - Ocarina Medley.ogg"); + track_add(library, + "tests/Music/Hyrule Symphony/13 - The Legend of Zelda Medley.ogg"); g_test_init(&argc, &argv, NULL); g_test_add_func("/Core/Playlist/NULL", test_null); + g_test_add_func("/Core/Playlist/Save and Load", test_save_load); ret = g_test_run(); playlist_deinit(); diff --git a/tests/core/queue.c b/tests/core/queue.c index b324f1f3..c3075221 100644 --- a/tests/core/queue.c +++ b/tests/core/queue.c @@ -340,17 +340,6 @@ static void test_save_load() queue_save_tracks(&q, &f); file_close(&f); g_assert_true(file_exists(&f)); - - g_assert_true(file_open(&f, OPEN_READ)); - queue_load_tracks(&r, &f); - file_close(&f); - - g_assert_cmpuint(queue_size(&r), ==, 13); - for (i = 0; i < 13; i++) - g_assert_true(queue_has(&r, track_get(i))); - - queue_deinit(&q); - queue_deinit(&r); } int main(int argc, char **argv)