From b7f99ddd3c55f3d1356bb162114cbdf85ffb6101 Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Fri, 9 Jul 2010 14:59:32 +0100 Subject: [PATCH] script: Let ClutterActor parse behaviours Up until now, the "behaviours" member of an actor definition was parsed by the ClutterScript parser itself - even though it's not strictly necessary. In an effort to minimize the ad hoc code in the Script parser, we should let ClutterActor handle all the special cases that involve actor-specific members. --- clutter/clutter-actor.c | 66 +++++++++++++++++++++++++ clutter/clutter-script-parser.c | 83 +------------------------------- clutter/clutter-script-private.h | 1 - clutter/clutter-script.c | 3 -- 4 files changed, 67 insertions(+), 86 deletions(-) diff --git a/clutter/clutter-actor.c b/clutter/clutter-actor.c index 1036344e4..16caeda12 100644 --- a/clutter/clutter-actor.c +++ b/clutter/clutter-actor.c @@ -291,6 +291,7 @@ #include "clutter-action.h" #include "clutter-actor-meta-private.h" #include "clutter-animatable.h" +#include "clutter-behaviour.h" #include "clutter-constraint.h" #include "clutter-container.h" #include "clutter-debug.h" @@ -8340,6 +8341,40 @@ parse_actor_metas (ClutterScript *script, return g_slist_reverse (retval); } +static GSList * +parse_behaviours (ClutterScript *script, + ClutterActor *actor, + JsonNode *node) +{ + GList *elements, *l; + GSList *retval = NULL; + + if (!JSON_NODE_HOLDS_ARRAY (node)) + return NULL; + + elements = json_array_get_elements (json_node_get_array (node)); + + for (l = elements; l != NULL; l = l->next) + { + JsonNode *element = l->data; + const gchar *id = _clutter_script_get_id_from_node (element); + GObject *behaviour; + + if (id == NULL || *id == '\0') + continue; + + behaviour = clutter_script_get_object (script, id); + if (behaviour == NULL) + continue; + + retval = g_slist_prepend (retval, behaviour); + } + + g_list_free (elements); + + return g_slist_reverse (retval); +} + static gboolean clutter_actor_parse_custom_node (ClutterScriptable *scriptable, ClutterScript *script, @@ -8398,6 +8433,17 @@ clutter_actor_parse_custom_node (ClutterScriptable *scriptable, else g_slice_free (RotationInfo, info); } + else if (strcmp (name, "behaviours") == 0) + { + GSList *l; + + l = parse_behaviours (script, actor, node); + + g_value_init (value, G_TYPE_POINTER); + g_value_set_pointer (value, l); + + retval = TRUE; + } else if (strcmp (name, "actions") == 0 || strcmp (name, "constraints") == 0 || strcmp (name, "effects") == 0) @@ -8457,6 +8503,26 @@ clutter_actor_set_custom_property (ClutterScriptable *scriptable, return; } + if (strcmp (name, "behaviours") == 0) + { + GSList *behaviours, *l; + + if (!G_VALUE_HOLDS (value, G_TYPE_POINTER)) + return; + + behaviours = g_value_get_pointer (value); + for (l = behaviours; l != NULL; l = l->next) + { + ClutterBehaviour *behaviour = l->data; + + clutter_behaviour_apply (behaviour, actor); + } + + g_slist_free (behaviours); + + return; + } + if (strcmp (name, "actions") == 0 || strcmp (name, "constraints") == 0 || strcmp (name, "effects") == 0) diff --git a/clutter/clutter-script-parser.c b/clutter/clutter-script-parser.c index f2bfd3fb6..0fe84162d 100644 --- a/clutter/clutter-script-parser.c +++ b/clutter/clutter-script-parser.c @@ -35,7 +35,6 @@ #include #include "clutter-actor.h" -#include "clutter-behaviour.h" #include "clutter-container.h" #include "clutter-debug.h" #include "clutter-enum-types.h" @@ -651,35 +650,6 @@ parse_signals (ClutterScript *script, return retval; } -static GList * -parse_behaviours (ObjectInfo *oinfo, - JsonNode *node) -{ - JsonArray *array; - GList *retval; - guint array_len, i; - - if (JSON_NODE_TYPE (node) != JSON_NODE_ARRAY) - return NULL; - - retval = oinfo->behaviours; - - array = json_node_get_array (node); - array_len = json_array_get_length (array); - - for (i = 0; i < array_len; i++) - { - JsonNode *child = json_array_get_element (array, i); - const gchar *id; - - id = _clutter_script_get_id_from_node (child); - if (id) - retval = g_list_prepend (retval, g_strdup (id)); - } - - return g_list_reverse (retval); -} - static ClutterTimeline * construct_timeline (ClutterScript *script, JsonObject *object) @@ -983,14 +953,6 @@ clutter_script_parser_object_end (JsonParser *json_parser, json_object_remove_member (object, "children"); } - if (json_object_has_member (object, "behaviours")) - { - val = json_object_get_member (object, "behaviours"); - oinfo->behaviours = parse_behaviours (oinfo, val); - - json_object_remove_member (object, "behaviours"); - } - if (json_object_has_member (object, "signals")) { val = json_object_get_member (object, "signals"); @@ -1740,46 +1702,6 @@ apply_child_properties (ClutterScript *script, oinfo->properties = unresolved; } -static void -apply_behaviours (ClutterScript *script, - ObjectInfo *oinfo) -{ - ClutterActor *actor = CLUTTER_ACTOR (oinfo->object); - GList *l, *unresolved; - - unresolved = NULL; - for (l = oinfo->behaviours; l != NULL; l = l->next) - { - const gchar *name = l->data; - ObjectInfo *behaviour_info; - GObject *object = NULL; - - behaviour_info = _clutter_script_get_object_info (script, name); - if (behaviour_info != NULL) - { - _clutter_script_construct_object (script, behaviour_info); - object = behaviour_info->object; - } - - if (object == NULL) - { - unresolved = g_list_prepend (unresolved, g_strdup (name)); - continue; - } - - CLUTTER_NOTE (SCRIPT, "Applying behaviour '%s' to actor of type '%s'", - name, - g_type_name (G_OBJECT_TYPE (actor))); - - clutter_behaviour_apply (CLUTTER_BEHAVIOUR (object), actor); - } - - g_list_foreach (oinfo->behaviours, (GFunc) g_free, NULL); - g_list_free (oinfo->behaviours); - - oinfo->behaviours = unresolved; -} - static void add_children (ClutterScript *script, ObjectInfo *oinfo) @@ -1839,9 +1761,6 @@ _clutter_script_check_unresolved (ClutterScript *script, if (oinfo->children != NULL && CLUTTER_IS_CONTAINER (oinfo->object)) add_children (script, oinfo); - if (oinfo->behaviours != NULL && CLUTTER_IS_ACTOR (oinfo->object)) - apply_behaviours (script, oinfo); - /* this is a bit *eugh*, but it allows us to effectively make sure * that child and layout properties are parsed and applied to the * right child @@ -1885,7 +1804,7 @@ _clutter_script_check_unresolved (ClutterScript *script, } } - if (oinfo->properties || oinfo->children || oinfo->behaviours) + if (oinfo->properties || oinfo->children) oinfo->has_unresolved = TRUE; else oinfo->has_unresolved = FALSE; diff --git a/clutter/clutter-script-private.h b/clutter/clutter-script-private.h index 0b03d13b7..f69410c66 100644 --- a/clutter/clutter-script-private.h +++ b/clutter/clutter-script-private.h @@ -58,7 +58,6 @@ typedef struct { GList *properties; GList *children; - GList *behaviours; GList *signals; GType gtype; diff --git a/clutter/clutter-script.c b/clutter/clutter-script.c index a286b72fd..92f086534 100644 --- a/clutter/clutter-script.c +++ b/clutter/clutter-script.c @@ -308,9 +308,6 @@ object_info_free (gpointer data) g_list_foreach (oinfo->children, (GFunc) g_free, NULL); g_list_free (oinfo->children); - g_list_foreach (oinfo->behaviours, (GFunc) g_free, NULL); - g_list_free (oinfo->behaviours); - /* we unref top-level objects and leave the actors alone, * unless we are unmerging in which case we have to destroy * the actor to unparent them