2015-12-02 10:22:11 -05:00
|
|
|
/*
|
2013-12-31 15:44:44 -05:00
|
|
|
* Copyright 2013 (c) Anna Schumaker.
|
2015-12-02 10:22:11 -05:00
|
|
|
*
|
|
|
|
* 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.
|
2013-12-31 15:44:44 -05:00
|
|
|
*/
|
2014-06-21 09:37:47 -04:00
|
|
|
#ifndef OCARINA_CORE_QUEUE_H
|
|
|
|
#define OCARINA_CORE_QUEUE_H
|
2013-12-31 15:44:44 -05:00
|
|
|
|
2014-06-05 10:19:22 -04:00
|
|
|
#include <core/file.h>
|
2014-12-02 08:24:36 -05:00
|
|
|
#include <core/tags/track.h>
|
2014-05-11 19:52:08 -04:00
|
|
|
|
2015-12-02 10:22:11 -05:00
|
|
|
struct queue;
|
2013-12-31 15:44:44 -05:00
|
|
|
|
2014-12-07 09:57:43 -05:00
|
|
|
|
2014-04-01 20:28:19 -04:00
|
|
|
enum queue_flags {
|
2015-11-23 08:36:29 -05:00
|
|
|
Q_ENABLED = (1 << 0), /* Queue is enabled. */
|
|
|
|
Q_RANDOM = (1 << 1), /* Queue will pick songs randomly. */
|
|
|
|
Q_REPEAT = (1 << 2), /* Queue will not remove songs when picked. */
|
|
|
|
Q_NO_SORT = (1 << 3), /* Queue will not be sorted. */
|
|
|
|
Q_SAVE_FLAGS = (1 << 4), /* Queue will be saved when flags change. */
|
|
|
|
Q_SAVE_SORT = (1 << 5), /* Queue will be saved when sorted. */
|
2015-11-25 09:04:10 -05:00
|
|
|
Q_ADD_FRONT = (1 << 6), /* Queue will add new tracks at the front. */
|
2013-12-31 15:44:44 -05:00
|
|
|
};
|
|
|
|
|
2014-10-17 09:42:45 -04:00
|
|
|
|
2015-11-23 08:36:29 -05:00
|
|
|
struct queue_ops {
|
2016-01-12 08:02:28 -05:00
|
|
|
/* Called to tell a higher layer that a queue has been initialized. */
|
2016-05-02 07:52:18 -04:00
|
|
|
void *(*qop_init)(struct queue *, void *);
|
2016-01-13 08:18:03 -05:00
|
|
|
|
|
|
|
/* Called to tell a higher layer that a queue is deinitializing. */
|
|
|
|
void (*qop_deinit)(struct queue *);
|
2016-01-12 08:02:28 -05:00
|
|
|
|
2015-11-29 19:45:39 -05:00
|
|
|
/* Called to tell a higher layer that a track has been added. */
|
|
|
|
void (*qop_added)(struct queue *, unsigned int);
|
|
|
|
|
2016-01-22 08:11:09 -05:00
|
|
|
/* Called to ask a higher layer if a track can be erased. */
|
|
|
|
bool (*qop_erase)(struct queue *, struct track *);
|
|
|
|
|
2015-11-29 20:01:12 -05:00
|
|
|
/* Called to tell a higher layer that a track has been removed. */
|
|
|
|
void (*qop_removed)(struct queue *, unsigned int);
|
|
|
|
|
2016-01-29 10:12:09 -05:00
|
|
|
/* Called to tell a higher layer that the queue has been cleared. */
|
|
|
|
void (*qop_cleared)(struct queue *, unsigned int);
|
|
|
|
|
2015-11-23 08:36:29 -05:00
|
|
|
/* Called to have a higher layer save the queue. */
|
|
|
|
void (*qop_save)(struct queue *, enum queue_flags);
|
2015-11-29 20:10:15 -05:00
|
|
|
|
2016-01-22 08:11:09 -05:00
|
|
|
/* Called to tell a higher layer that a track has been updated. */
|
2015-11-29 20:10:15 -05:00
|
|
|
void (*qop_updated)(struct queue *, unsigned int);
|
2015-11-23 08:36:29 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2016-04-03 09:29:32 -04:00
|
|
|
struct queue_iter {
|
|
|
|
GList *it_iter; /* The current link in the GQueue. */
|
|
|
|
guint it_pos; /* The current index into the queue. */
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-11-16 09:12:15 -05:00
|
|
|
struct queue {
|
2016-01-12 08:02:28 -05:00
|
|
|
unsigned int q_flags; /* The queue's set of flags. */
|
|
|
|
unsigned int q_length; /* The queue's total runtime (in seconds). */
|
2016-04-03 09:52:16 -04:00
|
|
|
GQueue q_tracks; /* The queue's list of tracks. */
|
2016-01-12 08:02:28 -05:00
|
|
|
GSList *q_sort; /* The queue's sort order. */
|
2016-04-03 09:52:16 -04:00
|
|
|
void *q_private; /* The queue's private data. */
|
2013-12-31 15:44:44 -05:00
|
|
|
|
2016-04-03 09:40:01 -04:00
|
|
|
struct queue_iter q_cur; /* The queue's last-played position. */
|
|
|
|
const struct queue_ops *q_ops; /* The queue's operations vector. */
|
2013-12-31 15:44:44 -05:00
|
|
|
};
|
|
|
|
|
2015-11-19 08:08:14 -05:00
|
|
|
|
2016-04-03 09:29:32 -04:00
|
|
|
|
|
|
|
/* Called to initialize a queue iterator. */
|
|
|
|
static inline void queue_iter_init(struct queue *queue, struct queue_iter *it)
|
|
|
|
{
|
2016-04-03 09:52:16 -04:00
|
|
|
it->it_iter = g_queue_peek_head_link(&queue->q_tracks);
|
|
|
|
it->it_pos = g_queue_link_index(&queue->q_tracks, it->it_iter);
|
2016-04-03 09:29:32 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/* 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)
|
|
|
|
{
|
2016-04-03 09:52:16 -04:00
|
|
|
it->it_iter = g_queue_peek_nth_link(&queue->q_tracks, pos);
|
2016-04-03 09:29:32 -04:00
|
|
|
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))
|
|
|
|
|
|
|
|
|
|
|
|
|
2015-11-23 08:36:29 -05:00
|
|
|
/* Called to initialize a queue. */
|
2016-05-02 07:52:18 -04:00
|
|
|
void queue_init(struct queue *, unsigned int, const struct queue_ops *, void *);
|
2015-11-23 08:36:29 -05:00
|
|
|
|
2015-12-07 10:00:19 -05:00
|
|
|
/* Called to deinitialize a queue. */
|
|
|
|
void queue_deinit(struct queue *);
|
|
|
|
|
2015-11-23 08:36:29 -05:00
|
|
|
|
2016-05-01 19:34:52 -04:00
|
|
|
/* Called to save queue flags */
|
|
|
|
void queue_save_flags(struct queue *, struct file *);
|
|
|
|
|
2016-04-25 07:58:19 -04:00
|
|
|
/* Called to save the list of queued tracks. */
|
|
|
|
void queue_save_tracks(struct queue *, struct file *);
|
|
|
|
|
2016-05-01 19:34:52 -04:00
|
|
|
/* Called to load queue flags from file. */
|
|
|
|
void queue_load_flags(struct queue *, struct file *);
|
|
|
|
|
2016-04-25 07:58:19 -04:00
|
|
|
/* Called to load queued tracks from file. */
|
|
|
|
void queue_load_tracks(struct queue *, struct file *);
|
|
|
|
|
|
|
|
|
2015-12-03 13:41:39 -05:00
|
|
|
/* 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);
|
|
|
|
|
2015-11-20 08:18:54 -05:00
|
|
|
/* 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;
|
|
|
|
}
|
|
|
|
|
2015-11-19 13:48:59 -05:00
|
|
|
/* Called to find the size of the queue. */
|
|
|
|
static inline unsigned int queue_size(struct queue *queue)
|
|
|
|
{
|
2016-04-03 09:52:16 -04:00
|
|
|
return g_queue_get_length(&queue->q_tracks);
|
2015-11-19 13:48:59 -05:00
|
|
|
}
|
|
|
|
|
2015-11-19 13:50:08 -05:00
|
|
|
/* Called to access the queued track at a given index. */
|
|
|
|
static inline struct track *queue_at(struct queue *queue, unsigned int index)
|
|
|
|
{
|
2016-04-03 09:52:16 -04:00
|
|
|
return (struct track *)g_queue_peek_nth(&queue->q_tracks, index);
|
2015-11-19 13:50:08 -05:00
|
|
|
}
|
|
|
|
|
2015-11-19 13:48:59 -05:00
|
|
|
|
2015-11-25 08:24:04 -05:00
|
|
|
/* Called to add a track to the queue. */
|
|
|
|
unsigned int queue_add(struct queue *, struct track *);
|
|
|
|
|
2016-01-22 08:11:09 -05:00
|
|
|
/*
|
|
|
|
* Called to erase a track from the queue by index.
|
|
|
|
* This can be prevented if qop_erase() returns "false".
|
|
|
|
*/
|
|
|
|
void queue_erase(struct queue *, unsigned int);
|
|
|
|
|
2015-11-28 15:24:03 -05:00
|
|
|
/* Called to remove a track from the queue by index. */
|
|
|
|
void queue_remove(struct queue *, unsigned int);
|
|
|
|
|
2015-11-29 16:34:51 -05:00
|
|
|
/* Called to remove all instances of the track from the queue. */
|
2016-04-16 16:36:57 -04:00
|
|
|
unsigned int queue_remove_all(struct queue *, struct track *);
|
2015-11-29 16:34:51 -05:00
|
|
|
|
2016-01-29 10:12:09 -05:00
|
|
|
/* Called to remove all tracks from the queue. */
|
|
|
|
void queue_clear(struct queue *);
|
|
|
|
|
2016-04-16 16:42:54 -04:00
|
|
|
/* Called to check if a queue has a track. */
|
|
|
|
bool queue_has(struct queue *, struct track *);
|
|
|
|
|
2015-11-20 08:02:54 -05:00
|
|
|
/* Called to tell the queue that a track has been updated. */
|
|
|
|
void queue_updated(struct queue *, struct track *);
|
|
|
|
|
|
|
|
|
2015-11-19 08:08:14 -05:00
|
|
|
/* Called to tell the queue that a specific index has been selected. */
|
2016-03-27 12:19:28 -04:00
|
|
|
struct track *queue_selected(struct queue *, unsigned int);
|
2015-11-19 08:08:14 -05:00
|
|
|
|
2015-11-19 08:25:53 -05:00
|
|
|
/* Called to pick the next track from the queue. */
|
|
|
|
struct track *queue_next(struct queue *);
|
|
|
|
|
2015-12-03 10:03:52 -05:00
|
|
|
/* Called to sort the queue without changing sort order. */
|
|
|
|
void queue_resort(struct queue *);
|
|
|
|
|
|
|
|
/* Called to change the sort order and resort the queue. */
|
2015-12-03 13:43:15 -05:00
|
|
|
void queue_sort(struct queue *, enum compare_t, bool);
|
|
|
|
|
2014-06-21 09:37:47 -04:00
|
|
|
#endif /* OCARINA_CORE_QUEUE_H */
|