/* * 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; enum queue_flags { Q_UNUSED_0 = (1 << 0), /* Removed: 6.5.4 */ Q_RANDOM = (1 << 1), /* Queue will pick songs randomly. */ Q_REPEAT = (1 << 2), /* Queue will not remove songs when picked. */ Q_UNUSED_3 = (1 << 3), /* Removed: 6.5.4 */ Q_UNUSED_4 = (1 << 4), /* Removed: 6.5.4 */ Q_UNUSED_5 = (1 << 5), /* Removed: 6.5.4 */ Q_UNUSED_6 = (1 << 6), /* Removed: 6.5.4 */ }; #define Q_UNUSED_MASK (~(Q_UNUSED_0 | Q_UNUSED_3 | Q_UNUSED_4 | Q_UNUSED_5 | Q_UNUSED_6)) 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 a track has been removed. */ void (*qop_removed)(struct queue *, unsigned int); /* Called to tell a higher layer that the queue has been cleared. */ void (*qop_cleared)(struct queue *, unsigned int); /* Called to tell a higher layer that a track has been updated. */ void (*qop_updated)(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_flags; /* The queue's set of flags. */ 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 *, unsigned int, const struct queue_ops *, void *); /* Called to deinitialize a queue. */ void queue_deinit(struct queue *); /* Called to save queue flags, sort order, and (optionally) iterator pos. */ void queue_save_flags(struct queue *, struct file *, bool); /* Called to save the list of queued tracks. */ void queue_save_tracks(struct queue *, struct file *); /* Called to load flags, sort order, and (optionally) iterator pos from file. */ void queue_load_flags(struct queue *, struct file *, bool); /* Called to load queued tracks from file. */ void queue_load_tracks(struct queue *, struct file *); /* Called to set a queue flag. */ void queue_set_flag(struct queue *, enum queue_flags); /* Called to clear a queue flag. */ void queue_unset_flag(struct queue *, enum queue_flags); /* Called to check if the queue has a specific flag set. */ static inline bool queue_has_flag(struct queue *queue, enum queue_flags flag) { return (queue->q_flags & flag) == (unsigned int)flag; } /* 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 a track from the queue by index. */ void queue_remove(struct queue *, unsigned int); /* Called to remove all instances of the track from the queue. */ unsigned int queue_remove_all(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 *); /* Called to tell the queue that a track has been updated. */ void queue_updated(struct queue *, struct track *); /* Called to tell the queue that a specific index has been selected. */ struct track *queue_selected(struct queue *, unsigned int); /* Called to pick the next track from the queue. */ struct track *queue_next(struct queue *); /* Called to sort the queue without changing sort order. */ void queue_resort(struct queue *); /* Called to change the sort order and resort the queue. */ void queue_sort(struct queue *, enum compare_t, bool); #endif /* OCARINA_CORE_QUEUE_H */