core/queue: Add queue_erase() and qop_erase()
This function is similar to queue_remove(), except the remove can be prevented if qop_erase() returns false. Signed-off-by: Anna Schumaker <Anna@OcarinaProject.net>
This commit is contained in:
parent
8d2b0caf6c
commit
aee4764a2c
18
core/queue.c
18
core/queue.c
|
@ -52,6 +52,15 @@ static inline unsigned int __queue_added(struct queue *queue,
|
||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool __queue_erase(struct queue *queue, struct _q_iter *it)
|
||||||
|
{
|
||||||
|
struct track *track = (struct track *)_q_iter_val(it);
|
||||||
|
|
||||||
|
if (queue->q_ops)
|
||||||
|
return queue->q_ops->qop_erase(queue, track);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static inline void __queue_remove(struct queue *queue, struct _q_iter *it)
|
static inline void __queue_remove(struct queue *queue, struct _q_iter *it)
|
||||||
{
|
{
|
||||||
unsigned int pos = it->it_pos;
|
unsigned int pos = it->it_pos;
|
||||||
|
@ -142,6 +151,15 @@ unsigned int queue_add(struct queue *queue, struct track *track)
|
||||||
return __queue_added(queue, track, pos);
|
return __queue_added(queue, track, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void queue_erase(struct queue *queue, unsigned int index)
|
||||||
|
{
|
||||||
|
struct _q_iter it;
|
||||||
|
|
||||||
|
_q_iter_set(&queue->q_tracks, &it, index);
|
||||||
|
if (__queue_erase(queue, &it))
|
||||||
|
__queue_remove(queue, &it);
|
||||||
|
}
|
||||||
|
|
||||||
void queue_remove(struct queue *queue, unsigned int index)
|
void queue_remove(struct queue *queue, unsigned int index)
|
||||||
{
|
{
|
||||||
struct _q_iter it;
|
struct _q_iter it;
|
||||||
|
|
|
@ -65,6 +65,11 @@ static void collection_added(struct queue *queue, unsigned int pos)
|
||||||
gui_queue_added(queue, pos);
|
gui_queue_added(queue, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool collection_erase(struct queue *queue, struct track *track)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static void collection_removed(struct queue *queue, unsigned int pos)
|
static void collection_removed(struct queue *queue, unsigned int pos)
|
||||||
{
|
{
|
||||||
if (collection_tab)
|
if (collection_tab)
|
||||||
|
@ -76,6 +81,7 @@ struct queue_ops collection_ops = {
|
||||||
collection_init,
|
collection_init,
|
||||||
gui_queue_free,
|
gui_queue_free,
|
||||||
collection_added,
|
collection_added,
|
||||||
|
collection_erase,
|
||||||
collection_removed,
|
collection_removed,
|
||||||
gui_queue_cleared,
|
gui_queue_cleared,
|
||||||
collection_save,
|
collection_save,
|
||||||
|
|
|
@ -50,6 +50,11 @@ static void history_added(struct queue *queue, unsigned int pos)
|
||||||
gui_queue_added(queue, pos);
|
gui_queue_added(queue, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool history_erase(struct queue *queue, struct track *track)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static void history_removed(struct queue *queue, unsigned int pos)
|
static void history_removed(struct queue *queue, unsigned int pos)
|
||||||
{
|
{
|
||||||
history_tab->on_track_removed(pos);
|
history_tab->on_track_removed(pos);
|
||||||
|
@ -60,6 +65,7 @@ struct queue_ops history_ops = {
|
||||||
history_init,
|
history_init,
|
||||||
gui_queue_free,
|
gui_queue_free,
|
||||||
history_added,
|
history_added,
|
||||||
|
history_erase,
|
||||||
history_removed,
|
history_removed,
|
||||||
gui_queue_cleared,
|
gui_queue_cleared,
|
||||||
NULL,
|
NULL,
|
||||||
|
|
|
@ -95,6 +95,11 @@ static void playlist_added(struct queue *queue, unsigned int pos)
|
||||||
gui_queue_added(queue, pos);
|
gui_queue_added(queue, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool playlist_erase(struct queue *queue, struct track *track)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static void playlist_removed(struct queue *queue, unsigned int pos)
|
static void playlist_removed(struct queue *queue, unsigned int pos)
|
||||||
{
|
{
|
||||||
p_tab->on_track_removed(pos);
|
p_tab->on_track_removed(pos);
|
||||||
|
@ -105,6 +110,7 @@ struct queue_ops playlist_ops = {
|
||||||
playlist_init,
|
playlist_init,
|
||||||
gui_queue_free,
|
gui_queue_free,
|
||||||
playlist_added,
|
playlist_added,
|
||||||
|
playlist_erase,
|
||||||
playlist_removed,
|
playlist_removed,
|
||||||
gui_queue_cleared,
|
gui_queue_cleared,
|
||||||
NULL,
|
NULL,
|
||||||
|
|
|
@ -40,6 +40,11 @@ static void tempq_added(struct queue *queue, unsigned int pos)
|
||||||
gui_queue_added(queue, pos);
|
gui_queue_added(queue, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool tempq_erase(struct queue *queue, struct track *track)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static void tempq_removed(struct queue *queue, unsigned int pos)
|
static void tempq_removed(struct queue *queue, unsigned int pos)
|
||||||
{
|
{
|
||||||
find_tab(queue)->on_track_removed(pos);
|
find_tab(queue)->on_track_removed(pos);
|
||||||
|
@ -51,6 +56,7 @@ struct queue_ops tempq_ops = {
|
||||||
tempq_init,
|
tempq_init,
|
||||||
gui_queue_free,
|
gui_queue_free,
|
||||||
tempq_added,
|
tempq_added,
|
||||||
|
tempq_erase,
|
||||||
tempq_removed,
|
tempq_removed,
|
||||||
gui_queue_cleared,
|
gui_queue_cleared,
|
||||||
tempq_save,
|
tempq_save,
|
||||||
|
|
|
@ -36,6 +36,9 @@ struct queue_ops {
|
||||||
/* Called to tell a higher layer that a track has been added. */
|
/* Called to tell a higher layer that a track has been added. */
|
||||||
void (*qop_added)(struct queue *, unsigned int);
|
void (*qop_added)(struct queue *, unsigned int);
|
||||||
|
|
||||||
|
/* Called to ask a higher layer if a track can be erased. */
|
||||||
|
bool (*qop_erase)(struct queue *, struct track *);
|
||||||
|
|
||||||
/* Called to tell a higher layer that a track has been removed. */
|
/* Called to tell a higher layer that a track has been removed. */
|
||||||
void (*qop_removed)(struct queue *, unsigned int);
|
void (*qop_removed)(struct queue *, unsigned int);
|
||||||
|
|
||||||
|
@ -45,7 +48,7 @@ struct queue_ops {
|
||||||
/* Called to have a higher layer save the queue. */
|
/* Called to have a higher layer save the queue. */
|
||||||
void (*qop_save)(struct queue *, enum queue_flags);
|
void (*qop_save)(struct queue *, enum queue_flags);
|
||||||
|
|
||||||
/* Called to hell a higher layer that a track has been updated. */
|
/* Called to tell a higher layer that a track has been updated. */
|
||||||
void (*qop_updated)(struct queue *, unsigned int);
|
void (*qop_updated)(struct queue *, unsigned int);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -97,6 +100,12 @@ static inline struct track *queue_at(struct queue *queue, unsigned int index)
|
||||||
/* Called to add a track to the queue. */
|
/* Called to add a track to the queue. */
|
||||||
unsigned int queue_add(struct queue *, struct track *);
|
unsigned int queue_add(struct queue *, struct track *);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Called to erase a track from the queue by index.
|
||||||
|
* This can be prevented if qop_erase() returns "false".
|
||||||
|
*/
|
||||||
|
void queue_erase(struct queue *, unsigned int);
|
||||||
|
|
||||||
/* Called to remove a track from the queue by index. */
|
/* Called to remove a track from the queue by index. */
|
||||||
void queue_remove(struct queue *, unsigned int);
|
void queue_remove(struct queue *, unsigned int);
|
||||||
|
|
||||||
|
|
|
@ -11,12 +11,15 @@
|
||||||
unsigned int count_init = 0;
|
unsigned int count_init = 0;
|
||||||
unsigned int count_deinit = 0;
|
unsigned int count_deinit = 0;
|
||||||
unsigned int count_added = 0;
|
unsigned int count_added = 0;
|
||||||
|
unsigned int count_erase = 0;
|
||||||
unsigned int count_deleted = 0;
|
unsigned int count_deleted = 0;
|
||||||
unsigned int count_cleared = 0;
|
unsigned int count_cleared = 0;
|
||||||
unsigned int count_flags = 0;
|
unsigned int count_flags = 0;
|
||||||
unsigned int count_sort = 0;
|
unsigned int count_sort = 0;
|
||||||
unsigned int count_updated = 0;
|
unsigned int count_updated = 0;
|
||||||
|
|
||||||
|
bool can_erase = true;
|
||||||
|
|
||||||
|
|
||||||
static void *queue_op_init(struct queue *queue)
|
static void *queue_op_init(struct queue *queue)
|
||||||
{
|
{
|
||||||
|
@ -34,6 +37,12 @@ static void queue_op_added(struct queue *queue, unsigned int pos)
|
||||||
count_added++;
|
count_added++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool queue_op_erase(struct queue *queue, struct track *track)
|
||||||
|
{
|
||||||
|
count_erase++;
|
||||||
|
return can_erase;
|
||||||
|
}
|
||||||
|
|
||||||
static void queue_op_removed(struct queue *queue, unsigned int pos)
|
static void queue_op_removed(struct queue *queue, unsigned int pos)
|
||||||
{
|
{
|
||||||
count_deleted++;
|
count_deleted++;
|
||||||
|
@ -62,6 +71,7 @@ static const struct queue_ops test_ops = {
|
||||||
.qop_init = queue_op_init,
|
.qop_init = queue_op_init,
|
||||||
.qop_deinit = queue_op_deinit,
|
.qop_deinit = queue_op_deinit,
|
||||||
.qop_added = queue_op_added,
|
.qop_added = queue_op_added,
|
||||||
|
.qop_erase = queue_op_erase,
|
||||||
.qop_removed = queue_op_removed,
|
.qop_removed = queue_op_removed,
|
||||||
.qop_cleared = queue_op_cleared,
|
.qop_cleared = queue_op_cleared,
|
||||||
.qop_save = queue_op_save,
|
.qop_save = queue_op_save,
|
||||||
|
@ -213,13 +223,25 @@ static void test_stress(unsigned int N)
|
||||||
test_equal(q.q_length, ex_length);
|
test_equal(q.q_length, ex_length);
|
||||||
test_equal(queue_size(&q), ex_size);
|
test_equal(queue_size(&q), ex_size);
|
||||||
|
|
||||||
/* queue_remove() */
|
/* queue_erase() = false */
|
||||||
|
can_erase = false;
|
||||||
|
for (i = 0; i < ex_size; i += 11) {
|
||||||
|
queue_erase(&q, i);
|
||||||
|
test_loop_equal(q.q_length, ex_length, i);
|
||||||
|
test_loop_equal(queue_size(&q), ex_size, i);
|
||||||
|
} test_loop_passed();
|
||||||
|
|
||||||
|
/* queue_remove() and queue_erase() == true */
|
||||||
|
can_erase = true;
|
||||||
track = track_get(1);
|
track = track_get(1);
|
||||||
ex_length -= track->tr_length * (N / 13);
|
ex_length -= track->tr_length * (N / 13);
|
||||||
ex_size -= (N / 13);
|
ex_size -= (N / 13);
|
||||||
for (i = 0; i < ex_size; i += 11) {
|
for (i = 0; i < ex_size; i += 11) {
|
||||||
test_loop_equal((void *)queue_at(&q, i), (void *)track, i);
|
test_loop_equal((void *)queue_at(&q, i), (void *)track, i);
|
||||||
queue_remove(&q, i);
|
if (i % 2 == 0)
|
||||||
|
queue_remove(&q, i);
|
||||||
|
else
|
||||||
|
queue_erase(&q, i);
|
||||||
} test_loop_passed();
|
} test_loop_passed();
|
||||||
test_equal(q.q_length, ex_length);
|
test_equal(q.q_length, ex_length);
|
||||||
test_equal(queue_size(&q), ex_size);
|
test_equal(queue_size(&q), ex_size);
|
||||||
|
|
Loading…
Reference in New Issue