/* We'll need to resend all operations */
for(op = c->ops; op; op = op->next)
op->sent = 0;
+ /* Drop our use a hint that we're disconnected */
+ if(c->log_callbacks && c->log_callbacks->state)
+ c->log_callbacks->state(c->log_v, c->statebits);
}
/** @brief Return current state */
c->state = state_connected;
byte_xasprintf(&r, "connected to %s", c->ident);
c->callbacks->report(c->u, r);
+ /* If this is a log client we expect to get a bunch of updates from the
+ * server straight away */
}
}
* Once a client is being used for logging it cannot be used for anything else.
* There is magic in authuser_opcallback() to re-submit the @c log command
* after reconnection.
+ *
+ * NB that the @c state callback may be called from within this function,
+ * i.e. not solely later on from the event loop callback.
*/
int disorder_eclient_log(disorder_eclient *c,
const disorder_eclient_log_callbacks *callbacks,
if(c->log_callbacks) return -1;
c->log_callbacks = callbacks;
c->log_v = v;
+ /* Repoort initial state */
+ if(c->log_callbacks->state)
+ c->log_callbacks->state(c->log_v, c->statebits);
stash_command(c, 0/*queuejump*/, log_opcallback, 0/*completed*/, v,
"log", (char *)0);
return 0;
static void logentry_completed(disorder_eclient *c,
int attribute((unused)) nvec, char **vec) {
if(!c->log_callbacks->completed) return;
- c->state &= ~DISORDER_PLAYING;
+ c->statebits &= ~DISORDER_PLAYING;
c->log_callbacks->completed(c->log_v, vec[0]);
if(c->log_callbacks->state)
c->log_callbacks->state(c->log_v, c->statebits | DISORDER_CONNECTED);
static void logentry_failed(disorder_eclient *c,
int attribute((unused)) nvec, char **vec) {
if(!c->log_callbacks->failed)return;
- c->state &= ~DISORDER_PLAYING;
+ c->statebits &= ~DISORDER_PLAYING;
c->log_callbacks->failed(c->log_v, vec[0], vec[1]);
if(c->log_callbacks->state)
c->log_callbacks->state(c->log_v, c->statebits | DISORDER_CONNECTED);
static void logentry_playing(disorder_eclient *c,
int attribute((unused)) nvec, char **vec) {
if(!c->log_callbacks->playing) return;
- c->state |= DISORDER_PLAYING;
+ c->statebits |= DISORDER_PLAYING;
c->log_callbacks->playing(c->log_v, vec[0], vec[1]);
if(c->log_callbacks->state)
c->log_callbacks->state(c->log_v, c->statebits | DISORDER_CONNECTED);
static void logentry_scratched(disorder_eclient *c,
int attribute((unused)) nvec, char **vec) {
if(!c->log_callbacks->scratched) return;
- c->state &= ~DISORDER_PLAYING;
+ c->statebits &= ~DISORDER_PLAYING;
c->log_callbacks->scratched(c->log_v, vec[0], vec[1]);
if(c->log_callbacks->state)
c->log_callbacks->state(c->log_v, c->statebits | DISORDER_CONNECTED);
c->log_callbacks->volume(c->log_v, (int)l, (int)r);
}
+/** @brief Convert @p statebits to a string */
+char *disorder_eclient_interpret_state(unsigned long statebits) {
+ struct dynstr d[1];
+ size_t n;
+
+ static const struct {
+ unsigned long bit;
+ const char *name;
+ } bits[] = {
+ { DISORDER_PLAYING_ENABLED, "playing_enabled" },
+ { DISORDER_RANDOM_ENABLED, "random_enabled" },
+ { DISORDER_TRACK_PAUSED, "track_paused" },
+ { DISORDER_PLAYING, "playing" },
+ { DISORDER_CONNECTED, "connected" },
+ };
+#define NBITS (sizeof bits / sizeof *bits)
+
+ dynstr_init(d);
+ if(!statebits)
+ dynstr_append(d, '0');
+ for(n = 0; n < NBITS; ++n)
+ if(statebits & bits[n].bit) {
+ if(d->nvec)
+ dynstr_append(d, '|');
+ dynstr_append_string(d, bits[n].name);
+ statebits ^= bits[n].bit;
+ }
+ if(statebits) {
+ char s[20];
+
+ if(d->nvec)
+ dynstr_append(d, '|');
+ sprintf(s, "%#lx", statebits);
+ dynstr_append_string(d, s);
+ }
+ dynstr_terminate(d);
+ return d->vec;
+}
+
/*
Local Variables:
c-basic-offset:2