chiark / gitweb /
Fix mis-merged trackdb_open().
[disorder] / lib / queue.h
index fa9aa8197ce3fa1842d5a68b8be84edcde485207..72e38769726442557231928b0d28a2743ebdabf2 100644 (file)
 /*
  * This file is part of DisOrder.
- * Copyright (C) 2004, 2005, 2006 Richard Kettlewell
+ * Copyright (C) 2004-2008 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 <http://www.gnu.org/licenses/>.
+ */
+/** @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 <time.h>
+
+/** @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 *playing_states[];
+extern const char *const playing_states[];
 
-/* queue entries form a circular doubly-linked list */
-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: */
-  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 */
+/** @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 struct queue_entry qhead;
-/* queue of things yet to be played.  the head will be played
- * soonest. */
+extern const char *const track_origins[];
+
+/** @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 {
+  /** @brief Next entry */
+  struct queue_entry *next;
+
+  /** @brief Previous entry */
+  struct queue_entry *prev;
+
+  /** @brief Path to track (a database key) */
+  const char *track;
 
-extern struct queue_entry phead;
-/* things that have been played in the past.  the head is the oldest. */
+  /** @brief Submitter or NULL
+   *
+   * Adopter, if @c origin is @ref origin_adopted.
+   */
+  const char *submitter;
 
-void queue_read(void);
-/* read the queue in.  Calls @fatal@ on error. */
+  /** @brief When submitted */
+  time_t when;
 
-void queue_write(void);
-/* write the queue out.  Calls @fatal@ on error. */
+  /** @brief When played */
+  time_t played;
 
-void recent_read(void);
-/* read the recently played list in.  Calls @fatal@ on error. */
+  /** @brief Current state
+   *
+   * Currently this includes some origin information but this is being phased
+   * out. */
+  enum playing_state state;
 
-void recent_write(void);
-/* write the recently played list out.  Calls @fatal@ on error. */
+  /** @brief Where track came from */
+  enum track_origin origin;
 
-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 Wait status from player
+   *
+   * Only valid in certain states (TODO).
+   */
+  long wstat;
 
-void queue_remove(struct queue_entry *q, const char *who);
-/* remove an from the queue */
+  /** @brief Who scratched this track or NULL */
+  const char *scratched;
 
-struct queue_entry *queue_find(const char *key);
-/* find a track in the queue by name or ID */
+  /** @brief Unique ID string */
+  const char *id;
 
-void queue_played(struct queue_entry *q);
-/* add @q@ to the played list */
+  /** @brief Estimated starting time */
+  time_t expected;
+
+  /** @brief Type word from plugin (playing/buffered tracks only) */
+  unsigned long type;                  /* type word from plugin */
+
+  /** @brief Plugin for this track (playing/buffered tracks only) */
+  const struct plugin *pl;
+
+  /** @brief Player-specific data (playing/buffered tracks only) */
+  void *data;
+
+  /** @brief How much of track has been played so far (seconds) */
+  long sofar;
+
+  /** @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: */
+
+  /** @brief When last paused or 0 */
+  time_t lastpaused;
+
+  /** @brief When last resumed or 0 */
+  time_t lastresumed;
+
+  /** @brief How much of track was played up to last pause (seconds) */
+  long uptopause;
+
+  /** @brief Owning queue (for Disobedience only) */
+  struct queuelike *ql;
+  
+  /** @brief Decoder (or player) process ID */
+  pid_t pid;
+};
+
+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,22 +231,6 @@ 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 */
-
 #endif /* QUEUE_H */
 
 /*