gegl r2191 - in trunk: . gegl/operation



Author: ok
Date: Fri Apr 18 09:30:45 2008
New Revision: 2191
URL: http://svn.gnome.org/viewvc/gegl?rev=2191&view=rev

Log:
* gegl/operation/gegl-operation-processors.c:
(gegl_class_register_alternate_vfunc): added new more general function
for runtime overriding of perclass vfuncs, that takes a pointer to the
class structure and the vfunc to operate on.
(gegl_operation_class_add_processor): use the new internal function
internally (still uses hard-coded logic for the GEGL op base classes
to look up the vfunc pointer.)


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 18 09:30:45 2008
@@ -44,67 +44,66 @@
 #include  "gegl-operation-sink.h"
 #include  "gegl-operation-source.h"
 
-void
-gegl_operation_class_add_processor (GeglOperationClass *cclass,
-                                    GCallback           process,
-                                    const gchar        *string)
+#include <glib/gprintf.h>
+
+typedef struct VFuncData
 {
-  gint i;
-  GType    type        = G_TYPE_FROM_CLASS (cclass);
-  GType    parent_type = g_type_parent (type);
-  gint     vfunc_offset;
-  gpointer process_vfunc_ptr;
+  GCallback callback[MAX_PROCESSOR];
+  gchar    *string[MAX_PROCESSOR];
+} VFuncData;
 
-#define ELSE_IF(type) else if(parent_type==type)
-if(parent_type == GEGL_TYPE_OPERATION)
-  vfunc_offset = G_STRUCT_OFFSET (GeglOperationClass, process);
-ELSE_IF( GEGL_TYPE_OPERATION_SOURCE)
-  vfunc_offset = G_STRUCT_OFFSET (GeglOperationSourceClass, process);
-ELSE_IF( GEGL_TYPE_OPERATION_SINK)
-  vfunc_offset = G_STRUCT_OFFSET (GeglOperationSinkClass, process);
-ELSE_IF( GEGL_TYPE_OPERATION_FILTER)
-  vfunc_offset = G_STRUCT_OFFSET (GeglOperationFilterClass, process);
-ELSE_IF( GEGL_TYPE_OPERATION_AREA_FILTER)
-  vfunc_offset = G_STRUCT_OFFSET (GeglOperationFilterClass, process);
-ELSE_IF( GEGL_TYPE_OPERATION_POINT_FILTER)
-  vfunc_offset = G_STRUCT_OFFSET (GeglOperationPointFilterClass, process);
-ELSE_IF( GEGL_TYPE_OPERATION_COMPOSER)
-  vfunc_offset = G_STRUCT_OFFSET (GeglOperationComposerClass, process);
-ELSE_IF( GEGL_TYPE_OPERATION_POINT_COMPOSER)
-  vfunc_offset = G_STRUCT_OFFSET (GeglOperationPointComposerClass, process);
-#undef ELSE_IF
-else
-  {
-     g_error ("%s unable to use %s as parent_type for %s",
-              G_STRFUNC, g_type_name (parent_type), g_type_name(G_TYPE_FROM_CLASS (cclass)));
-  }
-  process_vfunc_ptr = G_STRUCT_MEMBER_P(cclass, vfunc_offset);
-#define PROCESS_VFUNC (*(GCallback*) G_STRUCT_MEMBER_P ((cclass), (vfunc_offset)))
 
