gegl r2234 - in trunk: . gegl/operation
- From: ok svn gnome org
- To: svn-commits-list gnome org
- Subject: gegl r2234 - in trunk: . gegl/operation
- Date: Fri, 25 Apr 2008 20:10:01 +0100 (BST)
Author: ok
Date: Fri Apr 25 19:10:01 2008
New Revision: 2234
URL: http://svn.gnome.org/viewvc/gegl?rev=2234&view=rev
Log:
* gegl/operation/gegl-operation-processors.c:
(gegl_class_register_alternate_vfunc): moved the logic of selecting
an implementation to use to method invocation, by replacing the
default impementation with a dispatcher that handles virtual functions
with up to 10 arguments.
(dispatch): the static helper function that dispatches.
This change makes the code less general since it now only can have
one overridden vfunc per gtype. This should not be a problem for GEGLs
current use of the infrastructure.
Modified:
trunk/ChangeLog
trunk/gegl/operation/gegl-operation-processors.c
Modified: trunk/gegl/operation/gegl-operation-processors.c
==============================================================================
--- trunk/gegl/operation/gegl-operation-processors.c (original)
+++ trunk/gegl/operation/gegl-operation-processors.c Fri Apr 25 19:10:01 2008
@@ -48,12 +48,6 @@
#include <glib/gprintf.h>
-/* FIXME:
- *
- * pick the correct processor at runtime rather than at class init time
- * to allow the gegl_config request to override the initial conditions
- */
-
typedef struct VFuncData
{
GCallback callback[MAX_PROCESSOR];
@@ -66,6 +60,83 @@
GCallback process,
const gchar *string);
+/* this dispatcher allows overriding a callback without checking how many parameters
+ * are passed and how many parameters are needed, hopefully in a compiler/archi
+ * portable manner.
+ */
+static void
+dispatch (GObject *object,
+ gpointer arg1,
+ gpointer arg2,
+ gpointer arg3,
+ gpointer arg4,
+ gpointer arg5,
+ gpointer arg6,
+ gpointer arg7,
+ gpointer arg8,
+ gpointer arg9)
+{
+ void (*dispatch) (GObject *object,
+ gpointer arg1,
+ gpointer arg2,
+ gpointer arg3,
+ gpointer arg4,
+ gpointer arg5,
+ gpointer arg6,
+ gpointer arg7,
+ gpointer arg8,
+ gpointer arg9)=NULL;
+ VFuncData *data;
+ gint fast = 0;
+ gint good = 0;
+ gint reference = 0;
+ gint g4f = 0;
+ gint i;
+ gint choice;
+
+ data = g_type_get_qdata (G_OBJECT_TYPE(object),
+ g_quark_from_string("dispatch-data"));
+ if (!data)
+ {
+ g_error ("dispatch called on object without dispatch-data");
+ }
+
+ for (i=0;i<MAX_PROCESSOR;i++)
+ {
+ const gchar *string = data->string[i];
+ GCallback cb = data->callback[i];
+
+ if (string && cb!=NULL)
+ {
+ if (g_str_equal (string, "fast"))
+ fast = i;
+ if (g_str_equal (string, "g4float"))
+ g4f = i;
+ else if (g_str_equal (string, "good"))
+ good = i;
+ else if (g_str_equal (string, "reference"))
+ reference = i;
+ }
+ }
+ reference = 0;
+ g_assert (data->callback[reference]);
+
+ choice = reference;
+ if (gegl_config()->quality <= 0.5)
+ {
+ if (good) choice = good;
+ if (g4f) choice = g4f;
+ }
+ if (gegl_config()->quality <= 0.2)
+ {
+ if (fast) choice = fast;
+ }
+
+ GEGL_NOTE(PROCESSOR, "Using %s implementation for %s", data->string[choice], g_type_name (G_OBJECT_TYPE(object)));
+ dispatch = (void*)data->callback[choice];
+ dispatch (object, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9);
+}
+
void
gegl_class_register_alternate_vfunc (GObjectClass *cclass,
gpointer vfunc_ptr2,
@@ -86,6 +157,7 @@
{
data = g_new0 (VFuncData, 1);
g_type_set_qdata (type, quark, data);
+ g_type_set_qdata (type, g_quark_from_string("dispatch-data"), data);
}
/* Store the default implementation */
@@ -94,15 +166,21 @@
if (*vfunc_ptr == NULL)
g_error ("%s: No existing default () vfunc defined for %s",
G_STRFUNC, g_type_name (type));
- data->callback[0]=callback;
+ data->callback[0]=*vfunc_ptr;
data->string[0]=g_strdup ("reference");
}
-
+ *vfunc_ptr = (void*)dispatch; /* make our bootstrap replacement for the
+ * reference implementation take over
+ * dispatching of arguments, not sure if
+ * this is portable C or not.
+ */
+
/* Find a free slot for this one */
for (i=1; i<MAX_PROCESSOR; i++)
{
if (data->callback[i]==NULL)
{
+ /* store the callback and it's given name */
data->callback[i]=callback;
data->string[i]=g_strdup (string);
break;
@@ -113,50 +191,6 @@
g_warning ("Too many callbacks added to %s",
g_type_name (G_TYPE_FROM_CLASS (cclass)));
}
-
- {
- gint fast = 0;
- gint good = 0;
- gint reference = 0;
- gint g4f = 0;
-
- gint choice = 0;
-
- for (i=0;i<MAX_PROCESSOR;i++)
- {
- const gchar *string = data->string[i];
- GCallback cb = data->callback[i];
-
- if (string && cb!=NULL)
- {
- if (g_str_equal (string, "fast"))
- fast = i;
- if (g_str_equal (string, "g4float"))
- g4f = i;
- else if (g_str_equal (string, "good"))
- good = i;
- else if (g_str_equal (string, "reference"))
- reference = i;
- }
- }
- reference = 0;
- g_assert (data->callback[reference]);
-
- if (gegl_config()->quality <= 0.5)
- {
- if (good) choice = good;
- if (g4f) choice = g4f;
- }
- if (gegl_config()->quality <= 0.2)
- {
- if (good) choice = good;
- if (g4f) choice = g4f;
- if (fast) choice = fast;
- }
-
- GEGL_NOTE(PROCESSOR, "Using %s implementation for %s", data->string[choice], g_type_name (G_TYPE_FROM_CLASS (cclass)));
- *vfunc_ptr = data->callback[choice];
- }
}
void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]