[clutter] paint-node: Use JSON-GLib for debug serialization



commit f4d8fb054a911aaa69aef9fa40ff4fec4e385b4c
Author: Emmanuele Bassi <ebassi linux intel com>
Date:   Fri Feb 3 13:51:29 2012 +0000

    paint-node: Use JSON-GLib for debug serialization
    
    Instead of our homegrown string building; this at least ensures that
    we're generating proper data, instead of random strings. Plus, using
    JsonNode and JsonBuilder, we can ask the PaintNode subclasses to
    serialize themselves in a sensible way.

 clutter/clutter-paint-node-private.h |    3 +
 clutter/clutter-paint-node.c         |  201 +++++++++++++++-------------------
 clutter/clutter-paint-nodes.c        |   83 ++++++++++++++
 3 files changed, 175 insertions(+), 112 deletions(-)
---
diff --git a/clutter/clutter-paint-node-private.h b/clutter/clutter-paint-node-private.h
index 346bda8..8e45f34 100644
--- a/clutter/clutter-paint-node-private.h
+++ b/clutter/clutter-paint-node-private.h
@@ -26,6 +26,7 @@
 #define __CLUTTER_PAINT_NODE_PRIVATE_H__
 
 #include <glib-object.h>
+#include <json-glib/json-glib.h>
 #include <clutter/clutter-paint-node.h>
 
 G_BEGIN_DECLS
@@ -65,6 +66,8 @@ struct _ClutterPaintNodeClass
   gboolean (* pre_draw)  (ClutterPaintNode *node);
   void     (* draw)      (ClutterPaintNode *node);
   void     (* post_draw) (ClutterPaintNode *node);
+
+  JsonNode*(* serialize) (ClutterPaintNode *node);
 };
 
 typedef enum {
diff --git a/clutter/clutter-paint-node.c b/clutter/clutter-paint-node.c
index dc11191..a56f330 100644
--- a/clutter/clutter-paint-node.c
+++ b/clutter/clutter-paint-node.c
@@ -70,6 +70,7 @@
 
 #include <pango/pango.h>
 #include <cogl/cogl.h>
+#include <json-glib/json-glib.h>
 
 #include "clutter-paint-node-private.h"
 
@@ -778,47 +779,6 @@ clutter_paint_operation_clear (ClutterPaintOperation *op)
     }
 }
 
-static void
-clutter_paint_operation_to_string (const ClutterPaintOperation *op,
-                                   GString                     *buf,
-                                   int                          level)
-{
-  int i;
-
-  for (i = 0; i < level; i++)
-    g_string_append (buf, "  ");
-
-  g_string_append (buf, "{ ");
-
-  switch (op->opcode)
-    {
-    case PAINT_OP_INVALID:
-      break;
-
-    case PAINT_OP_TEX_RECT:
-      g_string_append_printf (buf, "\"texrect\" : [ %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f ]",
-                              op->op.texrect[0],
-                              op->op.texrect[1],
-                              op->op.texrect[2],
-                              op->op.texrect[3],
-                              op->op.texrect[4],
-                              op->op.texrect[5],
-                              op->op.texrect[6],
-                              op->op.texrect[7]);
-      break;
-
-    case PAINT_OP_PATH:
-      g_string_append_printf (buf, "\"path\" : \"0x%p\"", op->op.path);
-      break;
-
-    case PAINT_OP_PRIMITIVE:
-      g_string_append_printf (buf, "\"primitive\" : \"0x%p\"", op->op.primitive);
-      break;
-    }
-
-  g_string_append (buf, " }");
-}
-
 static inline void
 clutter_paint_op_init_tex_rect (ClutterPaintOperation *op,
                                 const ClutterActorBox *rect,
@@ -1016,113 +976,130 @@ _clutter_paint_node_paint (ClutterPaintNode *node)
     }
 }
 
-static void
-clutter_paint_node_to_string (ClutterPaintNode *node,
-                              GString          *buf,
-                              int               level)
+#ifdef CLUTTER_ENABLE_DEBUG
+static JsonNode *
+clutter_paint_node_serialize (ClutterPaintNode *node)
 {
-  ClutterPaintNode *iter;
-  int i;
+  ClutterPaintNodeClass *klass = CLUTTER_PAINT_NODE_GET_CLASS (node);
 
-  for (i = 0; i < level; i++)
-    g_string_append (buf, "  ");
+  if (klass->serialize != NULL)
+    return klass->serialize (node);
 
-  g_string_append_c (buf, '"');
-  g_string_append (buf, g_type_name (G_TYPE_FROM_INSTANCE (node)));
-  g_string_append_c (buf, '"');
+  return json_node_new (JSON_NODE_NULL);
+}
 
-  g_string_append (buf, " : {\n");
+static JsonNode *
+clutter_paint_node_to_json (ClutterPaintNode *node)
+{
+  JsonBuilder *builder;
+  JsonNode *res;
 
-  if (node->name != NULL)
-    {
-      for (i = 0; i < level + 1; i++)
-        g_string_append (buf, "  ");
+  builder = json_builder_new ();
 
-      g_string_append_printf (buf, "\"name\" : \"%s\"", node->name);
+  json_builder_begin_object (builder);
 
-      if (node->operations != NULL ||
-          node->first_child != NULL)
-        g_string_append_c (buf, ',');
+  json_builder_set_member_name (builder, "type");
+  json_builder_add_string_value (builder, g_type_name (G_TYPE_FROM_INSTANCE (node)));
 
-      g_string_append_c (buf, '\n');
-    }
+  json_builder_set_member_name (builder, "name");
+  json_builder_add_string_value (builder, node->name);
 
-  if (node->operations != NULL)
-    {
-      guint o;
+  json_builder_set_member_name (builder, "node-data");
+  json_builder_add_value (builder, clutter_paint_node_serialize (node));
 
-      for (i = 0; i < level + 1; i++)
-        g_string_append (buf, "  ");
+  json_builder_set_member_name (builder, "operations");
+  json_builder_begin_array (builder);
 
-      g_string_append (buf, "\"operations\" : [\n");
+  if (node->operations != NULL)
+    {
+      guint i;
 
-      for (o = 0; o < node->operations->len; o++)
+      for (i = 0; i < node->operations->len; i++)
         {
           const ClutterPaintOperation *op;
 
-          op = &g_array_index (node->operations, ClutterPaintOperation, o);
-          clutter_paint_operation_to_string (op, buf, level + 2);
-
-          if ((o + 1) != node->operations->len)
-            g_string_append_c (buf, ',');
-
-          g_string_append_c (buf, '\n');
+          op = &g_array_index (node->operations, ClutterPaintOperation, i);
+          json_builder_begin_object (builder);
+
+          switch (op->opcode)
+            {
+            case PAINT_OP_TEX_RECT:
+              json_builder_set_member_name (builder, "texrect");
+              json_builder_begin_array (builder);
+              json_builder_add_double_value (builder, op->op.texrect[0]);
+              json_builder_add_double_value (builder, op->op.texrect[1]);
+              json_builder_add_double_value (builder, op->op.texrect[2]);
+              json_builder_add_double_value (builder, op->op.texrect[3]);
+              json_builder_add_double_value (builder, op->op.texrect[4]);
+              json_builder_add_double_value (builder, op->op.texrect[5]);
+              json_builder_add_double_value (builder, op->op.texrect[6]);
+              json_builder_add_double_value (builder, op->op.texrect[7]);
+              json_builder_end_array (builder);
+              break;
+
+            case PAINT_OP_PATH:
+              json_builder_set_member_name (builder, "path");
+              json_builder_add_int_value (builder, (gint64) op->op.path);
+              break;
+
+            case PAINT_OP_PRIMITIVE:
+              json_builder_set_member_name (builder, "primitive");
+              json_builder_add_int_value (builder, (gint64) op->op.primitive);
+              break;
+
+            case PAINT_OP_INVALID:
+              break;
+            }
+
+          json_builder_end_object (builder);
         }
-
-      for (i = 0; i < level + 1; i++)
-        g_string_append (buf, "  ");
-
-      g_string_append (buf, "]");
-
-      if (node->first_child != NULL)
-        g_string_append_c (buf, ',');
-
-      g_string_append_c (buf, '\n');
     }
 
-  if (node->first_child == NULL)
-    goto out;
+  json_builder_end_array (builder);
 
-  for (i = 0; i < level + 1; i++)
-    g_string_append (buf, "  ");
+  json_builder_set_member_name (builder, "children");
+  json_builder_begin_array (builder);
 
-  g_string_append (buf, "\"children\" : [\n");
-
-  for (iter = node->first_child;
-       iter != NULL;
-       iter = iter->next_sibling)
+  if (node->first_child != NULL)
     {
-      clutter_paint_node_to_string (iter, buf, level + 2);
+      ClutterPaintNode *child;
+
+      for (child = node->first_child;
+           child != NULL;
+           child = child->next_sibling)
+        {
+          JsonNode *n = clutter_paint_node_to_json (child);
 
-      if (iter->next_sibling != NULL)
-        g_string_append (buf, ",\n");
-      else
-        g_string_append (buf, "\n");
+          json_builder_add_value (builder, n);
+        }
     }
 
-  for (i = 0; i < level + 1; i++)
-    g_string_append (buf, "  ");
+  json_builder_end_array (builder);
+
+  json_builder_end_object (builder);
 
-  g_string_append (buf, "]\n");
+  res = json_builder_get_root (builder);
 
-out:
-  for (i = 0; i < level; i++)
-    g_string_append (buf, "  ");
+  g_object_unref (builder);
 
-  g_string_append (buf, "}");
+  return res;
 }
+#endif /* CLUTTER_ENABLE_DEBUG */
 
 void
 _clutter_paint_node_dump_tree (ClutterPaintNode *node)
 {
 #ifdef CLUTTER_ENABLE_DEBUG
-  GString *buf = g_string_sized_new (1024);
+  JsonGenerator *gen = json_generator_new ();
+  char *str;
+  gsize len;
 
-  clutter_paint_node_to_string (node, buf, 0);
+  json_generator_set_root (gen, clutter_paint_node_to_json (node));
+  str = json_generator_to_data (gen, &len);
 
-  CLUTTER_NOTE (PAINT, "Render tree:\n%s", buf->str);
+  g_print ("Render tree starting from %p:\n%s\n", node, str);
 
-  g_string_free (buf, TRUE);
+  g_free (str);
 #endif /* CLUTTER_ENABLE_DEBUG */
 }
 
diff --git a/clutter/clutter-paint-nodes.c b/clutter/clutter-paint-nodes.c
index c0868b3..4a4a6c3 100644
--- a/clutter/clutter-paint-nodes.c
+++ b/clutter/clutter-paint-nodes.c
@@ -398,6 +398,46 @@ clutter_pipeline_node_post_draw (ClutterPaintNode *node)
   cogl_pop_source ();
 }
 
