diff --git a/ChangeLog b/ChangeLog index 4274f0ac8..a26306e4e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2007-10-10 Emmanuele Bassi + + * clutter/json/json-types.h: + * clutter/json/json-array.c: + * clutter/json/json-object.c: Resync with the upstream copy + of JSON-GLib; add json_object_remove_member() and + json_array_remove_element() and fix the g_hash_table_get_keys() + replacement for GLib 2.12. + + * clutter/clutter-script.c: Clean up the complex properties + parsing code. + 2007-10-10 Emmanuele Bassi * clutter/clutter-script.c (json_object_end): Add "type_func" diff --git a/clutter/clutter-script.c b/clutter/clutter-script.c index 9d3606bb4..d92d41556 100644 --- a/clutter/clutter-script.c +++ b/clutter/clutter-script.c @@ -341,6 +341,56 @@ construct_timeline (ClutterScript *script, return retval; } +static const gchar * +get_id_from_node (JsonNode *node) +{ + JsonObject *object; + + switch (JSON_NODE_TYPE (node)) + { + case JSON_NODE_OBJECT: + object = json_node_get_object (node); + if (json_object_has_member (object, "id")) + { + JsonNode *id = json_object_get_member (object, "id"); + + return json_node_get_string (id); + } + break; + + case JSON_NODE_VALUE: + return json_node_get_string (node); + + default: + break; + } + + return NULL; +} + +static ClutterUnit +get_units_from_node (JsonNode *node) +{ + ClutterUnit retval = 0; + GValue value = { 0, }; + + if (JSON_NODE_TYPE (node) != JSON_NODE_VALUE) + return 0; + + json_node_get_value (node, &value); + switch (G_VALUE_TYPE (&value)) + { + case G_TYPE_INT: + retval = CLUTTER_UNITS_FROM_INT (g_value_get_int (&value)); + break; + + default: + break; + } + + return retval; +} + static PropertyInfo * parse_member_to_property (ClutterScript *script, ObjectInfo *info, @@ -410,26 +460,33 @@ parse_member_to_property (ClutterScript *script, { JsonArray *array = json_node_get_array (node); JsonNode *val; - gint i; + gint array_len, i; ClutterMargin margin = { 0, }; - /* this is quite evil indeed */ - for (i = 0; i < json_array_get_length (array); i++) + array_len = json_array_get_length (array); + for (i = 0; i < array_len; i++) { + ClutterUnit units; + val = json_array_get_element (array, i); + units = get_units_from_node (val); + switch (i) { case 0: - margin.top = CLUTTER_UNITS_FROM_INT (json_node_get_int (val)); + margin.top = units; + margin.right = margin.top; + margin.bottom = margin.top; + margin.left = margin.top; break; case 1: - margin.right = CLUTTER_UNITS_FROM_INT (json_node_get_int (val)); + margin.right = margin.left = units; break; case 2: - margin.bottom = CLUTTER_UNITS_FROM_INT (json_node_get_int (val)); + margin.bottom = units; break; case 3: - margin.left = CLUTTER_UNITS_FROM_INT (json_node_get_int (val)); + margin.left = units; break; } } @@ -443,26 +500,33 @@ parse_member_to_property (ClutterScript *script, { JsonArray *array = json_node_get_array (node); JsonNode *val; - gint i; + gint array_len, i; ClutterPadding padding = { 0, }; - /* this is quite evil indeed */ - for (i = 0; i < json_array_get_length (array); i++) + array_len = json_array_get_length (array); + for (i = 0; i < array_len; i++) { + ClutterUnit units; + val = json_array_get_element (array, i); + units = get_units_from_node (val); + switch (i) { case 0: - padding.top = CLUTTER_UNITS_FROM_INT (json_node_get_int (val)); + padding.top = units; + padding.right = padding.top; + padding.bottom = padding.top; + padding.left = padding.top; break; case 1: - padding.right = CLUTTER_UNITS_FROM_INT (json_node_get_int (val)); + padding.right = padding.left = units; break; case 2: - padding.bottom = CLUTTER_UNITS_FROM_INT (json_node_get_int (val)); + padding.bottom = units; break; case 3: - padding.left = CLUTTER_UNITS_FROM_INT (json_node_get_int (val)); + padding.left = units; break; } } @@ -509,35 +573,14 @@ parse_member_to_property (ClutterScript *script, array_len = json_array_get_length (array); for (i = 0; i < array_len; i++) { - JsonObject *object; + const gchar *id; val = json_array_get_element (array, i); - - switch (JSON_NODE_TYPE (val)) - { - case JSON_NODE_OBJECT: - object = json_node_get_object (val); - - if (json_object_has_member (object, "id") && - json_object_has_member (object, "type")) - { - JsonNode *id = json_object_get_member (object, "id"); - - children = g_list_prepend (children, - json_node_dup_string (id)); - } - break; - - case JSON_NODE_VALUE: - if (json_node_get_string (val)) - children = g_list_prepend (children, - json_node_dup_string (val)); - break; - - default: - warn_invalid_value (script, name, val); - break; - } + id = get_id_from_node (val); + if (id) + children = g_list_prepend (children, g_strdup (id)); + else + warn_invalid_value (script, "id", val); } if (name[0] == 'c') /* children */ @@ -587,8 +630,10 @@ json_object_end (JsonParser *parser, if (json_object_has_member (object, "type_func")) { + /* remove "type_func", as it's not usef by anything else */ val = json_object_get_member (object, "type_func"); oinfo->type_func = json_node_dup_string (val); + json_object_remove_member (object, "type_func"); } oinfo->is_toplevel = FALSE; @@ -597,28 +642,23 @@ json_object_end (JsonParser *parser, for (l = members; l; l = l->next) { const gchar *name = l->data; + PropertyInfo *pinfo; + + if (strcmp (name, "id") == 0 || strcmp (name, "type") == 0) + continue; val = json_object_get_member (object, name); - if (strcmp (name, "id") == 0 || - strcmp (name, "type_func") == 0 || - strcmp (name, "type") == 0) + pinfo = parse_member_to_property (script, oinfo, name, val); + if (!pinfo) continue; - else - { - PropertyInfo *pinfo; - pinfo = parse_member_to_property (script, oinfo, name, val); - if (!pinfo) - continue; + oinfo->properties = g_list_prepend (oinfo->properties, pinfo); - oinfo->properties = g_list_prepend (oinfo->properties, pinfo); - - CLUTTER_NOTE (SCRIPT, "Added property `%s' (type:%s) for class `%s'", - pinfo->property_name, - g_type_name (G_VALUE_TYPE (&pinfo->value)), - oinfo->class_name); - } + CLUTTER_NOTE (SCRIPT, "Added property `%s' (type:%s) for class `%s'", + pinfo->property_name, + g_type_name (G_VALUE_TYPE (&pinfo->value)), + oinfo->class_name); } g_list_free (members); diff --git a/clutter/json/json-array.c b/clutter/json/json-array.c index e9727e881..7e2362154 100644 --- a/clutter/json/json-array.c +++ b/clutter/json/json-array.c @@ -32,6 +32,7 @@ * Since arrays can be expensive, they are reference counted. You can control * the lifetime of a #JsonArray using json_array_ref() and json_array_unref(). * + * To append an element, use json_array_add_element(). * To extract an element at a given index, use json_array_get_element(). * To retrieve the entire array in list form, use json_array_get_elements(). * To retrieve the length of the array, use json_array_get_length(). @@ -183,7 +184,8 @@ json_array_get_elements (JsonArray *array) * @array: a #JsonArray * @index_: the index of the element to retrieve * - * Retrieves the element at @index_ inside a #JsonArray. + * Retrieves the #JsonNode containing the value of the element at @index_ + * inside a #JsonArray. * * Return value: a pointer to the #JsonNode at the requested index */ @@ -218,7 +220,8 @@ json_array_get_length (JsonArray *array) * @array: a #JsonArray * @node: a #JsonNode * - * Appends @node inside @array. + * Appends @node inside @array. The array will take ownership of the + * #JsonNode. */ void json_array_add_element (JsonArray *array, @@ -229,3 +232,21 @@ json_array_add_element (JsonArray *array, g_ptr_array_add (array->elements, node); } + +/** + * json_array_remove_element: + * @array: a #JsonArray + * @index_: the position of the element to be removed + * + * Removes the #JsonNode inside @array at @index_ freeing its allocated + * resources. + */ +void +json_array_remove_element (JsonArray *array, + guint index_) +{ + g_return_if_fail (array != NULL); + g_return_if_fail (index_ < array->elements->len); + + json_node_free (g_ptr_array_remove_index (array->elements, index_)); +} diff --git a/clutter/json/json-object.c b/clutter/json/json-object.c index 18369bf91..b7359d74a 100644 --- a/clutter/json/json-object.c +++ b/clutter/json/json-object.c @@ -34,6 +34,7 @@ * Since objects can be expensive, they are reference counted. You can control * the lifetime of a #JsonObject using json_object_ref() and json_object_unref(). * + * To add a member with a given name, use json_object_add_member(). * To extract a member with a given name, use json_object_get_member(). * To retrieve the list of members, use json_object_get_members(). * To retrieve the size of the object (that is, the number of members it has), use @@ -137,6 +138,7 @@ json_object_unref (JsonObject *object) * @node: the value of the member * * Adds a member named @member_name and containing @node into a #JsonObject. + * The object will take ownership of the #JsonNode. */ void json_object_add_member (JsonObject *object, @@ -158,30 +160,30 @@ json_object_add_member (JsonObject *object, g_hash_table_replace (object->members, g_strdup (member_name), node); } -#if GLIB_MAJOR_VERSION >= 2 && GLIB_MINOR_VERSION < 14 +/* FIXME: yuck. we really need to depend on GLib 2.14 */ +#if GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION < 14 static void get_keys (gpointer key, gpointer value, - gpointer data) + gpointer user_data) { - GList **list = data; + GList **keys = user_data; - *list = g_list_prepend (*list, key); + *keys = g_list_prepend (*keys, key); } static GList * g_hash_table_get_keys (GHashTable *hash_table) { - GList *retval; + GList *retval = NULL; g_return_val_if_fail (hash_table != NULL, NULL); - retval = NULL; g_hash_table_foreach (hash_table, get_keys, &retval); - return g_list_reverse (retval); + return retval; } -#endif +#endif /* GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION < 14 */ /** * json_object_get_members: @@ -193,7 +195,7 @@ g_hash_table_get_keys (GHashTable *hash_table) * Return value: a #GList of member names. The content of the list * is owned by the #JsonObject and should never be modified or * freed. When you have finished using the returned list, use - * g_slist_free() to free the resources it has allocated. + * g_list_free() to free the resources it has allocated. */ GList * json_object_get_members (JsonObject *object) @@ -208,9 +210,10 @@ json_object_get_members (JsonObject *object) * @object: a #JsonObject * @member_name: the name of the JSON object member to access * - * Retrieves the value of @member_name inside a #JsonObject. + * Retrieves the #JsonNode containing the value of @member_name inside + * a #JsonObject. * - * Return value: a pointer to the value for the requested object + * Return value: a pointer to the node for the requested object * member, or %NULL */ JsonNode * @@ -246,9 +249,9 @@ json_object_has_member (JsonObject *object, * json_object_get_size: * @object: a #JsonObject * - * Retrieves the size of a #JsonObject. + * Retrieves the number of members of a #JsonObject. * - * Return value: the number of members the JSON object has + * Return value: the number of members */ guint json_object_get_size (JsonObject *object) @@ -257,3 +260,20 @@ json_object_get_size (JsonObject *object) return g_hash_table_size (object->members); } + +/** + * json_object_remove_member: + * @object: a #JsonObject + * @member_name: the name of the member to remove + * + * Removes @member_name from @object, freeing its allocated resources. + */ +void +json_object_remove_member (JsonObject *object, + const gchar *member_name) +{ + g_return_if_fail (object != NULL); + g_return_if_fail (member_name != NULL); + + g_hash_table_remove (object->members, member_name); +} diff --git a/clutter/json/json-types.h b/clutter/json/json-types.h index a95f7fd14..26086cbed 100644 --- a/clutter/json/json-types.h +++ b/clutter/json/json-types.h @@ -89,67 +89,71 @@ struct _JsonNode JsonNode *parent; }; -JsonNode * json_node_new (JsonNodeType type); -JsonNode * json_node_copy (JsonNode *node); -void json_node_free (JsonNode *node); +JsonNode * json_node_new (JsonNodeType type); +JsonNode * json_node_copy (JsonNode *node); +void json_node_free (JsonNode *node); -void json_node_set_object (JsonNode *node, - JsonObject *object); -void json_node_take_object (JsonNode *node, - JsonObject *object); -JsonObject * json_node_get_object (JsonNode *node); -JsonObject * json_node_dup_object (JsonNode *node); -void json_node_set_array (JsonNode *node, - JsonArray *array); -void json_node_take_array (JsonNode *node, - JsonArray *array); -JsonArray * json_node_get_array (JsonNode *node); -JsonArray * json_node_dup_array (JsonNode *node); -void json_node_set_value (JsonNode *node, - const GValue *value); -void json_node_get_value (JsonNode *node, - GValue *value); -void json_node_set_string (JsonNode *node, - const gchar *value); -G_CONST_RETURN gchar *json_node_get_string (JsonNode *node); -gchar * json_node_dup_string (JsonNode *node); -void json_node_set_int (JsonNode *node, - gint value); -gint json_node_get_int (JsonNode *node); -void json_node_set_double (JsonNode *node, - gdouble value); -gdouble json_node_get_double (JsonNode *node); -void json_node_set_boolean (JsonNode *node, - gboolean value); -gboolean json_node_get_boolean (JsonNode *node); -JsonNode * json_node_get_parent (JsonNode *node); -G_CONST_RETURN gchar *json_node_type_name (JsonNode *node); +void json_node_set_object (JsonNode *node, + JsonObject *object); +void json_node_take_object (JsonNode *node, + JsonObject *object); +JsonObject * json_node_get_object (JsonNode *node); +JsonObject * json_node_dup_object (JsonNode *node); +void json_node_set_array (JsonNode *node, + JsonArray *array); +void json_node_take_array (JsonNode *node, + JsonArray *array); +JsonArray * json_node_get_array (JsonNode *node); +JsonArray * json_node_dup_array (JsonNode *node); +void json_node_set_value (JsonNode *node, + const GValue *value); +void json_node_get_value (JsonNode *node, + GValue *value); +void json_node_set_string (JsonNode *node, + const gchar *value); +G_CONST_RETURN gchar *json_node_get_string (JsonNode *node); +gchar * json_node_dup_string (JsonNode *node); +void json_node_set_int (JsonNode *node, + gint value); +gint json_node_get_int (JsonNode *node); +void json_node_set_double (JsonNode *node, + gdouble value); +gdouble json_node_get_double (JsonNode *node); +void json_node_set_boolean (JsonNode *node, + gboolean value); +gboolean json_node_get_boolean (JsonNode *node); +JsonNode * json_node_get_parent (JsonNode *node); +G_CONST_RETURN gchar *json_node_type_name (JsonNode *node); -GType json_object_get_type (void) G_GNUC_CONST; -JsonObject * json_object_new (void); -JsonObject * json_object_ref (JsonObject *object); -void json_object_unref (JsonObject *object); -void json_object_add_member (JsonObject *object, - const gchar *member_name, - JsonNode *node); -GList * json_object_get_members (JsonObject *object); -JsonNode * json_object_get_member (JsonObject *object, - const gchar *member_name); -gboolean json_object_has_member (JsonObject *object, - const gchar *member_name); -guint json_object_get_size (JsonObject *object); +GType json_object_get_type (void) G_GNUC_CONST; +JsonObject * json_object_new (void); +JsonObject * json_object_ref (JsonObject *object); +void json_object_unref (JsonObject *object); +void json_object_add_member (JsonObject *object, + const gchar *member_name, + JsonNode *node); +GList * json_object_get_members (JsonObject *object); +JsonNode * json_object_get_member (JsonObject *object, + const gchar *member_name); +gboolean json_object_has_member (JsonObject *object, + const gchar *member_name); +void json_object_remove_member (JsonObject *object, + const gchar *member_name); +guint json_object_get_size (JsonObject *object); -GType json_array_get_type (void) G_GNUC_CONST; -JsonArray * json_array_new (void); -JsonArray * json_array_sized_new (guint n_elements); -JsonArray * json_array_ref (JsonArray *array); -void json_array_unref (JsonArray *array); -void json_array_add_element (JsonArray *array, - JsonNode *node); -GList * json_array_get_elements (JsonArray *array); -JsonNode * json_array_get_element (JsonArray *array, - guint index_); -guint json_array_get_length (JsonArray *array); +GType json_array_get_type (void) G_GNUC_CONST; +JsonArray * json_array_new (void); +JsonArray * json_array_sized_new (guint n_elements); +JsonArray * json_array_ref (JsonArray *array); +void json_array_unref (JsonArray *array); +void json_array_add_element (JsonArray *array, + JsonNode *node); +GList * json_array_get_elements (JsonArray *array); +JsonNode * json_array_get_element (JsonArray *array, + guint index_); +void json_array_remove_element (JsonArray *array, + guint index_); +guint json_array_get_length (JsonArray *array); G_END_DECLS