+void
+gegl_class_register_alternate_vfunc (GObjectClass *cclass,
+                                     gpointer      vfunc_ptr2,
+                                     GCallback     process,
+                                     const gchar  *string);
+
+void
+gegl_class_register_alternate_vfunc (GObjectClass *cclass,
+                                     gpointer      vfunc_ptr2,
+                                     GCallback     callback,
+                                     const gchar  *string)
+{
+  gint i;
+  GCallback *vfunc_ptr = vfunc_ptr2;
+  GType      type        = G_TYPE_FROM_CLASS (cclass);
+  gchar      tag[20];
+  GQuark     quark;
+  VFuncData *data;
+
+  g_sprintf (tag, "%p", vfunc_ptr);
+  quark = g_quark_from_string (tag);
+  data = g_type_get_qdata (type, quark);
+  if (!data)
+    {
+      data = g_new0 (VFuncData, 1);
+      g_type_set_qdata (type, quark, data);
+    }
 
   /* Store the default implementation */
-  if (cclass->processor[0]==NULL)
+  if (data->callback[0]==NULL)
     {
-      if (cclass->process == NULL)
-        g_error ("No process() vfunc defined for %s",
-                 g_type_name (G_TYPE_FROM_CLASS (cclass)));
-      cclass->processor[0]=process;
-      cclass->processor_string[0]=g_strdup ("reference");
+      if (*vfunc_ptr == NULL)
+        g_error ("%s: No exsiting default () vfunc defined for %s",
+                 G_STRFUNC, g_type_name (type));
+      data->callback[0]=callback;
+      data->string[0]=g_strdup ("reference");
     }
 
   /* Find a free slot for this one */
   for (i=1; i<MAX_PROCESSOR; i++)
     {
-      if (cclass->processor[i]==NULL)
+      if (data->callback[i]==NULL)
         {
-          cclass->processor[i]=process;
-          cclass->processor_string[i]=g_strdup (string);
+          data->callback[i]=callback;
+          data->string[i]=g_strdup (string);
           break;
         }
     }
   if (i>=MAX_PROCESSOR)
     {
-      g_warning ("Too many processors added to %s",
+      g_warning ("Too many callbacks added to %s",
                  g_type_name (G_TYPE_FROM_CLASS (cclass)));
     }
 
@@ -126,8 +125,8 @@
 
       for (i=0;i<MAX_PROCESSOR;i++)
         {
-          const gchar *string = cclass->processor_string[i];
-          GCallback    cb     = cclass->processor[i];
+          const gchar *string = data->string[i];
+          GCallback    cb     = data->callback[i];
 
           if (string && cb!=NULL)
             {
@@ -148,24 +147,25 @@
       if (g_str_equal (quality, "fast"))
         {
 #ifdef USE_SSE
-          g_print ("Setting %s processor for %s\n", fast?"fast":sse?"sse":good?"good":"reference",
+          g_print ("Setting %s callback for %s\n", fast?"fast":sse?"sse":good?"good":"reference",
           g_type_name (G_TYPE_FROM_CLASS (cclass)));
-          PROCESS_VFUNC = fast?fast:sse?sse:good?good:reference;
+          *vfunc_ptr = fast?fast:sse?sse:good?good:reference;
 #else
-          g_print ("Setting %s processor for %s\n", fast?"fast":good?"good":"reference",
+          g_print ("Setting %s callback for %s\n", fast?"fast":good?"good":"reference",
           g_type_name (G_TYPE_FROM_CLASS (cclass)));
-          PROCESS_VFUNC = fast?fast:good?good:reference;
+          *vfunc_ptr = fast?fast:good?good:reference;
 #endif
         }
       else if (g_str_equal (quality, "good"))
         {
 #ifdef USE_SSE
-          g_print ("Setting %s processor for %s\n", sse?"sse":good?"good":"reference",
+          g_print ("Setting %s callback for %s\n", sse?"sse":good?"good":"reference",
            g_type_name (G_TYPE_FROM_CLASS (cclass)));
+          *vfunc_ptr = sse?sse:good?good:reference;
 #else
-          g_print ("Setting %s processor for %s\n", good?"good":"reference",
+          g_print ("Setting %s callback for %s\n", good?"good":"reference",
            g_type_name (G_TYPE_FROM_CLASS (cclass)));
-          PROCESS_VFUNC = good?good:reference;
+          *vfunc_ptr = good?good:reference;
 #endif
         }
       else
@@ -174,10 +174,54 @@
 #ifdef USE_SSE
           if (sse && gegl_cpu_accel_get_support () & GEGL_CPU_ACCEL_X86_SSE)
             g_print ("Setting sse processor for %s\n", g_type_name (G_TYPE_FROM_CLASS (cclass)));
-          PROCESS_VFUNC = sse?sse:reference;
+          *vfunc_ptr = sse?sse:reference;
 #else
-          PROCESS_VFUNC = reference;
+          *vfunc_ptr = reference;
 #endif
         }
     }
 }
+
+
+
+void
+gegl_operation_class_add_processor (GeglOperationClass *cclass,
+                                    GCallback           process,
+                                    const gchar        *string)
+{
+  GType    type        = G_TYPE_FROM_CLASS (cclass);
+  GType    parent_type = g_type_parent (type);
+  gint     vfunc_offset;
+  gpointer process_vfunc_ptr;
+
+#define ELSE_IF(type) else if(parent_type==type)
+if(parent_type == GEGL_TYPE_OPERATION)
+  vfunc_offset = G_STRUCT_OFFSET (GeglOperationClass, process);
+ELSE_IF( GEGL_TYPE_OPERATION_SOURCE)
+  vfunc_offset = G_STRUCT_OFFSET (GeglOperationSourceClass, process);
+ELSE_IF( GEGL_TYPE_OPERATION_SINK)
+  vfunc_offset = G_STRUCT_OFFSET (GeglOperationSinkClass, process);
+ELSE_IF( GEGL_TYPE_OPERATION_FILTER)
+  vfunc_offset = G_STRUCT_OFFSET (GeglOperationFilterClass, process);
+ELSE_IF( GEGL_TYPE_OPERATION_AREA_FILTER)
+  vfunc_offset = G_STRUCT_OFFSET (GeglOperationFilterClass, process);
+ELSE_IF( GEGL_TYPE_OPERATION_POINT_FILTER)
+  vfunc_offset = G_STRUCT_OFFSET (GeglOperationPointFilterClass, process);
+ELSE_IF( GEGL_TYPE_OPERATION_COMPOSER)
+  vfunc_offset = G_STRUCT_OFFSET (GeglOperationComposerClass, process);
+ELSE_IF( GEGL_TYPE_OPERATION_POINT_COMPOSER)
+  vfunc_offset = G_STRUCT_OFFSET (GeglOperationPointComposerClass, process);
+#undef ELSE_IF
+else
+  {
+     g_error ("%s unable to use %s as parent_type for %s",
+              G_STRFUNC, g_type_name (parent_type), g_type_name(G_TYPE_FROM_CLASS (cclass)));
+  }
+  process_vfunc_ptr = G_STRUCT_MEMBER_P(cclass, vfunc_offset);
+#define PROCESS_VFUNC (*(GCallback*) G_STRUCT_MEMBER_P ((cclass), (vfunc_offset)))
+
+  gegl_class_register_alternate_vfunc (G_OBJECT_CLASS (cclass),
+                                       process_vfunc_ptr,
+                                       process,
+                                       string);
+}



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