From b17585237aec2185f4f703c16bf171fa870cd957 Mon Sep 17 00:00:00 2001 From: Anna Schumaker Date: Tue, 13 Sep 2016 10:59:20 -0400 Subject: [PATCH] core/playlist: Add a playlist_played() function This is used to notify when tracks have been played so dynamic playlists can be updated, and so the model can display the correct playcount. The old system playlist tests are mostly unnecessary at this point, so I remove them as part of this patch. Signed-off-by: Anna Schumaker --- core/audio.c | 4 +- core/playlist.c | 7 + core/playlists/artist.c | 9 ++ core/playlists/library.c | 9 ++ core/playlists/system.c | 12 ++ core/playlists/user.c | 12 ++ include/core/playlist.h | 3 + include/core/playlists/type.h | 3 + tests/core/playlists/artist.c | 1 + tests/core/playlists/library.c | 1 + tests/core/playlists/system.c | 249 +++++---------------------------- tests/core/playlists/user.c | 1 + 12 files changed, 97 insertions(+), 214 deletions(-) diff --git a/core/audio.c b/core/audio.c index 2bb6b6bf..d48f3118 100644 --- a/core/audio.c +++ b/core/audio.c @@ -242,9 +242,7 @@ struct track *audio_eos() /* Mark current track as played */ if (audio_track) { track_played(audio_track); - playlist_update(PL_SYSTEM, "Unplayed"); - playlist_update(PL_SYSTEM, "Most Played"); - playlist_update(PL_SYSTEM, "Least Played"); + playlist_played(audio_track); } /* Check pause count and pick the next track */ diff --git a/core/playlist.c b/core/playlist.c index b3e62770..220b5aa2 100644 --- a/core/playlist.c +++ b/core/playlist.c @@ -61,6 +61,13 @@ void playlist_save() playlist_types[i]->pl_save(); } +void playlist_played(struct track *track) +{ + unsigned int i; + for (i = 0; i < PL_MAX_TYPE; i++) + playlist_types[i]->pl_played(track); +} + struct playlist *playlist_new(enum playlist_type_t type, const gchar *name) { if (type < PL_MAX_TYPE && playlist_types[type]->pl_new) diff --git a/core/playlists/artist.c b/core/playlists/artist.c index 1f14a307..8b25696b 100644 --- a/core/playlists/artist.c +++ b/core/playlists/artist.c @@ -114,6 +114,14 @@ static struct playlist *pl_artist_get(unsigned int id) return artist ? artist->ar_playlist : NULL; } +static void pl_artist_played(struct track *track) +{ + struct artist *artist = track->tr_album->al_artist; + struct playlist *playlist = (struct playlist *)artist->ar_playlist; + if (playlist) + queue_updated(&playlist->pl_queue, track); +} + static void pl_artist_update(const gchar *name) { } @@ -123,6 +131,7 @@ struct playlist_type pl_artist = { .pl_save = pl_artist_save, .pl_lookup = pl_artist_lookup, .pl_get = pl_artist_get, + .pl_played = pl_artist_played, .pl_update = pl_artist_update, }; diff --git a/core/playlists/library.c b/core/playlists/library.c index 1a1df2c1..fec9eb82 100644 --- a/core/playlists/library.c +++ b/core/playlists/library.c @@ -245,6 +245,14 @@ static struct playlist *pl_library_new(const gchar *name) return library->li_playlist; } +static void pl_library_played(struct track *track) +{ + struct library *library = track->tr_library; + struct playlist *playlist = (struct playlist *)library->li_playlist; + if (playlist) + queue_updated(&playlist->pl_queue, track); +} + static void pl_library_update(const gchar *name) { struct playlist *playlist = __lib_pl_lookup(name); @@ -258,6 +266,7 @@ struct playlist_type pl_library = { .pl_lookup = pl_library_lookup, .pl_get = pl_library_get, .pl_new = pl_library_new, + .pl_played = pl_library_played, .pl_update = pl_library_update, }; diff --git a/core/playlists/system.c b/core/playlists/system.c index efe9c480..67c3aff6 100644 --- a/core/playlists/system.c +++ b/core/playlists/system.c @@ -489,6 +489,17 @@ static struct playlist *pl_system_get(unsigned int id) return (id < SYS_PL_NUM_PLAYLISTS) ? &sys_playlists[id]->spl_playlist : NULL; } +static void pl_system_played(struct track *track) +{ + unsigned int i; + for (i = 0; i < SYS_PL_NUM_PLAYLISTS; i++) + queue_updated(&pl_system_get(i)->pl_queue, track); + + pl_system_update("Unplayed"); + pl_system_update("Most Played"); + pl_system_update("Least Played"); +} + static void pl_system_update(const gchar *name) { struct sys_playlist *sys_pl = __sys_pl_lookup(name); @@ -501,6 +512,7 @@ struct playlist_type pl_system = { .pl_save = pl_system_save, .pl_lookup = pl_system_lookup, .pl_get = pl_system_get, + .pl_played = pl_system_played, .pl_update = pl_system_update, }; diff --git a/core/playlists/user.c b/core/playlists/user.c index 9b8232fe..b5552efa 100644 --- a/core/playlists/user.c +++ b/core/playlists/user.c @@ -120,6 +120,17 @@ static struct playlist *pl_user_new(const gchar *name) return dbe ? &USER_PLAYLIST(dbe)->pl_playlist : NULL; } +static void pl_user_played(struct track *track) +{ + struct db_entry *dbe, *next; + struct playlist *playlist; + + db_for_each(dbe, next, &user_db) { + playlist = &USER_PLAYLIST(dbe)->pl_playlist; + queue_updated(&playlist->pl_queue, track); + } +} + static void pl_user_update(const gchar *name) { } @@ -130,6 +141,7 @@ struct playlist_type pl_user = { .pl_lookup = pl_user_lookup, .pl_get = pl_user_get, .pl_new = pl_user_new, + .pl_played = pl_user_played, .pl_update = pl_user_update, }; diff --git a/include/core/playlist.h b/include/core/playlist.h index 1c7bbe03..7829a10a 100644 --- a/include/core/playlist.h +++ b/include/core/playlist.h @@ -24,6 +24,9 @@ void playlist_deinit(); /* Called to force-save all playlists. */ void playlist_save(); +/* Called to notify all playlists that a track has been played. */ +void playlist_played(struct track *); + /* Called to create a new playlist. */ struct playlist *playlist_new(enum playlist_type_t, const gchar *); diff --git a/include/core/playlists/type.h b/include/core/playlists/type.h index b2b50394..bf2a4897 100644 --- a/include/core/playlists/type.h +++ b/include/core/playlists/type.h @@ -74,6 +74,9 @@ struct playlist_type { /* Called to create a new playlist. */ struct playlist *(*pl_new)(const gchar *); + /* Called to notify that a track has been played. */ + void (*pl_played)(struct track *); + /* Called to update a playlist. */ void (*pl_update)(const gchar *); }; diff --git a/tests/core/playlists/artist.c b/tests/core/playlists/artist.c index 5dd55727..ce39f60b 100644 --- a/tests/core/playlists/artist.c +++ b/tests/core/playlists/artist.c @@ -43,6 +43,7 @@ void test_artist() g_assert_cmpuint(settings_get("core.playlist.cur.id"), ==, 0); g_assert(playlist_current() == playlist); g_assert_false(playlist_select(playlist)); + playlist_played(track_get(0)); g_assert_cmpuint(playlist_next()->tr_track, ==, 1); g_assert_cmpuint(playlist_size(playlist), ==, 2); diff --git a/tests/core/playlists/library.c b/tests/core/playlists/library.c index 50a90988..1f3b6136 100644 --- a/tests/core/playlists/library.c +++ b/tests/core/playlists/library.c @@ -65,6 +65,7 @@ void test_library() g_assert_false(playlist_remove(playlist, track_get(0))); g_assert_false(playlist_remove(playlist, track_get(1))); g_assert_cmpuint(playlist_size(playlist), ==, 48); + playlist_played(track_get(1)); g_assert_false(playlist_get_random(playlist)); playlist_set_random(playlist, true); diff --git a/tests/core/playlists/system.c b/tests/core/playlists/system.c index 94b06b08..3fa2e9fe 100644 --- a/tests/core/playlists/system.c +++ b/tests/core/playlists/system.c @@ -8,63 +8,6 @@ #include -#define __test_playlist_has(name, track, expected) \ - if (expected) \ - g_assert_true(playlist_has(playlist_lookup(PL_SYSTEM, name), track)); \ - else \ - g_assert_false(playlist_has(playlist_lookup(PL_SYSTEM, name), track)) - -#define __test_playlist_state(name, ex_size, ex_track0, ex_track1) \ - g_assert_cmpuint(playlist_size(playlist_lookup(PL_SYSTEM, name)), ==, ex_size); \ - __test_playlist_has(name, track_get(0), ex_track0); \ - __test_playlist_has(name, track_get(1), ex_track1) - -#define __test_playlist_add(name) \ - __test_playlist_state(name, 0, false, false); \ - g_assert_true( playlist_add(playlist_lookup(PL_SYSTEM, name), track_get(0))); \ - g_assert_false(playlist_add(playlist_lookup(PL_SYSTEM, name), track_get(0))); \ - g_assert_true( playlist_add(playlist_lookup(PL_SYSTEM, name), track_get(1))); \ - g_assert_false(playlist_add(playlist_lookup(PL_SYSTEM, name), track_get(1))); \ - __test_playlist_state(name, 2, true, true) - -#define __test_playlist_remove(name) \ - g_assert_true( playlist_remove(playlist_lookup(PL_SYSTEM, name), track_get(0))); \ - g_assert_false(playlist_remove(playlist_lookup(PL_SYSTEM, name), track_get(0))); \ - g_assert_true( playlist_remove(playlist_lookup(PL_SYSTEM, name), track_get(1))); \ - g_assert_false(playlist_remove(playlist_lookup(PL_SYSTEM, name), track_get(1))); \ - __test_playlist_state(name, 0, false, false) - -#define __test_playlist_update(name, ex_size, ex_track0, ex_track1) \ - playlist_update(PL_SYSTEM, name); \ - while (idle_run_task()) {}; \ - __test_playlist_state(name, ex_size, ex_track0, ex_track1) - -#define __test_playlist_hide_track(name, ex_size, ex_track0, ex_track1) \ - g_assert_true(playlist_add(playlist_lookup(PL_SYSTEM, "Hidden"), track_get(0))); \ - __test_playlist_state(name, ex_size, ex_track0, ex_track1); \ - g_assert_false(playlist_add(playlist_lookup(PL_SYSTEM, name), track_get(0))) - -#define __test_playlist_unhide_track(name, ex_size, ex_track0, ex_track1) \ - g_assert_true(playlist_remove(playlist_lookup(PL_SYSTEM, "Hidden"), track_get(0))); \ - __test_playlist_state(name, ex_size, ex_track0, ex_track1) - -#define __test_playlist_clear_hidden(name, ex_size, ex_track0, ex_track1) \ - g_assert_false(playlist_delete(playlist_lookup(PL_SYSTEM, "Hidden"))); \ - __test_playlist_state("Hidden", 0, false, false); \ - __test_playlist_state(name, ex_size, ex_track0, ex_track1); - -#define __test_playlist_reinit(name, ex_size, ex_track0, ex_track1) \ -do { \ - struct playlist *playlist; \ - pl_system_deinit(); \ - pl_system_init(NULL); \ - playlist = playlist_lookup(PL_SYSTEM, name); \ - g_assert_nonnull(playlist); \ - __test_playlist_state(name, 0, false, false); \ - while (idle_run_task()) {}; \ - __test_playlist_state(name, ex_size, ex_track0, ex_track1); \ -} while (0) - static inline struct playlist *__test_pl_favorites(void) { return playlist_lookup(PL_SYSTEM, "Favorites"); } static inline struct playlist *__test_pl_hidden(void) @@ -110,160 +53,22 @@ static void test_init() /* Add tracks to the collection. */ 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"); pl_system_new_track(track_get(0)); pl_system_new_track(track_get(1)); + pl_system_new_track(track_get(2)); g_assert_null(playlist_new(PL_SYSTEM, "New Playlist")); for (i = 0; i < SYS_PL_NUM_PLAYLISTS; i++) { playlist = playlist_get(PL_SYSTEM, i); if (i == SYS_PL_COLLECTION || i == SYS_PL_UNPLAYED) - g_assert_cmpuint(playlist_size(playlist), ==, 2); + g_assert_cmpuint(playlist_size(playlist), ==, 3); else g_assert_cmpuint(playlist_size(playlist), ==, 0); } } -static void test_invalid() -{ - playlist_update(PL_SYSTEM, NULL); -} - -static void test_favorites() -{ - __test_playlist_add("Favorites"); - __test_playlist_reinit("Favorites", 2, true, true); - __test_playlist_update("Favorites", 2, true, true); - __test_playlist_remove("Favorites"); -} - -static void test_hidden() -{ - __test_playlist_add("Hidden"); - __test_playlist_reinit("Hidden", 2, true, true); - __test_playlist_update("Hidden", 2, true, true); - __test_playlist_remove("Hidden"); -} - -static void test_queued() -{ - __test_playlist_add("Queued Tracks"); - __test_playlist_reinit("Queued Tracks", 2, true, true); - __test_playlist_remove("Queued Tracks"); - __test_playlist_update("Queued Tracks", 0, false, false); -} - -static void test_collection() -{ - pl_system_deinit(); - pl_system_init(NULL); - - __test_playlist_update("Collection", 2, true, true); - __test_playlist_hide_track("Collection", 1, false, true); - __test_playlist_reinit("Collection", 1, false, true); - __test_playlist_update("Collection", 1, false, true); - __test_playlist_unhide_track("Collection", 2, true, true); - __test_playlist_hide_track("Collection", 1, false, true); - __test_playlist_clear_hidden("Collection", 2, true, true); -} - -static void test_history() -{ - __test_playlist_state("History", 0, false, false); - g_assert_true(playlist_add(__test_pl_history(), track_get(0))); - g_assert_true(playlist_add(__test_pl_history(), track_get(0))); - g_assert_true(playlist_add(__test_pl_history(), track_get(1))); - g_assert_true(playlist_add(__test_pl_history(), track_get(1))); - __test_playlist_state("History", 4, true, true); - - g_assert(playlist_prev() == track_get(1)); - g_assert(playlist_prev() == track_get(0)); - g_assert_cmpuint(playlist_size(__test_pl_history()), ==, 4); - g_assert_true(playlist_add(__test_pl_history(), track_get(1))); - g_assert_cmpuint(playlist_size(__test_pl_history()), ==, 5); - g_assert(playlist_prev() == track_get(1)); - - __test_playlist_update("History", 5, true, true); -} - -static void test_unplayed() -{ - pl_system_deinit(); - pl_system_init(NULL); - - __test_playlist_reinit("Unplayed", 2, true, true); - - track_get(1)->tr_count = 1; - __test_playlist_update("Unplayed", 1, true, false); - - track_get(0)->tr_count = 1; - track_get(1)->tr_count = 0; - __test_playlist_update("Unplayed", 1, false, true); - - track_get(0)->tr_count = 0; - __test_playlist_update("Unplayed", 2, true, true); - - __test_playlist_hide_track("Unplayed", 1, false, true); - __test_playlist_reinit("Unplayed", 1, false, true); - __test_playlist_update("Unplayed", 1, false, true); - __test_playlist_unhide_track("Unplayed", 2, true, true); - __test_playlist_hide_track("Unplayed", 1, false, true); - __test_playlist_clear_hidden("Unplayed", 2, true, true); -} - -static void test_most_played() -{ - /* Set average = (4 / 2) = 2 */ - track_played(track_get(0)); - track_played(track_get(1)); - track_played(track_get(1)); - track_played(track_get(1)); - - pl_system_deinit(); - pl_system_init(NULL); - - __test_playlist_reinit("Most Played", 1, false, true); - - track_get(0)->tr_count = 3; - track_get(1)->tr_count = 1; - __test_playlist_update("Most Played", 1, true, false); - - __test_playlist_hide_track("Most Played", 0, false, false); - __test_playlist_reinit("Most Played", 0, false, false); - __test_playlist_update("Most Played", 0, false, false); - __test_playlist_unhide_track("Most Played", 1, true, false); - __test_playlist_hide_track("Most Played", 0, false, false); - __test_playlist_clear_hidden("Most Played", 1, true, false); -} - -static void test_least_played() -{ - /* Reset playcounts so track 1 is "least played" */ - track_get(0)->tr_count = 3; - track_get(1)->tr_count = 1; - - pl_system_deinit(); - pl_system_init(NULL); - - __test_playlist_reinit("Least Played", 1, false, true); - - track_get(0)->tr_count = 1; - track_get(1)->tr_count = 3; - __test_playlist_update("Least Played", 1, true, false); - - __test_playlist_hide_track("Least Played", 0, false, false); - __test_playlist_reinit("Least Played", 0, false, false); - __test_playlist_update("Least Played", 0, false, false); - __test_playlist_unhide_track("Least Played", 1, true, false); - __test_playlist_hide_track("Least Played", 0, false, false); - __test_playlist_clear_hidden("Least Played", 1, true, false); - - track_get(0)->tr_count = 3; - track_get(1)->tr_count = 1; - __test_playlist_update("Least Played", 1, false, true); - __test_playlist_update("Most Played", 1, true, false); -} - static void test_random() { struct playlist *playlist; @@ -306,15 +111,45 @@ static void test_sort() } } +static void test_played() +{ + g_assert_cmpuint(playlist_size(__test_pl_unplayed()), ==, 3); + g_assert_cmpuint(playlist_size(__test_pl_most_played()), ==, 0); + g_assert_cmpuint(playlist_size(__test_pl_least_played()), ==, 0); + + track_played(track_get(0)); + playlist_played(track_get(0)); + while (idle_run_task()) {} + + g_assert_cmpuint(playlist_size(__test_pl_unplayed()), ==, 2); + g_assert_cmpuint(playlist_size(__test_pl_most_played()), ==, 0); + g_assert_cmpuint(playlist_size(__test_pl_least_played()), ==, 1); + + g_assert_true(playlist_has(__test_pl_least_played(), track_get(0))); + g_assert_true(playlist_has(__test_pl_unplayed(), track_get(1))); + g_assert_true(playlist_has(__test_pl_unplayed(), track_get(2))); + + track_played(track_get(0)); + track_played(track_get(0)); + track_played(track_get(1)); + playlist_played(track_get(0)); + playlist_played(track_get(1)); + while (idle_run_task()) {} + + g_assert_cmpuint(playlist_size(__test_pl_unplayed()), ==, 1); + g_assert_cmpuint(playlist_size(__test_pl_most_played()), ==, 1); + g_assert_cmpuint(playlist_size(__test_pl_least_played()), ==, 1); + + g_assert_true(playlist_has(__test_pl_most_played(), track_get(0))); + g_assert_true(playlist_has(__test_pl_least_played(), track_get(1))); + g_assert_true(playlist_has(__test_pl_unplayed(), track_get(2))); +} + static void test_add() { - struct library *library = library_find("tests/Music"); struct playlist *playlist; unsigned int i; - track_add(library, "tests/Music/Hyrule Symphony/03 - Hyrule Field.ogg"); - pl_system_new_track(track_get(2)); - g_assert_true( playlist_add(__test_pl_favorites(), track_get(0))); g_assert_false(playlist_add(__test_pl_favorites(), track_get(0))); g_assert_true( playlist_add(__test_pl_queued(), track_get(0))); @@ -533,17 +368,9 @@ int main(int argc, char **argv) g_test_init(&argc, &argv, NULL); g_test_add_func("/Core/Playlists/System/Init", test_init); - g_test_add_func("/Core/Playlists/System/Invalid", test_invalid); - g_test_add_func("/Core/Playlists/System/Favorites", test_favorites); - g_test_add_func("/Core/Playlists/System/Hidden", test_hidden); - g_test_add_func("/Core/Playlists/System/Queued", test_queued); - g_test_add_func("/Core/Playlists/System/Collection", test_collection); - g_test_add_func("/Core/Playlists/System/History", test_history); - g_test_add_func("/Core/Playlists/System/Unplayed Tracks", test_unplayed); - g_test_add_func("/Core/Playlists/System/Most Played Tracks", test_most_played); - g_test_add_func("/Core/Playlists/System/Least Played Tracks", test_least_played); g_test_add_func("/Core/Playlists/System/Random", test_random); g_test_add_func("/Core/Playlists/System/Sort", test_sort); + g_test_add_func("/Core/Playlists/System/Played", test_played); g_test_add_func("/Core/Playlists/System/Add Tracks", test_add); g_test_add_func("/Core/Playlists/System/Remove Tracks", test_remove); g_test_add_func("/Core/Playlists/System/Delete", test_delete); diff --git a/tests/core/playlists/user.c b/tests/core/playlists/user.c index b338bc06..883412bf 100644 --- a/tests/core/playlists/user.c +++ b/tests/core/playlists/user.c @@ -47,6 +47,7 @@ void test_user() g_assert(playlist_next() == track_get(0)); g_assert_true(playlist_has(playlist, track_get(0))); g_assert_cmpuint(playlist_size(playlist), ==, 1); + playlist_played(track_get(0)); playlist_update(PL_USER, "Test Playlist"); pl_user_deinit();