core/queue: Convert q_sort to a GSList

I needed to bump the track comparison fields by one so I can use signed
values to indicate sort order.  I updated core/library.cpp to add and
subtract one as needed.

Signed-off-by: Anna Schumaker <Anna@OcarinaProject.net>
This commit is contained in:
Anna Schumaker 2015-12-02 09:18:10 -05:00
parent 6fa78dbf3a
commit 799a8d34b5
5 changed files with 58 additions and 54 deletions

View File

@ -23,14 +23,18 @@ public:
void save()
{
std::vector<struct sort_info>::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);

View File

@ -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);

View File

@ -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 <struct sort_info> 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. */
};

View File

@ -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. */
};

View File

@ -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();
}