gegl r2234 - in trunk: . gegl/operation



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]