core/queue: Replace vector with struct _queue

Signed-off-by: Anna Schumaker <Anna@OcarinaProject.net>
This commit is contained in:
Anna Schumaker 2015-12-01 11:17:25 -05:00
parent 0a331a44f5
commit 8fb64015b4
3 changed files with 51 additions and 80 deletions

View File

@ -25,20 +25,18 @@ TempQueue :: TempQueue(bool random, struct queue_ops *ops)
void TempQueue :: write(file &file)
{
file_writef(&file, "%u %zu", q_flags, q_tracks.size());
for (unsigned int i = 0; i < q_tracks.size(); i++)
file_writef(&file, " %u", q_tracks[i]->tr_dbe.dbe_index);
file_writef(&file, "%u %zu", q_flags, queue_size(this));
for (unsigned int i = 0; i < queue_size(this); i++)
file_writef(&file, " %u", queue_at(this, i)->tr_dbe.dbe_index);
}
void TempQueue :: read(file &file)
{
unsigned int n, id;
file_readf(&file, "%u %u", &q_flags, &n);
q_tracks.resize(n);
for (unsigned int i = 0; i < n; i++) {
file_readf(&file, "%u", &id);
q_tracks[i] = track_get(id);
q_length += q_tracks[i]->tr_length;
queue_add(this, track_get(id));
}
}

View File

