]> git.tuebingen.mpg.de Git - paraslash.git/blobdiff - afs.c
Rename mood_switch(), mood_close(), playlist_{open/close}.
[paraslash.git] / afs.c
diff --git a/afs.c b/afs.c
index 72e7acccf3284fd4bb7d94697eb3d2ce70217d29..cea8f2707491f00bab0f457a3463fd4762147a21 100644 (file)
--- a/afs.c
+++ b/afs.c
 #include "sched.h"
 #include "fd.h"
 #include "signal.h"
-#include "mood.h"
 #include "sideband.h"
 #include "command.h"
 
-static struct afs_table afs_tables[] = {
-       {.init = aft_init, .name = "audio_files"},
-       {.init = attribute_init, .name = "attributes"},
-       {.init = score_init, .name = "scores"},
-       {.init = moods_init, .name = "moods"},
-       {.init = lyrics_init, .name = "lyrics"},
-       {.init = images_init, .name = "images"},
-       {.init = playlists_init, .name = "playlists"},
+/**
+ * The array of tables of the audio file selector.
+ *
+ * We organize them in an array to be able to loop over all tables.
+ */
+static const struct afs_table {
+       /** The name is no table operation, so define it here. */
+       const char * const name;
+       /** The only way to invoke the ops is via this pointer. */
+       const struct afs_table_operations *ops;
+} afs_tables[] = {
+       {.name = "audio_files", .ops = &aft_ops},
+       {.name = "attributes", .ops = &attr_ops},
+       {.name = "scores", .ops = &score_ops},
+       {.name = "moods", .ops = &moods_ops},
+       {.name = "lyrics", .ops = &lyrics_ops},
+       {.name = "images", .ops = &images_ops},
+       {.name = "playlists", .ops = &playlists_ops},
 };
-
+/** Used to loop over the afs tables. */
 #define NUM_AFS_TABLES ARRAY_SIZE(afs_tables)
 
 struct command_task {
@@ -91,7 +100,7 @@ extern uint32_t afs_socket_cookie;
  */
 struct callback_query {
        /** The function to be called. */
-       afs_callback *handler;
+       afs_callback *cb;
        /** The number of bytes of the query */
        size_t query_size;
 };
@@ -182,7 +191,7 @@ int send_callback_request(afs_callback *f, struct osl_object *query,
        if (ret < 0)
                goto out;
        cq = query_shm;
-       cq->handler = f;
+       cq->cb = f;
        cq->query_size = query_shm_size - sizeof(*cq);
 
        if (query)
@@ -422,37 +431,30 @@ no_admissible_files:
        return write_all(server_socket, buf, 8);
 }
 
-static int activate_mood_or_playlist(const char *arg, int *num_admissible,
-               char **errmsg)
+static int activate_mood_or_playlist(const char *arg, struct para_buffer *pb)
 {
        enum play_mode mode;
        int ret;
+       char *msg;
 
        if (!arg) {
+               ret = mood_load(NULL, &msg);
+               mode = PLAY_MODE_MOOD;
+       } else if (!strncmp(arg, "p/", 2)) {
+               ret = playlist_load(arg + 2, &msg);
+               mode = PLAY_MODE_PLAYLIST;
+       } else if (!strncmp(arg, "m/", 2)) {
+               ret = mood_load(arg + 2, &msg);
                mode = PLAY_MODE_MOOD;
-               ret = change_current_mood(NULL, errmsg);
-               if (ret < 0) {
-                       if (num_admissible)
-                               *num_admissible = 0;
-                       return ret;
-               }
        } else {
-               if (!strncmp(arg, "p/", 2)) {
-                       ret = playlist_open(arg + 2, errmsg);
-                       mode = PLAY_MODE_PLAYLIST;
-               } else if (!strncmp(arg, "m/", 2)) {
-                       ret = change_current_mood(arg + 2, errmsg);
-                       mode = PLAY_MODE_MOOD;
-               } else {
-                       if (errmsg)
-                               *errmsg = make_message("%s: parse error", arg);
-                       return -ERRNO_TO_PARA_ERROR(EINVAL);
-               }
-               if (ret < 0)
-                       return ret;
+               ret = -ERRNO_TO_PARA_ERROR(EINVAL);
+               msg = make_message("%s: parse error", arg);
        }
-       if (num_admissible)
-               *num_admissible = ret;
+       if (pb)
+               para_printf(pb, "%s", msg);
+       free(msg);
+       if (ret < 0)
+               return ret;
        current_play_mode = mode;
        /*
         * We get called with arg == current_mop from the signal dispatcher
@@ -527,46 +529,30 @@ static int com_select_callback(struct afs_callback_arg *aca)
 {
        const struct lls_command *cmd = SERVER_CMD_CMD_PTR(SELECT);
        const char *arg;
-       int num_admissible, ret;
-       char *errmsg;
+       int ret;
 
        ret = lls_deserialize_parse_result(aca->query.data, cmd, &aca->lpr);
        assert(ret >= 0);
        arg = lls_input(0, aca->lpr);
-       ret = clear_score_table();
-       if (ret < 0) {
-               para_printf(&aca->pbout, "could not clear score table\n");
-               goto free_lpr;
-       }
+       score_clear();
        if (current_play_mode == PLAY_MODE_MOOD)
-               close_current_mood();
+               mood_unload();
        else
-               playlist_close();
-       ret = activate_mood_or_playlist(arg, &num_admissible, &errmsg);
+               playlist_unload();
+       ret = activate_mood_or_playlist(arg, &aca->pbout);
        if (ret >= 0)
-               goto out;
+               goto free_lpr;
        /* ignore subsequent errors (but log them) */
-       para_printf(&aca->pbout, "%s\n", errmsg);
-       free(errmsg);
-       para_printf(&aca->pbout, "could not activate %s\n", arg);
        if (current_mop && strcmp(current_mop, arg) != 0) {
                int ret2;
                para_printf(&aca->pbout, "switching back to %s\n", current_mop);
-               ret2 = activate_mood_or_playlist(current_mop, &num_admissible,
-                       &errmsg);
+               ret2 = activate_mood_or_playlist(current_mop, &aca->pbout);
                if (ret2 >= 0)
-                       goto out;
-               para_printf(&aca->pbout, "%s\n", errmsg);
-               free(errmsg);
+                       goto free_lpr;
                para_printf(&aca->pbout, "could not reactivate %s: %s\n",
                        current_mop, para_strerror(-ret2));
        }
-       para_printf(&aca->pbout, "activating dummy mood\n");
-       activate_mood_or_playlist(NULL, &num_admissible, NULL);
-out:
-       para_printf(&aca->pbout, "activated %s (%d admissible file%s)\n",
-               current_mop? current_mop : "dummy mood", num_admissible,
-                       num_admissible == 1? "" : "s");
+       activate_mood_or_playlist(NULL, &aca->pbout);
 free_lpr:
        lls_free_parse_result(aca->lpr, cmd);
        return ret;
@@ -588,12 +574,12 @@ EXPORT_SERVER_CMD_HANDLER(select);
 
 static void init_admissible_files(const char *arg)
 {
-       int ret = activate_mood_or_playlist(arg, NULL, NULL);
+       int ret = activate_mood_or_playlist(arg, NULL);
        if (ret < 0) {
                PARA_WARNING_LOG("could not activate %s: %s\n", arg,
                        para_strerror(-ret));
                if (arg)
-                       activate_mood_or_playlist(NULL, NULL, NULL);
+                       activate_mood_or_playlist(NULL, NULL);
        }
 }
 
@@ -621,7 +607,7 @@ static void close_afs_tables(void)
        int i;
        PARA_NOTICE_LOG("closing afs tables\n");
        for (i = 0; i < NUM_AFS_TABLES; i++)
-               afs_tables[i].close();
+               afs_tables[i].ops->close();
        free(database_dir);
        database_dir = NULL;
 }
@@ -660,7 +646,7 @@ static int open_afs_tables(void)
        PARA_NOTICE_LOG("opening %zu osl tables in %s\n", NUM_AFS_TABLES,
                database_dir);
        for (i = 0; i < NUM_AFS_TABLES; i++) {
-               ret = afs_tables[i].open(database_dir);
+               ret = afs_tables[i].ops->open(database_dir);
                if (ret >= 0)
                        continue;
                PARA_ERROR_LOG("could not open %s\n", afs_tables[i].name);
@@ -669,7 +655,7 @@ static int open_afs_tables(void)
        if (ret >= 0)
                return ret;
        while (i)
-               afs_tables[--i].close();
+               afs_tables[--i].ops->close();
        return ret;
 }
 
@@ -808,7 +794,7 @@ static int call_callback(int fd, int query_shmid)
                .fd = fd,
                .band = SBD_OUTPUT
        };
-       ret = cq->handler(&aca);
+       ret = cq->cb(&aca);
        ret2 = shm_detach(query_shm);
        if (ret2 < 0) {
                if (ret < 0) /* ignore (but log) detach error */
@@ -961,12 +947,10 @@ static int afs_poll(struct pollfd *fds, nfds_t nfds, int timeout)
 __noreturn void afs_init(int socket_fd)
 {
        static struct sched s;
-       int i, ret;
+       int ret;
 
        register_signal_task(&s);
        init_list_head(&afs_client_list);
-       for (i = 0; i < NUM_AFS_TABLES; i++)
-               afs_tables[i].init(&afs_tables[i]);
        ret = open_afs_tables();
        if (ret < 0)
                goto out;
@@ -988,7 +972,7 @@ __noreturn void afs_init(int socket_fd)
        }
        ret = schedule(&s);
        sched_shutdown(&s);
-       close_current_mood();
+       mood_unload();
 out_close:
        close_afs_tables();
 out:
@@ -1009,13 +993,13 @@ static int com_init_callback(struct afs_callback_arg *aca)
        close_afs_tables();
        get_database_dir();
        for (i = 0; i < NUM_AFS_TABLES; i++) {
-               struct afs_table *t = &afs_tables[i];
+               const struct afs_table *t = afs_tables + i;
 
                if (!(table_mask & (1 << i)))
                        continue;
-               if (!t->create)
+               if (!t->ops->create)
                        continue;
-               ret = t->create(database_dir);
+               ret = t->ops->create(database_dir);
                if (ret < 0) {
                        para_printf(&aca->pbout, "cannot create table %s\n",
                                t->name);
@@ -1047,7 +1031,7 @@ static int com_init(struct command_context *cc, struct lls_parse_result *lpr)
                table_mask = 0;
                for (i = 0; i < num_inputs; i++) {
                        for (j = 0; j < NUM_AFS_TABLES; j++) {
-                               struct afs_table *t = &afs_tables[j];
+                               const struct afs_table *t = afs_tables + j;
 
                                if (strcmp(lls_input(i, lpr), t->name))
                                        continue;
@@ -1121,10 +1105,10 @@ __must_check int afs_event(enum afs_events event, struct para_buffer *pb,
        int i, ret;
 
        for (i = 0; i < NUM_AFS_TABLES; i++) {
-               struct afs_table *t = &afs_tables[i];
-               if (!t->event_handler)
+               const struct afs_table *t = afs_tables + i;
+               if (!t->ops->event_handler)
                        continue;
-               ret = t->event_handler(event, pb, data);
+               ret = t->ops->event_handler(event, pb, data);
                if (ret < 0) {
                        PARA_CRIT_LOG("table %s, event %u: %s\n", t->name,
                                event, para_strerror(-ret));