diff --git a/core/playlist.c b/core/playlist.c index d3071f9c..53ed332b 100644 --- a/core/playlist.c +++ b/core/playlist.c @@ -91,6 +91,8 @@ void playlist_sort(enum playlist_type_t type, const gchar *name, struct track *playlist_next(void) { + if (playlist_size(PL_SYSTEM, "Queued Tracks") > 0) + return playlist_types[PL_SYSTEM]->pl_next("Queued Tracks"); return playlist_types[PL_SYSTEM]->pl_next("Collection"); } diff --git a/core/playlists/system.c b/core/playlists/system.c index c84cdec2..2cca82b2 100644 --- a/core/playlists/system.c +++ b/core/playlists/system.c @@ -12,6 +12,7 @@ static inline struct queue *__sys_pl_queue(enum sys_playlist_t); static void __sys_pl_save(); static struct file sys_file = FILE_INIT("playlist.db", 0, 0); +static struct file sys_deck_f = FILE_INIT("deck", 1, 1); static struct file sys_collection_f = FILE_INIT("library.q", 0, 0); static struct sys_playlist *sys_playlists[SYS_PL_NUM_PLAYLISTS]; @@ -104,6 +105,93 @@ static struct sys_playlist sys_hidden = { }; +/* + * Queued tracks playlist operations. + */ +static void sys_pl_queued_save(struct playlist *playlist) +{ + struct queue *queue = &playlist->pl_queue; + + if (file_open(&sys_deck_f, OPEN_WRITE)) { + if (queue_size(queue) == 0) + file_writef(&sys_deck_f, "%zu\n", 0); + else { + file_writef(&sys_deck_f, "%zu\n%u ", 1, queue->q_flags); + queue_save_tracks(queue, &sys_deck_f); + file_writef(&sys_deck_f, "\n"); + } + + file_close(&sys_deck_f); + } +} + +static bool sys_pl_queued_load() +{ + struct playlist *playlist = &sys_playlists[SYS_PL_QUEUED]->spl_playlist; + struct queue *queue = &playlist->pl_queue; + unsigned int num, i, flags = 0; + + if (!file_open(&sys_deck_f, OPEN_READ)) + return true; + + file_readf(&sys_deck_f, "%u", &num); + for (i = 0; i < num; i++) { + file_readf(&sys_deck_f, "%u", &flags); + flags &= ~(Q_SAVE_SORT | Q_SAVE_FLAGS); + if (i == 0) + queue->q_flags |= flags; + queue_load_tracks(queue, &sys_deck_f); + } + + file_close(&sys_deck_f); + return true; +} + +static void sys_pl_queued_init(struct playlist *playlist, + unsigned int flags, struct queue_ops *ops) +{ + queue_init(&playlist->pl_queue, Q_ENABLED, ops, playlist); +} + +static bool sys_pl_queued_add(struct playlist *playlist, struct track *track) +{ + bool ret = playlist_generic_add_track(playlist, track); + sys_pl_queued_save(playlist); + return ret; +} + +static bool sys_pl_queued_remove(struct playlist *playlist, struct track *track) +{ + bool ret = playlist_generic_remove_track(playlist, track); + sys_pl_queued_save(playlist); + return ret; +} + +static void sys_pl_queued_set_flag(struct playlist *playlist, + enum queue_flags flag, bool enabled) +{ + playlist_generic_set_flag(playlist, flag, enabled); + sys_pl_queued_save(playlist); +} + +static struct track *sys_pl_queued_next(struct playlist *playlist) +{ + struct track *track = playlist_generic_next(playlist); + sys_pl_queued_save(playlist); + return track; +} + +static struct sys_playlist sys_queued = { + .spl_playlist = DEFINE_PLAYLIST(PL_SYSTEM, "Queued Tracks"), + .spl_init = sys_pl_queued_init, + .spl_add = sys_pl_queued_add, + .spl_remove = sys_pl_queued_remove, + .spl_set_flag = sys_pl_queued_set_flag, + .spl_sort = playlist_generic_sort, + .spl_next = sys_pl_queued_next, +}; + + /* * Collection playlist operations. */ @@ -296,6 +384,7 @@ static struct sys_playlist sys_least_played = { static struct sys_playlist *sys_playlists[SYS_PL_NUM_PLAYLISTS] = { [SYS_PL_FAVORITES] = &sys_favorites, [SYS_PL_HIDDEN] = &sys_hidden, + [SYS_PL_QUEUED] = &sys_queued, [SYS_PL_COLLECTION] = &sys_collection, [SYS_PL_HISTORY] = &sys_history, [SYS_PL_UNPLAYED] = &sys_unplayed, @@ -435,6 +524,7 @@ void pl_system_init(struct queue_ops *ops) idle_schedule(IDLE_SYNC, __sys_pl_load, NULL); idle_schedule(IDLE_SYNC, sys_pl_collection_load, NULL); + idle_schedule(IDLE_SYNC, sys_pl_queued_load, NULL); for (i = 0; i < SYS_PL_NUM_PLAYLISTS; i++) { sys_pl = sys_playlists[i]; diff --git a/include/core/playlists/system.h b/include/core/playlists/system.h index 86d7b58b..e76e0a8c 100644 --- a/include/core/playlists/system.h +++ b/include/core/playlists/system.h @@ -9,6 +9,7 @@ enum sys_playlist_t { SYS_PL_FAVORITES, /* Songs that the user likes. */ SYS_PL_HIDDEN, /* Songs that the user has hidden. */ + SYS_PL_QUEUED, /* Songs that the user has queued up. */ SYS_PL_COLLECTION, /* Songs that have not been hidden. */ SYS_PL_HISTORY, /* Songs that have just been played. */ SYS_PL_UNPLAYED, /* Songs that have not been played yet. */ diff --git a/tests/core/playlists/system.c b/tests/core/playlists/system.c index 22d3ea6a..33349e22 100644 --- a/tests/core/playlists/system.c +++ b/tests/core/playlists/system.c @@ -116,6 +116,29 @@ static void test_hidden() __test_playlist_remove("Hidden"); } +static void test_queued() +{ + struct queue *queue = playlist_get_queue(PL_SYSTEM, "Queued Tracks"); + + g_assert_nonnull(queue); + g_assert_false(queue_has_flag(queue, Q_ADD_FRONT)); + g_assert_false(queue_has_flag(queue, Q_NO_SORT)); + g_assert_cmpuint(g_slist_length(queue->q_sort), ==, 0); + + __test_playlist_random("Queued Tracks"); + __test_playlist_add("Queued Tracks"); + + g_assert(playlist_next() == track_get(0)); + g_assert_cmpuint(playlist_size(PL_SYSTEM, "Queued Tracks"), ==, 1); + g_assert(playlist_next() == track_get(1)); + g_assert_cmpuint(playlist_size(PL_SYSTEM, "Queued Tracks"), ==, 0); + g_assert_nonnull(playlist_next()); + + __test_playlist_add("Queued Tracks"); + __test_playlist_remove("Queued Tracks"); + __test_playlist_update("Queued Tracks", 0, false, false); +} + static void test_collection() { struct queue *queue = playlist_get_queue(PL_SYSTEM, "Collection"); @@ -296,6 +319,7 @@ int main(int argc, char **argv) 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);