Complete afs event handling.
authorAndre Noll <maan@systemlinux.org>
Sun, 21 Oct 2007 11:43:22 +0000 (13:43 +0200)
committerAndre Noll <maan@systemlinux.org>
Sun, 21 Oct 2007 11:43:22 +0000 (13:43 +0200)
Add blob event handling. This definitely needs some
more fine-tuning, but that can be changed gradually
thanks to the generic event handling code.

In playlist mode there's nothing to do, as we're
not interested in any blob events. So install only
a dummy handler for the scoring system and decide
whether to reload the score table in mood.c.

afs.h
blob.c
mood.c
playlist.c
score.c

diff --git a/afs.h b/afs.h
index 57ceceb..db931d9 100644 (file)
--- a/afs.h
+++ b/afs.h
@@ -35,12 +35,9 @@ enum afs_events {
        AUDIO_FILE_RENAME,
        AUDIO_FILE_ADD,
        AUDIO_FILE_REMOVE,
-       LYRICS_ADD,
-       LYRICS_REMOVE,
-       LYRICS_RENAME,
-       IMAGE_ADD,
-       IMAGE_REMOVE,
-       IMAGE_RENAME,
+       BLOB_ADD,
+       BLOB_RENAME,
+       BLOB_REMOVE,
 
 };
 
@@ -60,19 +57,6 @@ struct afsi_change_event_data {
        struct afs_info *old_afsi;
 };
 
-union afs_event_data {
-       struct {
-               const char *name;
-               unsigned char bitnum;
-       } rmatt_event_data;
-       struct osl_row *row;
-       struct {
-               const struct osl_row *row;
-               struct afs_info *old_afsi;
-       } afsi_change;
-
-};
-
 struct afs_table {
        void (*init)(struct afs_table *t);
        const char *name;
@@ -154,6 +138,7 @@ int score_add(const struct osl_row *row, long score);
 int score_update(const struct osl_row *aft_row, long new_score);
 int get_num_admissible_files(unsigned *num);
 int score_delete(const struct osl_row *aft_row);
+int clear_score_table(void);
 int row_belongs_to_score_table(const struct osl_row *aft_row, unsigned *rank);
 
 /* attribute */
diff --git a/blob.c b/blob.c
index 2abf262..3539453 100644 (file)
--- a/blob.c
+++ b/blob.c
@@ -225,7 +225,7 @@ static int remove_blob(struct osl_table *table, struct osl_row *row,
 
 static int com_rmblob_callback(struct osl_table *table,
                const struct osl_object *query,
-               __a_unused struct osl_object *result)
+               struct osl_object *result)
 {
        int ret;
        struct rmblob_data rmbd = {.num_removed = 0};
@@ -244,14 +244,16 @@ static int com_rmblob_callback(struct osl_table *table,
                para_printf(&rmbd.pb, "%s\n", PARA_STRERROR(-ret));
        if (!rmbd.num_removed)
                para_printf(&rmbd.pb, "no matches, nothing removed\n");
-       else
+       else {
                para_printf(&rmbd.pb, "removed %d blobs\n", rmbd.num_removed);
+               afs_event(BLOB_RENAME, NULL, table);
+       }
        result->data = rmbd.pb.buf;
        result->size = rmbd.pb.size;
        return 1;
 }
 
-static int com_rmblob(callback_function *f, __a_unused int fd, int argc,
+static int com_rmblob(callback_function *f, int fd, int argc,
                char * const * const argv)
 {
        int ret;
@@ -328,7 +330,11 @@ static int com_addblob_callback(struct osl_table *table,
        objs[BLOBCOL_NAME].size = name_len;
        objs[BLOBCOL_DEF].data = name + name_len;
        objs[BLOBCOL_DEF].size = query->size - name_len;
-       return osl_add_row(table, objs);
+       ret = osl_add_row(table, objs);
+       if (ret < 0)
+               return ret;
+       afs_event(BLOB_ADD, NULL, table);
+       return 1;
 }
 
 static int com_addblob(callback_function *f, int fd, int argc,
@@ -360,10 +366,14 @@ static int com_mvblob_callback(struct osl_table *table,
                return ret;
        obj.data = dest;
        obj.size = strlen(dest) + 1;
-       return osl_update_object(table, row, BLOBCOL_NAME, &obj);
+       ret = osl_update_object(table, row, BLOBCOL_NAME, &obj);
+       if (ret < 0)
+               return ret;
+       afs_event(BLOB_RENAME, NULL, table);
+       return 1;
 }
 
-static int com_mvblob(callback_function *f,  __a_unused int fd,
+static int com_mvblob(callback_function *f, __a_unused int fd,
                int argc, char * const * const argv)
 {
        if (argc != 3)
diff --git a/mood.c b/mood.c
index a8d87cd..9074581 100644 (file)
--- a/mood.c
+++ b/mood.c
@@ -1047,10 +1047,14 @@ int reload_current_mood(void)
        int ret;
        char *mood_name;
 
+       PARA_NOTICE_LOG("reloading current mood\n");
        if (!current_mood)
                return 1;
        mood_name = para_strdup(current_mood->name);
        close_current_mood();
+       ret = clear_score_table();
+       if (ret < 0)
+               return ret;
        ret = change_current_mood(mood_name);
        free(mood_name);
        return ret;
@@ -1060,10 +1064,22 @@ int moods_event_handler(enum afs_events event, struct para_buffer *pb,
                void *data)
 {
        switch(event) {
+       /*
+        * The three blob events might change the set of admissible files,
+        * so we must reload the score list.
+        */
+       case BLOB_RENAME:
+       case BLOB_REMOVE:
+       case BLOB_ADD:
+               if (data == moods_table || data == playlists_table)
+                       return 1; /* no reload necessary for these */
+               return reload_current_mood();
+       /* these also require reload of the score table */
        case ATTRIBUTE_ADD:
        case ATTRIBUTE_REMOVE:
        case ATTRIBUTE_RENAME:
                return reload_current_mood();
+       /* changes to the aft only require to re-examine the audio file */
        case AFSI_CHANGE: {
                struct afsi_change_event_data *aced = data;
                return mood_update_audio_file(aced->aft_row, aced->old_afsi);
index 56e19fe..bf8fc73 100644 (file)
@@ -1,3 +1,9 @@
+/*
+ * Copyright (C) 2007 Andre Noll <maan@systemlinux.org>
+ *
+ * Licensed under the GPL v2. For licencing details see COPYING.
+ */
+
 #include "para.h"
 #include "error.h"
 #include "string.h"
diff --git a/score.c b/score.c
index abccb28..6cfa647 100644 (file)
--- a/score.c
+++ b/score.c
@@ -357,20 +357,21 @@ static int score_open(__a_unused const char *dir)
        return osl_open_table(&score_table_desc, &score_table);
 }
 
-static int score_event_handler(enum afs_events event, struct para_buffer *pb,
-               void *data)
+/**
+ * Remove all entries from the score table, but keep the table open.
+ *
+ * \return Standard.
+ */
+int clear_score_table(void)
 {
-       int ret;
+       score_close();
+       return score_open(NULL);
+}
 
-       switch(event) {
-       case ATTRIBUTE_ADD:
-       case ATTRIBUTE_REMOVE:
-       case ATTRIBUTE_RENAME: {
-               score_close();
-               return score_open(NULL);
-               }
-       default: return 1;
-       }
+static int score_event_handler(__a_unused enum afs_events event,
+               __a_unused struct para_buffer *pb, __a_unused void *data)
+{
+       return 1;
 }
 
 /**