[clutter] script: Allow resolving signals states added from code



commit 29d7c5a2979d63e9ce78a901090da6c0e82d85a8
Author: Emmanuele Bassi <ebassi linux intel com>
Date:   Fri Jun 10 17:16:45 2011 +0100

    script: Allow resolving signals states added from code
    
    Currently, defining states for object signals can only be done by
    defining a ClutterState inside the ClutterScript definition. We should
    allow creating a (named) ClutterState in code, and associating it to a
    ClutterScript instance â?? and have the Script resolve the "state" field
    of a signal definition correctly.

 clutter/clutter-script-parser.c |   31 +++++---------
 clutter/clutter-script.c        |   78 +++++++++++++++++++++++++++++++++++-
 clutter/clutter-script.h        |   83 ++++++++++++++++++++------------------
 3 files changed, 131 insertions(+), 61 deletions(-)
---
diff --git a/clutter/clutter-script-parser.c b/clutter/clutter-script-parser.c
index 27154f2..4477f5a 100644
--- a/clutter/clutter-script-parser.c
+++ b/clutter/clutter-script-parser.c
@@ -592,20 +592,11 @@ parse_signals (ClutterScript *script,
             }
         }
 
-      /* mandatory: "state" */
-      if (json_object_has_member (object, "state"))
+      /* mandatory: "target-state" or "handler" */
+      if (json_object_has_member (object, "target-state"))
         {
-          const gchar *state;
-          const gchar *target;
-
-          state = json_object_get_string_member (object, "state");
-          if (state == NULL)
-            {
-              _clutter_script_warn_invalid_value (script,
-                                                  "state", "string",
-                                                  val);
-              continue;
-            }
+          const gchar *state = NULL;
+          const gchar *target = NULL;
 
           target = json_object_get_string_member (object, "target-state");
           if (target == NULL)
@@ -616,10 +607,13 @@ parse_signals (ClutterScript *script,
               continue;
             }
 
+          if (json_object_has_member (object, "state"))
+            state = json_object_get_string_member (object, "state");
+
           CLUTTER_NOTE (SCRIPT,
                         "Added signal '%s' (state:%s, target:%s)",
                         name,
-                        state, target);
+                        state != NULL ? state : "<default>", target);
 
           sinfo = g_slice_new0 (SignalInfo);
           sinfo->is_handler = FALSE;
@@ -627,9 +621,7 @@ parse_signals (ClutterScript *script,
           sinfo->state = g_strdup (state);
           sinfo->target = g_strdup (target);
         }
-
-      /* mandatory: "handler" */
-      if (json_object_has_member (object, "handler"))
+      else if (json_object_has_member (object, "handler"))
         {
           const gchar *handler;
           const gchar *connect;
@@ -676,13 +668,12 @@ parse_signals (ClutterScript *script,
           sinfo->object = g_strdup (connect);
           sinfo->flags = flags;
         }
-
-      if (sinfo != NULL)
-        retval = g_list_prepend (retval, sinfo);
       else
         _clutter_script_warn_missing_attribute (script,
                                                 NULL,
                                                 "handler or state");
+      if (sinfo != NULL)
+        retval = g_list_prepend (retval, sinfo);
     }
 
   return retval;
diff --git a/clutter/clutter-script.c b/clutter/clutter-script.c
index 0143276..9a91f9d 100644
--- a/clutter/clutter-script.c
+++ b/clutter/clutter-script.c
@@ -231,6 +231,8 @@ struct _ClutterScriptPrivate
 
   ClutterScriptParser *parser;
 
+  GHashTable *states;
+
   gchar **search_paths;
 
   gchar *filename;
@@ -337,6 +339,7 @@ clutter_script_finalize (GObject *gobject)
   g_hash_table_destroy (priv->objects);
   g_strfreev (priv->search_paths);
   g_free (priv->filename);
+  g_hash_table_destroy (priv->states);
 
   G_OBJECT_CLASS (clutter_script_parent_class)->finalize (gobject);
 }
