2007-10-10 Emmanuele Bassi <ebassi@openedhand.com>

* 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.
This commit is contained in:
Emmanuele Bassi 2007-10-10 12:51:51 +00:00
parent 704aa0c6d7
commit 8b55030c14
5 changed files with 227 additions and 130 deletions

View File

@ -1,3 +1,15 @@
2007-10-10 Emmanuele Bassi <ebassi@openedhand.com>
* 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 <ebassi@openedhand.com> 2007-10-10 Emmanuele Bassi <ebassi@openedhand.com>
* clutter/clutter-script.c (json_object_end): Add "type_func" * clutter/clutter-script.c (json_object_end): Add "type_func"

View File

@ -341,6 +341,56 @@ construct_timeline (ClutterScript *script,
return retval; 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 * static PropertyInfo *
parse_member_to_property (ClutterScript *script, parse_member_to_property (ClutterScript *script,
ObjectInfo *info, ObjectInfo *info,
@ -410,26 +460,33 @@ parse_member_to_property (ClutterScript *script,
{ {
JsonArray *array = json_node_get_array (node); JsonArray *array = json_node_get_array (node);
JsonNode *val; JsonNode *val;
gint i; gint array_len, i;
ClutterMargin margin = { 0, }; ClutterMargin margin = { 0, };
/* this is quite evil indeed */ array_len = json_array_get_length (array);
for (i = 0; i < json_array_get_length (array); i++) for (i = 0; i < array_len; i++)
{ {
ClutterUnit units;
val = json_array_get_element (array, i); val = json_array_get_element (array, i);
units = get_units_from_node (val);
switch (i) switch (i)
{ {
case 0: 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; break;
case 1: case 1:
margin.right = CLUTTER_UNITS_FROM_INT (json_node_get_int (val)); margin.right = margin.left = units;
break; break;
case 2: case 2:
margin.bottom = CLUTTER_UNITS_FROM_INT (json_node_get_int (val)); margin.bottom = units;
break; break;
case 3: case 3:
margin.left = CLUTTER_UNITS_FROM_INT (json_node_get_int (val)); margin.left = units;
break; break;
} }
} }
@ -443,26 +500,33 @@ parse_member_to_property (ClutterScript *script,
{ {
JsonArray *array = json_node_get_array (node); JsonArray *array = json_node_get_array (node);
JsonNode *val; JsonNode *val;
gint i; gint array_len, i;
ClutterPadding padding = { 0, }; ClutterPadding padding = { 0, };
/* this is quite evil indeed */ array_len = json_array_get_length (array);
for (i = 0; i < json_array_get_length (array); i++) for (i = 0; i < array_len; i++)
{ {
ClutterUnit units;
val = json_array_get_element (array, i); val = json_array_get_element (array, i);
units = get_units_from_node (val);
switch (i) switch (i)
{ {
case 0: 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; break;
case 1: case 1:
padding.right = CLUTTER_UNITS_FROM_INT (json_node_get_int (val)); padding.right = padding.left = units;
break; break;
case 2: case 2:
padding.bottom = CLUTTER_UNITS_FROM_INT (json_node_get_int (val)); padding.bottom = units;
break; break;
case 3: case 3:
padding.left = CLUTTER_UNITS_FROM_INT (json_node_get_int (val)); padding.left = units;
break; break;
} }
} }
@ -509,35 +573,14 @@ parse_member_to_property (ClutterScript *script,
array_len = json_array_get_length (array); array_len = json_array_get_length (array);
for (i = 0; i < array_len; i++) for (i = 0; i < array_len; i++)
{ {
JsonObject *object; const gchar *id;
val = json_array_get_element (array, i); val = json_array_get_element (array, i);
id = get_id_from_node (val);
switch (JSON_NODE_TYPE (val)) if (id)
{ children = g_list_prepend (children, g_strdup (id));
case JSON_NODE_OBJECT: else
object = json_node_get_object (val); warn_invalid_value (script, "id", 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;
}
} }
if (name[0] == 'c') /* children */ if (name[0] == 'c') /* children */
@ -587,8 +630,10 @@ 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 */
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");
} }
oinfo->is_toplevel = FALSE; oinfo->is_toplevel = FALSE;
@ -597,17 +642,13 @@ json_object_end (JsonParser *parser,
for (l = members; l; l = l->next) for (l = members; l; l = l->next)
{ {
const gchar *name = l->data; const gchar *name = l->data;
PropertyInfo *pinfo;
if (strcmp (name, "id") == 0 || strcmp (name, "type") == 0)
continue;
val = json_object_get_member (object, name); val = json_object_get_member (object, name);
if (strcmp (name, "id") == 0 ||
strcmp (name, "type_func") == 0 ||
strcmp (name, "type") == 0)
continue;
else
{
PropertyInfo *pinfo;
pinfo = parse_member_to_property (script, oinfo, name, val); pinfo = parse_member_to_property (script, oinfo, name, val);
if (!pinfo) if (!pinfo)
continue; continue;
@ -619,7 +660,6 @@ json_object_end (JsonParser *parser,
g_type_name (G_VALUE_TYPE (&pinfo->value)), g_type_name (G_VALUE_TYPE (&pinfo->value)),
oinfo->class_name); oinfo->class_name);
} }
}
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) with %d properties",

View File

@ -32,6 +32,7 @@
* Since arrays can be expensive, they are reference counted. You can control * 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(). * 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 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 entire array in list form, use json_array_get_elements().
* To retrieve the length of the array, use json_array_get_length(). * 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 * @array: a #JsonArray
* @index_: the index of the element to retrieve * @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 * Return value: a pointer to the #JsonNode at the requested index
*/ */
@ -218,7 +220,8 @@ json_array_get_length (JsonArray *array)
* @array: a #JsonArray * @array: a #JsonArray
* @node: a #JsonNode * @node: a #JsonNode
* *
* Appends @node inside @array. * Appends @node inside @array. The array will take ownership of the
* #JsonNode.
*/ */
void void
json_array_add_element (JsonArray *array, json_array_add_element (JsonArray *array,
@ -229,3 +232,21 @@ json_array_add_element (JsonArray *array,
g_ptr_array_add (array->elements, node); 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_));
}

View File

@ -34,6 +34,7 @@
* Since objects can be expensive, they are reference counted. You can control * 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(). * 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 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 list of members, use json_object_get_members().
* To retrieve the size of the object (that is, the number of members it has), use * 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 * @node: the value of the member
* *
* Adds a member named @member_name and containing @node into a #JsonObject. * Adds a member named @member_name and containing @node into a #JsonObject.
* The object will take ownership of the #JsonNode.
*/ */
void void
json_object_add_member (JsonObject *object, 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); 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 static void
get_keys (gpointer key, get_keys (gpointer key,
gpointer value, 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 * static GList *
g_hash_table_get_keys (GHashTable *hash_table) g_hash_table_get_keys (GHashTable *hash_table)
{ {
GList *retval; GList *retval = NULL;
g_return_val_if_fail (hash_table != NULL, NULL); g_return_val_if_fail (hash_table != NULL, NULL);
retval = NULL;
g_hash_table_foreach (hash_table, get_keys, &retval); 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: * 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 * Return value: a #GList of member names. The content of the list
* is owned by the #JsonObject and should never be modified or * is owned by the #JsonObject and should never be modified or
* freed. When you have finished using the returned list, use * 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 * GList *
json_object_get_members (JsonObject *object) json_object_get_members (JsonObject *object)
@ -208,9 +210,10 @@ json_object_get_members (JsonObject *object)
* @object: a #JsonObject * @object: a #JsonObject
* @member_name: the name of the JSON object member to access * @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 * member, or %NULL
*/ */
JsonNode * JsonNode *
@ -246,9 +249,9 @@ json_object_has_member (JsonObject *object,
* json_object_get_size: * json_object_get_size:
* @object: a #JsonObject * @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 guint
json_object_get_size (JsonObject *object) json_object_get_size (JsonObject *object)
@ -257,3 +260,20 @@ json_object_get_size (JsonObject *object)
return g_hash_table_size (object->members); 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);
}

View File

@ -137,6 +137,8 @@ JsonNode * json_object_get_member (JsonObject *object,
const gchar *member_name); const gchar *member_name);
gboolean json_object_has_member (JsonObject *object, gboolean json_object_has_member (JsonObject *object,
const gchar *member_name); const gchar *member_name);
void json_object_remove_member (JsonObject *object,
const gchar *member_name);
guint json_object_get_size (JsonObject *object); guint json_object_get_size (JsonObject *object);
GType json_array_get_type (void) G_GNUC_CONST; GType json_array_get_type (void) G_GNUC_CONST;
@ -149,6 +151,8 @@ void json_array_add_element (JsonArray *array,
GList * json_array_get_elements (JsonArray *array); GList * json_array_get_elements (JsonArray *array);
JsonNode * json_array_get_element (JsonArray *array, JsonNode * json_array_get_element (JsonArray *array,
guint index_); guint index_);
void json_array_remove_element (JsonArray *array,
guint index_);
guint json_array_get_length (JsonArray *array); guint json_array_get_length (JsonArray *array);
G_END_DECLS G_END_DECLS