MPD 0.17~git
src/queue.h
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2003-2011 The Music Player Daemon Project
00003  * http://www.musicpd.org
00004  *
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License as published by
00007  * the Free Software Foundation; either version 2 of the License, or
00008  * (at your option) any later version.
00009  *
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License along
00016  * with this program; if not, write to the Free Software Foundation, Inc.,
00017  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
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 
00284 unsigned
00285 queue_append(struct queue *queue, struct song *song);
00286 
00290 void
00291 queue_swap(struct queue *queue, unsigned position1, unsigned position2);
00292 
00296 static inline void
00297 queue_swap_order(struct queue *queue, unsigned order1, unsigned order2)
00298 {
00299         unsigned tmp = queue->order[order1];
00300         queue->order[order1] = queue->order[order2];
00301         queue->order[order2] = tmp;
00302 }
00303 
00307 void
00308 queue_move(struct queue *queue, unsigned from, unsigned to);
00309 
00313 void
00314 queue_move_range(struct queue *queue, unsigned start, unsigned end, unsigned to);
00315 
00319 void
00320 queue_delete(struct queue *queue, unsigned position);
00321 
00325 void
00326 queue_clear(struct queue *queue);
00327 
00331 static inline void
00332 queue_restore_order(struct queue *queue)
00333 {
00334         for (unsigned i = 0; i < queue->length; ++i)
00335                 queue->order[i] = i;
00336 }
00337 
00342 void
00343 queue_shuffle_order_range_with_priority(struct queue *queue,
00344                                         unsigned start, unsigned end);
00345 
00350 void
00351 queue_shuffle_order(struct queue *queue);
00352 
00358 void
00359 queue_shuffle_order_last(struct queue *queue, unsigned start, unsigned end);
00360 
00365 void
00366 queue_shuffle_range(struct queue *queue, unsigned start, unsigned end);
00367 
00368 bool
00369 queue_set_priority(struct queue *queue, unsigned position,
00370                    uint8_t priority, int after_order);
00371 
00372 bool
00373 queue_set_priority_range(struct queue *queue,
00374                          unsigned start_position, unsigned end_position,
00375                          uint8_t priority, int after_order);
00376 
00377 #endif