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
00055 uint8_t priority;
00056 };
00057
00068 struct queue {
00070 unsigned max_length;
00071
00073 unsigned length;
00074
00076 uint32_t version;
00077
00079 struct queue_item *items;
00080
00082 unsigned *order;
00083
00085 int *id_to_position;
00086
00089 bool repeat;
00090
00092 bool single;
00093
00095 bool consume;
00096
00098 bool random;
00099
00101 GRand *rand;
00102 };
00103
00104 static inline unsigned
00105 queue_length(const struct queue *queue)
00106 {
00107 assert(queue->length <= queue->max_length);
00108
00109 return queue->length;
00110 }
00111
00115 static inline bool
00116 queue_is_empty(const struct queue *queue)
00117 {
00118 return queue->length == 0;
00119 }
00120
00124 static inline bool
00125 queue_is_full(const struct queue *queue)
00126 {
00127 assert(queue->length <= queue->max_length);
00128
00129 return queue->length >= queue->max_length;
00130 }
00131
00135 static inline bool
00136 queue_valid_position(const struct queue *queue, unsigned position)
00137 {
00138 return position < queue->length;
00139 }
00140
00144 static inline bool
00145 queue_valid_order(const struct queue *queue, unsigned order)
00146 {
00147 return order < queue->length;
00148 }
00149
00150 static inline int
00151 queue_id_to_position(const struct queue *queue, unsigned id)
00152 {
00153 if (id >= queue->max_length * QUEUE_HASH_MULT)
00154 return -1;
00155
00156 assert(queue->id_to_position[id] >= -1);
00157 assert(queue->id_to_position[id] < (int)queue->length);
00158
00159 return queue->id_to_position[id];
00160 }
00161
00162 static inline int
00163 queue_position_to_id(const struct queue *queue, unsigned position)
00164 {
00165 assert(position < queue->length);
00166
00167 return queue->items[position].id;
00168 }
00169
00170 static inline unsigned
00171 queue_order_to_position(const struct queue *queue, unsigned order)
00172 {
00173 assert(order < queue->length);
00174
00175 return queue->order[order];
00176 }
00177
00178 static inline unsigned
00179 queue_position_to_order(const struct queue *queue, unsigned position)
00180 {
00181 assert(position < queue->length);
00182
00183 for (unsigned i = 0;; ++i) {
00184 assert(i < queue->length);
00185
00186 if (queue->order[i] == position)
00187 return i;
00188 }
00189 }
00190
00191 G_GNUC_PURE
00192 static inline uint8_t
00193 queue_get_priority_at_position(const struct queue *queue, unsigned position)
00194 {
00195 assert(position < queue->length);
00196
00197 return queue->items[position].priority;
00198 }
00199
00203 static inline struct song *
00204 queue_get(const struct queue *queue, unsigned position)
00205 {
00206 assert(position < queue->length);
00207
00208 return queue->items[position].song;
00209 }
00210
00214 static inline struct song *
00215 queue_get_order(const struct queue *queue, unsigned order)
00216 {
00217 return queue_get(queue, queue_order_to_position(queue, order));
00218 }
00219
00224 static inline bool
00225 queue_song_newer(const struct queue *queue, unsigned position,
00226 uint32_t version)
00227 {
00228 assert(position < queue->length);
00229
00230 return version > queue->version ||
00231 queue->items[position].version >= version ||
00232 queue->items[position].version == 0;
00233 }
00234
00238 void
00239 queue_init(struct queue *queue, unsigned max_length);
00240
00245 void
00246 queue_finish(struct queue *queue);
00247
00254 int
00255 queue_next_order(const struct queue *queue, unsigned order);
00256
00261 void
00262 queue_increment_version(struct queue *queue);
00263
00268 void
00269 queue_modify(struct queue *queue, unsigned order);
00270
00274 void
00275 queue_modify_all(struct queue *queue);
00276
00286 unsigned
00287 queue_append(struct queue *queue, struct song *song, uint8_t priority);
00288
00292 void
00293 queue_swap(struct queue *queue, unsigned position1, unsigned position2);
00294
00298 static inline void
00299 queue_swap_order(struct queue *queue, unsigned order1, unsigned order2)
00300 {
00301 unsigned tmp = queue->order[order1];
00302 queue->order[order1] = queue->order[order2];
00303 queue->order[order2] = tmp;
00304 }
00305
00309 void
00310 queue_move(struct queue *queue, unsigned from, unsigned to);
00311
00315 void
00316 queue_move_range(struct queue *queue, unsigned start, unsigned end, unsigned to);
00317
00321 void
00322 queue_delete(struct queue *queue, unsigned position);
00323
00327 void
00328 queue_clear(struct queue *queue);
00329
00333 static inline void
00334 queue_restore_order(struct queue *queue)
00335 {
00336 for (unsigned i = 0; i < queue->length; ++i)
00337 queue->order[i] = i;
00338 }
00339
00344 void
00345 queue_shuffle_order_range_with_priority(struct queue *queue,
00346 unsigned start, unsigned end);
00347
00352 void
00353 queue_shuffle_order(struct queue *queue);
00354
00360 void
00361 queue_shuffle_order_last(struct queue *queue, unsigned start, unsigned end);
00362
00367 void
00368 queue_shuffle_range(struct queue *queue, unsigned start, unsigned end);
00369
00370 bool
00371 queue_set_priority(struct queue *queue, unsigned position,
00372 uint8_t priority, int after_order);
00373
00374 bool
00375 queue_set_priority_range(struct queue *queue,
00376 unsigned start_position, unsigned end_position,
00377 uint8_t priority, int after_order);
00378
00379 #endif