mantaraya36's blog

Brain dump

Update on Schema properties

My original proposal has of course changed substantially! First, instead of defining a new data structure with multiple types, I’ve started using xmmsv_t which already exists and does most of the work (IPC interchange, value serializing, memory mangement). I only needed to add support for floats. Easy, right?

It turned out to be very complicated as there is no way to serialize float values in a portable manner, because locales would interfere (if you plan to use sprintf) and because you cannot guarantee how floats will be stored in memory on all platforms (especially those which are not IEEE 754 compliant!). So I ended up with a comprimise which is using frexp to separate the float values mantissa and exponent, and encode them as two integers. This appears to give on simple testing a presicion of about 6 or 7 significant figures, which should be sufficient for XMMS2 config values. This is now available at my git repo:

https://github.com/mantaraya36/xmms2-mantaraya36/tree/config-schemas

I’ve also started work on the config properties side, and have settled on the following API for the new system:

/*
 * New config properties using schemas
 */
 xmms_config_node_t *xmms_config_node_lookup (const gchar *path);
 xmms_config_node_t *xmms_config_node_create (const gchar *name, xmmsv_type_t type);
/* Register nodes in the property tree. Callbacks are ignored for lists and dicts */
 xmms_config_node_t *xmms_config_node_register (xmms_config_node_t *node, xmms_object_handler_t cb, gpointer userdata);
gboolean xmms_config_node_unregister (xmms_config_node_t *node);
/* check node types */
 gboolean xmms_config_node_is_type (xmms_config_node_t *node, xmmsv_type_t type);
/* node query operations. Will return the first element if node is a list or array*/
 gint32 xmms_config_node_get_int (xmms_config_node_t *node, gboolean *ok); /* ok can be NULL */
 gfloat xmms_config_node_get_float (xmms_config_node_t *node, gboolean *ok);
 const gchar *xmms_config_node_get_string (xmms_config_node_t *node, gboolean *ok);
 xmms_config_node_t *xmms_config_node_get_index_node (xmms_config_node_t *parent_node, gint index);
 xmms_config_node_t *xmms_config_node_get_key_node (xmms_config_node_t *parent_node, const gchar *name);
/* node value setters. will set the vaue for the first element if node is a list or array */
 void xmms_config_node_set_int (xmms_config_node_t *node, gint value, gboolean *ok);
 void xmms_config_node_set_float (xmms_config_node_t *node, gfloat value, gboolean *ok);
 void xmms_config_node_set_string (xmms_config_node_t *node, const gchar *value, gboolean *ok);
 /* for dicts only: */
 void xmms_config_node_set_from_hash (xmms_config_node_t *parent_node, GHashTable *table);
 /* for lists only: */
 void xmms_config_node_set_from_array (xmms_config_node_t *parent_node, GArray *list);
/* element operations (for lists and dicts) */
 gint xmms_config_node_element_count (xmms_config_node_t *node);
 void xmms_config_node_element_remove_index (xmms_config_node_t *parent_node, gint index, gboolean *ok);
 void xmms_config_node_element_remove_key (xmms_config_node_t *parent_node, xmms_config_node_t *node, gboolean *ok);
/* query node elements values */
 gint xmms_config_node_get_element_int (xmms_config_node_t *parent_node, gint index, gboolean *ok);
 gfloat xmms_config_node_get_element_float (xmms_config_node_t *parent_node, gint index, gboolean *ok);
 const gchar *xmms_config_node_get_element_string (xmms_config_node_t *parent_node, gint index, gboolean *ok);
/* set node elements values */
 void xmms_config_node_set_element_int (xmms_config_node_t *parent_node, gint index, gint value, gboolean *ok);
 void xmms_config_node_set_element_float (xmms_config_node_t *parent_node, gint index, gfloat value, gboolean *ok);
 void xmms_config_node_set_element_string (xmms_config_node_t *parent_node, gint index, const gchar* value, gboolean *ok);
/* list node operations */
 void xmms_config_node_resize (xmms_config_node_t *node, gint size, gboolean *ok);
 void xmms_config_node_append (xmms_config_node_t *parent_node, xmms_config_node_t *node, gboolean *ok);
 void xmms_config_node_insert (xmms_config_node_t *parent_node, gint index, xmms_config_node_t *node, gboolean *ok);
/* callbacks (can only be set for value nodes) */
 void xmms_config_node_callback_set (xmms_config_node_t *node, xmms_object_handler_t cb, gpointer userdata);
 void xmms_config_node_callback_remove (xmms_config_node_t *node, xmms_object_handler_t cb, gpointer userdata);

Nodes will hold a copy of the value in the tree and the node’s address,, so any operations on nodes can be made thread-safe.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: