[PATCH 1/1] [core] Rework metadata key system



One of the initial goals of Grilo was that metadata keys should be dynamic:
besides having a pre-defined set of keys, both users and plugin's developers
should be able to add their own keys. So far, this goal was not addressed
properly.

The aim of this patch is that users/developers can add their own keys while
keeping one of the key features of current system: comparing keys must be quick
(this is how string-based keys were discarded).

In previously system, GrlKeyID were just numbers; in the new one, GrlKeyID are
pointers to GParamSpec. Being pointers, means that comparison can be done
quickly.

What are the main changes?

- No need for GRLKEYID_TO_POINTER / POINTER_TO_GRLKEYID: keys can be added
  directly to GLists.
- grl_plugin_registry_lookup_metadata_key() changed: returns the GrlKeyID with
  name specified.
- GRL_METADATA_KEY_FOO are still kept, but now they are variables instead of
  definitions.
- No need for GrlMetadataKey: GrlKeyID has the required data. Thus
  GRL_METADATA-KEY_GET_{NAME/ID/DESC} require a GrlKeyID.
- Added grl_plugin_registry_register_metadata_key (): registers a new key in
  the system. Key is built as a GParamSpec.
---
 src/Makefile.am                                    |    9 +-
 src/data/grl-data.c                                |   15 +-
 src/data/grl-media.c                               |   37 ++--
 ...{grl-metadata-key.c => grl-metadata-key-priv.h} |   25 +--
 src/grl-metadata-key.c                             |  214 +++++++++++++++++++-
 src/grl-metadata-key.h                             |  142 +++----------
 src/grl-metadata-source.c                          |   33 ++--
 src/grl-plugin-registry.c                          |  111 +++++-----
 src/grl-plugin-registry.h                          |    7 +-
 tools/grilo-test-ui/main.c                         |    8 +-
 10 files changed, 354 insertions(+), 247 deletions(-)
 copy src/{grl-metadata-key.c => grl-metadata-key-priv.h} (69%)

diff --git a/src/Makefile.am b/src/Makefile.am
index f2c4075..59c35e8 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -21,7 +21,7 @@ lib GRL_NAME@_la_LIBADD =	\
 lib GRL_NAME@_la_SOURCES =					\
 	grl-media-plugin.c grl-media-plugin-priv.h		\
 	grl-plugin-registry.c					\
-	grl-metadata-key.c					\
+	grl-metadata-key.c grl-metadata-key-priv.h		\
 	grl-metadata-source.c grl-metadata-source-priv.h	\
 	grl-media-source.c					\
 	grl-log.c
@@ -61,9 +61,10 @@ data_h_headers =		\
 
 lib GRL_NAME@inc_HEADERS += $(data_h_headers)
 
-noinst_HEADERS =		\
-	grl-media-plugin-priv.h	\
-	grl-metadata-source-priv.h
+noinst_HEADERS =			\
+	grl-media-plugin-priv.h		\
+	grl-metadata-source-priv.h	\
+	grl-metadata-key-priv.h
 
 MAINTAINERCLEANFILES =	\
 	*.in		\
diff --git a/src/data/grl-data.c b/src/data/grl-data.c
index 92a6b53..b6e1e8b 100644
--- a/src/data/grl-data.c
+++ b/src/data/grl-data.c
@@ -174,7 +174,7 @@ grl_data_get (GrlData *data, GrlKeyID key)
 {
   g_return_val_if_fail (GRL_IS_DATA (data), NULL);
 
-  return g_hash_table_lookup (data->priv->data, GRLKEYID_TO_POINTER(key));
+  return g_hash_table_lookup (data->priv->data, key);
 }
 
 /**
@@ -193,8 +193,7 @@ grl_data_set (GrlData *data, GrlKeyID key, const GValue *value)
   g_return_if_fail (GRL_IS_DATA (data));
 
   if (data->priv->overwrite ||
-      g_hash_table_lookup (data->priv->data,
-                           GRLKEYID_TO_POINTER (key)) == NULL) {
+      g_hash_table_lookup (data->priv->data, key) == NULL) {
     /* Dup value */
     if (value) {
       copy = g_new0 (GValue, 1);
@@ -202,7 +201,7 @@ grl_data_set (GrlData *data, GrlKeyID key, const GValue *value)
       g_value_copy (value, copy);
     }
 
-    g_hash_table_insert (data->priv->data, GRLKEYID_TO_POINTER(key), copy);
+    g_hash_table_insert (data->priv->data, key, copy);
   }
 }
 
