aboutsummaryrefslogtreecommitdiffstats
path: root/src/screen_artist.c
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2008-10-01 09:37:51 +0200
committerMax Kellermann <max@duempel.org>2008-10-01 09:37:51 +0200
commit440618f6fec47a90d51d93a7640571fb0f2bc89c (patch)
tree068a5e1935a802d86a587cb4528fbbd46fc15e98 /src/screen_artist.c
parent6860132693aa5844253891faf2318812ecfb0e2a (diff)
downloadmpd-440618f6fec47a90d51d93a7640571fb0f2bc89c.tar.gz
mpd-440618f6fec47a90d51d93a7640571fb0f2bc89c.tar.xz
mpd-440618f6fec47a90d51d93a7640571fb0f2bc89c.zip
screen_artist: convert metalist to GPtrArray
A linked list is quite uncomfortable here because there is a lot of indexed access to the list. Use a GPtrArray of strings instead. Note that mpdclient_get_artists_utf8() and mpdclient_get_albums_utf8() return a linked list, and sorting is also performed on the linked list. This will be optimized later.
Diffstat (limited to '')
-rw-r--r--src/screen_artist.c105
1 files changed, 72 insertions, 33 deletions
diff --git a/src/screen_artist.c b/src/screen_artist.c
index 81e565309..d88945340 100644
--- a/src/screen_artist.c
+++ b/src/screen_artist.c
@@ -41,8 +41,7 @@ typedef enum { LIST_ARTISTS, LIST_ALBUMS, LIST_SONGS } artist_mode_t;
static artist_mode_t mode = LIST_ARTISTS;
static char *artist = NULL;
static char *album = NULL;
-static unsigned metalist_length = 0;
-static GList *metalist = NULL;
+static GPtrArray *metalist = NULL;
static struct screen_browser browser;
@@ -70,7 +69,7 @@ artist_lw_callback(unsigned idx, mpd_unused int *highlight, mpd_unused void *dat
if (mode == LIST_ALBUMS) {
if (idx == 0)
return "[..]";
- else if (idx == metalist_length - 1) {
+ else if (idx == metalist->len + 1) {
str = utf8_to_locale(_("All tracks"));
g_snprintf(buf, BUFSIZE, "[%s]", str);
g_free(str);
@@ -80,9 +79,12 @@ artist_lw_callback(unsigned idx, mpd_unused int *highlight, mpd_unused void *dat
--idx;
}
- if ((str_utf8 = (char *)g_list_nth_data(metalist, idx)) == NULL)
+ if (idx >= metalist->len)
return NULL;
+ str_utf8 = g_ptr_array_index(metalist, idx);
+ assert(str_utf8 != NULL);
+
str = utf8_to_locale(str_utf8);
g_snprintf(buf, BUFSIZE, "[%s]", str);
g_free(str);
@@ -116,6 +118,34 @@ playlist_changed_callback(mpdclient_t *c, int event, gpointer data)
artist_repaint_if_active();
}
+static GPtrArray *
+g_list_to_ptr_array(GList *in)
+{
+ GPtrArray *out = g_ptr_array_sized_new(g_list_length(in));
+ GList *head = in;
+
+ while (in != NULL) {
+ g_ptr_array_add(out, in->data);
+ in = g_list_next(in);
+ }
+
+ g_list_free(head);
+ return out;
+}
+
+static void
+string_array_free(GPtrArray *array)
+{
+ unsigned i;
+
+ for (i = 0; i < array->len; ++i) {
+ char *value = g_ptr_array_index(array, i);
+ free(value);
+ }
+
+ g_ptr_array_free(array, TRUE);
+}
+
/* fetch artists/albums/songs from mpd */
static void
update_metalist(mpdclient_t *c, char *m_artist, char *m_album)
@@ -125,8 +155,11 @@ update_metalist(mpdclient_t *c, char *m_artist, char *m_album)
artist = NULL;
album = NULL;
- if (metalist)
- metalist = string_list_free(metalist);
+ if (metalist != NULL) {
+ string_array_free(metalist);
+ metalist = NULL;
+ }
+
if (browser.filelist) {
mpdclient_remove_playlist_callback(c, playlist_changed_callback);
filelist_free(browser.filelist);
@@ -160,23 +193,26 @@ update_metalist(mpdclient_t *c, char *m_artist, char *m_album)
mode = LIST_SONGS;
} else if (m_artist) {
/* retreive albums... */
+ GList *list;
artist = m_artist;
- metalist = mpdclient_get_albums_utf8(c, m_artist);
+ list = mpdclient_get_albums_utf8(c, m_artist);
/* sort list */
- metalist = g_list_sort(metalist, compare_utf8);
+ list = g_list_sort(list, compare_utf8);
+
+ metalist = g_list_to_ptr_array(list);
mode = LIST_ALBUMS;
} else {
/* retreive artists... */
+ GList *list;
- metalist = mpdclient_get_artists_utf8(c);
+ list = mpdclient_get_artists_utf8(c);
/* sort list */
- metalist = g_list_sort(metalist, compare_utf8);
+ list = g_list_sort(list, compare_utf8);
+
+ metalist = g_list_to_ptr_array(list);
mode = LIST_ARTISTS;
}
- metalist_length = g_list_length(metalist);
- if (mode == LIST_ALBUMS)
- metalist_length += 2;
}
/* db updated */
@@ -210,7 +246,7 @@ quit(void)
if (browser.filelist)
filelist_free(browser.filelist);
if (metalist)
- string_list_free(metalist);
+ string_array_free(metalist);
g_free(artist);
g_free(album);
artist = NULL;
@@ -297,13 +333,23 @@ add_query(mpdclient_t *c, int table, char *_filter)
}
}
+static unsigned
+metalist_length(void)
+{
+ assert(metalist != NULL);
+
+ return mode == LIST_ALBUMS
+ ? metalist->len + 2
+ : metalist->len;
+}
+
static int
artist_lw_cmd(command_t cmd)
{
switch (mode) {
case LIST_ARTISTS:
case LIST_ALBUMS:
- return list_window_cmd(browser.lw, metalist_length, cmd);
+ return list_window_cmd(browser.lw, metalist_length(), cmd);
case LIST_SONGS:
return list_window_cmd(browser.lw,
@@ -331,8 +377,8 @@ artist_cmd(screen_t *screen, mpdclient_t *c, command_t cmd)
case CMD_PLAY:
switch (mode) {
case LIST_ARTISTS:
- selected = (char *) g_list_nth_data(metalist,
- browser.lw->selected);
+ selected = g_ptr_array_index(metalist,
+ browser.lw->selected);
update_metalist(c, g_strdup(selected), NULL);
list_window_push_state(browser.lw_state, browser.lw);
@@ -348,14 +394,14 @@ artist_cmd(screen_t *screen, mpdclient_t *c, command_t cmd)
list_window_reset(browser.lw);
/* restore previous list window state */
list_window_pop_state(browser.lw_state, browser.lw);
- } else if (browser.lw->selected == metalist_length - 1) {
+ } else if (browser.lw->selected == metalist->len + 1) {
/* handle "show all" */
update_metalist(c, g_strdup(artist), g_strdup("\0"));
list_window_push_state(browser.lw_state, browser.lw);
} else {
/* select album */
- selected = g_list_nth_data(metalist,
- browser.lw->selected - 1);
+ selected = g_ptr_array_index(metalist,
+ browser.lw->selected - 1);
update_metalist(c, g_strdup(artist), g_strdup(selected));
list_window_push_state(browser.lw_state, browser.lw);
}
@@ -428,25 +474,18 @@ artist_cmd(screen_t *screen, mpdclient_t *c, command_t cmd)
case CMD_ADD:
switch(mode) {
case LIST_ARTISTS:
- selected = g_list_nth_data(metalist,
- browser.lw->selected);
- if (selected == NULL)
- return 1;
-
+ selected = g_ptr_array_index(metalist,
+ browser.lw->selected);
add_query(c, MPD_TABLE_ARTIST, selected);
cmd = CMD_LIST_NEXT; /* continue and select next item... */
break;
case LIST_ALBUMS:
- if (browser.lw->selected &&
- browser.lw->selected == metalist_length - 1)
+ if (browser.lw->selected == metalist->len + 1)
add_query(c, MPD_TABLE_ARTIST, artist);
else if (browser.lw->selected > 0) {
- selected = g_list_nth_data(metalist,
- browser.lw->selected - 1);
- if (selected == NULL)
- return 1;
-
+ selected = g_ptr_array_index(metalist,
+ browser.lw->selected - 1);
add_query(c, MPD_TABLE_ALBUM, selected);
cmd = CMD_LIST_NEXT; /* continue and select next item... */
}
@@ -480,7 +519,7 @@ artist_cmd(screen_t *screen, mpdclient_t *c, command_t cmd)
browser.filelist);
else if (metalist)
screen_find(screen,
- browser.lw, metalist_length,
+ browser.lw, metalist_length(),
cmd, artist_lw_callback, metalist);
else
return 1;