From e74c1c053c9b020457e0580c734b969a89eb1d82 Mon Sep 17 00:00:00 2001 From: Anna Schumaker Date: Fri, 16 Sep 2016 16:43:13 -0400 Subject: [PATCH] core/playlist: Implement sorting directly Rather than passing through to queue_sort(). Additionally, I remove the queue_sort() function. Signed-off-by: Anna Schumaker --- core/playlist.c | 3 +- core/playlists/generic.c | 24 ++++++++++-- core/queue.c | 21 ---------- include/core/queue.h | 3 -- tests/core/playlist.c | 58 +++++++++++++++++++++++++-- tests/core/queue.c | 84 +--------------------------------------- 6 files changed, 78 insertions(+), 115 deletions(-) diff --git a/core/playlist.c b/core/playlist.c index 97f2d00d..6fae406a 100644 --- a/core/playlist.c +++ b/core/playlist.c @@ -215,6 +215,7 @@ bool playlist_sort(struct playlist *playlist, enum compare_t sort) return false; playlist->pl_ops->pl_sort(playlist, sort); - playlist_types[playlist->pl_type]->pl_save(); + if (playlist->pl_type < PL_MAX_TYPE) + playlist_types[playlist->pl_type]->pl_save(); return g_slist_length(playlist->pl_queue.q_sort) > 0; } diff --git a/core/playlists/generic.c b/core/playlists/generic.c index c6156faa..0c47cbd8 100644 --- a/core/playlists/generic.c +++ b/core/playlists/generic.c @@ -8,6 +8,12 @@ static struct playlist_callbacks *callbacks = NULL; +static int __playlist_generic_find_sort(gconstpointer a, gconstpointer b) +{ + return abs(GPOINTER_TO_INT(a)) - abs(GPOINTER_TO_INT(b)); +} + + void playlist_generic_set_callbacks(struct playlist_callbacks *cb) { callbacks = cb; @@ -17,9 +23,9 @@ void playlist_generic_init(struct playlist *playlist, unsigned int flags, struct queue_ops *ops) { queue_init(&playlist->pl_queue, flags, ops, playlist); - queue_sort(&playlist->pl_queue, COMPARE_ARTIST); - queue_sort(&playlist->pl_queue, COMPARE_YEAR); - queue_sort(&playlist->pl_queue, COMPARE_TRACK); + playlist_generic_sort(playlist, COMPARE_ARTIST); + playlist_generic_sort(playlist, COMPARE_YEAR); + playlist_generic_sort(playlist, COMPARE_TRACK); playlist->pl_private = NULL; } @@ -143,7 +149,17 @@ void playlist_generic_set_flag(struct playlist *playlist, void playlist_generic_sort(struct playlist *playlist, enum compare_t sort) { - queue_sort(&playlist->pl_queue, sort); + GSList *found = g_slist_find_custom(playlist->pl_queue.q_sort, + GINT_TO_POINTER(sort), + __playlist_generic_find_sort); + + if (found) + found->data = GINT_TO_POINTER(-GPOINTER_TO_INT(found->data)); + else + playlist->pl_queue.q_sort = g_slist_append(playlist->pl_queue.q_sort, + GINT_TO_POINTER(sort)); + + queue_resort(&playlist->pl_queue); } struct track *playlist_generic_next(struct playlist *playlist) diff --git a/core/queue.c b/core/queue.c index 3829c687..257d7702 100644 --- a/core/queue.c +++ b/core/queue.c @@ -255,24 +255,3 @@ void queue_resort(struct queue *queue) for (unsigned int i = 0; i < queue_size(queue); i++) __queue_updated(queue, i); } - -void queue_sort(struct queue *queue, enum compare_t sort) -{ - GSList *cur = NULL; - int field; - - cur = queue->q_sort; - while (cur) { - field = GPOINTER_TO_INT(cur->data); - if (abs(field) == sort) { - cur->data = GINT_TO_POINTER(-field); - goto out_sort; - } - cur = g_slist_next(cur); - } - - queue->q_sort = g_slist_append(queue->q_sort, GINT_TO_POINTER(sort)); - -out_sort: - queue_resort(queue); -} diff --git a/include/core/queue.h b/include/core/queue.h index b0de3475..f2abf5d6 100644 --- a/include/core/queue.h +++ b/include/core/queue.h @@ -170,7 +170,4 @@ struct track *queue_next(struct queue *); /* Called to sort the queue without changing sort order. */ void queue_resort(struct queue *); -/* Called to change the sort order and resort the queue. */ -void queue_sort(struct queue *, enum compare_t); - #endif /* OCARINA_CORE_QUEUE_H */ diff --git a/tests/core/playlist.c b/tests/core/playlist.c index 3f6cbdfc..104d44f4 100644 --- a/tests/core/playlist.c +++ b/tests/core/playlist.c @@ -6,6 +6,11 @@ #include #include +static struct playlist_ops test_noop; +static struct playlist_ops test_ops = { + .pl_sort = playlist_generic_sort, +}; + static void test_null() { g_assert_null(playlist_new(PL_MAX_TYPE, "NULL")); @@ -42,19 +47,64 @@ static void test_null() static void test_sorting() { - struct playlist p = DEFINE_PLAYLIST(PL_MAX_TYPE, "Test", 0, NULL); + struct playlist p = DEFINE_PLAYLIST(PL_MAX_TYPE, "Test", 0, &test_ops); + struct track *track; + unsigned int i; playlist_generic_init(&p, 0, NULL); g_assert_cmpuint(g_slist_length(p.pl_queue.q_sort), ==, 3); playlist_clear_sort(&p); g_assert_cmpuint(g_slist_length(p.pl_queue.q_sort), ==, 0); + + for (i = 0; i < 13; i++) { + track = track_get(i); + track->tr_count = (track->tr_track % 2) ? 4 : 2; + playlist_generic_add_track_front(&p, track); + } + + p.pl_ops = &test_noop; + g_assert_false(playlist_sort(&p, COMPARE_TRACK)); + p.pl_ops = &test_ops; + + g_assert_true(playlist_sort(&p, COMPARE_TRACK)); + for (i = 0; i < 13; i++) { + track = queue_at(&p.pl_queue, i); + g_assert_cmpuint(track->tr_track, ==, i + 1); + } + + playlist_clear_sort(&p); + g_assert_true(playlist_sort(&p, COMPARE_COUNT)); + for (i = 0; i < 13; i++) { + track = queue_at(&p.pl_queue, i); + g_assert_cmpuint(track->tr_count, ==, (i < 6) ? 2 : 4); + } + + g_assert_true(playlist_sort(&p, COMPARE_TRACK)); + for (i = 0; i < 13; i++) { + track = queue_at(&p.pl_queue, i); + g_assert_cmpuint(track->tr_count, ==, (i < 6) ? 2 : 4); + if (i < 6) + g_assert_cmpuint(track->tr_track, ==, (i + 1) * 2); + else + g_assert_cmpuint(track->tr_track, ==, (2 * i) - 11); + } + + g_assert_true(playlist_sort(&p, COMPARE_COUNT)); + for (i = 0; i < 13; i++) { + track = queue_at(&p.pl_queue, i); + g_assert_cmpuint(track->tr_count, ==, (i < 7) ? 4 : 2); + if (i < 7) + g_assert_cmpuint(track->tr_track, ==, (2 * i) + 1); + else + g_assert_cmpuint(track->tr_track, ==, (2 * i) - 12); + } } static void test_save_load() { - struct playlist p = DEFINE_PLAYLIST(PL_MAX_TYPE, "Test", 0, NULL); + struct playlist p = DEFINE_PLAYLIST(PL_MAX_TYPE, "Test", 0, &test_ops); struct playlist q = DEFINE_PLAYLIST(PL_MAX_TYPE, "Test 2", 0, NULL); - struct playlist r = DEFINE_PLAYLIST(PL_MAX_TYPE, "Test", 0, NULL); + struct playlist r = DEFINE_PLAYLIST(PL_MAX_TYPE, "Test", 0, &test_ops); struct playlist s = DEFINE_PLAYLIST(PL_MAX_TYPE, "Test 2", 0, NULL); struct file f = FILE_INIT("test.playlist", 0); unsigned int i; @@ -65,7 +115,7 @@ static void test_save_load() } queue_set_flag(&p.pl_queue, Q_RANDOM); playlist_clear_sort(&p); - queue_sort(&p.pl_queue, COMPARE_TRACK); + playlist_sort(&p, COMPARE_TRACK); p.pl_queue.q_cur.it_pos = 3; q.pl_queue.q_cur.it_pos = 4; diff --git a/tests/core/queue.c b/tests/core/queue.c index f78fad38..d728107f 100644 --- a/tests/core/queue.c +++ b/tests/core/queue.c @@ -224,9 +224,8 @@ static void test_rand_select() for (i = 0; i < 13; i++) queue_add(&q, track_get(i)); - g_slist_free(q.q_sort); - q.q_sort = NULL; - queue_sort(&q, COMPARE_TRACK); + q.q_sort = g_slist_append(q.q_sort, GINT_TO_POINTER(COMPARE_TRACK)); + queue_resort(&q); /* * The comments below use the following notation: @@ -257,84 +256,6 @@ static void test_rand_select() queue_deinit(&q); } -static void test_sorting() -{ - unsigned int ex_count[] = { 7, 8, 9, 10, 11, 12, 13, 1, 2, 3, 4, 5, 6 }; - unsigned int ex_title[] = { 7, 10, 9, 4, 3, 6, 2, 5, 12, 11, 13, 1, 8 }; - unsigned int ex_co_ti[] = { 4, 3, 6, 2, 5, 1, 7, 10, 9, 12, 11, 13, 8 }; - struct track *track; - unsigned int i; - struct queue q; - - queue_init(&q, 0, &test_ops, NULL); - for (i = 0; i < 13; i++) { - track = track_get(i); - track->tr_count = (track->tr_track <= 6) ? 4 : 2; - queue_add_front(&q, track); - } - - for (i = 0; i < 13; i++) { - track = queue_at(&q, i); - g_assert_nonnull(track); - g_assert_cmpuint(track->tr_dbe.dbe_index, ==, 12 - i); - } - - g_slist_free(q.q_sort); - q.q_sort = NULL; - queue_sort(&q, COMPARE_TRACK); - for (i = 0; i < 13; i++) { - track = queue_at(&q, i); - g_assert_nonnull(track); - g_assert_cmpuint(track->tr_track, ==, i + 1); - } - - g_slist_free(q.q_sort); - q.q_sort = NULL; - queue_sort(&q, COMPARE_COUNT); - for (i = 0; i < 13; i++) { - track = queue_at(&q, i); - g_assert_nonnull(track); - g_assert_cmpuint(track->tr_track, ==, ex_count[i]); - } - - g_slist_free(q.q_sort); - q.q_sort = NULL; - queue_sort(&q, COMPARE_TITLE); - for (i = 0; i < 13; i++) { - track = queue_at(&q, i); - g_assert_nonnull(track); - g_assert_cmpuint(track->tr_track, ==, ex_title[i]); - } - - g_slist_free(q.q_sort); - q.q_sort = NULL; - queue_sort(&q, COMPARE_COUNT); - queue_sort(&q, COMPARE_TITLE); - queue_sort(&q, COMPARE_COUNT); - for (i = 0; i < 13; i++) { - track = queue_at(&q, i); - g_assert_nonnull(track); - g_assert_cmpuint(track->tr_track, ==, ex_co_ti[i]); - } - - g_slist_free(q.q_sort); - q.q_sort = NULL; - queue_sort(&q, COMPARE_ARTIST); - queue_sort(&q, COMPARE_ALBUM); - queue_sort(&q, COMPARE_TRACK); - queue_sort(&q, COMPARE_TRACK); - for (i = 0; i < 13; i++) { - track = queue_at(&q, i); - g_assert_nonnull(track); - g_assert_cmpuint(track->tr_track, ==, 13 - i); - } - - queue_deinit(&q); - g_assert_cmpuint(q.q_length, ==, 0); - g_assert_cmpuint(queue_size(&q),==, 0); - g_assert_null(q.q_sort); -} - int main(int argc, char **argv) { struct library *library; @@ -367,7 +288,6 @@ int main(int argc, char **argv) g_test_add_data_func("/Core/Queue/n = 13", GUINT_TO_POINTER( 13), test_queue); g_test_add_data_func("/Core/Queue/n = 100,009)", GUINT_TO_POINTER(100009), test_queue); g_test_add_func("/Core/Queue/Random Next and Selection", test_rand_select); - g_test_add_func("/Core/Queue/Sorting", test_sorting); ret = g_test_run(); tags_deinit();