[glib-controller] Pass the index type when creating a new Reference



commit 349cb717871928bb4feeca2de95af63c682ef4af
Author: Emmanuele Bassi <ebassi linux intel com>
Date:   Fri Apr 30 12:43:54 2010 +0100

    Pass the index type when creating a new Reference
    
    Instead of requiring the hard-coding of the index type inside the
    GController sub-classes we can pass it as a parameter when creating
    the GControllerReference.
    
    The main rationale for this change is that some data types, like
    GHashTable, can have a typed index - e.g. a string, or an integer
    pointer, or a direct pointer comparison; it makes sense to allow
    passing the type of the indices along when creating the reference
    so that the GController's logic resides entirely in the base class
    while leaving the option to override the reference creation entirely.
    
    Along with the index type we should also pass the GControllerAction,
    so that it gets stored inside the GControllerReference; this allows
    storing references and querying the action that led to their creation
    at any later point in the application logic.

 glib-controller/garraycontroller.c       |   10 ----
 glib-controller/gcontroller.c            |   71 ++++++++++++++---------------
 glib-controller/gcontroller.h            |   13 +++--
 glib-controller/gcontrollerreference.c   |   53 ++++++++++++++++++++++
 glib-controller/gcontrollerreference.h   |    1 +
 glib-controller/gcontrollertypes.h       |    5 +-
 glib-controller/ghashcontroller.c        |   10 ----
 glib-controller/gptrarraycontroller.c    |   10 ----
 glib-controller/tests/array-controller.c |    8 ++-
 glib-controller/tests/hash-controller.c  |   10 ++--
 10 files changed, 109 insertions(+), 82 deletions(-)
---
diff --git a/glib-controller/garraycontroller.c b/glib-controller/garraycontroller.c
index 4a0e02c..eb4bd9b 100644
--- a/glib-controller/garraycontroller.c
+++ b/glib-controller/garraycontroller.c
@@ -28,13 +28,6 @@ enum
 
 G_DEFINE_TYPE (GArrayController, g_array_controller, G_TYPE_CONTROLLER);
 
-static GType
-get_index_type (GController *controller)
-{
-  /* GArray indexes are unsigned integers */
-  return G_TYPE_UINT;
-}
-
 static void
 g_array_controller_set_property (GObject      *gobject,
                                  guint         prop_id,
@@ -89,12 +82,9 @@ g_array_controller_finalize (GObject *gobject)
 static void
 g_array_controller_class_init (GArrayControllerClass *klass)
 {
-  GControllerClass *controller_class = G_CONTROLLER_CLASS (klass);
   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
   GParamSpec *pspec;
 
-  controller_class->get_index_type = get_index_type;
-
   gobject_class->set_property = g_array_controller_set_property;
   gobject_class->get_property = g_array_controller_get_property;
   gobject_class->finalize = g_array_controller_finalize;
diff --git a/glib-controller/gcontroller.c b/glib-controller/gcontroller.c
index f367459..079684b 100644
--- a/glib-controller/gcontroller.c
+++ b/glib-controller/gcontroller.c
@@ -37,28 +37,17 @@ static guint controller_signals[LAST_SIGNAL] = { 0, };
 
 G_DEFINE_ABSTRACT_TYPE (GController, g_controller, G_TYPE_OBJECT);
 
-static GType
-get_index_type (GController *controller)
-{
-  return G_TYPE_INVALID;
-}
-
 static GControllerReference *
-create_reference (GController *controller,
-                  GValueArray *indices)
+create_reference (GController       *controller,
+                  GControllerAction  action,
+                  GType              index_type,
+                  GValueArray       *indices)
 {
-  GType index_type;
-
-  index_type = G_CONTROLLER_GET_CLASS (controller)->get_index_type (controller);
-  if (G_UNLIKELY (index_type == G_TYPE_INVALID))
-    {
-      g_critical ("The GController of type '%s' has an invalid index type",
-                  G_OBJECT_TYPE_NAME (controller));
-      return NULL;
-    }
+  g_assert (index_type != G_TYPE_INVALID);
 
   return g_object_new (G_TYPE_CONTROLLER_REFERENCE,
                        "controller", controller,
+                       "action", action,
                        "index-type", index_type,
                        "indices", indices,
                        NULL);
@@ -67,7 +56,6 @@ create_reference (GController *controller,
 static void
 g_controller_class_init (GControllerClass *klass)
 {
-  klass->get_index_type = get_index_type;
   klass->create_reference = create_reference;
 
   /**
@@ -107,15 +95,22 @@ g_controller_init (GController *self)
 }
 
 static GControllerReference *
-g_controller_create_reference_internal (GController *controller,
-                                        GValueArray *indices)
+g_controller_create_reference_internal (GController       *controller,
+                                        GControllerAction  action,
+                                        GType              index_type,
+                                        GValueArray       *indices)
 {
-  return G_CONTROLLER_GET_CLASS (controller)->create_reference (controller, indices);
+  return G_CONTROLLER_GET_CLASS (controller)->create_reference (controller,
+                                                                action,
+                                                                index_type,
+                                                                indices);
 }
 
 /**
  * g_controller_create_referencev
  * @controller: a #GController
+ * @action: the action for the reference
+ * @index_type: the type of the indices
  * @indices: (allow-none): a #GValueArray containing the indices
  *
  * Creates a new #GControllerReference for the given indices
@@ -133,17 +128,22 @@ g_controller_create_reference_internal (GController *controller,
  *   instance. Use g_object_unref() when done using the returned object
  */
 GControllerReference *
-g_controller_create_referencev (GController *controller,
-                                GValueArray *indices)
+g_controller_create_referencev (GController       *controller,
+                                GControllerAction  action,
+                                GType              index_type,
+                                GValueArray       *indices)
 {
   g_return_val_if_fail (G_IS_CONTROLLER (controller), NULL);
+  g_return_val_if_fail (index_type != G_TYPE_INVALID, NULL);
 
-  return g_controller_create_reference_internal (controller, indices);
+  return g_controller_create_reference_internal (controller, action, index_type, indices);
 }
 
 /**
  * g_controller_create_reference:
  * @controller: a #GController
+ * @action: the action for the reference
+ * @index_type: the type of the indices
  * @n_indices: the number of indices, or 0 to create an empty reference
  * @VarArgs: the indices
  *
@@ -156,28 +156,22 @@ g_controller_create_referencev (GController *controller,
  *   instance. Use g_object_unref() when done using the returned object
  */
 GControllerReference *
-g_controller_create_reference (GController *controller,
-                               gint         n_indices,
+g_controller_create_reference (GController       *controller,
+                               GControllerAction  action,
+                               GType              index_type,
+                               gint               n_indices,
                                ...)
 {
   GControllerReference *ref;
   GValueArray *indices;
-  GType index_type;
   va_list args;
   gint i;
 
   g_return_val_if_fail (G_IS_CONTROLLER (controller), NULL);
-
-  index_type = G_CONTROLLER_GET_CLASS (controller)->get_index_type (controller);
-  if (G_UNLIKELY (index_type == G_TYPE_INVALID))
-    {
-      g_critical ("The GController of type '%s' has an invalid index type",
-                  G_OBJECT_TYPE_NAME (controller));
-      return NULL;
-    }
+  g_return_val_if_fail (index_type != G_TYPE_INVALID, NULL);
 
   if (n_indices == 0)
-    return g_controller_create_reference_internal (controller, NULL);
+    return g_controller_create_reference_internal (controller, action, index_type, NULL);
 
   indices = g_value_array_new (n_indices);
 
@@ -211,7 +205,10 @@ g_controller_create_reference (GController *controller,
 
   va_end (args);
 
-  ref = g_controller_create_reference_internal (controller, indices);
+  ref = g_controller_create_reference_internal (controller,
+                                                action,
+                                                index_type,
+                                                indices);
 
   g_value_array_free (indices);
 
diff --git a/glib-controller/gcontroller.h b/glib-controller/gcontroller.h
index c29a672..834cc4d 100644
--- a/glib-controller/gcontroller.h
+++ b/glib-controller/gcontroller.h
@@ -23,8 +23,6 @@ struct _GController
 
 /**
  * GControllerClass:
- * @get_index_type: virtual function; sub-classes should return the type
- *   of the index inside a #GControllerReference
  * @create_reference: virtual function; sub-classes should create a new
  *   #GControllerReference instance for the given indexes
  * @changed: class handler for the #GController::changed signal
@@ -40,8 +38,9 @@ struct _GControllerClass
   /*< public >*/
 
   /* virtual functions */
-  GType                 (* get_index_type)   (GController          *controller);
   GControllerReference *(* create_reference) (GController          *controller,
+                                              GControllerAction     action,
+                                              GType                 index_type,
                                               GValueArray          *indexes);
 
   /* signals */
@@ -65,10 +64,14 @@ struct _GControllerClass
 GType g_controller_get_type (void) G_GNUC_CONST;
 
 GControllerReference *g_controller_create_reference  (GController          *controller,
-                                                      gint                  n_items,
+                                                      GControllerAction     action,
+                                                      GType                 index_type,
+                                                      gint                  n_indices,
                                                       ...);
 GControllerReference *g_controller_create_referencev (GController          *controller,
-                                                      GValueArray          *indexes);
+                                                      GControllerAction     action,
+                                                      GType                 index_type,
+                                                      GValueArray          *indices);
 
 void                  g_controller_emit_changed      (GController          *controller,
                                                       GControllerAction     action,
diff --git a/glib-controller/gcontrollerreference.c b/glib-controller/gcontrollerreference.c
index 3446183..f19067a 100644
--- a/glib-controller/gcontrollerreference.c
+++ b/glib-controller/gcontrollerreference.c
@@ -19,6 +19,8 @@
 
 #include "gcontrollerreference.h"
 #include "gcontroller.h"
+#include "gcontrollerenumtypes.h"
+#include "gcontrollertypes.h"
 
 #include <gobject/gvaluecollector.h>
 
@@ -26,6 +28,8 @@ struct _GControllerReferencePrivate
 {
   GController *controller;
 
+  GControllerAction action;
+
   GType index_type;
   GValueArray *indices;
 };
@@ -35,6 +39,7 @@ enum
   PROP_0,
 
   PROP_CONTROLLER,
+  PROP_ACTION,
   PROP_INDEX_TYPE,
   PROP_INDICES
 };
@@ -68,6 +73,13 @@ g_controller_reference_constructed (GObject *gobject)
 
   g_assert (G_IS_CONTROLLER (priv->controller));
 
+  if (priv->action == G_CONTROLLER_INVALID_ACTION)
+    {
+      g_critical ("The constructed reference for the GController "
+                  "of type '%s' does not have a valid action.",
+                  G_OBJECT_TYPE_NAME (priv->controller));
+    }
+
   if (priv->index_type == G_TYPE_INVALID)
     {
       g_critical ("The constructed reference for the GController "
@@ -90,6 +102,10 @@ g_controller_reference_set_property (GObject      *gobject,
       priv->controller = g_object_ref (g_value_get_object (value));
       break;
 
+    case PROP_ACTION:
+      priv->action = g_value_get_enum (value);
+      break;
+
     case PROP_INDEX_TYPE:
       priv->index_type = g_value_get_gtype (value);
       break;
@@ -118,6 +134,10 @@ g_controller_reference_get_property (GObject    *gobject,
       g_value_set_object (value, priv->controller);
       break;
 
+    case PROP_ACTION:
+      g_value_set_enum (value, priv->action);
+      break;
+
     case PROP_INDEX_TYPE:
       g_value_set_gtype (value, priv->index_type);
       break;
@@ -186,6 +206,21 @@ g_controller_reference_class_init (GControllerReferenceClass *klass)
   g_object_class_install_property (gobject_class, PROP_CONTROLLER, pspec);
 
   /**
+   * GControllerReference:action:
+   *
+   * The #GControllerAction that caused the creation of the reference
+   */
+  pspec = g_param_spec_enum ("action",
+                             "Action",
+                             "The action that caused the creation of the reference",
+                             G_TYPE_CONTROLLER_ACTION,
+                             G_CONTROLLER_INVALID_ACTION,
+                             G_PARAM_READWRITE |
+                             G_PARAM_CONSTRUCT_ONLY |
+                             G_PARAM_STATIC_STRINGS);
+  g_object_class_install_property (gobject_class, PROP_ACTION, pspec);
+
+  /**
    * GControllerReference:index-type:
    *
    * The #GType representation of an index stored by the reference
@@ -226,6 +261,8 @@ g_controller_reference_init (GControllerReference *self)
 
   self->priv->controller = NULL;
 
+  self->priv->action = G_CONTROLLER_INVALID_ACTION;
+
   self->priv->index_type = G_TYPE_INVALID;
   self->priv->indices = NULL;
 }
@@ -282,6 +319,22 @@ g_controller_reference_get_controller (GControllerReference *ref)
 }
 
 /**
+ * g_controller_reference_get_action:
+ * @ref: a #GControllerReference
+ *
+ * Retrieves the action that caused the creation of this reference
+ *
+ * Return value: a #GControllerAction
+ */
+GControllerAction
+g_controller_reference_get_action (GControllerReference *ref)
+{
+  g_return_val_if_fail (G_IS_CONTROLLER_REFERENCE (ref), G_CONTROLLER_INVALID_ACTION);
+
+  return ref->priv->action;
+}
+
+/**
  * g_controller_reference_add_index_value:
  * @ref: a #GControllerReference
  * @value: a #GValue containing an index
diff --git a/glib-controller/gcontrollerreference.h b/glib-controller/gcontrollerreference.h
index b5fcc78..93a7773 100644
--- a/glib-controller/gcontrollerreference.h
+++ b/glib-controller/gcontrollerreference.h
@@ -50,6 +50,7 @@ struct _GControllerReferenceClass
 GType g_controller_reference_get_type (void) G_GNUC_CONST;
 
 GController *         g_controller_reference_get_controller    (GControllerReference *ref);
+GControllerAction     g_controller_reference_get_action        (GControllerReference *ref);
 gint                  g_controller_reference_get_n_indices     (GControllerReference *ref);
 GType                 g_controller_reference_get_index_type    (GControllerReference *ref);
 
diff --git a/glib-controller/gcontrollertypes.h b/glib-controller/gcontrollertypes.h
index cd663e8..109c5fe 100644
--- a/glib-controller/gcontrollertypes.h
+++ b/glib-controller/gcontrollertypes.h
@@ -71,7 +71,7 @@ typedef struct _GHashController         GHashController;
 
 /**
  * GControllerAction:
- * @G_CONTROLLER_INVALID: Marker for initial/error state
+ * @G_CONTROLLER_INVALID_ACTION: Marker for initial/error state
  * @G_CONTROLLER_ADD: New items have been added to the storage
  *   controlled by a #GController
  * @G_CONTROLLER_REMOVE: Items have been removed from the storage
@@ -91,7 +91,8 @@ typedef struct _GHashController         GHashController;
  * This enumeration might be extended at later date
  */
 typedef enum { /*< prefix=G_CONTROLLER >*/
-  G_CONTROLLER_INVALID,
+  G_CONTROLLER_INVALID_ACTION,
+
   G_CONTROLLER_ADD,
   G_CONTROLLER_REMOVE,
   G_CONTROLLER_UPDATE,
diff --git a/glib-controller/ghashcontroller.c b/glib-controller/ghashcontroller.c
index e0d3411..80e8f8b 100644
--- a/glib-controller/ghashcontroller.c
+++ b/glib-controller/ghashcontroller.c
@@ -28,13 +28,6 @@ enum
 
 G_DEFINE_TYPE (GHashController, g_hash_controller, G_TYPE_CONTROLLER);
 
-static GType
-get_index_type (GController *controller)
-{
-  /* GHashTable indexes are pointers */
-  return G_TYPE_POINTER;
-}
-
 static void
 g_hash_controller_set_property (GObject      *gobject,
                                 guint         prop_id,
@@ -89,12 +82,9 @@ g_hash_controller_finalize (GObject *gobject)
 static void
 g_hash_controller_class_init (GHashControllerClass *klass)
 {
-  GControllerClass *controller_class = G_CONTROLLER_CLASS (klass);
   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
   GParamSpec *pspec;
 
-  controller_class->get_index_type = get_index_type;
-
   gobject_class->set_property = g_hash_controller_set_property;
   gobject_class->get_property = g_hash_controller_get_property;
   gobject_class->finalize = g_hash_controller_finalize;
diff --git a/glib-controller/gptrarraycontroller.c b/glib-controller/gptrarraycontroller.c
index 14e1be7..e6447c5 100644
--- a/glib-controller/gptrarraycontroller.c
+++ b/glib-controller/gptrarraycontroller.c
@@ -28,13 +28,6 @@ enum
 
 G_DEFINE_TYPE (GPtrArrayController, g_ptr_array_controller, G_TYPE_CONTROLLER);
 
-static GType
-get_index_type (GController *controller)
-{
-  /* GPtrArray indexes are unsigned integers */
-  return G_TYPE_UINT;
-}
-
 static void
 g_ptr_array_controller_set_property (GObject      *gobject,
                                      guint         prop_id,
@@ -89,12 +82,9 @@ g_ptr_array_controller_finalize (GObject *gobject)
 static void
 g_ptr_array_controller_class_init (GPtrArrayControllerClass *klass)
 {
-  GControllerClass *controller_class = G_CONTROLLER_CLASS (klass);
   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
   GParamSpec *pspec;
 
-  controller_class->get_index_type = get_index_type;
-
   gobject_class->set_property = g_ptr_array_controller_set_property;
   gobject_class->get_property = g_ptr_array_controller_get_property;
   gobject_class->finalize = g_ptr_array_controller_finalize;
diff --git a/glib-controller/tests/array-controller.c b/glib-controller/tests/array-controller.c
index 57150a2..6430c42 100644
--- a/glib-controller/tests/array-controller.c
+++ b/glib-controller/tests/array-controller.c
@@ -24,7 +24,9 @@ array_create_reference (void)
   GControllerReference *reference;
 
   controller = g_array_controller_new (NULL);
-  reference = g_controller_create_reference (controller, 1, 0);
+  reference = g_controller_create_reference (controller, G_CONTROLLER_CLEAR,
+                                             G_TYPE_UINT, 1,
+                                             0);
 
   g_assert (G_IS_CONTROLLER_REFERENCE (reference));
   g_assert (g_controller_reference_get_index_type (reference) == G_TYPE_UINT);
@@ -87,7 +89,7 @@ array_emit_changed (void)
   value = 42;
   g_array_append_val (array, value);
 
-  ref = g_controller_create_reference (controller, 1, 0);
+  ref = g_controller_create_reference (controller, G_CONTROLLER_ADD, G_TYPE_UINT, 1, 0);
   g_assert (G_IS_CONTROLLER_REFERENCE (ref));
   g_controller_emit_changed (controller, G_CONTROLLER_ADD, ref);
 
@@ -112,7 +114,7 @@ array_bulk_emit_changed (void)
 
   id = g_signal_connect (controller, "changed", G_CALLBACK (on_changed), &expected);
 
-  ref = g_controller_create_reference (controller, 0);
+  ref = g_controller_create_reference (controller, G_CONTROLLER_ADD, G_TYPE_UINT, 0);
   g_assert (G_IS_CONTROLLER_REFERENCE (ref));
 
   expected.action = G_CONTROLLER_ADD;
diff --git a/glib-controller/tests/hash-controller.c b/glib-controller/tests/hash-controller.c
index 79d592d..eaca86e 100644
--- a/glib-controller/tests/hash-controller.c
+++ b/glib-controller/tests/hash-controller.c
@@ -24,7 +24,7 @@ hash_create_reference (void)
   GControllerReference *reference;
 
   controller = g_hash_controller_new (NULL);
-  reference = g_controller_create_reference (controller, 1, GINT_TO_POINTER (0xdeadbeef));
+  reference = g_controller_create_reference (controller, G_CONTROLLER_CLEAR, G_TYPE_POINTER, 1, GINT_TO_POINTER (0xdeadbeef));
 
   g_assert (G_IS_CONTROLLER_REFERENCE (reference));
   g_assert (g_controller_reference_get_index_type (reference) == G_TYPE_POINTER);
@@ -61,14 +61,14 @@ on_changed (GController *controller,
 
   for (i = 0; i < n_indices; i++)
     {
-      gpointer idx = g_controller_reference_get_index_pointer (reference, i);
+      const gchar *idx = g_controller_reference_get_index_string (reference, i);
 
       if (g_test_verbose ())
         g_print ("Got '%s' (%p), expected '%s' (%p)\n",
                  (char *) idx, idx,
                  (char *) clos->indices[i], clos->indices[i]);
 
-      g_assert (idx == clos->indices[i]);
+      g_assert_cmpstr (idx, ==, clos->indices[i]);
     }
 }
 
@@ -87,14 +87,14 @@ hash_emit_changed (void)
   foo = g_strdup ("foo");
 
   expected.action = G_CONTROLLER_ADD;
-  expected.index_type = G_TYPE_POINTER;
+  expected.index_type = G_TYPE_STRING;
   expected.n_indices = 1;
   expected.indices = g_new (gchar*, expected.n_indices);
   expected.indices[0] = foo;
 
   g_hash_table_insert (hash, foo, g_strdup ("bar"));
 
-  ref = g_controller_create_reference (controller, 1, foo);
+  ref = g_controller_create_reference (controller, G_CONTROLLER_ADD, G_TYPE_STRING, 1, foo);
   g_assert (G_IS_CONTROLLER_REFERENCE (ref));
   g_controller_emit_changed (controller, G_CONTROLLER_ADD, ref);
 



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