queue: merged songs, songMod, positionToId into struct queue_item
Move everything which belongs together into one common struct. This simplifies the implementation of several queue operations.
This commit is contained in:
parent
f78cddb407
commit
aa9ffcd04d
78
src/queue.c
78
src/queue.c
@ -58,7 +58,7 @@ queue_increment_version(struct queue *queue)
|
|||||||
|
|
||||||
if (queue->version >= max) {
|
if (queue->version >= max) {
|
||||||
for (unsigned i = 0; i < queue->length; i++)
|
for (unsigned i = 0; i < queue->length; i++)
|
||||||
queue->songMod[i] = 0;
|
queue->items[i].version = 0;
|
||||||
|
|
||||||
queue->version = 1;
|
queue->version = 1;
|
||||||
}
|
}
|
||||||
@ -72,7 +72,7 @@ queue_modify(struct queue *queue, unsigned order)
|
|||||||
assert(order < queue->length);
|
assert(order < queue->length);
|
||||||
|
|
||||||
position = queue->order[order];
|
position = queue->order[order];
|
||||||
queue->songMod[position] = queue->version;
|
queue->items[position].version = queue->version;
|
||||||
|
|
||||||
queue_increment_version(queue);
|
queue_increment_version(queue);
|
||||||
}
|
}
|
||||||
@ -81,7 +81,7 @@ void
|
|||||||
queue_modify_all(struct queue *queue)
|
queue_modify_all(struct queue *queue)
|
||||||
{
|
{
|
||||||
for (unsigned i = 0; i < queue->length; i++)
|
for (unsigned i = 0; i < queue->length; i++)
|
||||||
queue->songMod[i] = queue->version;
|
queue->items[i].version = queue->version;
|
||||||
|
|
||||||
queue_increment_version(queue);
|
queue_increment_version(queue);
|
||||||
}
|
}
|
||||||
@ -93,12 +93,14 @@ queue_append(struct queue *queue, struct song *song)
|
|||||||
|
|
||||||
assert(!queue_is_full(queue));
|
assert(!queue_is_full(queue));
|
||||||
|
|
||||||
queue->songs[queue->length] = song;
|
queue->items[queue->length] = (struct queue_item){
|
||||||
queue->songMod[queue->length] = queue->version;
|
.song = song,
|
||||||
|
.id = id,
|
||||||
|
.version = queue->version,
|
||||||
|
};
|
||||||
|
|
||||||
queue->order[queue->length] = queue->length;
|
queue->order[queue->length] = queue->length;
|
||||||
queue->positionToId[queue->length] = id;
|
queue->idToPosition[id] = queue->length;
|
||||||
queue->idToPosition[queue->positionToId[queue->length]] =
|
|
||||||
queue->length;
|
|
||||||
|
|
||||||
++queue->length;
|
++queue->length;
|
||||||
|
|
||||||
@ -108,43 +110,34 @@ queue_append(struct queue *queue, struct song *song)
|
|||||||
void
|
void
|
||||||
queue_swap(struct queue *queue, unsigned position1, unsigned position2)
|
queue_swap(struct queue *queue, unsigned position1, unsigned position2)
|
||||||
{
|
{
|
||||||
struct song *sTemp;
|
struct queue_item tmp;
|
||||||
unsigned iTemp;
|
unsigned id1 = queue->items[position1].id;
|
||||||
|
unsigned id2 = queue->items[position2].id;
|
||||||
|
|
||||||
sTemp = queue->songs[position1];
|
tmp = queue->items[position1];
|
||||||
queue->songs[position1] = queue->songs[position2];
|
queue->items[position1] = queue->items[position2];
|
||||||
queue->songs[position2] = sTemp;
|
queue->items[position2] = tmp;
|
||||||
|
|
||||||
queue->songMod[position1] = queue->version;
|
queue->items[position1].version = queue->version;
|
||||||
queue->songMod[position2] = queue->version;
|
queue->items[position2].version = queue->version;
|
||||||
|
|
||||||
queue->idToPosition[queue->positionToId[position1]] = position2;
|
queue->idToPosition[id1] = position2;
|
||||||
queue->idToPosition[queue->positionToId[position2]] = position1;
|
queue->idToPosition[id2] = position1;
|
||||||
|
|
||||||
iTemp = queue->positionToId[position1];
|
|
||||||
queue->positionToId[position1] = queue->positionToId[position2];
|
|
||||||
queue->positionToId[position2] = iTemp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
queue_move_song_to(struct queue *queue, unsigned from, unsigned to)
|
queue_move_song_to(struct queue *queue, unsigned from, unsigned to)
|
||||||
{
|
{
|
||||||
unsigned from_id = queue->positionToId[from];
|
unsigned from_id = queue->items[from].id;
|
||||||
|
|
||||||
|
queue->items[to] = queue->items[from];
|
||||||
queue->idToPosition[from_id] = to;
|
queue->idToPosition[from_id] = to;
|
||||||
queue->positionToId[to] = from_id;
|
|
||||||
queue->songs[to] = queue->songs[from];
|
|
||||||
queue->songMod[to] = queue->version;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
queue_move(struct queue *queue, unsigned from, unsigned to)
|
queue_move(struct queue *queue, unsigned from, unsigned to)
|
||||||
{
|
{
|
||||||
struct song *song;
|
struct queue_item item = queue->items[from];
|
||||||
unsigned id;
|
|
||||||
|
|
||||||
song = queue_get(queue, from);
|
|
||||||
id = queue_position_to_id(queue, from);
|
|
||||||
|
|
||||||
/* move songs to one less in from->to */
|
/* move songs to one less in from->to */
|
||||||
|
|
||||||
@ -158,10 +151,9 @@ queue_move(struct queue *queue, unsigned from, unsigned to)
|
|||||||
|
|
||||||
/* put song at _to_ */
|
/* put song at _to_ */
|
||||||
|
|
||||||
queue->idToPosition[id] = to;
|
queue->idToPosition[item.id] = to;
|
||||||
queue->positionToId[to] = id;
|
queue->items[to] = item;
|
||||||
queue->songs[to] = song;
|
queue->items[to].version = queue->version;
|
||||||
queue->songMod[to] = queue->version;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -206,10 +198,12 @@ void
|
|||||||
queue_clear(struct queue *queue)
|
queue_clear(struct queue *queue)
|
||||||
{
|
{
|
||||||
for (unsigned i = 0; i < queue->length; i++) {
|
for (unsigned i = 0; i < queue->length; i++) {
|
||||||
if (!song_in_database(queue->songs[i]))
|
struct queue_item *item = &queue->items[i];
|
||||||
song_free(queue->songs[i]);
|
|
||||||
|
|
||||||
queue->idToPosition[queue->positionToId[i]] = -1;
|
if (!song_in_database(item->song))
|
||||||
|
song_free(item->song);
|
||||||
|
|
||||||
|
queue->idToPosition[item->id] = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
queue->length = 0;
|
queue->length = 0;
|
||||||
@ -224,15 +218,11 @@ queue_init(struct queue *queue, unsigned max_length)
|
|||||||
queue->repeat = false;
|
queue->repeat = false;
|
||||||
queue->random = false;
|
queue->random = false;
|
||||||
|
|
||||||
queue->songs = g_malloc(sizeof(queue->songs[0]) * max_length);
|
queue->items = g_new(struct queue_item, max_length);
|
||||||
queue->songMod = g_malloc(sizeof(queue->songMod[0]) *
|
|
||||||
max_length);
|
|
||||||
queue->order = g_malloc(sizeof(queue->order[0]) *
|
queue->order = g_malloc(sizeof(queue->order[0]) *
|
||||||
max_length);
|
max_length);
|
||||||
queue->idToPosition = g_malloc(sizeof(queue->idToPosition[0]) *
|
queue->idToPosition = g_malloc(sizeof(queue->idToPosition[0]) *
|
||||||
max_length * QUEUE_HASH_MULT);
|
max_length * QUEUE_HASH_MULT);
|
||||||
queue->positionToId = g_malloc(sizeof(queue->positionToId[0]) *
|
|
||||||
max_length);
|
|
||||||
|
|
||||||
for (unsigned i = 0; i < max_length * QUEUE_HASH_MULT; ++i)
|
for (unsigned i = 0; i < max_length * QUEUE_HASH_MULT; ++i)
|
||||||
queue->idToPosition[i] = -1;
|
queue->idToPosition[i] = -1;
|
||||||
@ -245,11 +235,9 @@ queue_finish(struct queue *queue)
|
|||||||
{
|
{
|
||||||
queue_clear(queue);
|
queue_clear(queue);
|
||||||
|
|
||||||
g_free(queue->songs);
|
g_free(queue->items);
|
||||||
g_free(queue->songMod);
|
|
||||||
g_free(queue->order);
|
g_free(queue->order);
|
||||||
g_free(queue->idToPosition);
|
g_free(queue->idToPosition);
|
||||||
g_free(queue->positionToId);
|
|
||||||
|
|
||||||
g_rand_free(queue->rand);
|
g_rand_free(queue->rand);
|
||||||
}
|
}
|
||||||
|
30
src/queue.h
30
src/queue.h
@ -33,6 +33,20 @@ enum {
|
|||||||
QUEUE_HASH_MULT = 4,
|
QUEUE_HASH_MULT = 4,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* One element of the queue: basically a song plus some queue specific
|
||||||
|
* information attached.
|
||||||
|
*/
|
||||||
|
struct queue_item {
|
||||||
|
struct song *song;
|
||||||
|
|
||||||
|
/** the unique id of this item in the queue */
|
||||||
|
unsigned id;
|
||||||
|
|
||||||
|
/** when was this item last changed? */
|
||||||
|
uint32_t version;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A queue of songs. This is the backend of the playlist: it contains
|
* A queue of songs. This is the backend of the playlist: it contains
|
||||||
* an ordered list of songs.
|
* an ordered list of songs.
|
||||||
@ -54,17 +68,11 @@ struct queue {
|
|||||||
uint32_t version;
|
uint32_t version;
|
||||||
|
|
||||||
/** all songs in "position" order */
|
/** all songs in "position" order */
|
||||||
struct song **songs;
|
struct queue_item *items;
|
||||||
|
|
||||||
/** holds version a song was modified on */
|
|
||||||
uint32_t *songMod;
|
|
||||||
|
|
||||||
/** map order numbers to positions */
|
/** map order numbers to positions */
|
||||||
unsigned *order;
|
unsigned *order;
|
||||||
|
|
||||||
/** map positions to song ids */
|
|
||||||
unsigned *positionToId;
|
|
||||||
|
|
||||||
/** map song ids to posiitons */
|
/** map song ids to posiitons */
|
||||||
int *idToPosition;
|
int *idToPosition;
|
||||||
|
|
||||||
@ -142,7 +150,7 @@ queue_position_to_id(const struct queue *queue, unsigned position)
|
|||||||
{
|
{
|
||||||
assert(position < queue->length);
|
assert(position < queue->length);
|
||||||
|
|
||||||
return queue->positionToId[position];
|
return queue->items[position].id;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline unsigned
|
static inline unsigned
|
||||||
@ -174,7 +182,7 @@ queue_get(const struct queue *queue, unsigned position)
|
|||||||
{
|
{
|
||||||
assert(position < queue->length);
|
assert(position < queue->length);
|
||||||
|
|
||||||
return queue->songs[position];
|
return queue->items[position].song;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -197,8 +205,8 @@ queue_song_newer(const struct queue *queue, unsigned position,
|
|||||||
assert(position < queue->length);
|
assert(position < queue->length);
|
||||||
|
|
||||||
return version > queue->version ||
|
return version > queue->version ||
|
||||||
queue->songMod[position] >= version ||
|
queue->items[position].version >= version ||
|
||||||
queue->songMod[position] == 0;
|
queue->items[position].version == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user