summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 20e286d)
raw | patch | inline | side by side (parent: 20e286d)
author | Max Kellermann <max@duempel.org> | |
Tue, 23 Sep 2008 10:08:53 +0000 (12:08 +0200) | ||
committer | Max Kellermann <max@duempel.org> | |
Tue, 23 Sep 2008 10:08:53 +0000 (12:08 +0200) |
Instead of letting our caller poll lyrics_result(), call it back as
soon as we have the result.
soon as we have the result.
src/lyrics.c | patch | blob | history | |
src/lyrics.h | patch | blob | history | |
src/screen_lyrics.c | patch | blob | history |
diff --git a/src/lyrics.c b/src/lyrics.c
index 917344701cf0d338af7d4526e155f4070004a61c..7a6124b6908be941383a4338dac6934f862822fd 100644 (file)
--- a/src/lyrics.c
+++ b/src/lyrics.c
struct lyrics_loader {
char *artist, *title;
- enum lyrics_loader_result result;
+ lyrics_callback_t callback;
+ void *callback_data;
guint next_plugin;
lyrics_next_plugin(loader);
} else {
- loader->result = LYRICS_SUCCESS;
+ loader->callback(loader->data, loader->callback_data);
}
}
ssize_t nbytes;
assert(loader != NULL);
- assert(loader->result = LYRICS_BUSY);
assert(loader->fd >= 0);
assert(loader->pid > 0);
assert(source == loader->channel);
return TRUE;
}
+/**
+ * This is a timer callback which calls the lyrics callback "some
+ * timer later". This solves the problem that lyrics_load() may fail
+ * immediately, leaving its return value in an undefined state.
+ * Instead, install a timer which calls the lyrics callback in the
+ * moment after.
+ */
+static gboolean
+lyrics_delayed_fail(gpointer data)
+{
+ struct lyrics_loader *loader = data;
+
+ assert(loader != NULL);
+ assert(loader->fd < 0);
+ assert(loader->pid < 0);
+ assert(loader->data == NULL);
+
+ loader->callback(NULL, loader->callback_data);
+
+ return FALSE;
+}
+
static int
lyrics_start_plugin(struct lyrics_loader *loader, const char *plugin_path)
{
pid_t pid;
assert(loader != NULL);
- assert(loader->result == LYRICS_BUSY);
assert(loader->pid < 0);
assert(loader->fd < 0);
assert(loader->data == NULL);
if (loader->next_plugin >= plugins->len) {
/* no plugins left */
- loader->result = LYRICS_FAILED;
+ g_timeout_add(0, lyrics_delayed_fail, loader);
return;
}
ret = lyrics_start_plugin(loader, plugin_path);
if (ret < 0) {
/* system error */
- loader->result = LYRICS_FAILED;
+ g_timeout_add(0, lyrics_delayed_fail, loader);
return;
}
}
struct lyrics_loader *
-lyrics_load(const char *artist, const char *title)
+lyrics_load(const char *artist, const char *title,
+ lyrics_callback_t callback, void *data)
{
struct lyrics_loader *loader = g_new(struct lyrics_loader, 1);
loader->artist = g_strdup(artist);
loader->title = g_strdup(title);
- loader->result = LYRICS_BUSY;
+ loader->callback = callback;
+ loader->data = data;
loader->next_plugin = 0;
loader->pid = -1;
loader->fd = -1;
if (loader->data != NULL)
g_string_free(loader->data, TRUE);
}
-
-enum lyrics_loader_result
-lyrics_result(struct lyrics_loader *loader)
-{
- return loader->result;
-}
-
-const GString *
-lyrics_get(struct lyrics_loader *loader)
-{
- assert(loader->result == LYRICS_SUCCESS);
- assert(loader->pid < 0);
- assert(loader->data != NULL);
-
- return loader->data;
-}
diff --git a/src/lyrics.h b/src/lyrics.h
index 34380c344b576b71b5e01bbe2850138389240554..613ccb338f289f2841acb8a615de6200b0a3aa19 100644 (file)
--- a/src/lyrics.h
+++ b/src/lyrics.h
#include <glib.h>
-enum lyrics_loader_result {
- LYRICS_SUCCESS,
- LYRICS_BUSY,
- LYRICS_FAILED
-};
+typedef void (*lyrics_callback_t)(const GString *result, void *data);
struct lyrics_loader;
void lyrics_deinit(void);
struct lyrics_loader *
-lyrics_load(const char *artist, const char *title);
+lyrics_load(const char *artist, const char *title,
+ lyrics_callback_t callback, void *callback_data);
void
lyrics_free(struct lyrics_loader *loader);
-enum lyrics_loader_result
-lyrics_result(struct lyrics_loader *loader);
-
-const GString *
-lyrics_get(struct lyrics_loader *loader);
-
#endif
diff --git a/src/screen_lyrics.c b/src/screen_lyrics.c
index cfc65893981ac9c119f2c93e88f09684ec17f5dc..9b9ea03a2f505145dcb31b51dc818cdb96518854 100644 (file)
--- a/src/screen_lyrics.c
+++ b/src/screen_lyrics.c
{
guint i;
- assert(current.loader == NULL ||
- lyrics_result(current.loader) == LYRICS_SUCCESS);
-
for (i = 0; i < current.lines->len; ++i)
g_free(g_ptr_array_index(current.lines, i));
g_ptr_array_set_size(current.lines, 0);
}
+static const char *
+list_callback(unsigned idx, int *highlight, void *data);
+
static void
screen_lyrics_set(const GString *str)
{
if (*p != 0)
g_ptr_array_add(current.lines, g_strdup(p));
+
+ /* paint new data */
+
+ if (get_cur_mode_id() == 104) { /* XXX don't use the literal number */
+ lw->clear = 1;
+ list_window_paint(lw, list_callback, NULL);
+ wrefresh(lw->w);
+
+ /* XXX repaint the screen title */
+ }
}
-static int
-screen_lyrics_poll(void)
+static void
+screen_lyrics_callback(const GString *result, mpd_unused void *data)
{
assert(current.loader != NULL);
- switch (lyrics_result(current.loader)) {
- case LYRICS_BUSY:
- return 0;
-
- case LYRICS_SUCCESS:
- screen_lyrics_set(lyrics_get(current.loader));
- lyrics_free(current.loader);
- current.loader = NULL;
- return 1;
-
- case LYRICS_FAILED:
- lyrics_free(current.loader);
- current.loader = NULL;
+ if (result != NULL)
+ screen_lyrics_set(result);
+ else
screen_status_message (_("No lyrics"));
- return -1;
- }
- assert(0);
- return -1;
+ lyrics_free(current.loader);
+ current.loader = NULL;
}
static void
strfsong(buffer, sizeof(buffer), "%title%", song);
current.title = g_strdup(buffer);
- current.loader = lyrics_load(current.artist, current.title);
+ current.loader = lyrics_load(current.artist, current.title,
+ screen_lyrics_callback, NULL);
}
static void lyrics_paint(screen_t *screen, mpdclient_t *c);
{
if (c->song != NULL && c->song != current.song)
screen_lyrics_load(c->song);
- else if (current.loader != NULL)
- screen_lyrics_poll();
}
return 1;
switch(cmd) {
- case CMD_SELECT:
- /* XXX */
- if (current.loader != NULL) {
- int ret = screen_lyrics_poll();
- if (ret != 0)
- lyrics_paint(NULL, NULL);
- }
- return 1;
case CMD_INTERRUPT:
if (current.loader != NULL) {
screen_lyrics_abort();