core/queue: Implement a new queue_iter
I plan to remove the containers/queue implementation, so we need a new iterator for queue access. Signed-off-by: Anna Schumaker <Anna@OcarinaProject.net>
This commit is contained in:
parent
6bb08ddbaa
commit
9835235acd
|
@ -53,6 +53,12 @@ struct queue_ops {
|
|||
};
|
||||
|
||||
|
||||
struct queue_iter {
|
||||
GList *it_iter; /* The current link in the GQueue. */
|
||||
guint it_pos; /* The current index into the queue. */
|
||||
};
|
||||
|
||||
|
||||
struct queue {
|
||||
unsigned int q_flags; /* The queue's set of flags. */
|
||||
unsigned int q_length; /* The queue's total runtime (in seconds). */
|
||||
|
@ -65,6 +71,47 @@ struct queue {
|
|||
};
|
||||
|
||||
|
||||
|
||||
/* Called to initialize a queue iterator. */
|
||||
static inline void queue_iter_init(struct queue *queue, struct queue_iter *it)
|
||||
{
|
||||
it->it_iter = g_queue_peek_head_link(&queue->q_tracks._queue);
|
||||
it->it_pos = g_queue_link_index(&queue->q_tracks._queue, it->it_iter);
|
||||
}
|
||||
|
||||
/* Called to advance a queue iterator by one step. */
|
||||
static inline void queue_iter_next(struct queue_iter *it)
|
||||
{
|
||||
it->it_iter = g_list_next(it->it_iter);
|
||||
it->it_pos++;
|
||||
}
|
||||
|
||||
/* Called to rewind a queue iterator by one step. */
|
||||
static inline void queue_iter_prev(struct queue_iter *it)
|
||||
{
|
||||
it->it_iter = g_list_previous(it->it_iter);
|
||||
it->it_pos--;
|
||||
}
|
||||
|
||||
/* Called to set a queue iterator to a specific position. */
|
||||
static inline void queue_iter_set(struct queue *queue, struct queue_iter *it,
|
||||
unsigned int pos)
|
||||
{
|
||||
it->it_iter = g_queue_peek_nth_link(&queue->q_tracks._queue, pos);
|
||||
it->it_pos = pos;
|
||||
}
|
||||
|
||||
/* Called to access the value of a queue iterator. */
|
||||
static inline struct track *queue_iter_val(struct queue_iter *it)
|
||||
{
|
||||
return (it->it_iter) ? it->it_iter->data : NULL;
|
||||
}
|
||||
|
||||
#define queue_for_each(queue, it) \
|
||||
for (queue_iter_init(queue, it); (it)->it_iter; queue_iter_next(it))
|
||||
|
||||
|
||||
|
||||
/* Called to initialize a queue. */
|
||||
void queue_init(struct queue *, unsigned int, const struct queue_ops *);
|
||||
|
||||
|
|
|
@ -111,6 +111,7 @@ static void __test_deinit_core()
|
|||
static void test_init()
|
||||
{
|
||||
struct queue q;
|
||||
struct queue_iter it;
|
||||
|
||||
__test_init_core();
|
||||
|
||||
|
@ -125,6 +126,11 @@ static void test_init()
|
|||
test_equal((void *)q.q_ops, NULL);
|
||||
test_equal((void *)queue_next(&q), (void *)NULL);
|
||||
|
||||
queue_iter_init(&q, &it);
|
||||
g_assert_null(it.it_iter);
|
||||
g_assert_cmpuint(it.it_pos, ==, (unsigned int)-1);
|
||||
g_assert_null(queue_iter_val(&it));
|
||||
|
||||
queue_deinit(&q);
|
||||
test_equal(count_deinit, 0);
|
||||
|
||||
|
@ -193,6 +199,7 @@ static void test_stress(unsigned int N)
|
|||
{
|
||||
unsigned int ex_length = 0;
|
||||
unsigned int ex_size = N;
|
||||
struct queue_iter it;
|
||||
struct track *track;
|
||||
unsigned int i;
|
||||
struct queue q;
|
||||
|
@ -214,6 +221,23 @@ static void test_stress(unsigned int N)
|
|||
test_equal(q.q_length, ex_length);
|
||||
test_equal(queue_size(&q), ex_size);
|
||||
|
||||
/* queue_iter_init() */
|
||||
if (N > 0) {
|
||||
queue_iter_init(&q, &it);
|
||||
g_assert_nonnull(it.it_iter);
|
||||
g_assert_cmpuint(it.it_pos, ==, 0);
|
||||
}
|
||||
|
||||
/* queue_for_each() */
|
||||
i = 0;
|
||||
queue_for_each(&q, &it) {
|
||||
g_assert_cmpuint(it.it_pos, ==, i);
|
||||
g_assert(queue_iter_val(&it) == track_get(i % 13));
|
||||
i++;
|
||||
}
|
||||
g_assert_cmpuint(i, ==, N);
|
||||
g_assert_cmpuint(queue_size(&q), ==, ex_size);
|
||||
|
||||
/* queue_remove_all() */
|
||||
track = track_get(0);
|
||||
ex_length -= track->tr_length * (N / 13);
|
||||
|
|
Loading…
Reference in New Issue