2015-12-02 10:22:11 -05:00
|
|
|
/*
|
2013-12-31 15:44:44 -05:00
|
|
|
* Copyright 2013 (c) Anna Schumaker.
|
|
|
|
*/
|
2014-06-05 10:19:22 -04:00
|
|
|
#include <core/queue.h>
|
2015-01-29 08:27:25 -05:00
|
|
|
#include <core/string.h>
|
2015-12-02 10:22:11 -05:00
|
|
|
#include <stdlib.h>
|
2014-01-22 21:17:51 -05:00
|
|
|
|
2013-12-31 15:44:44 -05:00
|
|
|
|
2015-12-01 11:17:25 -05:00
|
|
|
static int track_less_than(const void *a, const void *b, void *data)
|
2015-11-25 08:24:04 -05:00
|
|
|
{
|
2015-12-01 11:17:25 -05:00
|
|
|
struct track *lhs = (struct track *)a;
|
|
|
|
struct track *rhs = (struct track *)b;
|
2015-12-02 09:18:10 -05:00
|
|
|
GSList *cur = (GSList *)data;
|
|
|
|
int res, field;
|
2015-11-25 08:24:04 -05:00
|
|
|
|
2015-12-02 09:18:10 -05:00
|
|
|
while (cur) {
|
|
|
|
field = GPOINTER_TO_INT(cur->data);
|
|
|
|
if (field > 0)
|
2015-12-02 10:22:11 -05:00
|
|
|
res = track_compare(lhs, rhs, field);
|
2015-11-25 08:24:04 -05:00
|
|
|
else
|
2015-12-02 10:22:11 -05:00
|
|
|
res = track_compare(rhs, lhs, abs(field));
|
2015-12-02 09:18:10 -05:00
|
|
|
if (res == 0) {
|
|
|
|
cur = g_slist_next(cur);
|
2015-11-25 08:24:04 -05:00
|
|
|
continue;
|
2015-12-02 09:18:10 -05:00
|
|
|
}
|
2015-11-25 08:24:04 -05:00
|
|
|
break;
|
2015-12-02 09:18:10 -05:00
|
|
|
};
|
2015-12-01 11:17:25 -05:00
|
|
|
return res;
|
2015-11-25 08:24:04 -05:00
|
|
|
}
|
|
|
|
|
2016-05-02 07:52:18 -04:00
|
|
|
static inline void *__queue_init(struct queue *queue, void *data)
|
2016-01-12 08:02:28 -05:00
|
|
|
{
|
|
|
|
if (queue->q_ops)
|
2016-05-02 07:52:18 -04:00
|
|
|
return queue->q_ops->qop_init(queue, data);
|
2016-01-12 08:02:28 -05:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2016-01-13 08:18:03 -05:00
|
|
|
static inline void __queue_deinit(struct queue *queue)
|
|
|
|
{
|
|
|
|
if (queue->q_ops)
|
|
|
|
queue->q_ops->qop_deinit(queue);
|
|
|
|
}
|
|
|
|
|
2015-11-29 19:45:39 -05:00
|
|
|
static inline unsigned int __queue_added(struct queue *queue,
|
|
|
|
struct track *track,
|
|
|
|
unsigned int pos)
|
|
|
|
{
|
|
|
|
queue->q_length += track->tr_length;
|
|
|
|
if (queue->q_ops)
|
|
|
|
queue->q_ops->qop_added(queue, pos);
|
|
|
|
return pos;
|
|
|
|
}
|
|
|
|
|
2016-04-02 14:14:36 -04:00
|
|
|
static inline unsigned int __queue_add_head(struct queue *queue,
|
|
|
|
struct track *track)
|
|
|
|
{
|
2016-04-03 09:52:16 -04:00
|
|
|
g_queue_push_head(&queue->q_tracks, track);
|
2016-04-02 14:14:36 -04:00
|
|
|
return __queue_added(queue, track, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline unsigned int __queue_add_tail(struct queue *queue,
|
|
|
|
struct track *track)
|
|
|
|
{
|
2016-04-03 09:52:16 -04:00
|
|
|
g_queue_push_tail(&queue->q_tracks, track);
|
2016-04-02 14:14:36 -04:00
|
|
|
return __queue_added(queue, track, queue_size(queue) - 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline unsigned int __queue_add_sorted(struct queue *queue,
|
|
|
|
struct track *track)
|
|
|
|
{
|
2016-04-03 09:52:16 -04:00
|
|
|
struct queue_iter it;
|
2016-04-02 14:14:36 -04:00
|
|
|
|
2016-04-03 09:52:16 -04:00
|
|
|
queue_for_each(queue, &it) {
|
|
|
|
if (track_less_than(queue_iter_val(&it), track, queue->q_sort) > 0) {
|
|
|
|
g_queue_insert_before(&queue->q_tracks, it.it_iter, track);
|
2016-04-02 14:14:36 -04:00
|
|
|
return __queue_added(queue, track, it.it_pos);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return __queue_add_tail(queue, track);
|
|
|
|
}
|
|
|
|
|
2016-09-19 10:55:29 -04:00
|
|
|
void queue_init(struct queue *queue, const struct queue_ops *ops, void *data)
|
2015-11-23 08:36:29 -05:00
|
|
|
{
|
|
|
|
queue->q_length = 0;
|
2015-12-02 09:18:10 -05:00
|
|
|
queue->q_sort = NULL;
|
2015-11-23 08:36:29 -05:00
|
|
|
queue->q_ops = ops;
|
2015-12-01 11:17:25 -05:00
|
|
|
|
2016-04-03 09:52:16 -04:00
|
|
|
g_queue_init(&queue->q_tracks);
|
2016-04-03 09:40:01 -04:00
|
|
|
queue_iter_init(queue, &queue->q_cur);
|
2016-01-12 08:02:28 -05:00
|
|
|
|
2016-05-02 07:52:18 -04:00
|
|
|
queue->q_private = __queue_init(queue, data);
|
2015-11-23 08:36:29 -05:00
|
|
|
}
|
2013-12-31 15:44:44 -05:00
|
|
|
|
2015-12-07 10:00:19 -05:00
|
|
|
void queue_deinit(struct queue *queue)
|
|
|
|
{
|
2016-09-21 08:15:47 -04:00
|
|
|
g_queue_clear(&queue->q_tracks);
|
2016-01-13 08:18:03 -05:00
|
|
|
__queue_deinit(queue);
|
2015-12-07 10:00:19 -05:00
|
|
|
g_slist_free(queue->q_sort);
|
|
|
|
queue->q_sort = NULL;
|
|
|
|
}
|
|
|
|
|
2015-11-25 08:24:04 -05:00
|
|
|
unsigned int queue_add(struct queue *queue, struct track *track)
|
2014-01-02 21:58:18 -05:00
|
|
|
{
|
2016-04-02 14:14:36 -04:00
|
|
|
if (queue->q_sort)
|
|
|
|
return __queue_add_sorted(queue, track);
|
|
|
|
return __queue_add_tail(queue, track);
|
2014-01-02 21:58:18 -05:00
|
|
|
}
|
|
|
|
|
2016-09-08 09:08:18 -04:00
|
|
|
unsigned int queue_add_front(struct queue *queue, struct track *track)
|
|
|
|
{
|
|
|
|
return __queue_add_head(queue, track);
|
|
|
|
}
|