diff --git a/core/playlists/generic.c b/core/playlists/generic.c index f225efb1..51a7b841 100644 --- a/core/playlists/generic.c +++ b/core/playlists/generic.c @@ -132,7 +132,18 @@ bool playlist_generic_can_select(struct playlist *playlist) void playlist_generic_clear(struct playlist *playlist) { - queue_clear(&playlist->pl_queue); + unsigned int n; + + if (!playlist) + return; + + n = queue_size(&playlist->pl_queue); + g_queue_clear(&playlist->pl_queue.q_tracks); + playlist->pl_queue.q_length = 0; + playlist->pl_queue.q_cur.it_iter = NULL; + playlist->pl_queue.q_cur.it_pos = UINT_MAX; + if (callbacks) + callbacks->pl_cb_removed(playlist, NULL, n); } bool playlist_generic_add_track(struct playlist *playlist, struct track *track) @@ -154,7 +165,7 @@ bool playlist_generic_add_track_front(struct playlist *playlist, bool playlist_generic_remove(struct playlist *playlist, struct track *track) { - unsigned int i, count; + unsigned int count; if (!playlist || !track) return false; @@ -168,10 +179,8 @@ bool playlist_generic_remove(struct playlist *playlist, struct track *track) &playlist->pl_queue.q_tracks, playlist->pl_queue.q_cur.it_iter); - if (callbacks) { - for (i = 0; i < count; i++) - callbacks->pl_cb_removed(playlist, track); - } + if (callbacks) + callbacks->pl_cb_removed(playlist, track, count); return count > 0; } diff --git a/core/queue.c b/core/queue.c index 839a7373..96c55096 100644 --- a/core/queue.c +++ b/core/queue.c @@ -79,13 +79,6 @@ static inline unsigned int __queue_add_sorted(struct queue *queue, return __queue_add_tail(queue, track); } -static inline void __queue_clear(struct queue *queue, unsigned int n) -{ - queue->q_length = 0; - if (queue->q_ops) - queue->q_ops->qop_cleared(queue, n); -} - void queue_init(struct queue *queue, const struct queue_ops *ops, void *data) { queue->q_length = 0; @@ -100,7 +93,7 @@ void queue_init(struct queue *queue, const struct queue_ops *ops, void *data) void queue_deinit(struct queue *queue) { - queue_clear(queue); + g_queue_clear(&queue->q_tracks); __queue_deinit(queue); g_slist_free(queue->q_sort); queue->q_sort = NULL; @@ -117,11 +110,3 @@ unsigned int queue_add_front(struct queue *queue, struct track *track) { return __queue_add_head(queue, track); } - -void queue_clear(struct queue *queue) -{ - unsigned int n = queue_size(queue); - - g_queue_clear(&queue->q_tracks); - __queue_clear(queue, n); -} diff --git a/gui/model.c b/gui/model.c index b65bd50a..67a85ce8 100644 --- a/gui/model.c +++ b/gui/model.c @@ -290,25 +290,13 @@ void gui_model_add(struct playlist *playlist, unsigned int row) gtk_tree_path_free(path); } -void gui_model_remove(struct playlist *playlist, struct track *track) -{ - GtkTreePath *path; - - if (cur_playlist != playlist) - return; - - path = gtk_tree_path_new_from_indices(0, -1); - gtk_tree_model_row_deleted(GTK_TREE_MODEL(gui_model), path); - __gui_model_set_runtime(); - gtk_tree_path_free(path); -} - -void gui_model_clear(struct playlist *playlist, unsigned int n) +void gui_model_remove(struct playlist *playlist, struct track *track, + unsigned int n) { GtkTreePath *path; unsigned int i; - if (!gui_model || cur_playlist != playlist) + if (cur_playlist != playlist) return; path = gtk_tree_path_new_from_indices(n - 1, -1); @@ -316,9 +304,9 @@ void gui_model_clear(struct playlist *playlist, unsigned int n) gtk_tree_model_row_deleted(GTK_TREE_MODEL(gui_model), path); gtk_tree_path_prev(path); } + gtk_tree_path_free(path); __gui_model_set_runtime(); - gtk_tree_path_free(path); } void gui_model_update(struct playlist *playlist, struct track *track) @@ -333,7 +321,8 @@ void gui_model_update(struct playlist *playlist, struct track *track) void gui_model_set_playlist(struct playlist *playlist) { if (cur_playlist) - gui_model_clear(cur_playlist, queue_size(&cur_playlist->pl_queue)); + gui_model_remove(cur_playlist, NULL, + queue_size(&cur_playlist->pl_queue)); cur_playlist = playlist; __gui_model_set_runtime(); diff --git a/gui/playlist.c b/gui/playlist.c index 2b958e58..435672b8 100644 --- a/gui/playlist.c +++ b/gui/playlist.c @@ -48,24 +48,18 @@ static void __gui_playlist_added(struct queue *queue, unsigned int row) __gui_playlist_update_size(queue->q_private); } -static void __gui_playlist_removed(struct playlist *playlist, struct track *track) +static void __gui_playlist_removed(struct playlist *playlist, struct track *track, + unsigned int n) { - gui_model_remove(playlist, track); + gui_model_remove(playlist, track, n); __gui_playlist_update_size(playlist); } -static void __gui_playlist_cleared(struct queue *queue, unsigned int n) -{ - gui_model_clear(queue->q_private, n); - __gui_playlist_update_size(queue->q_private); -} - struct queue_ops playlist_ops = { .qop_init = __gui_playlist_init, .qop_deinit = __gui_playlist_deinit, .qop_added = __gui_playlist_added, - .qop_cleared = __gui_playlist_cleared, }; struct playlist_callbacks playlist_cb = { diff --git a/include/core/playlists/generic.h b/include/core/playlists/generic.h index e601c6c2..7b1bbe38 100644 --- a/include/core/playlists/generic.h +++ b/include/core/playlists/generic.h @@ -14,8 +14,12 @@ enum playlist_save_flags { #define PL_SAVE_ALL (PL_SAVE_TRACKS | PL_SAVE_METADATA) struct playlist_callbacks { - /* Called to notify that a track has been removed. */ - void (*pl_cb_removed)(struct playlist *, struct track *); + /* + * Called to notify that N instances of a track have been removed. + * Track may be NULL to indicate that several different tracks were + * removed at once. + */ + void (*pl_cb_removed)(struct playlist *, struct track *, unsigned int n); /* * Called to notify that a track has been updated. diff --git a/include/core/queue.h b/include/core/queue.h index a6569942..25d2e0e1 100644 --- a/include/core/queue.h +++ b/include/core/queue.h @@ -23,9 +23,6 @@ struct queue_ops { /* Called to tell a higher layer that a track has been added. */ void (*qop_added)(struct queue *, unsigned int); - - /* Called to tell a higher layer that the queue has been cleared. */ - void (*qop_cleared)(struct queue *, unsigned int); }; @@ -113,7 +110,4 @@ unsigned int queue_add(struct queue *, struct track *); /* Called to add a track to the front of the queue. */ unsigned int queue_add_front(struct queue *, struct track *); -/* Called to remove all tracks from the queue. */ -void queue_clear(struct queue *); - #endif /* OCARINA_CORE_QUEUE_H */ diff --git a/include/gui/model.h b/include/gui/model.h index 38cbb47a..464ffe16 100644 --- a/include/gui/model.h +++ b/include/gui/model.h @@ -55,10 +55,7 @@ GType gui_model_get_type(); void gui_model_add(struct playlist *, unsigned int); /* Called to remove a row from the model */ -void gui_model_remove(struct playlist *, struct track *); - -/* Called to remove all rows from the model */ -void gui_model_clear(struct playlist *, unsigned int); +void gui_model_remove(struct playlist *, struct track *, unsigned int); /* * Called to update a row in the model diff --git a/tests/core/playlist.c b/tests/core/playlist.c index ef7bacf4..022032f6 100644 --- a/tests/core/playlist.c +++ b/tests/core/playlist.c @@ -9,6 +9,13 @@ static struct playlist *cb_playlist = NULL; static struct track *cb_track = NULL; +static void test_pl_removed(struct playlist *playlist, struct track *track, + unsigned int n) +{ + cb_playlist = playlist; + cb_track = track; +} + static void test_pl_callback(struct playlist *playlist, struct track *track) { cb_playlist = playlist; @@ -23,7 +30,7 @@ static struct playlist_ops test_ops = { .pl_sort = playlist_generic_sort, }; static struct playlist_callbacks test_cb = { - .pl_cb_removed = test_pl_callback, + .pl_cb_removed = test_pl_removed, .pl_cb_updated = test_pl_callback, }; @@ -60,6 +67,7 @@ static void test_null() g_assert_false(playlist_generic_remove(NULL, NULL)); playlist_generic_update(NULL, NULL); + playlist_generic_clear(NULL); playlist_generic_save(NULL, NULL, PL_SAVE_ALL); playlist_generic_load(NULL, NULL, PL_SAVE_ALL); @@ -99,12 +107,31 @@ static void test_playlist() g_assert(cb_track == track_get(i)); g_assert_cmpuint(p.pl_queue.q_length, ==, ex_length); g_assert_cmpuint(p.pl_queue.q_cur.it_pos, ==, (11 - i)); + if (i < 12) + g_assert_nonnull(p.pl_queue.q_cur.it_iter); } g_assert_false(playlist_generic_remove(&p, NULL)); g_assert_false(playlist_has(&p, track_get(i))); g_assert(cb_playlist == &p); g_assert(cb_track == track_get(12)); g_assert_cmpuint(p.pl_queue.q_length, ==, ex_length); + g_assert_cmpuint(p.pl_queue.q_cur.it_pos, ==, UINT_MAX); + g_assert_null(p.pl_queue.q_cur.it_iter); + + /* Re-add the tracks! */ + for (i = 0; i < 13; i++) { + playlist_generic_add_track_front(&p, track_get(i)); + g_assert_true(playlist_has(&p, track_get(i))); + ex_length += track_get(i)->tr_length; + } + + /* Now clear the playlist. */ + queue_iter_set(&p.pl_queue, &p.pl_queue.q_cur, 12); + playlist_generic_clear(&p); + g_assert_cmpuint(playlist_size(&p), ==, 0); + g_assert_cmpuint(p.pl_queue.q_length, ==, 0); + g_assert_cmpuint(p.pl_queue.q_cur.it_pos, ==, UINT_MAX); + g_assert_null(p.pl_queue.q_cur.it_iter); } static void test_sorting() diff --git a/tests/core/playlists/system.c b/tests/core/playlists/system.c index 457f7c2d..3879235b 100644 --- a/tests/core/playlists/system.c +++ b/tests/core/playlists/system.c @@ -330,7 +330,7 @@ static void test_next() g_assert_cmpuint(playlist_size(__test_pl_queued()), ==, 0); g_assert(playlist_current() == __test_pl_collection()); - queue_clear(&__test_pl_history()->pl_queue); + playlist_generic_clear(__test_pl_history()); 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))); diff --git a/tests/core/queue.c b/tests/core/queue.c index 00a0c4b3..9157345f 100644 --- a/tests/core/queue.c +++ b/tests/core/queue.c @@ -10,7 +10,6 @@ unsigned int count_init = 0; unsigned int count_deinit = 0; unsigned int count_added = 0; -unsigned int count_cleared = 0; static void *queue_op_init(struct queue *queue, void *data) @@ -29,17 +28,11 @@ static void queue_op_added(struct queue *queue, unsigned int pos) count_added++; } -static void queue_op_cleared(struct queue *queue, unsigned int n) -{ - count_cleared++; -} - static const struct queue_ops test_ops = { .qop_init = queue_op_init, .qop_deinit = queue_op_deinit, .qop_added = queue_op_added, - .qop_cleared = queue_op_cleared, }; @@ -89,7 +82,6 @@ static void test_queue(gconstpointer arg) struct queue q; count_added = 0; - count_cleared = 0; queue_init(&q, &test_ops, NULL); @@ -120,13 +112,7 @@ static void test_queue(gconstpointer arg) g_assert_cmpuint(i, ==, N); g_assert_cmpuint(queue_size(&q), ==, ex_size); - queue_clear(&q); - g_assert_cmpuint(count_cleared, ==, 1); - g_assert_cmpuint(queue_size(&q), ==, 0); - g_assert_cmpuint(q.q_length, ==, 0); - queue_deinit(&q); - g_assert_cmpuint(count_cleared, ==, 2); g_assert_null(q.q_sort); } diff --git a/tests/gui/filter.c b/tests/gui/filter.c index 58dd92bb..7e84a0be 100644 --- a/tests/gui/filter.c +++ b/tests/gui/filter.c @@ -14,14 +14,11 @@ void test_queue_deinit(struct queue *queue) { gui_filter_clear_search(queue->q_private); } void test_queue_add(struct queue *queue, unsigned int n) { gui_model_add(queue->q_private, n); } -void test_queue_clear(struct queue *queue, unsigned int n) - { gui_model_clear(queue->q_private, n); } struct queue_ops test_ops = { .qop_init = test_queue_init, .qop_deinit = test_queue_deinit, .qop_added = test_queue_add, - .qop_cleared = test_queue_clear, }; void test_on_load(struct track *track) {} diff --git a/tests/gui/model.c b/tests/gui/model.c index 6c936db0..5ca04dc3 100644 --- a/tests/gui/model.c +++ b/tests/gui/model.c @@ -29,8 +29,6 @@ void test_queue_deinit(struct queue *queue) { } void test_queue_add(struct queue *queue, unsigned int n) { gui_model_add(queue->q_private, n); } -void test_queue_clear(struct queue *queue, unsigned int n) - { gui_model_clear(queue->q_private, n); } void test_on_load(struct track *track) {} void test_on_state_change(GstState state) {} void test_on_config_pause(int count) {} @@ -39,7 +37,6 @@ struct queue_ops test_ops = { .qop_init = test_queue_init, .qop_deinit = test_queue_deinit, .qop_added = test_queue_add, - .qop_cleared = test_queue_clear, }; struct playlist_callbacks test_cb = {