From 3035257f2c6be10a639ee4bb4b343831763da02c Mon Sep 17 00:00:00 2001 Message-Id: <3035257f2c6be10a639ee4bb4b343831763da02c.1716542297.git.mdw@distorted.org.uk> From: Mark Wooding Date: Sun, 8 Jun 2008 14:15:18 +0100 Subject: [PATCH] disorder_eclient_queue_response now gets error as well as success responses. Organization: Straylight/Edgeware From: Richard Kettlewell --- disobedience/queue.c | 70 +++++++++++++++++++++----------------------- lib/eclient.c | 35 +++++++++++++--------- lib/eclient.h | 17 +++++++++-- 3 files changed, 70 insertions(+), 52 deletions(-) diff --git a/disobedience/queue.c b/disobedience/queue.c index c3d62b0..7f3a278 100644 --- a/disobedience/queue.c +++ b/disobedience/queue.c @@ -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; diff --git a/lib/eclient.c b/lib/eclient.c index a753a52..768220f 100644 --- a/lib/eclient.c +++ b/lib/eclient.c @@ -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 */ diff --git a/lib/eclient.h b/lib/eclient.h index 56ff9e6..e37dda9 100644 --- a/lib/eclient.h +++ b/lib/eclient.h @@ -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 */ -- [mdw]