chiark / gitweb /
disorder_eclient_queue_response now gets error as well as success
authorRichard Kettlewell <rjk@greenend.org.uk>
Sun, 8 Jun 2008 13:15:18 +0000 (14:15 +0100)
committerRichard Kettlewell <rjk@greenend.org.uk>
Sun, 8 Jun 2008 13:15:18 +0000 (14:15 +0100)
responses.

disobedience/queue.c
lib/eclient.c
lib/eclient.h

index c3d62b00a8fc9a9bcd559dcfcba1253e3cdcfaac..7f3a278c45137b09d9656596c6ae7596e3c37a59 100644 (file)
@@ -1041,32 +1041,40 @@ static void redisplay_queue(struct queuelike *ql) {
 }
 
 /** @brief Called with new queue/recent contents */ 
-static void queuelike_completed(void *v, struct queue_entry *q) {
-  struct callbackdata *cbd = v;
-  struct queuelike *ql = cbd->u.ql;
-
-  D(("queuelike_complete"));
-  /* Install the new queue */
-  update_queue(ql, ql->fixup ? ql->fixup(q) : q);
-  /* Update the display */
-  redisplay_queue(ql);
-  if(ql->notify)
-    ql->notify();
-  /* Update sensitivity of main menu items */
-  menu_update(-1);
+static void queuelike_completed(void *v,
+                                const char *error,
+                                struct queue_entry *q) {
+  if(error)
+    popup_protocol_error(0, error);
+  else {
+    struct queuelike *const ql = v;
+    
+    D(("queuelike_complete"));
+    /* Install the new queue */
+    update_queue(ql, ql->fixup ? ql->fixup(q) : q);
+    /* Update the display */
+    redisplay_queue(ql);
+    if(ql->notify)
+      ql->notify();
+    /* Update sensitivity of main menu items */
+    menu_update(-1);
+  }
 }
 
 /** @brief Called with a new currently playing track */
 static void playing_completed(void attribute((unused)) *v,
+                              const char *error,
                               struct queue_entry *q) {
-  struct callbackdata cbd;
-  D(("playing_completed"));
-  playing_track = q;
-  /* Record when we got the playing track data so we know how old the 'sofar'
-   * field is */
-  time(&last_playing);
-  cbd.u.ql = &ql_queue;
-  queuelike_completed(&cbd, actual_queue);
+  if(error)
+    popup_protocol_error(0, error);
+  else {
+    D(("playing_completed"));
+    playing_track = q;
+    /* Record when we got the playing track data so we know how old the 'sofar'
+     * field is */
+    time(&last_playing);
+    queuelike_completed(&ql_queue, 0, actual_queue);
+  }
 }
 
 /** @brief Called when the queue is scrolled */
@@ -1380,14 +1388,9 @@ GtkWidget *queue_widget(void) {
  * cmmand or because it is to be played) or moved within the queue
  */
 void queue_update(void) {
-  struct callbackdata *cbd;
-
   D(("queue_update"));
-  cbd = xmalloc(sizeof *cbd);
-  cbd->onerror = 0;
-  cbd->u.ql = &ql_queue;
   gtk_label_set_text(GTK_LABEL(report_label), "updating queue");
-  disorder_eclient_queue(client, queuelike_completed, cbd);
+  disorder_eclient_queue(client, queuelike_completed, &ql_queue);
 }
 
 /* Recently played tracks -------------------------------------------------- */
@@ -1433,14 +1436,9 @@ GtkWidget *recent_widget(void) {
  * Called whenever a track is added to it or removed from it.
  */
 void recent_update(void) {
-  struct callbackdata *cbd;
-
   D(("recent_update"));
-  cbd = xmalloc(sizeof *cbd);
-  cbd->onerror = 0;
-  cbd->u.ql = &ql_recent;
   gtk_label_set_text(GTK_LABEL(report_label), "updating recently played list");
-  disorder_eclient_recent(client, queuelike_completed, cbd);
+  disorder_eclient_recent(client, queuelike_completed, &ql_recent);
 }
 
 /* Newly added tracks ------------------------------------------------------ */
@@ -1468,7 +1466,7 @@ GtkWidget *added_widget(void) {
  * disobedience/queue.c requires @ref queue_entry structures with a valid and
  * unique @c id field.  This function fakes it.
  */
-static void new_completed(void *v, int nvec, char **vec) {
+static void new_completed(void attribute((unused)) *v, int nvec, char **vec) {
   struct queue_entry *q, *qh, *qlast = 0, **qq = &qh;
   int n;
 
@@ -1482,13 +1480,13 @@ static void new_completed(void *v, int nvec, char **vec) {
     qlast = q;
   }
   *qq = 0;
-  queuelike_completed(v, qh);
+  queuelike_completed(&ql_added, 0, qh);
 }
 
 /** @brief Update the newly-added list */
 void added_update(void) {
   struct callbackdata *cbd;
-  D(("added_updae"));
+  D(("added_update"));
 
   cbd = xmalloc(sizeof *cbd);
   cbd->onerror = 0;
index a753a52de8bf40c40f3cdfb2fb6d9e28d17afd5a..768220f88e69212749ba285f8405462a5eb0b0c4 100644 (file)
@@ -913,7 +913,10 @@ static void eclient_queue_error(const char *msg,
 /* for commands that expect a queue dump */
 static void queue_response_opcallback(disorder_eclient *c,
                                       struct operation *op) {
+  disorder_eclient_queue_response *const completed
+    = (disorder_eclient_queue_response *)op->completed;
   int n;
+  int parse_failed = 0;
   struct queue_entry *q, *qh = 0, **qtail = &qh, *qlast = 0;
   
   D(("queue_response_callback"));
@@ -927,18 +930,24 @@ static void queue_response_opcallback(disorder_eclient *c,
         *qtail = q;
         qtail = &q->next;
         qlast = q;
-      }
+      } else
+        parse_failed = 1;
     }
-    if(op->completed)
-      ((disorder_eclient_queue_response *)op->completed)(op->v, qh);
+    /* Currently we pass the partial queue to the callback along with the
+     * error.  This might not be very useful in practice... */
+    if(parse_failed)
+      completed(op->v, "cannot parse result", qh);
+    else
+      completed(op->v, 0, qh);
   } else
-    /* TODO don't use protocol_error here */
-    protocol_error(c, op, c->rc, "%s: %s", c->ident, c->line);
+    completed(op->v, errorstring(c), 0);
 } 
 
 /* for 'playing' */
 static void playing_response_opcallback(disorder_eclient *c,
                                         struct operation *op) {
+  disorder_eclient_queue_response *const completed
+    = (disorder_eclient_queue_response *)op->completed;
   struct queue_entry *q;
 
   D(("playing_response_callback"));
@@ -947,21 +956,19 @@ static void playing_response_opcallback(disorder_eclient *c,
     case 2:
       if(queue_unmarshall(q = xmalloc(sizeof *q), c->line + 4,
                           eclient_queue_error, c))
-        return;
+        completed(op->v, "cannot parse result", 0);
+      else
+        completed(op->v, 0, q);
       break;
     case 9:
-      q = 0;
+      completed(op->v, 0, 0);
       break;
     default:
-      /* TODO don't use protocol_error here */
-      protocol_error(c, op, c->rc, "%s: %s", c->ident, c->line);
-      return;
+      completed(op->v, errorstring(c), 0);
+      break;
     }
-    if(op->completed)
-      ((disorder_eclient_queue_response *)op->completed)(op->v, q);
   } else
-    /* TODO don't use protocol_error here */
-    protocol_error(c, op, c->rc, "%s: %s", c->ident, c->line);
+    completed(op->v, errorstring(c), 0);
 }
 
 /* for commands that expect a list of some sort */
index 56ff9e607bc4cc95ac64cfc4898f97a17f62f794..e37dda9f51e8c363364912706eee688d5c3e4ec8 100644 (file)
@@ -196,8 +196,21 @@ typedef void disorder_eclient_volume_response(void *v,
                                               const char *error,
                                               int l, int r);
 
-typedef void disorder_eclient_queue_response(void *v, struct queue_entry *q);
-/* completion callback for queue/recent listing */
+/** @brief Queue request completion callback
+ * @param v User data
+ * @param error Error string or NULL on success
+ * @param q Head of queue data list
+ *
+ * @p error will be NULL on success.  In this case @p q be the (head of the)
+ * result.
+ *
+ * @p error will be non-NULL on failure.  In this case @p q may be NULL but
+ * MIGHT also be some subset of the queue.  For consistent behavior it should
+ * be ignored in the error case.
+ */
+typedef void disorder_eclient_queue_response(void *v,
+                                             const char *error,
+                                             struct queue_entry *q);
 
 typedef void disorder_eclient_list_response(void *v, int nvec, char **vec);
 /* completion callback for file listing etc */