X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~mdw/git/disorder/blobdiff_plain/763d5e6ad88ef3ba1cd1d7742d060e4f1e54c6b8..5f624baebe43889bb2810720cb9cc6d0812f49cb:/lib/queue.h
diff --git a/lib/queue.h b/lib/queue.h
index fa9aa81..9bad76e 100644
--- a/lib/queue.h
+++ b/lib/queue.h
@@ -1,100 +1,235 @@
/*
* This file is part of DisOrder.
- * Copyright (C) 2004, 2005, 2006 Richard Kettlewell
+ * Copyright (C) 2004-2009 Richard Kettlewell
*
- * This program is free software; you can redistribute it and/or modify
+ * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
+ * along with this program. If not, see .
+ */
+/** @file lib/queue.h
+ * @brief Track queues
+ *
+ * Used for the queue, the recently played list and the currently playing
+ * track, both in the server and in clients.
*/
-
#ifndef QUEUE_H
#define QUEUE_H
+#include
+
+/** @brief Possible track states */
enum playing_state {
- playing_failed, /* failed to play */
- playing_isscratch, /* this is a scratch track */
- playing_no_player, /* couldn't find a player */
- playing_ok, /* played OK */
- playing_paused, /* started but paused */
- playing_quitting, /* interrupt because server quit */
- playing_random, /* unplayed randomly chosen track */
- playing_scratched, /* was scratched */
- playing_started, /* started to play */
- playing_unplayed /* haven't played this track yet */
+ /** @brief Track failed to play */
+ playing_failed,
+
+ /** @brief OBSOLETE
+ *
+ * Formerly denoted an unplayed scratch. This is now indicated by @p
+ * playing_unplayed and @p origin_scratch.
+ */
+ playing_isscratch,
+
+ /** @brief OBSOLETE
+ *
+ * Formerly meant that no player could be found. Nothing sets this any more.
+ */
+ playing_no_player,
+
+ /** @brief Play completed successfully
+ *
+ * Currently this actually means it finished decoding - it might still be
+ * buffered in the speaker, RTP player, sound card, etc.
+ *
+ * It might also mean that it's a (short!) track that hasn't been played at
+ * all yet but has been fully decoded ahead of time! (This is very confusing
+ * so might change.)
+ */
+ playing_ok,
+
+ /** @brief Track is playing, but paused */
+ playing_paused,
+
+ /** @brief Track is playing but the server is quitting */
+ playing_quitting,
+
+ /** @brief OBSOLETE
+ *
+ * Formerly this meant a track that was picked at random and has not yet been
+ * played. This situation is now indicated by @p playing_unplayed and @p
+ * origin_random (or @p origin_adopted).
+ */
+ playing_random,
+
+ /** @brief Track was scratched */
+ playing_scratched,
+
+ /** @brief Track is now playing
+ *
+ * This refers to the actual playing track, not something being decoded ahead
+ * of time.
+ */
+ playing_started,
+
+ /** @brief Track has not been played yet */
+ playing_unplayed
+};
+
+extern const char *const playing_states[];
+
+/** @brief Possible track origins
+ *
+ * This is a newly introduced field. The aim is ultimately to separate the
+ * concepts of the track origin and its current state. NB that both are
+ * potentially mutable!
+ */
+enum track_origin {
+ /** @brief Track was picked at random and then adopted by a user
+ *
+ * @c submitter identifies who adopted it.
+ */
+ origin_adopted,
+
+ /** @brief Track was picked by a user
+ *
+ * @c submitter identifies who picked it
+ */
+ origin_picked,
+
+ /** @brief Track was picked at random
+ *
+ * @c submitter will be NULL
+ */
+ origin_random,
+
+ /** @brief Track was scheduled by a user
+ *
+ * @c submitter identifies who picked it
+ */
+ origin_scheduled,
+
+ /** @brief Track is a scratch
+ *
+ * @c submitter identifies who did the scratching
+ */
+ origin_scratch
};
-extern const char *playing_states[];
+extern const char *const track_origins[];
-/* queue entries form a circular doubly-linked list */
+/** @brief One queue/recently played entry
+ *
+ * The queue and recently played list form a doubly linked list with the head
+ * and tail referred to from @ref qhead and @ref phead.
+ */
struct queue_entry {
- struct queue_entry *next; /* next entry */
- struct queue_entry *prev; /* previous entry */
- const char *track; /* path to track */
- const char *submitter; /* name of submitter */
- time_t when; /* time submitted */
- time_t played; /* when played */
- enum playing_state state; /* state */
- long wstat; /* wait status */
- const char *scratched; /* scratched by */
- const char *id; /* queue entry ID */
- time_t expected; /* expected started time */
- /* for playing or soon-to-be-played tracks only: */
+ /** @brief Next entry */
+ struct queue_entry *next;
+
+ /** @brief Previous entry */
+ struct queue_entry *prev;
+
+ /** @brief Path to track (a database key) */
+ const char *track;
+
+ /** @brief Submitter or NULL
+ *
+ * Adopter, if @c origin is @ref origin_adopted.
+ */
+ const char *submitter;
+
+ /** @brief When submitted */
+ time_t when;
+
+ /** @brief When played */
+ time_t played;
+
+ /** @brief Current state
+ *
+ * Currently this includes some origin information but this is being phased
+ * out. */
+ enum playing_state state;
+
+ /** @brief Where track came from */
+ enum track_origin origin;
+
+ /** @brief Wait status from player
+ *
+ * Only valid in certain states (TODO).
+ */
+ long wstat;
+
+ /** @brief Who scratched this track or NULL */
+ const char *scratched;
+
+ /** @brief Unique ID string */
+ const char *id;
+
+ /** @brief Estimated starting time */
+ time_t expected;
+
+ /** @brief Type word from plugin (playing/buffered tracks only) */
unsigned long type; /* type word from plugin */
- const struct plugin *pl; /* plugin that's playing this track */
- void *data; /* player data */
- long sofar; /* how much played so far */
- /* For DISORDER_PLAYER_PAUSES only: */
- time_t lastpaused, lastresumed; /* when last paused/resumed, or 0 */
- long uptopause; /* how much played up to last pause */
- /* For Disobedience */
- struct queuelike *ql; /* owning queue */
-};
-extern struct queue_entry qhead;
-/* queue of things yet to be played. the head will be played
- * soonest. */
+ /** @brief Plugin for this track (playing/buffered tracks only) */
+ const struct plugin *pl;
-extern struct queue_entry phead;
-/* things that have been played in the past. the head is the oldest. */
+ /** @brief Player-specific data (playing/buffered tracks only) */
+ void *data;
-void queue_read(void);
-/* read the queue in. Calls @fatal@ on error. */
+ /** @brief How much of track has been played so far (seconds) */
+ long sofar;
-void queue_write(void);
-/* write the queue out. Calls @fatal@ on error. */
+ /** @brief True if track preparation is underway
+ *
+ * This is set when a decoder has been started and is expected to connect to
+ * the speaker, but the speaker has not sent as @ref SM_ARRIVED message back
+ * yet. */
+ int preparing;
-void recent_read(void);
-/* read the recently played list in. Calls @fatal@ on error. */
+ /** @brief True if decoder is connected to speaker
+ *
+ * This is not a @ref playing_state for a couple of reasons
+ * - it is orthogonal to @ref playing_started and @ref playing_unplayed
+ * - it would have to be hidden to other users of @c queue_entry
+ *
+ * For non-raw tracks this should always be zero.
+ */
+ int prepared;
+ /* For DISORDER_PLAYER_PAUSES only: */
-void recent_write(void);
-/* write the recently played list out. Calls @fatal@ on error. */
+ /** @brief When last paused or 0 */
+ time_t lastpaused;
-struct queue_entry *queue_add(const char *track, const char *submitter,
- int where);
-#define WHERE_START 0 /* Add to head of queue */
-#define WHERE_END 1 /* Add to end of queue */
-#define WHERE_BEFORE_RANDOM 2 /* End, or before random track */
-/* add an entry to the queue. Return a pointer to the new entry. */
+ /** @brief When last resumed or 0 */
+ time_t lastresumed;
-void queue_remove(struct queue_entry *q, const char *who);
-/* remove an from the queue */
+ /** @brief How much of track was played up to last pause (seconds) */
+ long uptopause;
-struct queue_entry *queue_find(const char *key);
-/* find a track in the queue by name or ID */
+ /** @brief Owning queue (for Disobedience only) */
+ struct queuelike *ql;
+
+ /** @brief Decoder (or player) process ID */
+ pid_t pid;
-void queue_played(struct queue_entry *q);
-/* add @q@ to the played list */
+ /** @brief Termination signal sent to subprocess
+ *
+ * Used to supress 'terminated' messages.
+ */
+ int killed;
+};
+
+void queue_insert_entry(struct queue_entry *b, struct queue_entry *n);
+void queue_delete_entry(struct queue_entry *node);
int queue_unmarshall(struct queue_entry *q, const char *s,
void (*error_handler)(const char *, void *),
@@ -109,21 +244,7 @@ int queue_unmarshall_vec(struct queue_entry *q, int nvec, char **vec,
char *queue_marshall(const struct queue_entry *q);
/* marshall @q@ into a UTF-8 string */
-void queue_id(struct queue_entry *q);
-/* give @q@ an ID */
-
-int queue_move(struct queue_entry *q, int delta, const char *who);
-/* move element @q@ in the queue towards the front (@delta@ > 0) or towards the
- * back (@delta@ < 0). The return value is the leftover delta once we've hit
- * the end in whichever direction we were going. */
-
-void queue_moveafter(struct queue_entry *target,
- int nqs, struct queue_entry **qs, const char *who);
-/* Move all the elements QS to just after TARGET, or to the head if
- * TARGET=0. */
-
-void queue_fix_sofar(struct queue_entry *q);
-/* Fix up the sofar field for standalone players */
+void queue_free(struct queue_entry *q, int rest);
#endif /* QUEUE_H */