00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef QUEUE_H
00021 #define QUEUE_H
00022
00023 #include <glib.h>
00024
00025 #include <assert.h>
00026 #include <stdbool.h>
00027 #include <stdint.h>
00028
00029 enum {
00034 QUEUE_HASH_MULT = 4,
00035 };
00036
00041 struct queue_item {
00042 struct song *song;
00043
00045 unsigned id;
00046
00048 uint32_t version;
00049 };
00050
00061 struct queue {
00063 unsigned max_length;
00064
00066 unsigned length;
00067
00069 uint32_t version;
00070
00072 struct queue_item *items;
00073
00075 unsigned *order;
00076
00078 int *idToPosition;
00079
00082 bool repeat;
00083
00085 bool single;
00086
00088 bool consume;
00089
00091 bool random;
00092
00094 GRand *rand;
00095 };
00096
00097 static inline unsigned
00098 queue_length(const struct queue *queue)
00099 {
00100 assert(queue->length <= queue->max_length);
00101
00102 return queue->length;
00103 }
00104
00108 static inline bool
00109 queue_is_empty(const struct queue *queue)
00110 {
00111 return queue->length == 0;
00112 }
00113
00117 static inline bool
00118 queue_is_full(const struct queue *queue)
00119 {
00120 assert(queue->length <= queue->max_length);
00121
00122 return queue->length >= queue->max_length;
00123 }
00124
00128 static inline bool
00129 queue_valid_position(const struct queue *queue, unsigned position)
00130 {
00131 return position < queue->length;
00132 }
00133
00137 static inline bool
00138 queue_valid_order(const struct queue *queue, unsigned order)
00139 {
00140 return order < queue->length;
00141 }
00142
00143 static inline int
00144 queue_id_to_position(const struct queue *queue, unsigned id)
00145 {
00146 if (id >= queue->max_length * QUEUE_HASH_MULT)
00147 return -1;
00148
00149 assert(queue->idToPosition[id] >= -1);
00150 assert(queue->idToPosition[id] < (int)queue->length);
00151
00152 return queue->idToPosition[id];
00153 }
00154
00155 static inline int
00156 queue_position_to_id(const struct queue *queue, unsigned position)
00157 {
00158 assert(position < queue->length);
00159
00160 return queue->items[position].id;
00161 }
00162
00163 static inline unsigned
00164 queue_order_to_position(const struct queue *queue, unsigned order)
00165 {
00166 assert(order < queue->length);
00167
00168 return queue->order[order];
00169 }
00170
00171 static inline unsigned
00172 queue_position_to_order(const struct queue *queue, unsigned position)
00173 {
00174 assert(position < queue->length);
00175
00176 for (unsigned i = 0;; ++i) {
00177 assert(i < queue->length);
00178
00179 if (queue->order[i] == position)
00180 return i;
00181 }
00182 }
00183
00187 static inline struct song *
00188 queue_get(const struct queue *queue, unsigned position)
00189 {
00190 assert(position < queue->length);
00191
00192 return queue->items[position].song;
00193 }
00194
00198 static inline struct song *
00199 queue_get_order(const struct queue *queue, unsigned order)
00200 {
00201 return queue_get(queue, queue_order_to_position(queue, order));
00202 }
00203
00208 static inline bool
00209 queue_song_newer(const struct queue *queue, unsigned position,
00210 uint32_t version)
00211 {
00212 assert(position < queue->length);
00213
00214 return version > queue->version ||
00215 queue->items[position].version >= version ||
00216 queue->items[position].version == 0;
00217 }
00218
00222 void
00223 queue_init(struct queue *queue, unsigned max_length);
00224
00229 void
00230 queue_finish(struct queue *queue);
00231
00238 int
00239 queue_next_order(const struct queue *queue, unsigned order);
00240
00245 void
00246 queue_increment_version(struct queue *queue);
00247
00252 void
00253 queue_modify(struct queue *queue, unsigned order);
00254
00258 void
00259 queue_modify_all(struct queue *queue);
00260
00268 unsigned
00269 queue_append(struct queue *queue, struct song *song);
00270
00274 void
00275 queue_swap(struct queue *queue, unsigned position1, unsigned position2);
00276
00280 static inline void
00281 queue_swap_order(struct queue *queue, unsigned order1, unsigned order2)
00282 {
00283 unsigned tmp = queue->order[order1];
00284 queue->order[order1] = queue->order[order2];
00285 queue->order[order2] = tmp;
00286 }
00287
00291 void
00292 queue_move(struct queue *queue, unsigned from, unsigned to);
00293
00297 void
00298 queue_move_range(struct queue *queue, unsigned start, unsigned end, unsigned to);
00299
00303 void
00304 queue_delete(struct queue *queue, unsigned position);
00305
00309 void
00310 queue_clear(struct queue *queue);
00311
00315 static inline void
00316 queue_restore_order(struct queue *queue)
00317 {
00318 for (unsigned i = 0; i < queue->length; ++i)
00319 queue->order[i] = i;
00320 }
00321
00326 void
00327 queue_shuffle_order(struct queue *queue);
00328
00334 void
00335 queue_shuffle_order_last(struct queue *queue, unsigned start, unsigned end);
00336
00341 void
00342 queue_shuffle_range(struct queue *queue, unsigned start, unsigned end);
00343
00344 #endif