diff --git a/core/playlist.c b/core/playlist.c index a18564fa..b3e62770 100644 --- a/core/playlist.c +++ b/core/playlist.c @@ -124,6 +124,27 @@ bool playlist_select(struct playlist *playlist) return true; } +struct track *playlist_next(void) +{ + struct track *track; + + if (!current) + return NULL; + + track = current->pl_ops->pl_next(current); + if (track) + playlist_types[current->pl_type]->pl_save(); + if (playlist_size(current) == 0) + playlist_select(previous); + return track; +} + +struct track *playlist_prev(void) +{ + struct playlist *history = playlist_lookup(PL_SYSTEM, "History"); + return history->pl_ops->pl_next(history); +} + bool playlist_add(struct playlist *playlist, struct track *track) { bool ret; @@ -191,21 +212,3 @@ bool playlist_sort(struct playlist *playlist, enum compare_t sort, bool reset) playlist_types[playlist->pl_type]->pl_save(); return g_slist_length(playlist->pl_queue.q_sort) > 0; } - -struct track *playlist_next(void) -{ - struct track *track; - - if (!current) - return NULL; - - track = playlist_types[current->pl_type]->pl_next(current->pl_name); - if (playlist_size(current) == 0) - playlist_select(previous); - return track; -} - -struct track *playlist_prev(void) -{ - return playlist_types[PL_SYSTEM]->pl_next("History"); -} diff --git a/core/playlists/artist.c b/core/playlists/artist.c index 41eb1535..1f14a307 100644 --- a/core/playlists/artist.c +++ b/core/playlists/artist.c @@ -10,6 +10,7 @@ static struct file artist_file = FILE_INIT("playlist.artist", 0); static struct playlist_ops pl_artist_ops = { .pl_can_select = playlist_generic_can_select, + .pl_next = playlist_generic_next, .pl_set_flag = playlist_generic_set_flag, .pl_sort = playlist_generic_sort, }; @@ -117,21 +118,12 @@ static void pl_artist_update(const gchar *name) { } -static struct track *pl_artist_next(const gchar *name) -{ - struct playlist *playlist = __artist_pl_lookup(name); - struct track *track = playlist_generic_next(playlist);; - pl_artist_save(); - return track; -} - struct playlist_type pl_artist = { .pl_save = pl_artist_save, .pl_lookup = pl_artist_lookup, .pl_get = pl_artist_get, .pl_update = pl_artist_update, - .pl_next = pl_artist_next, }; diff --git a/core/playlists/library.c b/core/playlists/library.c index b824d684..1a1df2c1 100644 --- a/core/playlists/library.c +++ b/core/playlists/library.c @@ -196,6 +196,7 @@ static bool pl_library_delete(struct playlist *playlist) static struct playlist_ops pl_library_ops = { .pl_can_select = playlist_generic_can_select, .pl_delete = pl_library_delete, + .pl_next = playlist_generic_next, .pl_set_flag = playlist_generic_set_flag, .pl_sort = playlist_generic_sort, }; @@ -251,14 +252,6 @@ static void pl_library_update(const gchar *name) idle_schedule(IDLE_SYNC, __lib_pl_update, playlist); } -static struct track *pl_library_next(const gchar *name) -{ - struct playlist *playlist = __lib_pl_lookup(name); - struct track *track = playlist_generic_next(playlist); - pl_library_save(); - return track; -} - struct playlist_type pl_library = { .pl_save = pl_library_save, @@ -266,7 +259,6 @@ struct playlist_type pl_library = { .pl_get = pl_library_get, .pl_new = pl_library_new, .pl_update = pl_library_update, - .pl_next = pl_library_next, }; diff --git a/core/playlists/system.c b/core/playlists/system.c index 4ba2ea44..efe9c480 100644 --- a/core/playlists/system.c +++ b/core/playlists/system.c @@ -55,6 +55,7 @@ static void sys_pl_save_full(struct playlist *playlist, struct file *file) static void sys_pl_load_partial(struct playlist *playlist, struct file *file) { queue_load_flags(&playlist->pl_queue, file, true); + queue_set_flag(&playlist->pl_queue, Q_REPEAT); } static void sys_pl_load_full(struct playlist *playlist, struct file *file) @@ -80,6 +81,7 @@ static struct playlist_ops favorites_ops = { .pl_add = playlist_generic_add_track, .pl_can_select = playlist_generic_can_select, .pl_delete = sys_pl_delete_clear, + .pl_next = playlist_generic_next, .pl_remove = playlist_generic_remove_track, .pl_set_flag = playlist_generic_set_flag, .pl_sort = playlist_generic_sort, @@ -91,7 +93,6 @@ static struct sys_playlist sys_favorites = { .spl_init = playlist_generic_init, .spl_save = sys_pl_save_full, .spl_load = sys_pl_load_full, - .spl_next = playlist_generic_next, }; @@ -139,6 +140,7 @@ static struct playlist_ops hidden_ops = { .pl_add = sys_pl_hidden_add, .pl_can_select = playlist_generic_can_select, .pl_delete = sys_pl_hidden_clear, + .pl_next = playlist_generic_next, .pl_remove = sys_pl_hidden_remove, .pl_set_flag = playlist_generic_set_flag, .pl_sort = playlist_generic_sort, @@ -150,7 +152,6 @@ static struct sys_playlist sys_hidden = { .spl_init = playlist_generic_init, .spl_save = sys_pl_save_full, .spl_load = sys_pl_load_full, - .spl_next = playlist_generic_next, }; @@ -182,13 +183,24 @@ static bool sys_pl_queued_load() static void sys_pl_queued_init(struct playlist *playlist, unsigned int flags, struct queue_ops *ops) { - queue_init(&playlist->pl_queue, 0, ops, playlist); + queue_init(&playlist->pl_queue, Q_REPEAT, ops, playlist); +} + +static struct track *sys_pl_queued_next(struct playlist *playlist) +{ + struct track *track = playlist_generic_next(playlist); + unsigned int pos = playlist->pl_queue.q_cur.it_pos; + + queue_iter_prev(&playlist->pl_queue.q_cur); + queue_remove(&playlist->pl_queue, pos); + return track; } static struct playlist_ops queued_ops = { .pl_add = playlist_generic_add_track, .pl_can_select = playlist_generic_can_select, .pl_delete = sys_pl_delete_clear, + .pl_next = sys_pl_queued_next, .pl_remove = playlist_generic_remove_track, .pl_set_flag = playlist_generic_set_flag, .pl_sort = playlist_generic_sort, @@ -200,7 +212,6 @@ static struct sys_playlist sys_queued = { .spl_init = sys_pl_queued_init, .spl_save = sys_pl_save_full, .spl_load = sys_pl_load_full, - .spl_next = playlist_generic_next, }; @@ -228,6 +239,7 @@ static bool sys_pl_collection_update(struct playlist *playlist, static struct playlist_ops collection_ops = { .pl_can_select = playlist_generic_can_select, + .pl_next = playlist_generic_next, .pl_remove = sys_pl_hidden_add, .pl_set_flag = playlist_generic_set_flag, .pl_sort = playlist_generic_sort, @@ -240,7 +252,6 @@ static struct sys_playlist sys_collection = { .spl_save = sys_pl_save_partial, .spl_load = sys_pl_load_partial, .spl_update = sys_pl_collection_update, - .spl_next = playlist_generic_next, }; @@ -261,7 +272,8 @@ static bool sys_pl_history_add(struct playlist *playlist, struct track *track) } static struct playlist_ops history_ops = { - .pl_add = sys_pl_history_add, + .pl_add = sys_pl_history_add, + .pl_next = playlist_generic_next, }; static struct sys_playlist sys_history = { @@ -270,7 +282,6 @@ static struct sys_playlist sys_history = { .spl_init = sys_pl_history_init, .spl_save = sys_pl_save_partial, .spl_load = sys_pl_load_partial, - .spl_next = playlist_generic_next, }; @@ -287,6 +298,7 @@ static bool sys_pl_unplayed_update(struct playlist *playlist, static struct playlist_ops unplayed_ops = { .pl_can_select = playlist_generic_can_select, + .pl_next = playlist_generic_next, .pl_set_flag = playlist_generic_set_flag, .pl_sort = playlist_generic_sort, }; @@ -298,7 +310,6 @@ static struct sys_playlist sys_unplayed = { .spl_save = sys_pl_save_partial, .spl_load = sys_pl_load_partial, .spl_update = sys_pl_unplayed_update, - .spl_next = playlist_generic_next, }; @@ -316,6 +327,7 @@ static bool sys_pl_most_played_update(struct playlist *playlist, static struct playlist_ops most_played_ops = { .pl_can_select = playlist_generic_can_select, + .pl_next = playlist_generic_next, .pl_set_flag = playlist_generic_set_flag, .pl_sort = playlist_generic_sort, }; @@ -327,7 +339,6 @@ static struct sys_playlist sys_most_played = { .spl_save = sys_pl_save_partial, .spl_load = sys_pl_load_partial, .spl_update = sys_pl_most_played_update, - .spl_next = playlist_generic_next, }; @@ -345,6 +356,7 @@ static bool sys_pl_least_played_update(struct playlist *playlist, static struct playlist_ops least_played_ops = { .pl_can_select = playlist_generic_can_select, + .pl_next = playlist_generic_next, .pl_set_flag = playlist_generic_set_flag, .pl_sort = playlist_generic_sort, }; @@ -356,7 +368,6 @@ static struct sys_playlist sys_least_played = { .spl_save = sys_pl_save_partial, .spl_load = sys_pl_load_partial, .spl_update = sys_pl_least_played_update, - .spl_next = playlist_generic_next, }; @@ -485,24 +496,12 @@ static void pl_system_update(const gchar *name) playlist_generic_update(&sys_pl->spl_playlist, sys_pl->spl_update); } -static struct track *pl_system_next(const gchar *name) -{ - struct sys_playlist *sys_pl = __sys_pl_lookup(name); - struct track *track = NULL;; - if (sys_pl) { - track = sys_pl->spl_next(&sys_pl->spl_playlist); - __sys_pl_save(); - } - return track; -} - struct playlist_type pl_system = { .pl_save = pl_system_save, .pl_lookup = pl_system_lookup, .pl_get = pl_system_get, .pl_update = pl_system_update, - .pl_next = pl_system_next, }; diff --git a/core/playlists/user.c b/core/playlists/user.c index e58a1ca3..9b8232fe 100644 --- a/core/playlists/user.c +++ b/core/playlists/user.c @@ -86,6 +86,7 @@ static struct playlist_ops user_ops = { .pl_add = playlist_generic_add_track, .pl_can_select = playlist_generic_can_select, .pl_delete = pl_user_delete, + .pl_next = playlist_generic_next, .pl_remove = playlist_generic_remove_track, .pl_set_flag = playlist_generic_set_flag, .pl_sort = playlist_generic_sort, @@ -123,14 +124,6 @@ static void pl_user_update(const gchar *name) { } -static struct track *pl_user_next(const gchar *name) -{ - struct playlist *playlist = pl_user_lookup(name); - struct track *track = playlist_generic_next(playlist); - pl_user_save(); - return track; -} - struct playlist_type pl_user = { .pl_save = pl_user_save, @@ -138,7 +131,6 @@ struct playlist_type pl_user = { .pl_get = pl_user_get, .pl_new = pl_user_new, .pl_update = pl_user_update, - .pl_next = pl_user_next, }; diff --git a/include/core/playlist.h b/include/core/playlist.h index 93ad97a6..1c7bbe03 100644 --- a/include/core/playlist.h +++ b/include/core/playlist.h @@ -43,6 +43,12 @@ struct playlist *playlist_current(void); /* Called to select the current playlist. */ bool playlist_select(struct playlist *); +/* Called to get the next track from the default playlist. */ +struct track *playlist_next(void); + +/* Called to get a previously played track. */ +struct track *playlist_prev(void); + /* Called to add a track to a playlist. */ bool playlist_add(struct playlist *, struct track *); @@ -70,11 +76,4 @@ bool playlist_get_random(struct playlist *); /* Called to change the sort order of the playlist. */ bool playlist_sort(struct playlist *, enum compare_t, bool); - -/* Called to get the next track from the default playlist. */ -struct track *playlist_next(void); - -/* Called to get a previously played track. */ -struct track *playlist_prev(void); - #endif /* OCARINA_CORE_PLAYLIST_H */ diff --git a/include/core/playlists/system.h b/include/core/playlists/system.h index 521af07a..9066a649 100644 --- a/include/core/playlists/system.h +++ b/include/core/playlists/system.h @@ -25,7 +25,6 @@ struct sys_playlist { void (*spl_save)(struct playlist *, struct file *); void (*spl_load)(struct playlist *, struct file *); bool (*spl_update)(struct playlist *, struct track *); - struct track *(*spl_next)(struct playlist *); }; diff --git a/include/core/playlists/type.h b/include/core/playlists/type.h index ca02ca3c..b2b50394 100644 --- a/include/core/playlists/type.h +++ b/include/core/playlists/type.h @@ -30,6 +30,9 @@ struct playlist_ops { /* Called to delete a playlist. */ bool (*pl_delete)(struct playlist *); + /* Called to pick the next track from a playlist. */ + struct track *(*pl_next)(struct playlist *); + /* Called to remove a track from the playlist. */ bool (*pl_remove)(struct playlist *, struct track *); @@ -73,9 +76,6 @@ struct playlist_type { /* Called to update a playlist. */ void (*pl_update)(const gchar *); - - /* Called to pick the next track from a playlist. */ - struct track *(*pl_next)(const gchar *); }; diff --git a/tests/core/playlists/artist.c b/tests/core/playlists/artist.c index 08e19c87..5dd55727 100644 --- a/tests/core/playlists/artist.c +++ b/tests/core/playlists/artist.c @@ -44,6 +44,11 @@ void test_artist() g_assert(playlist_current() == playlist); g_assert_false(playlist_select(playlist)); + g_assert_cmpuint(playlist_next()->tr_track, ==, 1); + g_assert_cmpuint(playlist_size(playlist), ==, 2); + g_assert_true(playlist_has(playlist, track_get(0))); + g_assert_true(playlist_has(playlist, track_get(1))); + g_assert_false(playlist_delete(playlist)); pl_artist_deinit(); g_assert_null(artist->ar_playlist); diff --git a/tests/core/playlists/system.c b/tests/core/playlists/system.c index cedf998d..94b06b08 100644 --- a/tests/core/playlists/system.c +++ b/tests/core/playlists/system.c @@ -97,6 +97,14 @@ static void test_init() g_assert(playlist_lookup(PL_SYSTEM, playlist->pl_name) == playlist); g_assert_cmpuint(playlist->pl_id, ==, i); g_assert_false(playlist_select(playlist)); + + g_assert_true(queue_has_flag(&playlist->pl_queue, Q_REPEAT)); + if (i == SYS_PL_QUEUED || i == SYS_PL_HISTORY) { + g_assert_cmpuint( + g_slist_length(playlist->pl_queue.q_sort), ==, 0); + } else + g_assert_cmpuint( + g_slist_length(playlist->pl_queue.q_sort), ==, 3); } /* Add tracks to the collection. */ @@ -141,18 +149,6 @@ static void test_queued() { __test_playlist_add("Queued Tracks"); __test_playlist_reinit("Queued Tracks", 2, true, true); - - g_assert(playlist_next() == track_get(0)); - g_assert_cmpuint(playlist_size(__test_pl_queued()), ==, 1); - playlist_select(__test_pl_collection()); - g_assert(playlist_next() == track_get(0)); - g_assert_cmpuint(playlist_size(__test_pl_queued()), ==, 1); - playlist_select(__test_pl_queued()); - g_assert(playlist_next() == track_get(1)); - g_assert_cmpuint(playlist_size(__test_pl_queued()), ==, 0); - g_assert(playlist_next() == track_get(1)); - - __test_playlist_add("Queued Tracks"); __test_playlist_remove("Queued Tracks"); __test_playlist_update("Queued Tracks", 0, false, false); } @@ -470,6 +466,44 @@ static void test_delete() g_assert_cmpuint(playlist_size(__test_pl_least_played()), ==, 1); } +static void test_next() +{ + playlist_select(__test_pl_collection()); + g_assert_cmpuint(playlist_next()->tr_track, ==, 1); + g_assert_cmpuint(playlist_size(__test_pl_collection()), ==, 3); + g_assert_cmpuint(playlist_next()->tr_track, ==, 2); + g_assert_cmpuint(playlist_size(__test_pl_collection()), ==, 3); + g_assert_cmpuint(playlist_next()->tr_track, ==, 3); + g_assert_cmpuint(playlist_size(__test_pl_collection()), ==, 3); + g_assert_cmpuint(playlist_next()->tr_track, ==, 1); + g_assert_cmpuint(playlist_size(__test_pl_collection()), ==, 3); + + playlist_add(__test_pl_queued(), track_get(0)); + playlist_add(__test_pl_queued(), track_get(1)); + g_assert_cmpuint(playlist_size(__test_pl_queued()), ==, 2); + g_assert(playlist_current() == __test_pl_queued()); + + g_assert(playlist_next() == track_get(0)); + g_assert_cmpuint(playlist_size(__test_pl_queued()), ==, 1); + g_assert(playlist_current() == __test_pl_queued()); + + g_assert(playlist_next() == track_get(1)); + g_assert_cmpuint(playlist_size(__test_pl_queued()), ==, 0); + g_assert(playlist_current() == __test_pl_collection()); + + queue_clear(&__test_pl_history()->pl_queue); + g_assert_cmpuint(playlist_size(__test_pl_history()), ==, 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(2))); + g_assert_cmpuint(playlist_size(__test_pl_history()), ==, 3); + g_assert(playlist_prev() == track_get(1)); + g_assert(playlist_prev() == track_get(0)); + g_assert(playlist_prev() == track_get(2)); + g_assert_cmpuint(playlist_size(__test_pl_history()), ==, 3); + +} + static void test_delete_tracks() { unsigned int i; @@ -513,6 +547,7 @@ int main(int argc, char **argv) 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); + g_test_add_func("/Core/Playlists/System/Next", test_next); g_test_add_func("/Core/PLaylists/System/Delete Tracks", test_delete_tracks); ret = g_test_run(); diff --git a/tests/core/playlists/user.c b/tests/core/playlists/user.c index 2f66c6d1..b338bc06 100644 --- a/tests/core/playlists/user.c +++ b/tests/core/playlists/user.c @@ -44,6 +44,10 @@ void test_user() g_assert_false(playlist_select(playlist)); g_assert_false(playlist_select(NULL)); + g_assert(playlist_next() == track_get(0)); + g_assert_true(playlist_has(playlist, track_get(0))); + g_assert_cmpuint(playlist_size(playlist), ==, 1); + playlist_update(PL_USER, "Test Playlist"); pl_user_deinit(); g_assert_cmpuint(db->db_size, ==, 0);