+static JsonNode *
+clutter_pipeline_node_serialize (ClutterPaintNode *node)
+{
+  ClutterPipelineNode *pnode = CLUTTER_PIPELINE_NODE (node);
+  JsonBuilder *builder;
+  CoglColor color;
+  JsonNode *res;
+
+  if (pnode->pipeline == NULL)
+    return json_node_new (JSON_NODE_NULL);
+
+  builder = json_builder_new ();
+  json_builder_begin_object (builder);
+
+  cogl_pipeline_get_color (pnode->pipeline, &color);
+  json_builder_set_member_name (builder, "color");
+  json_builder_begin_array (builder);
+  json_builder_add_double_value (builder, cogl_color_get_red (&color));
+  json_builder_add_double_value (builder, cogl_color_get_green (&color));
+  json_builder_add_double_value (builder, cogl_color_get_blue (&color));
+  json_builder_add_double_value (builder, cogl_color_get_alpha (&color));
+  json_builder_end_array (builder);
+
+#if 0
+  json_builder_set_member_name (builder, "layers");
+  json_builder_begin_array (builder);
+  cogl_pipeline_foreach_layer (pnode->pipeline,
+                               clutter_pipeline_node_serialize_layer,
+                               builder);
+  json_builder_end_array (builder);
+#endif
+
+  json_builder_end_object (builder);
+
+  res = json_builder_get_root (builder);
+  g_object_unref (builder);
+
+  return res;
+}
+
 static void
 clutter_pipeline_node_class_init (ClutterPipelineNodeClass *klass)
 {
@@ -408,6 +448,7 @@ clutter_pipeline_node_class_init (ClutterPipelineNodeClass *klass)
   node_class->draw = clutter_pipeline_node_draw;
   node_class->post_draw = clutter_pipeline_node_post_draw;
   node_class->finalize = clutter_pipeline_node_finalize;
+  node_class->serialize = clutter_pipeline_node_serialize;
 }
 
 static void
@@ -714,6 +755,47 @@ clutter_text_node_draw (ClutterPaintNode *node)
     }
 }
 
+static JsonNode *
+clutter_text_node_serialize (ClutterPaintNode *node)
+{
+  ClutterTextNode *tnode = CLUTTER_TEXT_NODE (node);
+  JsonBuilder *builder;
+  JsonNode *res;
+
+  builder = json_builder_new ();
+
+  json_builder_begin_object (builder);
+
+  json_builder_set_member_name (builder, "layout");
+
+  if (pango_layout_get_character_count (tnode->layout) > 12)
+    {
+      const char *text = pango_layout_get_text (tnode->layout);
+      char *str;
+
+      str = g_strndup (text, 12);
+      json_builder_add_string_value (builder, str);
+      g_free (str);
+    }
+  else
+    json_builder_add_string_value (builder, pango_layout_get_text (tnode->layout));
+
+  json_builder_set_member_name (builder, "color");
+  json_builder_begin_array (builder);
+  json_builder_add_double_value (builder, cogl_color_get_red (&tnode->color));
+  json_builder_add_double_value (builder, cogl_color_get_green (&tnode->color));
+  json_builder_add_double_value (builder, cogl_color_get_blue (&tnode->color));
+  json_builder_add_double_value (builder, cogl_color_get_alpha (&tnode->color));
+  json_builder_end_array (builder);
+
+  json_builder_end_object (builder);
+
+  res = json_builder_get_root (builder);
+  g_object_unref (builder);
+
+  return res;
+}
+
 static void
 clutter_text_node_class_init (ClutterTextNodeClass *klass)
 {
@@ -722,6 +804,7 @@ clutter_text_node_class_init (ClutterTextNodeClass *klass)
   node_class->pre_draw = clutter_text_node_pre_draw;
   node_class->draw = clutter_text_node_draw;
   node_class->finalize = clutter_text_node_finalize;
+  node_class->serialize = clutter_text_node_serialize;
 }
 
 static void



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