diff --git a/core/library.cpp b/core/library.cpp index ae41d371..3caa6548 100644 --- a/core/library.cpp +++ b/core/library.cpp @@ -23,14 +23,18 @@ public: void save() { - std::vector::iterator it; + GSList *cur = q_sort; + int field; if (!file_open(&f, OPEN_WRITE)) return; - file_writef(&f, "%u %u", q_flags, q_sort.size()); - for (it = q_sort.begin(); it != q_sort.end(); it++) - file_writef(&f, " %u %d", it->field, it->ascending); + file_writef(&f, "%u %u", q_flags, g_slist_length(q_sort)); + while (cur) { + field = GPOINTER_TO_INT(cur->data); + file_writef(&f, " %u %d", abs(field) - 1, field > 0); + cur = g_slist_next(cur); + } file_writef(&f, "\n"); file_close(&f); } @@ -47,9 +51,9 @@ public: file_readf(&f, "%u %u", &q_flags, &n); for (unsigned int i = 0; i < n; i++) { file_readf(&f, "%u %d", &field, &ascending); - queue_sort(this, (compare_t)field, (i == 0) ? true : false); + queue_sort(this, (compare_t)(field + 1), (i == 0) ? true : false); if (ascending == false) - queue_sort(this, (compare_t)field, false); + queue_sort(this, (compare_t)(field + 1), false); } file_close(&f); } @@ -151,7 +155,7 @@ void collection :: init(struct queue_ops *ops) } library_q.load(); - if (library_q.q_sort.size() == 0) { + if (!library_q.q_sort) { queue_sort(&library_q, COMPARE_ARTIST, true); queue_sort(&library_q, COMPARE_YEAR, false); queue_sort(&library_q, COMPARE_TRACK, false); diff --git a/core/queue.cpp b/core/queue.cpp index 49522b22..eb74a34c 100644 --- a/core/queue.cpp +++ b/core/queue.cpp @@ -15,18 +15,21 @@ static int track_less_than(const void *a, const void *b, void *data) { struct track *lhs = (struct track *)a; struct track *rhs = (struct track *)b; - struct queue *queue = (struct queue *)data; - int res; + GSList *cur = (GSList *)data; + int res, field; - for (unsigned int i = 0; i < queue->q_sort.size(); i++) { - if (queue->q_sort[i].ascending == true) - res = track_compare(lhs, rhs, queue->q_sort[i].field); + while (cur) { + field = GPOINTER_TO_INT(cur->data); + if (field > 0) + res = track_compare(lhs, rhs, (compare_t)field); else - res = track_compare(rhs, lhs, queue->q_sort[i].field); - if (res == 0) + res = track_compare(rhs, lhs, (compare_t)abs(field)); + if (res == 0) { + cur = g_slist_next(cur); continue; + } break; - } + }; return res; } @@ -78,6 +81,7 @@ void queue_init(struct queue *queue, unsigned int flags, { queue->q_flags = flags; queue->q_length = 0; + queue->q_sort = NULL; queue->q_ops = ops; queue->q_cur.it_pos = -1; @@ -104,8 +108,9 @@ unsigned int queue_add(struct queue *queue, struct track *track) if (queue_has_flag(queue, Q_ADD_FRONT)) pos = _q_add_head(&queue->q_tracks, track); - else if (queue->q_sort.size() > 0) - pos = _q_add_sorted(&queue->q_tracks, track, track_less_than, queue); + else if (queue->q_sort) + pos = _q_add_sorted(&queue->q_tracks, track, + track_less_than, queue->q_sort); else pos = _q_add_tail(&queue->q_tracks, track); @@ -173,28 +178,32 @@ struct track *queue_next(struct queue *queue) return __queue_selected(queue); } -void queue_sort(struct queue *queue, enum compare_t field, bool reset) +void queue_sort(struct queue *queue, enum compare_t sort, bool reset) { - bool found = false; - struct sort_info info = { field, true }; + GSList *cur = NULL; + int field; if (queue_has_flag(queue, Q_NO_SORT)) return; - if (reset) - queue->q_sort.clear(); - - for (unsigned int i = 0; i < queue->q_sort.size(); i++) { - if (queue->q_sort[i].field == info.field) { - queue->q_sort[i].ascending = !queue->q_sort[i].ascending; - found = true; - break; - } + if (reset) { + g_slist_free(queue->q_sort); + queue->q_sort = NULL; } - if (!found) - queue->q_sort.push_back(info); + 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); + } - _q_sort(&queue->q_tracks, track_less_than, queue); + queue->q_sort = g_slist_append(queue->q_sort, GINT_TO_POINTER(sort)); + +out_sort: + _q_sort(&queue->q_tracks, track_less_than, queue->q_sort); for (unsigned int i = 0; i < queue_size(queue); i++) __queue_updated(queue, i); diff --git a/include/core/queue.h b/include/core/queue.h index 07eda4e5..cdfc34b1 100644 --- a/include/core/queue.h +++ b/include/core/queue.h @@ -43,15 +43,6 @@ struct queue_ops { }; -/** - * Struct for passing sort parameters. - */ -struct sort_info { - compare_t field; - bool ascending; -}; - - /** * Queues are lists of songs that the user has requested to play next, * although not necessarily in a specific order. @@ -66,8 +57,7 @@ struct queue { unsigned int q_length; /* The queue's total runtime (in seconds). */ struct _queue q_tracks; /* The queue's list of tracks. */ struct _q_iter q_cur; /* The queue's last-played position. */ - - std :: vector q_sort; /* The queue's sort settings. */ + GSList *q_sort; /* The queue's sort order. */ const struct queue_ops *q_ops; /* The queue's operations vector. */ }; diff --git a/include/core/tags/track.h b/include/core/tags/track.h index 4062d8d9..3f15e5c5 100644 --- a/include/core/tags/track.h +++ b/include/core/tags/track.h @@ -29,15 +29,15 @@ enum compare_t { - COMPARE_ARTIST, /* Compare tracks by artist name. */ - COMPARE_ALBUM, /* Compare tracks by album name. */ - COMPARE_COUNT, /* Compare tracks by play count. */ - COMPARE_GENRE, /* Compare tracks by genre. */ - COMPARE_LENGTH, /* Compare tracks by length. */ - COMPARE_PLAYED, /* Compare tracks by last played date. */ - COMPARE_TITLE, /* Compare tracks by title. */ - COMPARE_TRACK, /* Compare tracks by track number. */ - COMPARE_YEAR, /* Compare tracks by year. */ + COMPARE_ARTIST = 1, /* Compare tracks by artist name. */ + COMPARE_ALBUM = 2, /* Compare tracks by album name. */ + COMPARE_COUNT = 3, /* Compare tracks by play count. */ + COMPARE_GENRE = 4, /* Compare tracks by genre. */ + COMPARE_LENGTH = 5, /* Compare tracks by length. */ + COMPARE_PLAYED = 6, /* Compare tracks by last played date. */ + COMPARE_TITLE = 7, /* Compare tracks by title. */ + COMPARE_TRACK = 8, /* Compare tracks by track number. */ + COMPARE_YEAR = 9, /* Compare tracks by year. */ }; diff --git a/tests/core/queue.cpp b/tests/core/queue.cpp index 28c5e17f..a9090b33 100644 --- a/tests/core/queue.cpp +++ b/tests/core/queue.cpp @@ -89,7 +89,7 @@ static void test_init() test_equal(q.q_cur.it_pos, (unsigned int)-1); test_equal(q.q_flags, 0); test_equal(q.q_length, 0); - test_equal(q.q_sort.size(), (size_t)0); + test_equal(q.q_sort, NULL); test_equal(q.q_ops, NULL); test_equal(queue_next(&q), (struct track *)NULL); @@ -98,7 +98,7 @@ static void test_init() test_equal(q.q_cur.it_pos, (unsigned int)-1); test_equal(q.q_flags, Q_ENABLED | Q_RANDOM); test_equal(q.q_length, 0); - test_equal(q.q_sort.size(), 0); + test_equal(q.q_sort, NULL); test_equal(q.q_ops, &test_ops); test_equal(queue_next(&q), (struct track *)NULL); } @@ -377,6 +377,7 @@ static void test_sorting() test_equal(count_sort, 6); g_queue_clear(&q.q_tracks._queue); + g_slist_free(q.q_sort); __test_deinit_core(); }