[gegl] gegl-serialize: Improve error handling for parsing of properties.



commit 358caf05a071e61064b36ecd407373ab60db1294
Author: Øyvind Kolås <pippin gimp org>
Date:   Sat Mar 19 13:51:11 2016 +0100

    gegl-serialize: Improve error handling for parsing of properties.

 bin/gegl.c               |    7 ++-
 bin/ui.c                 |   11 +++-
 gegl/gegl-serialize.c    |  129 ++++++++++++++++++++++++++++++++++++++++------
 gegl/gegl-utils.h        |    4 +-
 operations/common/gegl.c |   15 +++++-
 5 files changed, 143 insertions(+), 23 deletions(-)
---
diff --git a/bin/gegl.c b/bin/gegl.c
index 017c613..9d3a295 100644
--- a/bin/gegl.c
+++ b/bin/gegl.c
@@ -204,7 +204,12 @@ main (gint    argc,
   GeglNode *iter = gegl_node_get_producer (proxy, "input", NULL);
   if (o->rest)
     {
-      gegl_create_chain_argv (o->rest, iter, proxy);
+      GError *error = NULL;
+      gegl_create_chain_argv (o->rest, iter, proxy, 0, &error);
+      if (error)
+      {
+        fprintf (stderr, "Error: %s\n", error->message);
+      }
       if (o->serialize)
       {
         fprintf (stderr, "%s\n", gegl_serialize (iter, 
diff --git a/bin/ui.c b/bin/ui.c
index d7884ca..c70065b 100644
--- a/bin/ui.c
+++ b/bin/ui.c
@@ -1342,12 +1342,17 @@ static void load_path (State *o)
         zoom_to_fit (o);
     }
   }
-
   if (o->ops)
   {
+    GError *error = NULL;
     gegl_create_chain_argv (o->ops,
-                      gegl_node_get_producer (o->sink, "input", NULL),
-                      o->sink);
+                    gegl_node_get_producer (o->sink, "input", NULL),
+                    o->sink, 0,
+                    &error);
+    if (error)
+    {
+      fprintf (stderr, "Error: %s\n", error->message);
+    }
   }
 
   mrg_queue_draw (o->mrg, NULL);
diff --git a/gegl/gegl-serialize.c b/gegl/gegl-serialize.c
index 600888f..c46b600 100644
--- a/gegl/gegl-serialize.c
+++ b/gegl/gegl-serialize.c
@@ -18,8 +18,9 @@
 
 #include "gegl.h"
 #include <string.h>
+#include <stdio.h>
 
-void gegl_create_chain_argv (char **ops, GeglNode *start, GeglNode *proxy)
+void gegl_create_chain_argv (char **ops, GeglNode *start, GeglNode *proxy, double time, GError **error)
 {
   GeglNode   *iter[10] = {start, NULL};
   GeglNode   *new = NULL;
@@ -27,7 +28,10 @@ void gegl_create_chain_argv (char **ops, GeglNode *start, GeglNode *proxy)
   int         level = 0;
   char       *level_op[10];
   char       *level_pad[10];
+  int         in_keyframes = 0;
+  char       *prop = NULL;
   GHashTable *ht = NULL;
+  GeglCurve  *curve = NULL;
 
   level_op[level] = *arg;
  
@@ -35,7 +39,48 @@ void gegl_create_chain_argv (char **ops, GeglNode *start, GeglNode *proxy)
 
   while (*arg)
     {
-      if (strchr (*arg, ']'))
+      if (in_keyframes)
+      {
+        char *key = g_strdup (*arg);
+        char *eq = strchr (key, '=');
+        char *value = NULL;
+        
+        if (eq)
+        {
+          value = eq + 1;
+          value[-1] = '\0';
+          gegl_curve_add_point (curve, g_strtod (key, NULL),
+                                       g_strtod (value, NULL));
+        }
+        else
+        {
+          if (!strcmp (*arg, "l"))
+          {
+            fprintf (stderr, "linear\n");
+          }
+          else if (!strcmp (*arg, "s"))
+          {
+            fprintf (stderr, "step\n");
+          }
+          else if (!strcmp (*arg, "c"))
+          {
+            fprintf (stderr, "cubic\n");
+          }
+        }
+
+        g_free (key);
+
+        if (strchr (*arg, '}')) {
+
+          gegl_node_set (new, prop, gegl_curve_calc_value (
+              g_object_get_qdata (G_OBJECT (new),
+                  g_quark_from_static_string(prop)), time), NULL);
+          /* set interpolated values to initially passed in time */
+
+          in_keyframes = 0;
+        };
+      }
+      else if (strchr (*arg, ']'))
       {
         level--;
         gegl_node_connect_to (iter[level+1], "output", iter[level], level_pad[level]);
@@ -45,7 +90,22 @@ void gegl_create_chain_argv (char **ops, GeglNode *start, GeglNode *proxy)
       if (strchr (*arg, '=')) /* contains = sign, must be a property assignment */
       {
         char *match= strchr (*arg, '=');
-        if (match[1] == '[')
+        if (match[1] == '{')
+        {
+          char *key = g_strdup (*arg);
+          char *value = strchr (key, '=') + 1;
+          value[-1] = '\0';
+          curve = gegl_curve_new (-1000.0, 1000.0);
+          in_keyframes = 1;
+          if (prop)
+            g_free (prop);
+          prop = g_strdup (key);
+
+          g_object_set_qdata_full (G_OBJECT (new), g_quark_from_static_string(key), curve, g_object_unref);
+
+          g_free (key);
+        }
+        else if (match[1] == '[')
         {
           char *pad = g_strdup (*arg);
           char *value = strchr (pad, '=') + 1;
@@ -60,7 +120,7 @@ void gegl_create_chain_argv (char **ops, GeglNode *start, GeglNode *proxy)
         }
         else
         {
-          GType target_type = G_TYPE_INT;
+          GType target_type = 0;
           GValue gvalue={0,};
           char *key = g_strdup (*arg);
           char *value = strchr (key, '=') + 1;
@@ -89,12 +149,31 @@ void gegl_create_chain_argv (char **ops, GeglNode *start, GeglNode *proxy)
               if (!strcmp (pspecs[i]->name, key))
                 target_type = pspecs[i]->value_type;
             }
-            if (target_type == G_TYPE_DOUBLE || target_type == G_TYPE_FLOAT)
+
+            if (target_type == 0)
+            {
+              if (error && gegl_has_operation (level_op[level]))
+              {
+                GString *str = g_string_new ("");
+                g_string_append_printf (str, "%s has no %s property, but has ",
+                  level_op[level], key);
+                for (i = 0; i < n_props; i++)
+                {
+                  g_string_append_printf (str, "'%s', ", pspecs[i]->name);
+                }
+                *error = g_error_new_literal (g_quark_from_static_string ("gegl"),
+                                              0, str->str);
+                g_string_free (str, TRUE);
+              }
+            }
+            else
+            if (g_type_is_a (target_type, G_TYPE_DOUBLE) ||
+                g_type_is_a (target_type, G_TYPE_FLOAT))
               {
                 double val = g_strtod (value, NULL);
                 gegl_node_set (iter[level], key, val, NULL);
               }
-            else if (target_type == G_TYPE_BOOLEAN) {
+            else if (g_type_is_a (target_type, G_TYPE_BOOLEAN)) {
             if (!strcmp (value, "true") || !strcmp (value, "TRUE") ||
                 !strcmp (value, "YES") || !strcmp (value, "yes") ||
                 !strcmp (value, "y") || !strcmp (value, "Y") ||
@@ -107,7 +186,7 @@ void gegl_create_chain_argv (char **ops, GeglNode *start, GeglNode *proxy)
                 gegl_node_set (iter[level], key, FALSE, NULL);
               }
             }
-            else if (target_type == G_TYPE_INT)
+            else if (g_type_is_a (target_type, G_TYPE_INT))
             {
               int val = g_strtod (value, NULL);
               gegl_node_set (iter[level], key, val, NULL);
@@ -177,31 +256,49 @@ void gegl_create_chain_argv (char **ops, GeglNode *start, GeglNode *proxy)
             g_snprintf (temp, 1023, "gegl:%s", *arg);
             level_op[level] = (void*)g_intern_string (temp);
           }
-        new = gegl_node_new_child (gegl_node_get_parent (proxy), "operation",
-                        level_op[level], NULL);
 
-        if (iter[level])
-          gegl_node_link_many (iter[level], new, proxy, NULL);
-        else
-          gegl_node_link_many (new, proxy, NULL);
-        iter[level] = new;
+
+          if (gegl_has_operation (level_op[level]))
+          {
+             new = gegl_node_new_child (gegl_node_get_parent (proxy), "operation",
+                                        level_op[level], NULL);
+
+             if (iter[level])
+               gegl_node_link_many (iter[level], new, proxy, NULL);
+             else
+               gegl_node_link_many (new, proxy, NULL);
+             iter[level] = new;
+          }
+          else if (error)
+          {
+            GString *str = g_string_new ("");
+            g_string_append_printf (str, "No such op '%s'", level_op[level]);
+            *error = g_error_new_literal (g_quark_from_static_string ("gegl"),
+                                          0, str->str);
+             g_string_free (str, TRUE);
+          }
+
       }
       }
       arg++;
     }
 
+  if (prop)
+  {
+    g_free (prop);
+  }
   g_hash_table_unref (ht);
   gegl_node_link_many (iter[level], proxy, NULL);
 }
 
-void gegl_create_chain (const char *str, GeglNode *op_start, GeglNode *op_end)
+void gegl_create_chain (const char *str, GeglNode *op_start, GeglNode *op_end, double time, GError **error)
 {
   gchar **argv = NULL;
   gint    argc = 0;
   g_shell_parse_argv (str, &argc, &argv, NULL);
   if (argv)
   {
-    gegl_create_chain_argv (argv, op_start, op_end);
+    gegl_create_chain_argv (argv, op_start, op_end, time, error);
     g_strfreev (argv);
   }
 }
diff --git a/gegl/gegl-utils.h b/gegl/gegl-utils.h
index 417b31d..3554d32 100644
--- a/gegl/gegl-utils.h
+++ b/gegl/gegl-utils.h
@@ -262,8 +262,8 @@ gint        _gegl_float_epsilon_equal (float     v1,
 
 /**
   */
-void   gegl_create_chain      (const char *str, GeglNode *op_start, GeglNode *op_end);
-void   gegl_create_chain_argv (char **ops, GeglNode *start, GeglNode *proxy);
+void   gegl_create_chain      (const char *str, GeglNode *op_start, GeglNode *op_end, double time, GError 
**error);
+void gegl_create_chain_argv (char **ops, GeglNode *start, GeglNode *proxy, double time, GError **error);
 gchar *gegl_serialize         (GeglNode *start, GeglNode *end);
 
 G_END_DECLS
diff --git a/operations/common/gegl.c b/operations/common/gegl.c
index 511f49f..5d1cd64 100644
--- a/operations/common/gegl.c
+++ b/operations/common/gegl.c
@@ -25,6 +25,9 @@ property_string (string, _("pipeline"), "invert")
     description(_("[op [property=value] [property=value]] [[op] [property=value]"))
     ui_meta ("multiline", "true")
 
+property_string (error, _("error"), "")
+ui_meta ("error", "true")
+
 #else
 
 #define GEGL_OP_META
@@ -61,6 +64,7 @@ prepare (GeglOperation *operation)
 {
   GeglProperties *o = GEGL_PROPERTIES (operation);
   GeglNode *gegl, *input, *output;
+  GError *error = NULL;
 
   gegl = operation->node;
 
@@ -74,7 +78,16 @@ prepare (GeglOperation *operation)
   output   = gegl_node_get_output_proxy (gegl, "output");
 
 //  gegl_node_link_many (input, output, NULL);
-  gegl_create_chain (o->string, input, output);
+  gegl_create_chain (o->string, input, output, 0.0, &error);
+
+  if (error)
+  {
+    //gegl_node_set (gegl, "error", error->message, NULL);
+    g_object_set (operation, "error", error->message, NULL);
+    g_object_notify (operation, "error");
+    g_error_free (error);
+    error = NULL;
+  }
   /*
   gegl_operation_meta_redirect (operation, "scale", multiply, "value");
   gegl_operation_meta_redirect (operation, "std-dev", blur, "std-dev-x");


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