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:
parent
6fa78dbf3a
commit
799a8d34b5
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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. */
|
||||
};
|
||||
|
|
|
@ -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. */
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue