[glib-controller] Pass the index type when creating a new Reference
- From: Emmanuele Bassi <ebassi src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib-controller] Pass the index type when creating a new Reference
- Date: Fri, 30 Apr 2010 11:52:06 +0000 (UTC)
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]