/* * Copyright 2013 (c) Anna Schumaker. * * Queues are lists of tracks that the user has requested to play next. * Users of queues are expected to implement their own save and load functions, * and to provide a filled out queue_ops structure during initialization. */ #ifndef OCARINA_CORE_QUEUE_H #define OCARINA_CORE_QUEUE_H #include #include struct queue; struct queue_ops { /* Called to tell a higher layer that a queue has been initialized. */ void *(*qop_init)(struct queue *, void *); /* Called to tell a higher layer that a queue is deinitializing. */ void (*qop_deinit)(struct queue *); /* Called to tell a higher layer that a track has been added. */ void (*qop_added)(struct queue *, unsigned int); /* Called to tell a higher layer that the queue has been cleared. */ void (*qop_cleared)(struct queue *, unsigned int); }; struct queue_iter { GList *it_iter; /* The current link in the GQueue. */ guint it_pos; /* The current index into the queue. */ }; struct queue { unsigned int q_length; /* The queue's total runtime (in seconds). */ GQueue q_tracks; /* The queue's list of tracks. */ GSList *q_sort; /* The queue's sort order. */ void *q_private; /* The queue's private data. */ struct queue_iter q_cur; /* The queue's last-played position. */ const struct queue_ops *q_ops; /* The queue's operations vector. */ }; /* Called to initialize a queue iterator. */ static inline void queue_iter_init(struct queue *queue, struct queue_iter *it) { it->it_iter = g_queue_peek_head_link(&queue->q_tracks); it->it_pos = g_queue_link_index(&queue->q_tracks, it->it_iter); } /* Called to advance a queue iterator by one step. */ static inline void queue_iter_next(struct queue_iter *it) { it->it_iter = g_list_next(it->it_iter); it->it_pos++; } /* Called to rewind a queue iterator by one step. */ static inline void queue_iter_prev(struct queue_iter *it) { it->it_iter = g_list_previous(it->it_iter); it->it_pos--; } /* Called to set a queue iterator to a specific position. */ static inline void queue_iter_set(struct queue *queue, struct queue_iter *it, unsigned int pos) { it->it_iter = g_queue_peek_nth_link(&queue->q_tracks, pos); it->it_pos = pos; } /* Called to access the value of a queue iterator. */ static inline struct track *queue_iter_val(struct queue_iter *it) { return (it->it_iter) ? it->it_iter->data : NULL; } #define queue_for_each(queue, it) \ for (queue_iter_init(queue, it); (it)->it_iter; queue_iter_next(it)) /* Called to initialize a queue. */ void queue_init(struct queue *, const struct queue_ops *, void *); /* Called to deinitialize a queue. */ void queue_deinit(struct queue *); /* Called to find the size of the queue. */ static inline unsigned int queue_size(struct queue *queue) { return g_queue_get_length(&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 (struct track *)g_queue_peek_nth(&queue->q_tracks, index); } /* Called to add a track to the queue. */ unsigned int queue_add(struct queue *, struct track *); /* Called to add a track to the front of the queue. */ unsigned int queue_add_front(struct queue *, struct track *); /* Called to remove all tracks from the queue. */ void queue_clear(struct queue *); /* Called to check if a queue has a track. */ bool queue_has(struct queue *, struct track *); #endif /* OCARINA_CORE_QUEUE_H */