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;
|
return false;
|
||||||
|
|
||||||
playlist->pl_ops->pl_sort(playlist, sort);
|
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;
|
return g_slist_length(playlist->pl_queue.q_sort) > 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,12 @@
|
||||||
static struct playlist_callbacks *callbacks = NULL;
|
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)
|
void playlist_generic_set_callbacks(struct playlist_callbacks *cb)
|
||||||
{
|
{
|
||||||
callbacks = cb;
|
callbacks = cb;
|
||||||
|
@ -17,9 +23,9 @@ void playlist_generic_init(struct playlist *playlist, unsigned int flags,
|
||||||
struct queue_ops *ops)
|
struct queue_ops *ops)
|
||||||
{
|
{
|
||||||
queue_init(&playlist->pl_queue, flags, ops, playlist);
|
queue_init(&playlist->pl_queue, flags, ops, playlist);
|
||||||
queue_sort(&playlist->pl_queue, COMPARE_ARTIST);
|
playlist_generic_sort(playlist, COMPARE_ARTIST);
|
||||||
queue_sort(&playlist->pl_queue, COMPARE_YEAR);
|
playlist_generic_sort(playlist, COMPARE_YEAR);
|
||||||
queue_sort(&playlist->pl_queue, COMPARE_TRACK);
|
playlist_generic_sort(playlist, COMPARE_TRACK);
|
||||||
playlist->pl_private = NULL;
|
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)
|
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)
|
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++)
|
for (unsigned int i = 0; i < queue_size(queue); i++)
|
||||||
__queue_updated(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. */
|
/* Called to sort the queue without changing sort order. */
|
||||||
void queue_resort(struct queue *);
|
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 */
|
#endif /* OCARINA_CORE_QUEUE_H */
|
||||||
|
|
|
@ -6,6 +6,11 @@
|
||||||
#include <core/settings.h>
|
#include <core/settings.h>
|
||||||
#include <core/tags/tags.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()
|
static void test_null()
|
||||||
{
|
{
|
||||||
g_assert_null(playlist_new(PL_MAX_TYPE, "NULL"));
|
g_assert_null(playlist_new(PL_MAX_TYPE, "NULL"));
|
||||||
|
@ -42,19 +47,64 @@ static void test_null()
|
||||||
|
|
||||||
static void test_sorting()
|
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);
|
playlist_generic_init(&p, 0, NULL);
|
||||||
g_assert_cmpuint(g_slist_length(p.pl_queue.q_sort), ==, 3);
|
g_assert_cmpuint(g_slist_length(p.pl_queue.q_sort), ==, 3);
|
||||||
playlist_clear_sort(&p);
|
playlist_clear_sort(&p);
|
||||||
g_assert_cmpuint(g_slist_length(p.pl_queue.q_sort), ==, 0);
|
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()
|
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 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 playlist s = DEFINE_PLAYLIST(PL_MAX_TYPE, "Test 2", 0, NULL);
|
||||||
struct file f = FILE_INIT("test.playlist", 0);
|
struct file f = FILE_INIT("test.playlist", 0);
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
@ -65,7 +115,7 @@ static void test_save_load()
|
||||||
}
|
}
|
||||||
queue_set_flag(&p.pl_queue, Q_RANDOM);
|
queue_set_flag(&p.pl_queue, Q_RANDOM);
|
||||||
playlist_clear_sort(&p);
|
playlist_clear_sort(&p);
|
||||||
queue_sort(&p.pl_queue, COMPARE_TRACK);
|
playlist_sort(&p, COMPARE_TRACK);
|
||||||
p.pl_queue.q_cur.it_pos = 3;
|
p.pl_queue.q_cur.it_pos = 3;
|
||||||
q.pl_queue.q_cur.it_pos = 4;
|
q.pl_queue.q_cur.it_pos = 4;
|
||||||
|
|
||||||
|
|
|
@ -224,9 +224,8 @@ static void test_rand_select()
|
||||||
|
|
||||||
for (i = 0; i < 13; i++)
|
for (i = 0; i < 13; i++)
|
||||||
queue_add(&q, track_get(i));
|
queue_add(&q, track_get(i));
|
||||||
g_slist_free(q.q_sort);
|
q.q_sort = g_slist_append(q.q_sort, GINT_TO_POINTER(COMPARE_TRACK));
|
||||||
q.q_sort = NULL;
|
queue_resort(&q);
|
||||||
queue_sort(&q, COMPARE_TRACK);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The comments below use the following notation:
|
* The comments below use the following notation:
|
||||||
|
@ -257,84 +256,6 @@ static void test_rand_select()
|
||||||
queue_deinit(&q);
|
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)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
struct library *library;
|
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 = 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_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/Random Next and Selection", test_rand_select);
|
||||||
g_test_add_func("/Core/Queue/Sorting", test_sorting);
|
|
||||||
ret = g_test_run();
|
ret = g_test_run();
|
||||||
|
|
||||||
tags_deinit();
|
tags_deinit();
|
||||||
|
|
Loading…
Reference in New Issue