diff --git a/clutter/clutter-script-parser.c b/clutter/clutter-script-parser.c index 27154f2b2..4477f5a8f 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 : "", 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 0143276a2..9a91f9d4f 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 58702ddae..a866b2d85 100644 --- a/clutter/clutter-script.h +++ b/clutter/clutter-script.h @@ -28,7 +28,8 @@ #ifndef __CLUTTER_SCRIPT_H__ #define __CLUTTER_SCRIPT_H__ -#include +#include +#include G_BEGIN_DECLS @@ -143,44 +144,48 @@ struct _ClutterScriptClass void (*_clutter_reserved8) (void); }; -GType clutter_script_get_type (void) G_GNUC_CONST; +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); +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); +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_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); -GType clutter_script_get_type_from_name (ClutterScript *script, - const gchar *type_name); +void clutter_script_connect_signals (ClutterScript *script, + gpointer user_data); +void clutter_script_connect_signals_full (ClutterScript *script, + ClutterScriptConnectFunc func, + gpointer user_data); -const gchar * clutter_get_script_id (GObject *gobject); +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); -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; +const gchar * clutter_get_script_id (GObject *gobject); G_END_DECLS