core/playlist: Implement sorting directly
Rather than passing through to queue_sort(). Additionally, I remove the queue_sort() function. Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This commit is contained in:
parent
793a8a5817
commit
e74c1c053c
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
21
core/queue.c
21
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);
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -6,6 +6,11 @@
|
|||
#include <core/settings.h>
|
||||
#include <core/tags/tags.h>
|
||||
|
||||
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;
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue