grim/guifications3

Converted the builtin type queries to GfTypeQueryContext.
org.guifications.gf3
2009-10-15, Gary Kramlich
6aa03b22e94f
Converted the builtin type queries to GfTypeQueryContext.
Updated GfTypeQuery to include the context and userdata for each function.
--- a/gflib/gflib/gf_type.c Thu Oct 15 04:12:14 2009 -0500
+++ b/gflib/gflib/gf_type.c Thu Oct 15 05:20:11 2009 -0500
@@ -54,24 +54,24 @@
* query context stuff
*****************************************************************************/
static inline void
-gf_type_query_context_real_params(GfTypeQueryContextPrivate *priv,
- GObjectClass *klass)
+gf_type_query_context_real_params(GfTypeQueryContext *ctx,
+ GObjectClass *klass)
{
+ GfTypeQueryContextPrivate *priv = GF_TYPE_QUERY_CONTEXT_GET_PRIVATE(ctx);
GParamSpec **pspecs = NULL;
guint n_pspecs = 0, p = 0;
pspecs = g_object_class_list_properties(klass, &n_pspecs);
for(p = 0; p < n_pspecs; p++)
if(priv->query->param)
- priv->query->param(pspecs[p]);
+ priv->query->param(ctx, pspecs[p], priv->data);
g_free(pspecs);
}
static inline void
-gf_type_query_context_real_signals(GfTypeQueryContextPrivate *priv,
- GType type)
-{
+gf_type_query_context_real_signals(GfTypeQueryContext *ctx, GType type) {
+ GfTypeQueryContextPrivate *priv = GF_TYPE_QUERY_CONTEXT_GET_PRIVATE(ctx);
guint *signal_ids = NULL, n_ids = 0, s = 0;
signal_ids = g_signal_list_ids(type, &n_ids);
@@ -81,16 +81,15 @@
g_signal_query(signal_ids[s], &query);
if(priv->query->signal)
- priv->query->signal(&query);
+ priv->query->signal(ctx, &query, priv->data);
}
g_free(signal_ids);
}
static inline void
-gf_type_query_context_real_query_object(GfTypeQueryContextPrivate *priv,
- GType type)
-{
+gf_type_query_context_real_query_object(GfTypeQueryContext *ctx, GType type) {
+ GfTypeQueryContextPrivate *priv = GF_TYPE_QUERY_CONTEXT_GET_PRIVATE(ctx);
GObjectClass *klass = NULL;
GTypeQuery query;
guint t = 0;
@@ -101,23 +100,23 @@
g_type_query(type, &query);
if(priv->query->start_object)
- priv->query->start_object(&query);
+ priv->query->start_object(ctx, &query, priv->data);
/* if the query doesn't have a function for params signals don't bother
* with digging through them.
*/
if(priv->query->param)
- gf_type_query_context_real_params(priv, klass);
+ gf_type_query_context_real_params(ctx, klass);
/* ditto for signals */
if(priv->query->signal)
- gf_type_query_context_real_signals(priv, type);
+ gf_type_query_context_real_signals(ctx, type);
/* we're done with this object. finish it up before moving to it's
* children.
*/
if(priv->query->end_object)
- priv->query->end_object(&query);
+ priv->query->end_object(ctx, &query, priv->data);
/* now dig through the children if we're recursive */
if(priv->recursive) {
@@ -128,7 +127,7 @@
child = g_type_class_ref(types[t]);
- gf_type_query_context_real_query_object(priv, types[t]);
+ gf_type_query_context_real_query_object(ctx, types[t]);
g_type_class_unref(child);
}
@@ -141,9 +140,7 @@
static void
gf_type_query_context_real_query(GfTypeQueryContext *ctx, GType type) {
- GfTypeQueryContextPrivate *priv = GF_TYPE_QUERY_CONTEXT_GET_PRIVATE(ctx);
-
- gf_type_query_context_real_query_object(priv, type);
+ gf_type_query_context_real_query_object(ctx, type);
}
/******************************************************************************
@@ -452,56 +449,95 @@
}
/******************************************************************************
- * Introspection API
+ * Builtin Queries
*****************************************************************************/
-typedef gboolean (*GfTypeChildrenTest)(GType type, gpointer data);
+typedef gboolean (*GfTypeQueryBuiltInTest)(GType type, gpointer data);
+
+typedef struct {
+ GQueue *queue;
+ GfTypeQueryBuiltInTest test;
+ gpointer data;
+} GfTypeQueryBuiltInData;
static void
-gf_type_children_find_r(GType type, GfTypeChildrenTest test,
- GQueue **queue, gpointer data)
+gf_type_query_built_in_object_start(GfTypeQueryContext *ctx,
+ const GTypeQuery *query, gpointer data)
{
- GType *children;
- guint n, i;
+ GfTypeQueryBuiltInData *built_in_data = (GfTypeQueryBuiltInData *)data;
- if(test) {
- if(test(type, data)) {
- g_queue_push_tail(*queue, GINT_TO_POINTER(type));
+ if(built_in_data->test) {
+ if(built_in_data->test(query->type, built_in_data->data)) {
+ g_queue_push_tail(built_in_data->queue, GSIZE_TO_POINTER(query->type));
}
} else {
- g_queue_push_tail(*queue, GINT_TO_POINTER(type));
+ g_queue_push_tail(built_in_data->queue, GSIZE_TO_POINTER(query->type));
}
-
- children = g_type_children(type, &n);
- for(i = 0; i < n; i++)
- gf_type_children_find_r(children[i], test, queue, data);
- g_free(children);
}
-GType *
-gf_type_children_find(GType type, GfTypeChildrenTest test,
- guint *n_children, gpointer data)
+static GfTypeQuery built_in_query = {
+ gf_type_query_built_in_object_start,
+ NULL,
+ NULL,
+ NULL
+};
+
+static GType *
+gf_type_query_built_in_helper(GType type, GfTypeQueryBuiltInTest test,
+ guint *n_children, gpointer data)
{
- GType *children;
- GQueue *queue;
- GList *l;
- guint i;
+ GfTypeQueryContext *ctx = NULL;
+ GfTypeQueryBuiltInData *built_in_data = NULL;
+ GQueue *queue = NULL;
+ GType *types = NULL;
+ GList *l = NULL;
+ guint i = 0;
queue = g_queue_new();
- gf_type_children_find_r(type, test, &queue, data);
+ built_in_data = g_new0(GfTypeQueryBuiltInData, 1);
+ built_in_data->queue = queue;
+ built_in_data->test = test;
+ built_in_data->data = data;
- children = g_new0(GType, queue->length + 1);
- for(i = 0, l = queue->head; i < queue->length || l; i++, l = l->next)
- children[i] = GPOINTER_TO_INT(l->data);
+ ctx = gf_type_query_context_new(&built_in_query, TRUE, built_in_data,
+ g_free);
+
+ gf_type_query_context_run(ctx, type);
+
+ types = g_new0(GType, queue->length + 1);
+ for(i = 0, l = queue->head; i < queue->length; i++, l = l->next)
+ types[i] = GPOINTER_TO_SIZE(l->data);
if(n_children)
*n_children = queue->length;
+ /* clean up the queue and the query context. The queue context will kill
+ * the data when it is unrefed.
+ */
g_queue_free(queue);
+ g_object_unref(G_OBJECT(ctx));
- return children;
+ return types;
}
+/******************************************************************************
+ * Built in tests
+ *****************************************************************************/
+static gboolean
+gf_type_children_test_concrete(GType type, gpointer data) {
+ return (!g_type_test_flags(type, G_TYPE_FLAG_ABSTRACT));
+}
+
+static gboolean
+gf_type_interface_implementor(GType type, gpointer data) {
+ GType interface = GPOINTER_TO_INT(data);
+
+ return g_type_is_a(type, interface);
+}
+
+/******************************************************************************
+ * Introspection API
+ *****************************************************************************/
/**
* gf_type_children:
* @type : The #GType of the base class who's children we want.
@@ -517,12 +553,7 @@
*/
GType *
gf_type_children(GType type, guint *n_children) {
- return gf_type_children_find(type, NULL, n_children, NULL);
-}
-
-static gboolean
-gf_type_children_test_concrete(GType type, gpointer data) {
- return (!g_type_test_flags(type, G_TYPE_FLAG_ABSTRACT));
+ return gf_type_query_built_in_helper(type, NULL, n_children, NULL);
}
/**
@@ -538,16 +569,9 @@
*/
GType *
gf_type_concrete_children(GType type, guint *n_children) {
- return gf_type_children_find(type,
- gf_type_children_test_concrete,
- n_children, NULL);
-}
-
-static gboolean
-gf_type_interface_implementor(GType type, gpointer data) {
- GType interface = GPOINTER_TO_INT(data);
-
- return g_type_is_a(type, interface);
+ return gf_type_query_built_in_helper(type,
+ gf_type_children_test_concrete,
+ n_children, NULL);
}
/**
@@ -563,9 +587,9 @@
*/
GType *
gf_type_interface_implementors(GType type, guint *n_children) {
- return gf_type_children_find(G_TYPE_OBJECT,
- gf_type_interface_implementor,
- n_children, GINT_TO_POINTER(type));
+ return gf_type_query_built_in_helper(G_TYPE_OBJECT,
+ gf_type_interface_implementor,
+ n_children, GINT_TO_POINTER(type));
}
--- a/gflib/gflib/gf_type.h Thu Oct 15 04:12:14 2009 -0500
+++ b/gflib/gflib/gf_type.h Thu Oct 15 05:20:11 2009 -0500
@@ -65,11 +65,11 @@
* #gf_type_query_context_query.
*/
struct _GfTypeQuery {
- void (*start_object)(const GTypeQuery *query);
- void (*end_object)(const GTypeQuery *query);
+ void (*start_object)(GfTypeQueryContext *ctx, const GTypeQuery *query, gpointer data);
+ void (*end_object)(GfTypeQueryContext *ctx, const GTypeQuery *query, gpointer data);
- void (*param)(const GParamSpec *pspec);
- void (*signal)(const GSignalQuery *query);
+ void (*param)(GfTypeQueryContext *ctx, const GParamSpec *pspec, gpointer data);
+ void (*signal)(GfTypeQueryContext *ctx, const GSignalQuery *query, gpointer data);
};
G_BEGIN_DECLS