@@ -427,6 +430,9 @@ clutter_script_init (ClutterScript *script)
   priv->objects = g_hash_table_new_full (g_str_hash, g_str_equal,
                                          NULL,
                                          object_info_free);
+  priv->states = g_hash_table_new_full (g_str_hash, g_str_equal,
+                                        g_free,
+                                        (GDestroyNotify) g_object_unref);
 }
 
 /**
@@ -987,14 +993,22 @@ connect_each_object (gpointer key,
         }
       else
         {
-          GObject *state_object;
+          GObject *state_object = NULL;
           const gchar *signal_name, *signal_detail;
           gchar **components;
           GQuark signal_quark;
           guint signal_id;
           HookData *hook_data;
 
-          state_object = clutter_script_get_object (script, sinfo->state);
+          if (sinfo->state == NULL)
+            state_object = (GObject *) clutter_script_get_state (script, NULL);
+          else
+            {
+              state_object = clutter_script_get_object (script, sinfo->state);
+              if (state_object == NULL)
+                state_object = (GObject *) clutter_script_get_state (script, sinfo->state);
+            }
+
           if (state_object == NULL)
             continue;
 
@@ -1254,6 +1268,66 @@ clutter_script_list_objects (ClutterScript *script)
   return retval;
 }
 
+/**
+ * clutter_script_add_state:
+ * @script: a #ClutterScript
+ * @state_name: (allow-none): a name for the @state, or %NULL to
+ *   set the default #ClutterState
+ *
+ * Adds a #ClutterState using the given name to the #ClutterScript instance.
+ *
+ * The #ClutterScript instance will use @state to resolve target states when
+ * connecting signal handlers.
+ *
+ * The #ClutterScript instance will take a reference on the #ClutterState
+ * passed to this function.
+ *
+ * Since: 1.8
+ */
+void
+clutter_script_add_state (ClutterScript *script,
+                          const gchar   *state_name,
+                          ClutterState  *state)
+{
+  g_return_if_fail (CLUTTER_IS_SCRIPT (script));
+  g_return_if_fail (CLUTTER_IS_STATE (state));
+
+  if (state_name == NULL || *state_name == '\0')
+    state_name = "__clutter_script_default_state";
+
+  g_hash_table_replace (script->priv->states,
+                        g_strdup (state_name),
+                        g_object_ref (state));
+}
+
+/**
+ * clutter_script_get_state:
+ * @script: a #ClutterScript
+ * @state_name: (allow-none): the name of the #ClutterState, or %NULL
+ *
+ * Retrieves the #ClutterState for the given @state_name.
+ *
+ * If @state_name is %NULL, this function will return the default
+ * #ClutterState instance.
+ *
+ * Return value: (transfer none): a pointer to the #ClutterState for the
+ *   given name. The #ClutterState is owned by the #ClutterScript instance
+ *   and it should not be unreferenced
+ *
+ * Since: 1.8
+ */
+ClutterState *
+clutter_script_get_state (ClutterScript *script,
+                          const gchar   *state_name)
+{
+  g_return_val_if_fail (CLUTTER_IS_SCRIPT (script), NULL);
+
+  if (state_name == NULL || *state_name == '\0')
+    state_name = "__clutter_script_default_state";
+
+  return g_hash_table_lookup (script->priv->states, state_name);
+}
+
 /*
  * _clutter_script_generate_fake_id:
  * @script: a #ClutterScript
diff --git a/clutter/clutter-script.h b/clutter/clutter-script.h
index 58702dd..a866b2d 100644
--- a/clutter/clutter-script.h
+++ b/clutter/clutter-script.h
@@ -28,7 +28,8 @@
 #ifndef __CLUTTER_SCRIPT_H__
 #define __CLUTTER_SCRIPT_H__
 
-#include <glib-object.h>
+#include <clutter/clutter-types.h>
+#include <clutter/clutter-state.h>
 
 G_BEGIN_DECLS
 
@@ -143,44 +144,48 @@ struct _ClutterScriptClass
   void (*_clutter_reserved8) (void);
 };
 
-GType          clutter_script_get_type        (void) G_GNUC_CONST;
-
-ClutterScript *clutter_script_new                  (void);
-guint          clutter_script_load_from_file       (ClutterScript  *script,
-                                                    const gchar    *filename,
-                                                    GError        **error);
-guint          clutter_script_load_from_data       (ClutterScript  *script,
-                                                    const gchar    *data,
-                                                    gssize          length,
-                                                    GError        **error);
-
-GObject *      clutter_script_get_object           (ClutterScript  *script,
-                                                    const gchar    *name);
-gint           clutter_script_get_objects          (ClutterScript  *script,
-                                                    const gchar    *first_name,
-                                                    ...) G_GNUC_NULL_TERMINATED;
-GList *        clutter_script_list_objects         (ClutterScript  *script);
-
-void           clutter_script_unmerge_objects      (ClutterScript  *script,
-                                                    guint           merge_id);
-void           clutter_script_ensure_objects       (ClutterScript  *script);
-
-GType          clutter_script_get_type_from_name   (ClutterScript  *script,
-                                                    const gchar    *type_name);
-
-const gchar *  clutter_get_script_id               (GObject        *gobject);
-
-void           clutter_script_connect_signals      (ClutterScript  *script,
-                                                    gpointer        user_data);
-void           clutter_script_connect_signals_full (ClutterScript  *script,
-                                                    ClutterScriptConnectFunc func,
-                                                    gpointer        user_data);
-
-void           clutter_script_add_search_paths     (ClutterScript       *script,
-                                                    const gchar * const  paths[],
-                                                    gsize                n_paths);
-gchar *        clutter_script_lookup_filename      (ClutterScript       *script,
-                                                    const gchar         *filename) G_GNUC_MALLOC;
+GType clutter_script_get_type (void) G_GNUC_CONST;
+
+ClutterScript * clutter_script_new                      (void);
+guint           clutter_script_load_from_file           (ClutterScript             *script,
+                                                         const gchar               *filename,
+                                                         GError                   **error);
+guint           clutter_script_load_from_data           (ClutterScript             *script,
+                                                         const gchar               *data,
+                                                         gssize                     length,
+                                                         GError                   **error);
+
+GObject *       clutter_script_get_object               (ClutterScript             *script,
+                                                         const gchar               *name);
+gint            clutter_script_get_objects              (ClutterScript             *script,
+                                                         const gchar               *first_name,
+                                                         ...) G_GNUC_NULL_TERMINATED;
+GList *         clutter_script_list_objects             (ClutterScript             *script);
+void            clutter_script_unmerge_objects          (ClutterScript             *script,
+                                                         guint                      merge_id);
+void            clutter_script_ensure_objects           (ClutterScript             *script);
+
+void            clutter_script_add_state                (ClutterScript             *script,
+                                                         const gchar               *state_name,
+                                                         ClutterState              *state);
+ClutterState *  clutter_script_get_state                (ClutterScript             *script,
+                                                         const gchar               *state_name);
+
+void            clutter_script_connect_signals          (ClutterScript             *script,
+                                                         gpointer                   user_data);
+void            clutter_script_connect_signals_full     (ClutterScript             *script,
+                                                         ClutterScriptConnectFunc   func,
+                                                         gpointer                   user_data);
+
+void            clutter_script_add_search_paths         (ClutterScript             *script,
+                                                         const gchar * const        paths[],
+                                                         gsize                      n_paths);
+gchar *         clutter_script_lookup_filename          (ClutterScript             *script,
+                                                         const gchar               *filename) G_GNUC_MALLOC;
+GType           clutter_script_get_type_from_name       (ClutterScript             *script,
+                                                         const gchar               *type_name);
+
+const gchar *   clutter_get_script_id                   (GObject                   *gobject);
 
 G_END_DECLS
 



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