2007-10-18 Emmanuele Bassi <ebassi@openedhand.com>
* clutter/clutter-script-private.h: * clutter/clutter-script.h: * clutter/clutter-script.c: Allow id-less objects: as long as they have a "type" member, a unique id will be provided. (json_object_end): Add merge id to the object information structure. (apply_behaviours), (add_children): Keep the unresolved objects around. (construct_stage), (clutter_script_construct_object): If an object has unresolved children or behaviours try resolving them when we ask for it. (json_parse_end), (clutter_script_ensure_objects): Ensure that the objects are fully constructed as best as we can when finished parsing. (object_info_free), (remove_by_merge_id): (clutter_script_unmerge_objects): Remove objects under the same merge id returned by the loading functions. (Fixes bug #558)
This commit is contained in:
parent
1ccbe04505
commit
f1105807fb
26
ChangeLog
26
ChangeLog
@ -1,3 +1,29 @@
|
|||||||
|
2007-10-18 Emmanuele Bassi <ebassi@openedhand.com>
|
||||||
|
|
||||||
|
* clutter/clutter-script-private.h:
|
||||||
|
* clutter/clutter-script.h:
|
||||||
|
* clutter/clutter-script.c: Allow id-less objects: as long
|
||||||
|
as they have a "type" member, a unique id will be provided.
|
||||||
|
|
||||||
|
(json_object_end): Add merge id to the object information
|
||||||
|
structure.
|
||||||
|
|
||||||
|
(apply_behaviours), (add_children): Keep the unresolved
|
||||||
|
objects around.
|
||||||
|
|
||||||
|
(construct_stage), (clutter_script_construct_object): If an
|
||||||
|
object has unresolved children or behaviours try resolving
|
||||||
|
them when we ask for it.
|
||||||
|
|
||||||
|
(json_parse_end), (clutter_script_ensure_objects): Ensure
|
||||||
|
that the objects are fully constructed as best as we can when
|
||||||
|
finished parsing.
|
||||||
|
|
||||||
|
(object_info_free), (remove_by_merge_id):
|
||||||
|
(clutter_script_unmerge_objects): Remove objects under the
|
||||||
|
same merge id returned by the loading functions. (Fixes
|
||||||
|
bug #558)
|
||||||
|
|
||||||
2007-10-18 Matthew Allum <mallum@openedhand.com>
|
2007-10-18 Matthew Allum <mallum@openedhand.com>
|
||||||
|
|
||||||
* clutter/clutter-score.c:
|
* clutter/clutter-score.c:
|
||||||
|
@ -45,7 +45,11 @@ typedef struct {
|
|||||||
GType gtype;
|
GType gtype;
|
||||||
GObject *object;
|
GObject *object;
|
||||||
|
|
||||||
|
guint merge_id;
|
||||||
|
|
||||||
guint is_toplevel : 1;
|
guint is_toplevel : 1;
|
||||||
|
guint has_unresolved : 1;
|
||||||
|
guint is_unmerged : 1;
|
||||||
} ObjectInfo;
|
} ObjectInfo;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -145,6 +145,7 @@ struct _ClutterScriptPrivate
|
|||||||
GHashTable *objects;
|
GHashTable *objects;
|
||||||
|
|
||||||
guint last_merge_id;
|
guint last_merge_id;
|
||||||
|
guint last_unknown;
|
||||||
|
|
||||||
JsonParser *parser;
|
JsonParser *parser;
|
||||||
|
|
||||||
@ -632,10 +633,24 @@ json_object_end (JsonParser *parser,
|
|||||||
JsonNode *val;
|
JsonNode *val;
|
||||||
GList *members, *l;
|
GList *members, *l;
|
||||||
|
|
||||||
/* ignore any non-named object */
|
|
||||||
if (!json_object_has_member (object, "id"))
|
if (!json_object_has_member (object, "id"))
|
||||||
|
{
|
||||||
|
gchar *fake;
|
||||||
|
|
||||||
|
if (!json_object_has_member (object, "type"))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
fake = g_strdup_printf ("script-%d-%d",
|
||||||
|
priv->last_merge_id,
|
||||||
|
priv->last_unknown++);
|
||||||
|
|
||||||
|
val = json_node_new (JSON_NODE_VALUE);
|
||||||
|
json_node_set_string (val, fake);
|
||||||
|
json_object_add_member (object, "id", val);
|
||||||
|
|
||||||
|
g_free (fake);
|
||||||
|
}
|
||||||
|
|
||||||
if (!json_object_has_member (object, "type"))
|
if (!json_object_has_member (object, "type"))
|
||||||
{
|
{
|
||||||
val = json_object_get_member (object, "id");
|
val = json_object_get_member (object, "id");
|
||||||
@ -645,6 +660,7 @@ json_object_end (JsonParser *parser,
|
|||||||
}
|
}
|
||||||
|
|
||||||
oinfo = g_slice_new0 (ObjectInfo);
|
oinfo = g_slice_new0 (ObjectInfo);
|
||||||
|
oinfo->merge_id = priv->last_merge_id;
|
||||||
|
|
||||||
val = json_object_get_member (object, "id");
|
val = json_object_get_member (object, "id");
|
||||||
oinfo->id = json_node_dup_string (val);
|
oinfo->id = json_node_dup_string (val);
|
||||||
@ -654,13 +670,14 @@ json_object_end (JsonParser *parser,
|
|||||||
|
|
||||||
if (json_object_has_member (object, "type_func"))
|
if (json_object_has_member (object, "type_func"))
|
||||||
{
|
{
|
||||||
/* remove "type_func", as it's not usef by anything else */
|
/* remove "type_func", as it's not used by anything else */
|
||||||
val = json_object_get_member (object, "type_func");
|
val = json_object_get_member (object, "type_func");
|
||||||
oinfo->type_func = json_node_dup_string (val);
|
oinfo->type_func = json_node_dup_string (val);
|
||||||
json_object_remove_member (object, "type_func");
|
json_object_remove_member (object, "type_func");
|
||||||
}
|
}
|
||||||
|
|
||||||
oinfo->is_toplevel = FALSE;
|
oinfo->is_toplevel = FALSE;
|
||||||
|
oinfo->is_unmerged = FALSE;
|
||||||
|
|
||||||
members = json_object_get_members (object);
|
members = json_object_get_members (object);
|
||||||
for (l = members; l; l = l->next)
|
for (l = members; l; l = l->next)
|
||||||
@ -686,9 +703,10 @@ json_object_end (JsonParser *parser,
|
|||||||
}
|
}
|
||||||
g_list_free (members);
|
g_list_free (members);
|
||||||
|
|
||||||
CLUTTER_NOTE (SCRIPT, "Added object `%s' (type:%s) with %d properties",
|
CLUTTER_NOTE (SCRIPT, "Added object `%s' (type:%s, id:%d) with %d properties",
|
||||||
oinfo->id,
|
oinfo->id,
|
||||||
oinfo->class_name,
|
oinfo->class_name,
|
||||||
|
oinfo->merge_id,
|
||||||
g_list_length (oinfo->properties));
|
g_list_length (oinfo->properties));
|
||||||
|
|
||||||
g_hash_table_replace (priv->objects, g_strdup (oinfo->id), oinfo);
|
g_hash_table_replace (priv->objects, g_strdup (oinfo->id), oinfo);
|
||||||
@ -932,12 +950,13 @@ translate_properties (ClutterScript *script,
|
|||||||
static void
|
static void
|
||||||
apply_behaviours (ClutterScript *script,
|
apply_behaviours (ClutterScript *script,
|
||||||
ClutterActor *actor,
|
ClutterActor *actor,
|
||||||
GList *behaviours)
|
ObjectInfo *oinfo)
|
||||||
{
|
{
|
||||||
GObject *object;
|
GObject *object;
|
||||||
GList *l;
|
GList *l, *unresolved;
|
||||||
|
|
||||||
for (l = behaviours; l != NULL; l = l->next)
|
unresolved = NULL;
|
||||||
|
for (l = oinfo->behaviours; l != NULL; l = l->next)
|
||||||
{
|
{
|
||||||
const gchar *name = l->data;
|
const gchar *name = l->data;
|
||||||
|
|
||||||
@ -949,7 +968,11 @@ apply_behaviours (ClutterScript *script,
|
|||||||
oinfo = g_hash_table_lookup (script->priv->objects, name);
|
oinfo = g_hash_table_lookup (script->priv->objects, name);
|
||||||
if (oinfo)
|
if (oinfo)
|
||||||
object = clutter_script_construct_object (script, oinfo);
|
object = clutter_script_construct_object (script, oinfo);
|
||||||
else
|
}
|
||||||
|
|
||||||
|
if (!object)
|
||||||
|
{
|
||||||
|
unresolved = g_list_prepend (unresolved, g_strdup (name));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -959,17 +982,23 @@ apply_behaviours (ClutterScript *script,
|
|||||||
|
|
||||||
clutter_behaviour_apply (CLUTTER_BEHAVIOUR (object), 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
|
static void
|
||||||
add_children (ClutterScript *script,
|
add_children (ClutterScript *script,
|
||||||
ClutterContainer *container,
|
ClutterContainer *container,
|
||||||
GList *children)
|
ObjectInfo *oinfo)
|
||||||
{
|
{
|
||||||
GObject *object;
|
GObject *object;
|
||||||
GList *l;
|
GList *l, *unresolved;
|
||||||
|
|
||||||
for (l = children; l != NULL; l = l->next)
|
unresolved = NULL;
|
||||||
|
for (l = oinfo->children; l != NULL; l = l->next)
|
||||||
{
|
{
|
||||||
const gchar *name = l->data;
|
const gchar *name = l->data;
|
||||||
|
|
||||||
@ -981,7 +1010,11 @@ add_children (ClutterScript *script,
|
|||||||
oinfo = g_hash_table_lookup (script->priv->objects, name);
|
oinfo = g_hash_table_lookup (script->priv->objects, name);
|
||||||
if (oinfo)
|
if (oinfo)
|
||||||
object = clutter_script_construct_object (script, oinfo);
|
object = clutter_script_construct_object (script, oinfo);
|
||||||
else
|
}
|
||||||
|
|
||||||
|
if (!object)
|
||||||
|
{
|
||||||
|
unresolved = g_list_prepend (unresolved, g_strdup (name));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -991,6 +1024,11 @@ add_children (ClutterScript *script,
|
|||||||
|
|
||||||
clutter_container_add_actor (container, CLUTTER_ACTOR (object));
|
clutter_container_add_actor (container, CLUTTER_ACTOR (object));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_list_foreach (oinfo->children, (GFunc) g_free, NULL);
|
||||||
|
g_list_free (oinfo->children);
|
||||||
|
|
||||||
|
oinfo->children = unresolved;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GObject *
|
static GObject *
|
||||||
@ -1000,9 +1038,11 @@ construct_stage (ClutterScript *script,
|
|||||||
GObjectClass *oclass = g_type_class_ref (CLUTTER_TYPE_STAGE);
|
GObjectClass *oclass = g_type_class_ref (CLUTTER_TYPE_STAGE);
|
||||||
GList *l;
|
GList *l;
|
||||||
|
|
||||||
if (oinfo->object)
|
if (oinfo->object && !oinfo->has_unresolved)
|
||||||
return oinfo->object;
|
return oinfo->object;
|
||||||
|
|
||||||
|
if (!oinfo->object)
|
||||||
|
{
|
||||||
oinfo->object = G_OBJECT (clutter_stage_get_default ());
|
oinfo->object = G_OBJECT (clutter_stage_get_default ());
|
||||||
|
|
||||||
for (l = oinfo->properties; l; l = l->next)
|
for (l = oinfo->properties; l; l = l->next)
|
||||||
@ -1032,20 +1072,18 @@ construct_stage (ClutterScript *script,
|
|||||||
}
|
}
|
||||||
|
|
||||||
g_object_set_property (oinfo->object, name, &value);
|
g_object_set_property (oinfo->object, name, &value);
|
||||||
|
|
||||||
g_value_unset (&value);
|
g_value_unset (&value);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_type_class_unref (oclass);
|
g_type_class_unref (oclass);
|
||||||
|
|
||||||
if (oinfo->children)
|
|
||||||
{
|
|
||||||
/* we know ClutterStage is a ClutterContainer */
|
|
||||||
add_children (script,
|
|
||||||
CLUTTER_CONTAINER (oinfo->object),
|
|
||||||
oinfo->children);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* we know ClutterStage is a ClutterContainer */
|
||||||
|
if (oinfo->children)
|
||||||
|
add_children (script, CLUTTER_CONTAINER (oinfo->object), oinfo);
|
||||||
|
|
||||||
|
oinfo->has_unresolved = (oinfo->children != NULL);
|
||||||
|
|
||||||
g_object_set_data_full (oinfo->object, "clutter-script-name",
|
g_object_set_data_full (oinfo->object, "clutter-script-name",
|
||||||
g_strdup (oinfo->id),
|
g_strdup (oinfo->id),
|
||||||
g_free);
|
g_free);
|
||||||
@ -1060,7 +1098,7 @@ clutter_script_construct_object (ClutterScript *script,
|
|||||||
guint n_params, i;
|
guint n_params, i;
|
||||||
GParameter *params;
|
GParameter *params;
|
||||||
|
|
||||||
if (oinfo->object)
|
if (oinfo->object && !oinfo->has_unresolved)
|
||||||
return oinfo->object;
|
return oinfo->object;
|
||||||
|
|
||||||
if (oinfo->gtype == G_TYPE_INVALID)
|
if (oinfo->gtype == G_TYPE_INVALID)
|
||||||
@ -1081,6 +1119,8 @@ clutter_script_construct_object (ClutterScript *script,
|
|||||||
if (g_type_is_a (oinfo->gtype, CLUTTER_TYPE_STAGE))
|
if (g_type_is_a (oinfo->gtype, CLUTTER_TYPE_STAGE))
|
||||||
return construct_stage (script, oinfo);
|
return construct_stage (script, oinfo);
|
||||||
|
|
||||||
|
if (!oinfo->object)
|
||||||
|
{
|
||||||
params = NULL;
|
params = NULL;
|
||||||
translate_properties (script, oinfo, &n_params, ¶ms);
|
translate_properties (script, oinfo, &n_params, ¶ms);
|
||||||
|
|
||||||
@ -1098,12 +1138,6 @@ clutter_script_construct_object (ClutterScript *script,
|
|||||||
|
|
||||||
g_free (params);
|
g_free (params);
|
||||||
|
|
||||||
if (CLUTTER_IS_CONTAINER (oinfo->object) && oinfo->children)
|
|
||||||
add_children (script, CLUTTER_CONTAINER (oinfo->object), oinfo->children);
|
|
||||||
|
|
||||||
if (CLUTTER_IS_ACTOR (oinfo->object) && oinfo->behaviours)
|
|
||||||
apply_behaviours (script, CLUTTER_ACTOR (oinfo->object), oinfo->behaviours);
|
|
||||||
|
|
||||||
if (CLUTTER_IS_BEHAVIOUR (oinfo->object) ||
|
if (CLUTTER_IS_BEHAVIOUR (oinfo->object) ||
|
||||||
CLUTTER_IS_TIMELINE (oinfo->object))
|
CLUTTER_IS_TIMELINE (oinfo->object))
|
||||||
oinfo->is_toplevel = TRUE;
|
oinfo->is_toplevel = TRUE;
|
||||||
@ -1112,12 +1146,21 @@ clutter_script_construct_object (ClutterScript *script,
|
|||||||
g_object_set_data_full (oinfo->object, "clutter-script-name",
|
g_object_set_data_full (oinfo->object, "clutter-script-name",
|
||||||
g_strdup (oinfo->id),
|
g_strdup (oinfo->id),
|
||||||
g_free);
|
g_free);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CLUTTER_IS_CONTAINER (oinfo->object) && oinfo->children)
|
||||||
|
add_children (script, CLUTTER_CONTAINER (oinfo->object), oinfo);
|
||||||
|
|
||||||
|
if (CLUTTER_IS_ACTOR (oinfo->object) && oinfo->behaviours)
|
||||||
|
apply_behaviours (script, CLUTTER_ACTOR (oinfo->object), oinfo);
|
||||||
|
|
||||||
|
oinfo->has_unresolved = (oinfo->children || oinfo->behaviours);
|
||||||
|
|
||||||
return oinfo->object;
|
return oinfo->object;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
for_each_object (gpointer key,
|
construct_each_object (gpointer key,
|
||||||
gpointer value,
|
gpointer value,
|
||||||
gpointer data)
|
gpointer data)
|
||||||
{
|
{
|
||||||
@ -1134,7 +1177,7 @@ json_parse_end (JsonParser *parser,
|
|||||||
ClutterScript *script = user_data;
|
ClutterScript *script = user_data;
|
||||||
ClutterScriptPrivate *priv = script->priv;
|
ClutterScriptPrivate *priv = script->priv;
|
||||||
|
|
||||||
g_hash_table_foreach (priv->objects, for_each_object, script);
|
g_hash_table_foreach (priv->objects, construct_each_object, script);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1166,7 +1209,16 @@ object_info_free (gpointer data)
|
|||||||
g_list_free (oinfo->behaviours);
|
g_list_free (oinfo->behaviours);
|
||||||
|
|
||||||
if (oinfo->is_toplevel && oinfo->object)
|
if (oinfo->is_toplevel && oinfo->object)
|
||||||
|
{
|
||||||
g_object_unref (oinfo->object);
|
g_object_unref (oinfo->object);
|
||||||
|
oinfo->object = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (oinfo->is_unmerged && oinfo->object)
|
||||||
|
{
|
||||||
|
clutter_actor_destroy (CLUTTER_ACTOR (oinfo->object));
|
||||||
|
oinfo->object = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
g_slice_free (ObjectInfo, oinfo);
|
g_slice_free (ObjectInfo, oinfo);
|
||||||
}
|
}
|
||||||
@ -1247,7 +1299,8 @@ clutter_script_new (void)
|
|||||||
* the currently loaded ones, if any.
|
* the currently loaded ones, if any.
|
||||||
*
|
*
|
||||||
* Return value: on error, zero is returned and @error is set
|
* Return value: on error, zero is returned and @error is set
|
||||||
* accordingly. On success, a positive integer is returned.
|
* accordingly. On success, the merge id for the UI definitions is
|
||||||
|
* returned. You can use the merge id with clutter_script_unmerge().
|
||||||
*
|
*
|
||||||
* Since: 0.6
|
* Since: 0.6
|
||||||
*/
|
*/
|
||||||
@ -1267,16 +1320,16 @@ clutter_script_load_from_file (ClutterScript *script,
|
|||||||
g_free (priv->filename);
|
g_free (priv->filename);
|
||||||
priv->filename = g_strdup (filename);
|
priv->filename = g_strdup (filename);
|
||||||
priv->is_filename = TRUE;
|
priv->is_filename = TRUE;
|
||||||
|
priv->last_merge_id += 1;
|
||||||
|
|
||||||
internal_error = NULL;
|
internal_error = NULL;
|
||||||
json_parser_load_from_file (priv->parser, filename, &internal_error);
|
json_parser_load_from_file (priv->parser, filename, &internal_error);
|
||||||
if (internal_error)
|
if (internal_error)
|
||||||
{
|
{
|
||||||
g_propagate_error (error, internal_error);
|
g_propagate_error (error, internal_error);
|
||||||
|
priv->last_merge_id -= 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
priv->last_merge_id += 1;
|
|
||||||
|
|
||||||
return priv->last_merge_id;
|
return priv->last_merge_id;
|
||||||
}
|
}
|
||||||
@ -1293,7 +1346,8 @@ clutter_script_load_from_file (ClutterScript *script,
|
|||||||
* the currently loaded ones, if any.
|
* the currently loaded ones, if any.
|
||||||
*
|
*
|
||||||
* Return value: on error, zero is returned and @error is set
|
* Return value: on error, zero is returned and @error is set
|
||||||
* accordingly. On success, a positive integer is returned.
|
* accordingly. On success, the merge id for the UI definitions is
|
||||||
|
* returned. You can use the merge id with clutter_script_unmerge().
|
||||||
*
|
*
|
||||||
* Since: 0.6
|
* Since: 0.6
|
||||||
*/
|
*/
|
||||||
@ -1314,16 +1368,16 @@ clutter_script_load_from_data (ClutterScript *script,
|
|||||||
g_free (priv->filename);
|
g_free (priv->filename);
|
||||||
priv->filename = NULL;
|
priv->filename = NULL;
|
||||||
priv->is_filename = FALSE;
|
priv->is_filename = FALSE;
|
||||||
|
priv->last_merge_id += 1;
|
||||||
|
|
||||||
internal_error = NULL;
|
internal_error = NULL;
|
||||||
json_parser_load_from_data (priv->parser, data, length, &internal_error);
|
json_parser_load_from_data (priv->parser, data, length, &internal_error);
|
||||||
if (internal_error)
|
if (internal_error)
|
||||||
{
|
{
|
||||||
g_propagate_error (error, internal_error);
|
g_propagate_error (error, internal_error);
|
||||||
|
priv->last_merge_id -= 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
priv->last_merge_id += 1;
|
|
||||||
|
|
||||||
return priv->last_merge_id;
|
return priv->last_merge_id;
|
||||||
}
|
}
|
||||||
@ -1409,6 +1463,84 @@ clutter_script_get_objects (ClutterScript *script,
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
ClutterScript *script;
|
||||||
|
guint merge_id;
|
||||||
|
GSList *ids;
|
||||||
|
} UnmergeData;
|
||||||
|
|
||||||
|
static void
|
||||||
|
remove_by_merge_id (gpointer key,
|
||||||
|
gpointer value,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
gchar *name = key;
|
||||||
|
ObjectInfo *oinfo = value;
|
||||||
|
UnmergeData *unmerge_data = data;
|
||||||
|
|
||||||
|
if (oinfo->merge_id == unmerge_data->merge_id)
|
||||||
|
{
|
||||||
|
unmerge_data->ids = g_slist_prepend (unmerge_data->ids, g_strdup (name));
|
||||||
|
oinfo->is_unmerged = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_script_unmerge_objects:
|
||||||
|
* @script: a #ClutterScript
|
||||||
|
* @merge_id: merge id returned when loading a UI definition
|
||||||
|
*
|
||||||
|
* Unmerges the objects identified by @merge_id.
|
||||||
|
*
|
||||||
|
* Since: 0.6
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
clutter_script_unmerge_objects (ClutterScript *script,
|
||||||
|
guint merge_id)
|
||||||
|
{
|
||||||
|
ClutterScriptPrivate *priv;
|
||||||
|
UnmergeData data;
|
||||||
|
GSList *l;
|
||||||
|
|
||||||
|
g_return_if_fail (CLUTTER_IS_SCRIPT (script));
|
||||||
|
g_return_if_fail (merge_id > 0);
|
||||||
|
|
||||||
|
priv = script->priv;
|
||||||
|
|
||||||
|
data.script = script;
|
||||||
|
data.merge_id = merge_id;
|
||||||
|
data.ids = NULL;
|
||||||
|
g_hash_table_foreach (priv->objects, remove_by_merge_id, &data);
|
||||||
|
|
||||||
|
for (l = data.ids; l != NULL; l = l->next)
|
||||||
|
g_hash_table_remove (priv->objects, l->data);
|
||||||
|
|
||||||
|
g_slist_foreach (data.ids, (GFunc) g_free, NULL);
|
||||||
|
g_slist_free (data.ids);
|
||||||
|
|
||||||
|
clutter_script_ensure_objects (script);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_script_ensure_object:
|
||||||
|
* @script: a #ClutterScript
|
||||||
|
*
|
||||||
|
* Ensure that every object defined inside @script is correctly
|
||||||
|
* constructed. You should rarely need to use this function.
|
||||||
|
*
|
||||||
|
* Since: 0.6
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
clutter_script_ensure_objects (ClutterScript *script)
|
||||||
|
{
|
||||||
|
ClutterScriptPrivate *priv;
|
||||||
|
|
||||||
|
g_return_if_fail (CLUTTER_IS_SCRIPT (script));
|
||||||
|
|
||||||
|
priv = script->priv;
|
||||||
|
g_hash_table_foreach (priv->objects, construct_each_object, script);
|
||||||
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
clutter_script_enum_from_string (GType type,
|
clutter_script_enum_from_string (GType type,
|
||||||
const gchar *string,
|
const gchar *string,
|
||||||
@ -1538,16 +1670,6 @@ clutter_script_flags_from_string (GType type,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
|
||||||
clutter_script_value_from_data (ClutterScript *script,
|
|
||||||
GType gtype,
|
|
||||||
const gchar *data,
|
|
||||||
GValue *value,
|
|
||||||
GError **error)
|
|
||||||
{
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
GQuark
|
GQuark
|
||||||
clutter_script_error_quark (void)
|
clutter_script_error_quark (void)
|
||||||
{
|
{
|
||||||
|
@ -97,6 +97,9 @@ GObject * clutter_script_get_object (ClutterScript *script,
|
|||||||
GList * clutter_script_get_objects (ClutterScript *script,
|
GList * clutter_script_get_objects (ClutterScript *script,
|
||||||
const gchar *first_name,
|
const gchar *first_name,
|
||||||
...) G_GNUC_NULL_TERMINATED;
|
...) G_GNUC_NULL_TERMINATED;
|
||||||
|
void clutter_script_unmerge_objects (ClutterScript *script,
|
||||||
|
guint merge_id);
|
||||||
|
void clutter_script_ensure_objects (ClutterScript *script);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
2007-10-18 Emmanuele Bassi <ebassi@openedhand.com>
|
||||||
|
|
||||||
|
* clutter-sections.txt: Add new ClutterScript API.
|
||||||
|
|
||||||
2007-10-10 Emmanuele Bassi <ebassi@openedhand.com>
|
2007-10-10 Emmanuele Bassi <ebassi@openedhand.com>
|
||||||
|
|
||||||
* clutter-sections.txt: Add new API and rearrange the subsections.
|
* clutter-sections.txt: Add new API and rearrange the subsections.
|
||||||
|
@ -1098,6 +1098,8 @@ clutter_script_load_from_data
|
|||||||
clutter_script_load_from_file
|
clutter_script_load_from_file
|
||||||
clutter_script_get_object
|
clutter_script_get_object
|
||||||
clutter_script_get_objects
|
clutter_script_get_objects
|
||||||
|
clutter_script_unmerge_objects
|
||||||
|
clutter_script_ensure_objects
|
||||||
<SUBSECTION Standard>
|
<SUBSECTION Standard>
|
||||||
CLUTTER_TYPE_SCRIPT
|
CLUTTER_TYPE_SCRIPT
|
||||||
CLUTTER_SCRIPT
|
CLUTTER_SCRIPT
|
||||||
|
@ -5,6 +5,22 @@
|
|||||||
|
|
||||||
#include <clutter/clutter.h>
|
#include <clutter/clutter.h>
|
||||||
|
|
||||||
|
static ClutterScript *script = NULL;
|
||||||
|
static guint merge_id = 0;
|
||||||
|
|
||||||
|
static const gchar *test_unmerge =
|
||||||
|
"{"
|
||||||
|
" \"id\" : \"blue-button\","
|
||||||
|
" \"type\" : \"ClutterRectangle\","
|
||||||
|
" \"color\" : \"#0000ffff\","
|
||||||
|
" \"x\" : 350,"
|
||||||
|
" \"y\" : 50,"
|
||||||
|
" \"width\" : 100,"
|
||||||
|
" \"height\" : 100,"
|
||||||
|
" \"visible\" : true,"
|
||||||
|
" \"reactive\" : true"
|
||||||
|
"}";
|
||||||
|
|
||||||
static const gchar *test_behaviour =
|
static const gchar *test_behaviour =
|
||||||
"["
|
"["
|
||||||
" {"
|
" {"
|
||||||
@ -37,11 +53,18 @@ static const gchar *test_behaviour =
|
|||||||
" }"
|
" }"
|
||||||
"]";
|
"]";
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
blue_button_press (ClutterActor *actor,
|
||||||
|
ClutterButtonEvent *event,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
clutter_script_unmerge_objects (script, merge_id);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main (int argc, char *argv[])
|
main (int argc, char *argv[])
|
||||||
{
|
{
|
||||||
ClutterScript *script;
|
GObject *stage, *timeline, *blue_button;
|
||||||
GObject *stage, *timeline;
|
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
|
|
||||||
clutter_init (&argc, &argv);
|
clutter_init (&argc, &argv);
|
||||||
@ -69,9 +92,25 @@ main (int argc, char *argv[])
|
|||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
merge_id = clutter_script_load_from_data (script, test_unmerge, -1, &error);
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
g_print ("*** Error:\n"
|
||||||
|
"*** %s\n", error->message);
|
||||||
|
g_error_free (error);
|
||||||
|
g_object_unref (script);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
stage = clutter_script_get_object (script, "main-stage");
|
stage = clutter_script_get_object (script, "main-stage");
|
||||||
clutter_actor_show (CLUTTER_ACTOR (stage));
|
clutter_actor_show (CLUTTER_ACTOR (stage));
|
||||||
|
|
||||||
|
blue_button = clutter_script_get_object (script, "blue-button");
|
||||||
|
g_signal_connect (blue_button,
|
||||||
|
"button-press-event",
|
||||||
|
G_CALLBACK (blue_button_press),
|
||||||
|
NULL);
|
||||||
|
|
||||||
timeline = clutter_script_get_object (script, "main-timeline");
|
timeline = clutter_script_get_object (script, "main-timeline");
|
||||||
clutter_timeline_start (CLUTTER_TIMELINE (timeline));
|
clutter_timeline_start (CLUTTER_TIMELINE (timeline));
|
||||||
|
|
||||||
|
@ -27,16 +27,6 @@
|
|||||||
"visible" : true,
|
"visible" : true,
|
||||||
"behaviours" : [ "fade-behaviour" ]
|
"behaviours" : [ "fade-behaviour" ]
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"id" : "blue-button",
|
|
||||||
"type" : "ClutterRectangle",
|
|
||||||
"color" : "#0000ffff",
|
|
||||||
"x" : 350,
|
|
||||||
"y" : 50,
|
|
||||||
"width" : 100,
|
|
||||||
"height" : 100,
|
|
||||||
"visible" : true,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"id" : "red-hand",
|
"id" : "red-hand",
|
||||||
"type" : "ClutterTexture",
|
"type" : "ClutterTexture",
|
||||||
@ -46,7 +36,8 @@
|
|||||||
"opacity" : 100,
|
"opacity" : 100,
|
||||||
"visible" : true,
|
"visible" : true,
|
||||||
"behaviours" : [ "rotate-behaviour", "fade-behaviour" ]
|
"behaviours" : [ "rotate-behaviour", "fade-behaviour" ]
|
||||||
}
|
},
|
||||||
|
"blue-button"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user