@@ -362,7 +361,7 @@ grl_data_remove (GrlData *data, GrlKeyID key)
 {
   g_return_if_fail (GRL_IS_DATA (data));
 
-  g_hash_table_remove (data->priv->data, GRLKEYID_TO_POINTER(key));
+  g_hash_table_remove (data->priv->data, key);
 }
 
 /**
@@ -379,8 +378,7 @@ grl_data_has_key (GrlData *data, GrlKeyID key)
 {
   g_return_val_if_fail (GRL_IS_DATA (data), FALSE);
 
-  return g_hash_table_lookup_extended (data->priv->data,
-                                       GRLKEYID_TO_POINTER(key), NULL, NULL);
+  return g_hash_table_lookup_extended (data->priv->data, key, NULL, NULL);
 }
 
 /**
@@ -419,8 +417,7 @@ grl_data_key_is_known (GrlData *data, GrlKeyID key)
 
   g_return_val_if_fail (GRL_IS_DATA (data), FALSE);
 
-  v = g_hash_table_lookup (data->priv->data,
-                           GRLKEYID_TO_POINTER(key));
+  v = g_hash_table_lookup (data->priv->data, key);
 
   if (!v) {
     return FALSE;
diff --git a/src/data/grl-media.c b/src/data/grl-media.c
index 006358b..a16c831 100644
--- a/src/data/grl-media.c
+++ b/src/data/grl-media.c
@@ -204,7 +204,7 @@ grl_media_serialize_extended (GrlMedia *media,
       va_start (va_serial, serial_type);
       keylist = va_arg (va_serial, GList *);
       for (key = keylist; key; key = g_list_next (key)) {
-        grlkey = POINTER_TO_GRLKEYID (key->data);
+        grlkey = key->data;
         /* Skip id and source keys */
         if (grlkey == GRL_METADATA_KEY_ID ||
             grlkey == GRL_METADATA_KEY_SOURCE) {
@@ -214,8 +214,7 @@ grl_media_serialize_extended (GrlMedia *media,
         if (value) {
           g_string_append_printf (serial,
                                   "%s=",
-                                  GRL_METADATA_KEY_GET_NAME (grl_plugin_registry_lookup_metadata_key (registry,
-                                                                                                      grlkey)));
+                                  GRL_METADATA_KEY_GET_NAME (grlkey));
           if (G_VALUE_HOLDS_STRING (value)) {
             g_string_append_uri_escaped (serial,
                                          g_value_get_string (value),
@@ -266,10 +265,10 @@ grl_media_unserialize (const gchar *serial)
   GrlKeyID grlkey;
   GrlMedia *media;
   GrlPluginRegistry *registry;
+  const gchar *keyname;
   gchar *escaped_id;
   gchar *escaped_source;
   gchar *id;
-  gchar *keyname;
   gchar *keyvalue;
   gchar *protocol;
   gchar *query;
@@ -356,29 +355,23 @@ grl_media_unserialize (const gchar *serial)
     registry = grl_plugin_registry_get_instance ();
     keylist = grl_plugin_registry_get_metadata_keys (registry);
     for (key = keylist; key; key = g_list_next (key)) {
-      grlkey = POINTER_TO_GRLKEYID (key->data);
-      keyname =
-        GRL_METADATA_KEY_GET_NAME (grl_plugin_registry_lookup_metadata_key (registry,
-                                                                            grlkey));
+      grlkey = key->data;
+      keyname = GRL_METADATA_KEY_GET_NAME (grlkey);
       keyvalue = g_hash_table_lookup (properties, keyname);
       if (keyvalue) {
-        switch (grlkey) {
-        case GRL_METADATA_KEY_DURATION:
-        case GRL_METADATA_KEY_CHILDCOUNT:
-        case GRL_METADATA_KEY_WIDTH:
-        case GRL_METADATA_KEY_HEIGHT:
-        case GRL_METADATA_KEY_BITRATE:
-        case GRL_METADATA_KEY_PLAY_COUNT:
-        case GRL_METADATA_KEY_LAST_POSITION:
+        if (grlkey == GRL_METADATA_KEY_DURATION ||
+            grlkey == GRL_METADATA_KEY_CHILDCOUNT ||
+            grlkey == GRL_METADATA_KEY_WIDTH ||
+            grlkey == GRL_METADATA_KEY_HEIGHT ||
+            grlkey == GRL_METADATA_KEY_BITRATE ||
+            grlkey == GRL_METADATA_KEY_PLAY_COUNT ||
+            grlkey == GRL_METADATA_KEY_LAST_POSITION) {
           grl_data_set_int (GRL_DATA (media), grlkey, atoi (keyvalue));
-          break;
-        case GRL_METADATA_KEY_FRAMERATE:
-        case GRL_METADATA_KEY_RATING:
+        } else if (grlkey == GRL_METADATA_KEY_FRAMERATE ||
+                   grlkey == GRL_METADATA_KEY_RATING) {
           grl_data_set_float (GRL_DATA (media), grlkey, atof (keyvalue));
-          break;
-        default:
+        } else {
           grl_data_set_string (GRL_DATA (media), grlkey, keyvalue);
-          break;
         }
       }
     }
diff --git a/src/grl-metadata-key.c b/src/grl-metadata-key-priv.h
similarity index 69%
copy from src/grl-metadata-key.c
copy to src/grl-metadata-key-priv.h
index 60bd9dd..d260acb 100644
--- a/src/grl-metadata-key.c
+++ b/src/grl-metadata-key-priv.h
@@ -20,24 +20,13 @@
  *
  */
 
-#include "grl-metadata-key.h"
-
-#include <stdarg.h>
+#ifndef _GRL_METADATA_KEY_PRIV_H_
+#define _GRL_METADATA_KEY_PRIV_H_
 
-GList *
-grl_metadata_key_list_new (GrlKeyID first_key, ...)
-{
-  GList *keylist = NULL;
-  GrlKeyID key;
-  va_list vakeys;
+#include <grl-plugin-registry.h>
+#include "grl-metadata-key.h"
 
-  key = first_key;
-  va_start (vakeys, first_key);
-  while (key) {
-    keylist = g_list_prepend (keylist, GRLKEYID_TO_POINTER (key));
-    key = va_arg (vakeys, GrlKeyID);
-  }
-  va_end (vakeys);
+void
+grl_metadata_key_setup_system_keys (GrlPluginRegistry *registry);
 
-  return g_list_reverse (keylist);
-}
+#endif /* _GRL_METADATA_KEY_PRIV_H_ */
diff --git a/src/grl-metadata-key.c b/src/grl-metadata-key.c
index 60bd9dd..6e2931f 100644
--- a/src/grl-metadata-key.c
+++ b/src/grl-metadata-key.c
@@ -21,9 +21,37 @@
  */
 
 #include "grl-metadata-key.h"
+#include "grl-metadata-key-priv.h"
 
 #include <stdarg.h>
 
+GrlKeyID GRL_METADATA_KEY_ALBUM = NULL;
+GrlKeyID GRL_METADATA_KEY_ARTIST = NULL;
+GrlKeyID GRL_METADATA_KEY_AUTHOR = NULL;
+GrlKeyID GRL_METADATA_KEY_DATE = NULL;
+GrlKeyID GRL_METADATA_KEY_DESCRIPTION = NULL;
+GrlKeyID GRL_METADATA_KEY_GENRE = NULL;
+GrlKeyID GRL_METADATA_KEY_ID = NULL;
+GrlKeyID GRL_METADATA_KEY_LAST_PLAYED = NULL;
+GrlKeyID GRL_METADATA_KEY_LYRICS = NULL;
+GrlKeyID GRL_METADATA_KEY_MIME = NULL;
+GrlKeyID GRL_METADATA_KEY_SITE = NULL;
+GrlKeyID GRL_METADATA_KEY_SOURCE = NULL;
+GrlKeyID GRL_METADATA_KEY_THUMBNAIL = NULL;
+GrlKeyID GRL_METADATA_KEY_TITLE = NULL;
+GrlKeyID GRL_METADATA_KEY_URL = NULL;
+
+GrlKeyID GRL_METADATA_KEY_BITRATE = NULL;
+GrlKeyID GRL_METADATA_KEY_CHILDCOUNT = NULL;
+GrlKeyID GRL_METADATA_KEY_DURATION = NULL;
+GrlKeyID GRL_METADATA_KEY_HEIGHT = NULL;
+GrlKeyID GRL_METADATA_KEY_LAST_POSITION = NULL;
+GrlKeyID GRL_METADATA_KEY_PLAY_COUNT = NULL;
+GrlKeyID GRL_METADATA_KEY_WIDTH = NULL;
+
+GrlKeyID GRL_METADATA_KEY_FRAMERATE = NULL;
+GrlKeyID GRL_METADATA_KEY_RATING = NULL;
+
 GList *
 grl_metadata_key_list_new (GrlKeyID first_key, ...)
 {
@@ -34,10 +62,194 @@ grl_metadata_key_list_new (GrlKeyID first_key, ...)
   key = first_key;
   va_start (vakeys, first_key);
   while (key) {
-    keylist = g_list_prepend (keylist, GRLKEYID_TO_POINTER (key));
+    keylist = g_list_prepend (keylist, key);
     key = va_arg (vakeys, GrlKeyID);
   }
   va_end (vakeys);
 
   return g_list_reverse (keylist);
 }
+
+void
+grl_metadata_key_setup_system_keys (GrlPluginRegistry *registry)
+{
+  GRL_METADATA_KEY_ALBUM =
+    grl_plugin_registry_register_metadata_key (registry,
+                                               g_param_spec_string ("album",
+                                                                    "Album",
+                                                                    "Album the media belongs to",
+                                                                    NULL,
+                                                                    G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE));
+  GRL_METADATA_KEY_ARTIST =
+    grl_plugin_registry_register_metadata_key (registry,
+                                               g_param_spec_string ("artist",
+                                                                    "Artist",
+                                                                    "Main artist",
+                                                                    NULL,
+                                                                    G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE));
+  GRL_METADATA_KEY_AUTHOR =
+    grl_plugin_registry_register_metadata_key (registry,
+                                               g_param_spec_string ("author",
+                                                                    "Author",
+                                                                    "Creator of the media",
+                                                                    NULL,
+                                                                    G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE));
+  GRL_METADATA_KEY_DATE =
+    grl_plugin_registry_register_metadata_key (registry,
+                                               g_param_spec_string ("date",
+                                                                    "Date",
+                                                                    "Publishing or recording date",
+                                                                    NULL,
+                                                                    G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE));
+  GRL_METADATA_KEY_DESCRIPTION =
+    grl_plugin_registry_register_metadata_key (registry,
+                                               g_param_spec_string ("description",
+                                                                    "Description",
+                                                                    "Description of the media",
+                                                                    NULL,
+                                                                    G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE));
+  GRL_METADATA_KEY_GENRE =
+    grl_plugin_registry_register_metadata_key (registry,
+                                               g_param_spec_string ("genre",
+                                                                    "Genre",
+                                                                    "Genre of the media",
+                                                                    NULL,
+                                                                    G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE));
+  GRL_METADATA_KEY_ID =
+    grl_plugin_registry_register_metadata_key (registry,
+                                               g_param_spec_string ("id",
+                                                                    "ID",
+                                                                    "Identifier of media",
+                                                                    NULL,
+                                                                    G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE));
+  GRL_METADATA_KEY_LAST_PLAYED =
+    grl_plugin_registry_register_metadata_key (registry,
+                                               g_param_spec_string ("last-played-time",
+                                                                    "LastPlayedTime",
+                                                                    "Last time the media was played",
+                                                                    NULL,
+                                                                    G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE));
+  GRL_METADATA_KEY_LYRICS =
+    grl_plugin_registry_register_metadata_key (registry,
+                                               g_param_spec_string ("lyrics",
+                                                                    "Lyrics",
+                                                                    "Song lyrics",
+                                                                    NULL,
+                                                                    G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE));
+  GRL_METADATA_KEY_MIME =
+    grl_plugin_registry_register_metadata_key (registry,
+                                               g_param_spec_string ("mime-type",
+                                                                    "MimeType",
+                                                                    "Media mime type",
+                                                                    NULL,
+                                                                    G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE));
+  GRL_METADATA_KEY_SITE =
+    grl_plugin_registry_register_metadata_key (registry,
+                                               g_param_spec_string ("site",
+                                                                    "Site",
+                                                                    "Site",
+                                                                    NULL,
+                                                                    G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE));
+  GRL_METADATA_KEY_SOURCE =
+    grl_plugin_registry_register_metadata_key (registry,
+                                               g_param_spec_string ("source",
+                                                                    "Source",
+                                                                    "Source ID prioviding the content",
+                                                                    NULL,
+                                                                    G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE));
+  GRL_METADATA_KEY_THUMBNAIL =
+    grl_plugin_registry_register_metadata_key (registry,
+                                               g_param_spec_string ("thumbnail",
+                                                                    "Thumbnail",
+                                                                    "Thumbnail image",
+                                                                    NULL,
+                                                                    G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE));
+  GRL_METADATA_KEY_TITLE =
+    grl_plugin_registry_register_metadata_key (registry,
+                                               g_param_spec_string ("title",
+                                                                    "Title",
+                                                                    "Title of the media",
+                                                                    NULL,
+                                                                    G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE));
+  GRL_METADATA_KEY_URL =
+    grl_plugin_registry_register_metadata_key (registry,
+                                               g_param_spec_string ("url",
+                                                                    "URL",
+                                                                    "Media URL",
+                                                                    NULL,
+                                                                    G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE));
+
+  GRL_METADATA_KEY_BITRATE =
+    grl_plugin_registry_register_metadata_key (registry,
+                                               g_param_spec_int ("bitrate",
+                                                                 "Bitrate",
+                                                                 "Media bitrate in KBits/s",
+                                                                 0, G_MAXINT,
+                                                                 0,
+                                                                 G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE));
+  GRL_METADATA_KEY_CHILDCOUNT =
+    grl_plugin_registry_register_metadata_key (registry,
+                                               g_param_spec_int ("childcount",
+                                                                 "Childcount",
+                                                                 "Number of items contained in a container",
+                                                                 -1, G_MAXINT,
+                                                                 GRL_METADATA_KEY_CHILDCOUNT_UNKNOWN,
+                                                                 G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE));
+  GRL_METADATA_KEY_DURATION =
+    grl_plugin_registry_register_metadata_key (registry,
+                                               g_param_spec_int ("duration",
+                                                                 "Duration",
+                                                                 "Media duration",
+                                                                 0, G_MAXINT,
+                                                                 0,
+                                                                 G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE));
+  GRL_METADATA_KEY_HEIGHT =
+    grl_plugin_registry_register_metadata_key (registry,
+                                               g_param_spec_int ("height",
+                                                                 "Height",
+                                                                 "Height of media ('y' resolution)",
+                                                                 0, G_MAXINT,
+                                                                 0,
+                                                                 G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE));
+  GRL_METADATA_KEY_LAST_POSITION =
+    grl_plugin_registry_register_metadata_key (registry,
+                                               g_param_spec_int ("playback-interrupted-time",
+                                                                 "PlaybackInterruptedTime",
+                                                                 "Time at which playback was interrupted",
+                                                                 0, G_MAXINT,
+                                                                 0,
+                                                                 G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE));
+  GRL_METADATA_KEY_PLAY_COUNT =
+    grl_plugin_registry_register_metadata_key (registry,
+                                               g_param_spec_int ("play-count",
+                                                                 "PlayCount",
+                                                                 "How many times media was played",
+                                                                 0, G_MAXINT,
+                                                                 0,
+                                                                 G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE));
+  GRL_METADATA_KEY_WIDTH =
+    grl_plugin_registry_register_metadata_key (registry,
+                                               g_param_spec_int ("width",
+                                                                 "Width",
+                                                                 "Width of media ('x' resolution)",
+                                                                 0, G_MAXINT,
+                                                                 0,
+                                                                 G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE));
+
+  GRL_METADATA_KEY_FRAMERATE =
+    grl_plugin_registry_register_metadata_key (registry,
+                                               g_param_spec_float ("framerate",
+                                                                   "Framerate",
+                                                                   "Frames per second",
+                                                                   0, G_MAXFLOAT,
+                                                                   0,
+                                                                   G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE));
+  GRL_METADATA_KEY_RATING =
+    grl_plugin_registry_register_metadata_key (registry,
+                                               g_param_spec_float ("rating",
+                                                                   "Rating",
+                                                                   "Media rating",
+                                                                   0, G_MAXFLOAT,
+                                                                   0,
+                                                                   G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE));
+}
diff --git a/src/grl-metadata-key.h b/src/grl-metadata-key.h
index 48f36bb..f110c38 100644
--- a/src/grl-metadata-key.h
+++ b/src/grl-metadata-key.h
@@ -28,120 +28,42 @@
 #define _GRL_METADATA_KEY_H_
 
 #include <glib.h>
+#include <glib-object.h>
 
-#define GRL_METADATA_KEY_GET_ID(key)   ((key)->id)
-#define GRL_METADATA_KEY_GET_NAME(key) ((key)->name)
-#define GRL_METADATA_KEY_GET_DESC(key) ((key)->desc)
+#define GRL_METADATA_KEY_GET_ID(key)   (key)
+#define GRL_METADATA_KEY_GET_NAME(key) (g_param_spec_get_name (key))
+#define GRL_METADATA_KEY_GET_DESC(key) (g_param_spec_get_blurb(key))
 
-#define GRL_METADATA_KEY_TITLE              1
-#define GRL_METADATA_KEY_TITLE_NAME         "title"
-#define GRL_METADATA_KEY_TITLE_DESC         "Title of the media"
-
-#define GRL_METADATA_KEY_URL                2
-#define GRL_METADATA_KEY_URL_NAME           "url"
-#define GRL_METADATA_KEY_URL_DESC           "Media URL"
-
-#define GRL_METADATA_KEY_ARTIST             3
-#define GRL_METADATA_KEY_ARTIST_NAME        "artist"
-#define GRL_METADATA_KEY_ARTIST_DESC        "Main artist"
-
-#define GRL_METADATA_KEY_ALBUM              4
-#define GRL_METADATA_KEY_ALBUM_NAME         "album"
-#define GRL_METADATA_KEY_ALBUM_DESC         "Album the media belongs to"
-
-#define GRL_METADATA_KEY_GENRE              5
-#define GRL_METADATA_KEY_GENRE_NAME         "genre"
-#define GRL_METADATA_KEY_GENRE_DESC         "Genre of the media"
-
-#define GRL_METADATA_KEY_THUMBNAIL          6
-#define GRL_METADATA_KEY_THUMBNAIL_NAME     "thumbnail"
-#define GRL_METADATA_KEY_THUMBNAIL_DESC     "Thumbnail image"
-
-#define GRL_METADATA_KEY_ID                 7
-#define GRL_METADATA_KEY_ID_NAME            "id"
-#define GRL_METADATA_KEY_ID_DESC            "Identifier of media"
-
-#define GRL_METADATA_KEY_AUTHOR             8
-#define GRL_METADATA_KEY_AUTHOR_NAME        "author"
-#define GRL_METADATA_KEY_AUTHOR_DESC        "Creator of the media"
-
-#define GRL_METADATA_KEY_DESCRIPTION        9
-#define GRL_METADATA_KEY_DESCRIPTION_NAME   "description"
-#define GRL_METADATA_KEY_DESCRIPTION_DESC   "Description of the media"
-
-#define GRL_METADATA_KEY_SOURCE             10
-#define GRL_METADATA_KEY_SOURCE_NAME        "source"
-#define GRL_METADATA_KEY_SOURCE_DESC        "Source ID providing the content"
-
-#define GRL_METADATA_KEY_LYRICS             11
-#define GRL_METADATA_KEY_LYRICS_NAME        "lyrics"
-#define GRL_METADATA_KEY_LYRICS_DESC        "Song lyrics"
-
-#define GRL_METADATA_KEY_SITE               12
-#define GRL_METADATA_KEY_SITE_NAME          "site"
-#define GRL_METADATA_KEY_SITE_DESC          "Site"
-
-#define GRL_METADATA_KEY_DURATION           13
-#define GRL_METADATA_KEY_DURATION_NAME      "duration"
-#define GRL_METADATA_KEY_DURATION_DESC      "Media duration"
-
-#define GRL_METADATA_KEY_DATE               14
-#define GRL_METADATA_KEY_DATE_NAME          "date"
-#define GRL_METADATA_KEY_DATE_DESC          "Publishing or recording date"
-
-#define GRL_METADATA_KEY_CHILDCOUNT         15
-#define GRL_METADATA_KEY_CHILDCOUNT_NAME    "childcount"
-#define GRL_METADATA_KEY_CHILDCOUNT_DESC    "Number of items contained in a container"
 #define GRL_METADATA_KEY_CHILDCOUNT_UNKNOWN -1
 
-#define GRL_METADATA_KEY_MIME               16
-#define GRL_METADATA_KEY_MIME_NAME          "mime-type"
-#define GRL_METADATA_KEY_MIME_DESC          "Media mime type"
-
-#define GRL_METADATA_KEY_WIDTH              17
-#define GRL_METADATA_KEY_WIDTH_NAME         "width"
-#define GRL_METADATA_KEY_WIDTH_DESC         "Width of media ('x' resolution)"
-
-#define GRL_METADATA_KEY_HEIGHT             18
-#define GRL_METADATA_KEY_HEIGHT_NAME        "height"
-#define GRL_METADATA_KEY_HEIGHT_DESC        "height of media ('y' resolution)"
-
-#define GRL_METADATA_KEY_FRAMERATE          19
-#define GRL_METADATA_KEY_FRAMERATE_NAME     "framerate"
-#define GRL_METADATA_KEY_FRAMERATE_DESC     "Frames per second"
-
-#define GRL_METADATA_KEY_RATING             20
-#define GRL_METADATA_KEY_RATING_NAME        "rating"
-#define GRL_METADATA_KEY_RATING_DESC        "Media rating"
-
-#define GRL_METADATA_KEY_BITRATE            21
-#define GRL_METADATA_KEY_BITRATE_NAME       "bitrate"
-#define GRL_METADATA_KEY_BITRATE_DESC       "Media bitrate in Kbits/s"
-
-#define GRL_METADATA_KEY_PLAY_COUNT         22
-#define GRL_METADATA_KEY_PLAY_COUNT_NAME    "play-count"
-#define GRL_METADATA_KEY_PLAY_COUNT_DESC    "Media play count"
-
-#define GRL_METADATA_KEY_LAST_PLAYED        23
-#define GRL_METADATA_KEY_LAST_PLAYED_NAME   "last-played-time"
-#define GRL_METADATA_KEY_LAST_PLAYED_DESC   "Last time the media was played"
-
-#define GRL_METADATA_KEY_LAST_POSITION      24
-#define GRL_METADATA_KEY_LAST_POSITION_NAME "playback-interrupted-time"
-#define GRL_METADATA_KEY_LAST_POSITION_DESC "Time at which playback was interrupted"
-
-#define GRL_KEYID_FORMAT "u"
-
-#define POINTER_TO_GRLKEYID(p) GPOINTER_TO_UINT((p))
-#define GRLKEYID_TO_POINTER(m) GUINT_TO_POINTER((m))
-
-typedef guint GrlKeyID;
-
-typedef struct {
-  GrlKeyID id;
-  gchar *name;
-  gchar *desc;
-} GrlMetadataKey;
+typedef GParamSpec* GrlKeyID;
+
+extern GrlKeyID GRL_METADATA_KEY_TITLE;
+extern GrlKeyID GRL_METADATA_KEY_URL;
+extern GrlKeyID GRL_METADATA_KEY_ARTIST;
+extern GrlKeyID GRL_METADATA_KEY_ALBUM;
+extern GrlKeyID GRL_METADATA_KEY_GENRE;
+extern GrlKeyID GRL_METADATA_KEY_THUMBNAIL;
+extern GrlKeyID GRL_METADATA_KEY_ID;
+extern GrlKeyID GRL_METADATA_KEY_AUTHOR;
+extern GrlKeyID GRL_METADATA_KEY_DESCRIPTION;
+extern GrlKeyID GRL_METADATA_KEY_SOURCE;
+extern GrlKeyID GRL_METADATA_KEY_LYRICS;
+extern GrlKeyID GRL_METADATA_KEY_SITE;
+extern GrlKeyID GRL_METADATA_KEY_DURATION;
+extern GrlKeyID GRL_METADATA_KEY_DATE;
+extern GrlKeyID GRL_METADATA_KEY_CHILDCOUNT;
+extern GrlKeyID GRL_METADATA_KEY_MIME;
+extern GrlKeyID GRL_METADATA_KEY_WIDTH;
+extern GrlKeyID GRL_METADATA_KEY_HEIGHT;
+extern GrlKeyID GRL_METADATA_KEY_FRAMERATE;
+extern GrlKeyID GRL_METADATA_KEY_RATING;
+extern GrlKeyID GRL_METADATA_KEY_BITRATE;
+extern GrlKeyID GRL_METADATA_KEY_PLAY_COUNT;
+extern GrlKeyID GRL_METADATA_KEY_LAST_PLAYED;
+extern GrlKeyID GRL_METADATA_KEY_LAST_POSITION;
+
+#define GRL_KEYID_FORMAT "p"
 
 G_BEGIN_DECLS
 
diff --git a/src/grl-metadata-source.c b/src/grl-metadata-source.c
index e8c7e5f..d98c6eb 100644
--- a/src/grl-metadata-source.c
+++ b/src/grl-metadata-source.c
@@ -260,7 +260,7 @@ print_keys (gchar *label, const GList *keys)
 {
   g_print ("%s: [", label);
   while (keys) {
-    g_print (" %" GRL_KEYID_FORMAT, POINTER_TO_GRLKEYID (keys->data));
+    g_print (" %" GRL_KEYID_FORMAT, keys->data);
     keys = g_list_next (keys);
   }
   g_print (" ]\n");
@@ -620,7 +620,6 @@ grl_metadata_source_filter_supported (GrlMetadataSource *source,
   GList *filtered_keys = NULL;
   gboolean got_match;
   GList *iter_keys_prev;
-  GrlKeyID supported_key;
 
   g_return_val_if_fail (GRL_IS_METADATA_SOURCE (source), NULL);
 
@@ -631,10 +630,9 @@ grl_metadata_source_filter_supported (GrlMetadataSource *source,
     got_match = FALSE;
     iter_supported = (GList *) supported_keys;
 
-    key = POINTER_TO_GRLKEYID (iter_keys->data);
+    key = iter_keys->data;
     while (!got_match && iter_supported) {
-      supported_key = POINTER_TO_GRLKEYID (iter_supported->data);
-      if (key == supported_key) {
+      if (key == iter_supported->data) {
 	got_match = TRUE;
       }
       iter_supported = g_list_next (iter_supported);
@@ -645,8 +643,7 @@ grl_metadata_source_filter_supported (GrlMetadataSource *source,
 
     if (got_match) {
       if (return_filtered) {
-	filtered_keys = g_list_prepend (filtered_keys,
-                                        GRLKEYID_TO_POINTER (key));
+	filtered_keys = g_list_prepend (filtered_keys, key);
       }
       *keys = g_list_delete_link (*keys, iter_keys_prev);
       got_match = FALSE;
@@ -677,7 +674,6 @@ grl_metadata_source_filter_slow (GrlMetadataSource *source,
   const GList *slow_keys;
   GList *iter_slow;
   GList *iter_keys;
-  GrlKeyID key;
   GList *filtered_keys = NULL;
   gboolean got_match;
   GrlKeyID slow_key;
@@ -698,10 +694,9 @@ grl_metadata_source_filter_slow (GrlMetadataSource *source,
     got_match = FALSE;
     iter_keys = *keys;
 
-    slow_key = POINTER_TO_GRLKEYID (iter_slow->data);
+    slow_key = iter_slow->data;
     while (!got_match && iter_keys) {
-      key = POINTER_TO_GRLKEYID (iter_keys->data);
-      if (key == slow_key) {
+      if (iter_keys->data == slow_key) {
 	got_match = TRUE;
       } else {
 	iter_keys = g_list_next (iter_keys);
@@ -713,7 +708,7 @@ grl_metadata_source_filter_slow (GrlMetadataSource *source,
     if (got_match) {
       if (return_filtered) {
 	filtered_keys =
-	  g_list_prepend (filtered_keys, GRLKEYID_TO_POINTER (slow_key));
+	  g_list_prepend (filtered_keys, slow_key);
       }
       *keys = g_list_delete_link (*keys, iter_keys);
       got_match = FALSE;
@@ -744,7 +739,6 @@ grl_metadata_source_filter_writable (GrlMetadataSource *source,
   const GList *writable_keys;
   GList *iter_writable;
   GList *iter_keys;
-  GrlKeyID key;
   GList *filtered_keys = NULL;
   gboolean got_match;
   GrlKeyID writable_key;
@@ -767,10 +761,9 @@ grl_metadata_source_filter_writable (GrlMetadataSource *source,
     got_match = FALSE;
     iter_keys = *keys;
 
-    writable_key = POINTER_TO_GRLKEYID (iter_writable->data);
+    writable_key = iter_writable->data;
     while (!got_match && iter_keys) {
-      key = POINTER_TO_GRLKEYID (iter_keys->data);
-      if (key == writable_key) {
+      if (iter_keys->data == writable_key) {
 	got_match = TRUE;
       } else {
 	iter_keys = g_list_next (iter_keys);
@@ -782,7 +775,7 @@ grl_metadata_source_filter_writable (GrlMetadataSource *source,
     if (got_match) {
       if (return_filtered) {
 	filtered_keys =
-	  g_list_prepend (filtered_keys, GRLKEYID_TO_POINTER (writable_key));
+	  g_list_prepend (filtered_keys, writable_key);
       }
       *keys = g_list_delete_link (*keys, iter_keys);
       got_match = FALSE;
@@ -871,7 +864,7 @@ grl_metadata_source_setup_full_resolution_mode (GrlMetadataSource *source,
     GList *iter_prev;
     iter = supported_keys;
     while (iter) {
-      GrlKeyID key = POINTER_TO_GRLKEYID (iter->data);
+      GrlKeyID key = iter->data;
       GList *deps =
 	g_list_copy ((GList *) grl_metadata_source_key_depends (_source, key));
 
@@ -883,7 +876,7 @@ grl_metadata_source_setup_full_resolution_mode (GrlMetadataSource *source,
       if (!deps) {
 	g_debug ("    Key '%" GRL_KEYID_FORMAT "' cannot be resolved from metadata", key);
 	supported_keys = g_list_delete_link (supported_keys, iter_prev);
-	key_list = g_list_prepend (key_list, GRLKEYID_TO_POINTER (key));
+	key_list = g_list_prepend (key_list, key);
 	continue;
       }
       g_debug ("    Key '%" GRL_KEYID_FORMAT "' might be resolved using external metadata", key);
@@ -901,7 +894,7 @@ grl_metadata_source_setup_full_resolution_mode (GrlMetadataSource *source,
 	  g_list_delete_link (supported_keys, iter_prev);
 	/* Put the key back in the list, maybe some other soure can
 	   resolve it */
-	key_list = g_list_prepend (key_list, GRLKEYID_TO_POINTER (key));
+	key_list = g_list_prepend (key_list, key);
       } else {
 	g_debug ("      Dependencies supported by source, including key");
 	/* Add these dependencies to the list of keys for
diff --git a/src/grl-plugin-registry.c b/src/grl-plugin-registry.c
index 1fe7e13..f573cd5 100644
--- a/src/grl-plugin-registry.c
+++ b/src/grl-plugin-registry.c
@@ -39,14 +39,12 @@
 
 #include "grl-plugin-registry.h"
 #include "grl-media-plugin-priv.h"
-
+#include "grl-metadata-key-priv.h"
 #include "config.h"
 
 #include <string.h>
 #include <gmodule.h>
 
-#define SYSTEM_KEYS_MAX 256
-
 #define GRL_PLUGIN_PATH_DEFAULT GRL_PLUGINS_DIR
 
 #undef G_LOG_DOMAIN
@@ -57,21 +55,14 @@
                                GRL_TYPE_PLUGIN_REGISTRY,        \
                                GrlPluginRegistryPrivate))
 
-#define GRL_REGISTER_SYSTEM_METADATA_KEY(r, key)        \
-  { r->priv->system_keys[key].id = key;			\
-    r->priv->system_keys[key].name = key##_NAME;	\
-    r->priv->system_keys[key].desc = key##_DESC;	\
-  }
-
 struct _GrlPluginRegistryPrivate {
   GHashTable *configs;
   GHashTable *plugins;
   GHashTable *sources;
-  GrlMetadataKey *system_keys;
+  GParamSpecPool *system_keys;
   GHashTable *ranks;
 };
 
-static void grl_plugin_registry_setup_system_keys (GrlPluginRegistry *registry);
 static void grl_plugin_registry_setup_ranks (GrlPluginRegistry *registry);
 
 /* ================ GrlPluginRegistry GObject ================ */
@@ -139,45 +130,16 @@ grl_plugin_registry_init (GrlPluginRegistry *registry)
   registry->priv->plugins = g_hash_table_new (g_str_hash, g_str_equal);
   registry->priv->sources =
     g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+  registry->priv->system_keys =
+    g_param_spec_pool_new (FALSE);
 
-  grl_plugin_registry_setup_system_keys (registry);
+  grl_metadata_key_setup_system_keys (registry);
   grl_plugin_registry_setup_ranks (registry);
 }
 
 /* ================ Utitilies ================ */
 
 static void
-grl_plugin_registry_setup_system_keys (GrlPluginRegistry *registry)
-{
-  registry->priv->system_keys = g_new0 (GrlMetadataKey, SYSTEM_KEYS_MAX);
-
-  GRL_REGISTER_SYSTEM_METADATA_KEY (registry, GRL_METADATA_KEY_TITLE);
-  GRL_REGISTER_SYSTEM_METADATA_KEY (registry, GRL_METADATA_KEY_URL);
-  GRL_REGISTER_SYSTEM_METADATA_KEY (registry, GRL_METADATA_KEY_ARTIST);
-  GRL_REGISTER_SYSTEM_METADATA_KEY (registry, GRL_METADATA_KEY_ALBUM);
-  GRL_REGISTER_SYSTEM_METADATA_KEY (registry, GRL_METADATA_KEY_GENRE);
-  GRL_REGISTER_SYSTEM_METADATA_KEY (registry, GRL_METADATA_KEY_THUMBNAIL);
-  GRL_REGISTER_SYSTEM_METADATA_KEY (registry, GRL_METADATA_KEY_ID);
-  GRL_REGISTER_SYSTEM_METADATA_KEY (registry, GRL_METADATA_KEY_AUTHOR);
-  GRL_REGISTER_SYSTEM_METADATA_KEY (registry, GRL_METADATA_KEY_DESCRIPTION);
-  GRL_REGISTER_SYSTEM_METADATA_KEY (registry, GRL_METADATA_KEY_SOURCE);
-  GRL_REGISTER_SYSTEM_METADATA_KEY (registry, GRL_METADATA_KEY_LYRICS);
-  GRL_REGISTER_SYSTEM_METADATA_KEY (registry, GRL_METADATA_KEY_SITE);
-  GRL_REGISTER_SYSTEM_METADATA_KEY (registry, GRL_METADATA_KEY_DURATION);
-  GRL_REGISTER_SYSTEM_METADATA_KEY (registry, GRL_METADATA_KEY_DATE);
-  GRL_REGISTER_SYSTEM_METADATA_KEY (registry, GRL_METADATA_KEY_CHILDCOUNT);
-  GRL_REGISTER_SYSTEM_METADATA_KEY (registry, GRL_METADATA_KEY_MIME);
-  GRL_REGISTER_SYSTEM_METADATA_KEY (registry, GRL_METADATA_KEY_WIDTH);
-  GRL_REGISTER_SYSTEM_METADATA_KEY (registry, GRL_METADATA_KEY_HEIGHT);
-  GRL_REGISTER_SYSTEM_METADATA_KEY (registry, GRL_METADATA_KEY_FRAMERATE);
-  GRL_REGISTER_SYSTEM_METADATA_KEY (registry, GRL_METADATA_KEY_RATING);
-  GRL_REGISTER_SYSTEM_METADATA_KEY (registry, GRL_METADATA_KEY_BITRATE);
-  GRL_REGISTER_SYSTEM_METADATA_KEY (registry, GRL_METADATA_KEY_PLAY_COUNT);
-  GRL_REGISTER_SYSTEM_METADATA_KEY (registry, GRL_METADATA_KEY_LAST_PLAYED);
-  GRL_REGISTER_SYSTEM_METADATA_KEY (registry, GRL_METADATA_KEY_LAST_POSITION);
-}
-
-static void
 config_plugin_rank (GrlPluginRegistry *registry,
 		    const gchar *plugin_id,
 		    gint rank)
@@ -603,20 +565,49 @@ grl_plugin_registry_unload (GrlPluginRegistry *registry,
   }
 }
 
+const GrlKeyID
+grl_plugin_registry_register_metadata_key (GrlPluginRegistry *registry,
+                                           GParamSpec *key)
+{
+  g_return_val_if_fail (GRL_IS_PLUGIN_REGISTRY (registry), NULL);
+  g_return_val_if_fail (G_IS_PARAM_SPEC (key), NULL);
+
+  /* Check if key is already registered */
+  if (g_param_spec_pool_lookup (registry->priv->system_keys,
+                                g_param_spec_get_name (key),
+                                GRL_TYPE_MEDIA,
+                                FALSE)) {
+    g_warning ("metadata key '%s' already registered",
+               g_param_spec_get_name (key));
+    return NULL;
+  } else {
+    g_param_spec_pool_insert (registry->priv->system_keys,
+                              key,
+                              GRL_TYPE_MEDIA);
+    return key;
+  }
+}
+
 /**
  * grl_plugin_registry_lookup_metadata_key:
  * @registry: the registry instance
- * @key_id: the key identifier
+ * @key_id: the key name
  *
- * Look up for the metadata key structure givne the @key_id.
+ * Look up for the metadata key with name @key_name.
  *
- * Returns: (transfer none): The metadata key structure.
+ * Returns: (transfer none): The metadata key, or @NULL if not found
  */
-const GrlMetadataKey *
+const GrlKeyID
 grl_plugin_registry_lookup_metadata_key (GrlPluginRegistry *registry,
-                                         GrlKeyID key_id)
+                                         const gchar *key_name)
 {
-  return &registry->priv->system_keys[key_id];
+  g_return_val_if_fail (GRL_IS_PLUGIN_REGISTRY (registry), NULL);
+  g_return_val_if_fail (key_name, NULL);
+
+  return g_param_spec_pool_lookup (registry->priv->system_keys,
+                                   key_name,
+                                   GRL_TYPE_MEDIA,
+                                   FALSE);
 }
 
 /**
@@ -630,16 +621,26 @@ grl_plugin_registry_lookup_metadata_key (GrlPluginRegistry *registry,
 GList *
 grl_plugin_registry_get_metadata_keys (GrlPluginRegistry *registry)
 {
-  GrlKeyID last_key = GRL_METADATA_KEY_LAST_POSITION;
-  GrlKeyID key;
-  GList *keys = NULL;
+  GList *key_list = NULL;
+  GParamSpec **keys;
+  guint i;
+  guint keys_length;
 
-  for (key = last_key; key > 0; key--) {
-    keys = g_list_prepend (keys, GRLKEYID_TO_POINTER (key));
+  g_return_val_if_fail (GRL_IS_PLUGIN_REGISTRY (registry), NULL);
+
+  keys = g_param_spec_pool_list (registry->priv->system_keys,
+                                 GRL_TYPE_MEDIA,
+                                 &keys_length);
+
+  for (i = 0; i < keys_length; i++) {
+    key_list = g_list_prepend (key_list, keys[i]);
   }
 
-  return g_list_reverse (keys);
+  g_free (keys);
+
+  return key_list;
 }
+
 /**
  * grl_plugin_registry_add_config:
  * @registry: the registry instance
diff --git a/src/grl-plugin-registry.h b/src/grl-plugin-registry.h
index b925cb6..d0b6dbb 100644
--- a/src/grl-plugin-registry.h
+++ b/src/grl-plugin-registry.h
@@ -240,8 +240,11 @@ GrlMediaPlugin **grl_plugin_registry_get_sources_by_operations (GrlPluginRegistr
                                                                 GrlSupportedOps ops,
                                                                 gboolean ranked);
 
-const GrlMetadataKey *grl_plugin_registry_lookup_metadata_key (GrlPluginRegistry *registry,
-                                                               GrlKeyID key_id);
+const GrlKeyID grl_plugin_registry_register_metadata_key (GrlPluginRegistry *registry,
+                                                          GParamSpec *key);
+
+const GrlKeyID grl_plugin_registry_lookup_metadata_key (GrlPluginRegistry *registry,
+                                                        const gchar *key_name);
 
 GList *grl_plugin_registry_get_metadata_keys (GrlPluginRegistry *registry);
 
diff --git a/tools/grilo-test-ui/main.c b/tools/grilo-test-ui/main.c
index 148cce9..edeae1d 100644
--- a/tools/grilo-test-ui/main.c
+++ b/tools/grilo-test-ui/main.c
@@ -404,16 +404,12 @@ metadata_cb (GrlMediaSource *source,
     keys = grl_data_get_keys (GRL_DATA (media));
     i = keys;
     while (i) {
-      const GrlMetadataKey *key =
-	grl_plugin_registry_lookup_metadata_key (registry,
-                                                 POINTER_TO_GRLKEYID (i->data));
-      const GValue *g_value = grl_data_get (GRL_DATA (media),
-                                               POINTER_TO_GRLKEYID (i->data));
+      const GValue *g_value = grl_data_get (GRL_DATA (media), i->data);
       gchar *value = g_value ? g_strdup_value_contents (g_value) : "";
       gtk_list_store_append (GTK_LIST_STORE (view->metadata_model), &iter);
       gtk_list_store_set (GTK_LIST_STORE (view->metadata_model),
 			  &iter,
-			  METADATA_MODEL_NAME, GRL_METADATA_KEY_GET_NAME (key),
+			  METADATA_MODEL_NAME, GRL_METADATA_KEY_GET_NAME (i->data),
 			  METADATA_MODEL_VALUE, value,
 			  -1);
       i = g_list_next (i);
-- 
1.7.0.4



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]