@ -11,24 +11,25 @@ extern "C" {
#include <sstream>
static bool track_less_than(struct track *lhs, struct track *rhs,
std::vector<struct sort_info> &order)
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;
for (unsigned int i = 0; i < order.size(); i++) {
if (order[i].ascending == true)
res = track_compare(lhs, rhs, order[i].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);
else
res = track_compare(rhs, lhs, order[i].field);
res = track_compare(rhs, lhs, queue->q_sort[i].field);
if (res == 0)
continue;
break;
}
return res < 0;
return res;
}
static inline unsigned int __queue_added(struct queue *queue,
struct track *track,
unsigned int pos)
@ -39,10 +40,11 @@ static inline unsigned int __queue_added(struct queue *queue,
return pos;
}
static inline void __queue_removed(struct queue *queue,
struct track *track,
unsigned int pos)
static inline void __queue_remove(struct queue *queue, struct _q_iter *it)
{
unsigned int pos = it->it_pos;
struct track *track = (struct track *)_q_remove_it(&queue->q_tracks, it);
queue->q_length -= track->tr_length;
if (queue->q_cur == pos)
queue->q_cur--;
@ -62,34 +64,6 @@ static inline void __queue_save(struct queue *queue, enum queue_flags flag)
queue->q_ops->qop_save(queue, flag);
}
static unsigned int __queue_find_sorted_id(struct queue *queue, struct track *rhs)
{
struct track *lhs;
unsigned int mid, begin = 0, end = queue_size(queue) - 1;
if (queue_size(queue) == 0)
return 0;
while (end > begin) {
mid = begin + ((end - begin) / 2);
lhs = queue->q_tracks[mid];
if (track_less_than(lhs, rhs, queue->q_sort))
begin = mid + 1;
else {
if (mid == begin)
return begin;
else
end = mid - 1;
}
}
lhs = queue->q_tracks[begin];
if (track_less_than(lhs, rhs, queue->q_sort))
return begin + 1;
return begin;
}
void queue_init(struct queue *queue, unsigned int flags,
const struct queue_ops *ops)
{
@ -97,6 +71,8 @@ void queue_init(struct queue *queue, unsigned int flags,
queue->q_flags = flags;
queue->q_length = 0;
queue->q_ops = ops;
_q_init(&queue->q_tracks);
}
void queue_set_flag(struct queue *queue, enum queue_flags flag)
@ -113,38 +89,46 @@ void queue_unset_flag(struct queue *queue, enum queue_flags flag)
unsigned int queue_add(struct queue *queue, struct track *track)
{
unsigned int pos = queue_size(queue);
unsigned int pos;
if (queue_has_flag(queue, Q_ADD_FRONT))
pos = 0;
pos = _q_add_head(&queue->q_tracks, track);
else if (queue->q_sort.size() > 0)
pos = __queue_find_sorted_id(queue, track);
pos = _q_add_sorted(&queue->q_tracks, track, track_less_than, queue);
else
pos = _q_add_tail(&queue->q_tracks, track);
queue->q_tracks.insert(queue->q_tracks.begin() + pos, track);
return __queue_added(queue, track, pos);
}
void queue_remove(struct queue *queue, unsigned int index)
{
struct track *track = queue->q_tracks[index];
queue->q_tracks.erase(queue->q_tracks.begin() + index);
__queue_removed(queue, track, index);
struct _q_iter it;
_q_iter_set(&queue->q_tracks, &it, index);
__queue_remove(queue, &it);
}
void queue_remove_all(struct queue *queue, struct track *track)
{
for (unsigned int i = 0; i < queue->q_tracks.size(); i++) {
while (i < queue->q_tracks.size() &&
queue->q_tracks[i] == track)
queue_remove(queue, i);
struct _q_iter it;
while (queue_at(queue, 0) == track)
queue_remove(queue, 0);
_q_for_each(&queue->q_tracks, &it) {
if (_q_iter_val(&it) == track)
__queue_remove(queue, &it);
}
}
void queue_updated(struct queue *queue, struct track *track)
{
for (unsigned int i = 0; i < queue_size(queue); i++) {
if (queue->q_tracks[i] == track)
__queue_updated(queue, i);
struct _q_iter it;
_q_for_each(&queue->q_tracks, &it) {
if (_q_iter_val(&it) == track)
__queue_updated(queue, it.it_pos);
}
}
@ -172,21 +156,11 @@ struct track *queue_next(struct queue *queue)
queue->q_cur++;
queue->q_cur %= size;
res = queue->q_tracks[queue->q_cur];
res = queue_at(queue, queue->q_cur);
queue_selected(queue, queue->q_cur);
return res;
}
class SortTracks {
public:
std::vector<struct sort_info> fields;
SortTracks(std::vector<sort_info> f) : fields(f) {}
bool operator()(struct track *lhs, struct track *rhs)
{
return track_less_than(lhs, rhs, fields);
}
};
void queue_sort(struct queue *queue, enum compare_t field, bool reset)
{
bool found = false;
@ -208,11 +182,9 @@ void queue_sort(struct queue *queue, enum compare_t field, bool reset)
if (!found)
queue->q_sort.push_back(info);
std::stable_sort(queue->q_tracks.begin(),
queue->q_tracks.end(),
SortTracks(queue->q_sort));
_q_sort(&queue->q_tracks, track_less_than, queue);
for (unsigned int i = 0; i < queue->q_tracks.size(); i++)
for (unsigned int i = 0; i < queue_size(queue); i++)
__queue_updated(queue, i);
__queue_save(queue, Q_SAVE_SORT);
}

View File

@ -5,6 +5,7 @@
#define OCARINA_CORE_QUEUE_H
extern "C" {
#include <core/containers/queue.h>
#include <core/file.h>
#include <core/tags/track.h>
}
@ -61,11 +62,11 @@ struct sort_info {
* ... << _flags << _tracks.size() << tracks[N]->index() << ...;
*/
struct queue {
unsigned int q_cur; /* The queue's last-played index. */
unsigned int q_flags; /* The queue's set of flags. */
unsigned int q_length; /* The queue's total runtime (in seconds). */
unsigned int q_cur; /* The queue's last-played index. */
unsigned int q_flags; /* The queue's set of flags. */
unsigned int q_length; /* The queue's total runtime (in seconds). */
struct _queue q_tracks; /* The queue's list of tracks. */
std :: vector <struct track *> q_tracks; /* The queue's list of tracks. */
std :: vector <struct sort_info> q_sort; /* The queue's sort settings. */
const struct queue_ops *q_ops; /* The queue's operations vector. */
@ -91,13 +92,13 @@ static inline bool queue_has_flag(struct queue *queue, enum queue_flags flag)
/* Called to find the size of the queue. */
static inline unsigned int queue_size(struct queue *queue)
{
return queue->q_tracks.size();
return _q_size(&queue->q_tracks);
}
/* Called to access the queued track at a given index. */
static inline struct track *queue_at(struct queue *queue, unsigned int index)
{
return queue->q_tracks[index];
return (struct track *)g_queue_peek_nth(&queue->q_tracks._queue, index);
}