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();