/srv/mercurial-server/detachablepurple: 1175063eb8b9: Make the P...

Gilles Bedel gillux at cpw.pidgin.im
Fri Jun 15 22:01:43 EDT 2012


Changeset: 1175063eb8b9778804b99c49d7895ddd5a7cbea1
Author:	 Gilles Bedel <gillux at cpw.pidgin.im>
Date:	 2012-05-20 15:38 +0000
Branch:	 cpw.gillux.detachablepurple
URL: http://hg.pidgin.im/srv/mercurial-server/detachablepurple/rev/1175063eb8b9

Description:

Make the PurpleObject loading function public, with some enhancements
that will allow the loading of cross-referenced objects (i.e. with
properties that references each other, like PurpleBlistNodes).

diffstat:

 libpurple/dbus/constructor.c |  95 +++++++++++++++++++++++++++++++++++++++----
 libpurple/dbus/constructor.h |  89 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 174 insertions(+), 10 deletions(-)

diffs (240 lines):

diff --git a/libpurple/dbus/constructor.c b/libpurple/dbus/constructor.c
--- a/libpurple/dbus/constructor.c
+++ b/libpurple/dbus/constructor.c
@@ -247,8 +247,82 @@
 	                     purple_constructor_pack_pobject_props(pobj));
 }
 
-static gpointer
-load_pobject(GVariant *vpobject, GType type)
+static void
+purple_constructor_reload_pobj_objpath_props_cb(GVariant *vpobject,
+                                                gpointer  user_data)
+{
+	purple_constructor_reload_pobj_objpath_props(vpobject);
+}
+
+void
+purple_constructor_reload_pobjs_objpath_props(GVariant *pobjects)
+{
+	purple_constructor_foreach_pobjects
+	  (pobjects, purple_constructor_reload_pobj_objpath_props_cb, NULL);
+}
+
+void
+purple_constructor_reload_pobj_objpath_props(GVariant *vpobject)
+{
+	GVariantIter iter;
+	GVariant *props, *prop, *prop_value;
+	gchar *prop_name, *dbus_path;
+	gpointer obj;
+
+	g_variant_get(vpobject, "(o at a(sv))", &dbus_path, &props);
+	obj = purple_dbus_get_gobject_by_path(dbus_path);
+	g_return_if_fail(obj != NULL);
+
+	g_variant_iter_init(&iter, props);
+	while ((prop = g_variant_iter_next_value(&iter)) != NULL) {
+		g_variant_get(prop, "(sv)", &prop_name, &prop_value);
+		if (g_variant_is_of_type(prop_value, G_VARIANT_TYPE_OBJECT_PATH)) {
+			purple_object_set_dbus_property(PURPLE_OBJECT(obj),
+			                                prop_name, prop_value);
+		}
+		g_free(prop_name);
+		g_variant_unref(prop_value);
+		g_variant_unref(prop);
+	}
+	g_variant_unref(props);
+}
+
+static void
+purple_constructor_load_pobj_cb(GVariant *vpobject, gpointer user_data)
+{
+	purple_constructor_load_pobj(vpobject, *(GType*)user_data);
+}
+
+void
+purple_constructor_load_pobjs(GVariant *pobjects, GType type)
+{
+	purple_constructor_foreach_pobjects
+	  (pobjects, purple_constructor_load_pobj_cb, &type);
+}
+
+gpointer
+purple_constructor_load_pobj(GVariant *vpobject, GType type)
+{
+	gpointer obj = purple_constructor_load_pobj_unsync(vpobject, type);
+	purple_object_set_synchronized(PURPLE_OBJECT(obj), TRUE);
+	return obj;
+}
+
+static void
+purple_constructor_load_pobj_unsync_cb(GVariant *vpobject, gpointer user_data)
+{
+	purple_constructor_load_pobj_unsync(vpobject, *(GType*)user_data);
+}
+
+void
+purple_constructor_load_pobjs_unsync(GVariant *pobjects, GType type)
+{
+	purple_constructor_foreach_pobjects
+	  (pobjects, purple_constructor_load_pobj_unsync_cb, &type);
+}
+
+gpointer
+purple_constructor_load_pobj_unsync(GVariant *vpobject, GType type)
 {
 	PurpleObject *pobject;
 	gpointer *obj;
@@ -269,19 +343,19 @@
 	return obj;
 }
 
-static void
-load_pobjects(GVariant *box, GType type)
+void
+purple_constructor_foreach_pobjects(GVariant *box,
+                                    PurpleConstructorForeachFunc treatment,
+                                    gpointer user_data)
 {
 	GVariantIter iter;
 	GVariant *array, *pobject;
-	gpointer obj;
 
 	g_variant_get(box, "(@a(oa(sv)))", &array);
 
 	g_variant_iter_init(&iter, array);
 	while ((pobject = g_variant_iter_next_value(&iter)) != NULL) {
-		obj = load_pobject(pobject, type);
-		purple_object_set_synchronized(PURPLE_OBJECT(obj), TRUE);
+		treatment(pobject, user_data);
 		g_variant_unref(pobject);
 	}
 	g_variant_unref(array);
@@ -319,7 +393,8 @@
 	                              purple_constructor_interface_info.name,
 	                              method);
 	if (ret) {
-		load_pobjects(ret, type);
+		purple_constructor_foreach_pobjects
+		  (ret, purple_constructor_load_pobj_cb, &type);
 		g_variant_unref(ret);
 	}
 }
@@ -392,8 +467,8 @@
 	ret = purple_object_dbus_call(PURPLE_OBJECT(con), "NewAccount",
 	                              username, protocol_id);
 	if (ret) {
-		account = PURPLE_ACCOUNT(load_pobject(ret, "PurpleAccount"));
-		purple_object_set_synchronized(PURPLE_OBJECT(account), TRUE);
+		account = PURPLE_ACCOUNT
+		       (purple_constructor_load_pobj(ret, PURPLE_TYPE_ACCOUNT));
 	}
 	return account;
 }
diff --git a/libpurple/dbus/constructor.h b/libpurple/dbus/constructor.h
--- a/libpurple/dbus/constructor.h
+++ b/libpurple/dbus/constructor.h
@@ -43,6 +43,16 @@
 G_BEGIN_DECLS
 
 /**
+ * A function type suitable for purple_constructor_foreach_pobjects().
+ * 
+ * @param pobj An "(oa(sv))" type GVariant defining the object. See
+ *        purple_constructor_load_pobj() for an explanation of "oa(sv)".
+ * @param user_data user_data passed to purple_constructor_foreach_pobjects().
+ */
+typedef void (*PurpleConstructorForeachFunc)(GVariant *pobj,
+                                             gpointer  user_data);
+
+/**
  * Creates the PurpleConstructor singleton.
  */
 void purple_constructor_do_init(void);
@@ -87,6 +97,85 @@
 GVariant *purple_constructor_pack_pobject(gpointer pobject);
 
 /**
+ * Call a given function on each object of an array of objects.
+ *
+ * @param pobjects A GVariant of packed PurpleObjects. Its type must be either
+ *        "a(oa(sv))" or "(a(oa(sv)))". See purple_constructor_load_pobj() for
+ *        an explanation of the "oa(sv)" part.
+ * @param treatment A function to call on each object in the pobjects array.
+ * @param user_data User data passed to the treatment function.
+ */
+void purple_constructor_foreach_pobjects(GVariant *pobjects,
+                                         PurpleConstructorForeachFunc treatment,
+                                         gpointer user_data);
+
+/**
+ * Unpacks a PurpleObject and instantiate a GObject of type type_name
+ * with the properties and D-Bus name as defined in pobject. Also runs
+ * the purple_object_dbus_init() function on this newly-created object.
+ *
+ * @param pobject An "(oa(sv))" GVariant defining a PurpleObject. "o" is the
+ *        object path name and a(sv) is an array of properties (s is the name
+ *        of the property, v is its value).
+ * @param type A GType of a class derived from PurpleObject.
+ * @returns A newly-created object of type type_name, or NULL on error.
+ */
+gpointer purple_constructor_load_pobj(GVariant *pobject, GType type);
+
+/**
+ * Do the same as purple_constructor_load_pobj(), except that it opers
+ * an array of objects.
+ *
+ * @param pobject An "a(oa(sv))" GVariant defining an array of PurpleObjects.
+ *        See purple_constructor_load_pobj() for an explanation of "oa(sv)".
+ * @param type A GType of a class derived from PurpleObject.
+ */
+void purple_constructor_load_pobjs(GVariant *pobjects, GType type);
+
+/**
+ * Does the same as purple_constructor_load_pobj() but without marking the
+ * created object as "synchronized", so that further operations may be done
+ * on the object before it’s D-Bus-ready.
+ *
+ * @param pobject An "(oa(sv))" GVariant defining a PurpleObject. See
+ *        purple_constructor_load_pobj() for an explanation of "oa(sv)".
+ * @param type A GType of a class derived from PurpleObject.
+ * @returns A newly-created object of type type_name, or NULL on error.
+ */
+gpointer purple_constructor_load_pobj_unsync(GVariant *pobject, GType type);
+
+/**
+ * Do the same as purple_constructor_load_pobj_unsync(), except that it opers
+ * an array of objects.
+ *
+ * @param pobject An "a(oa(sv))" GVariant defining an array of PurpleObjects.
+ *        See purple_constructor_load_pobj() for an explanation of "oa(sv)".
+ * @param type A GType of a class derived from PurpleObject.
+ */
+void purple_constructor_load_pobjs_unsync(GVariant *pobjects, GType type);
+
+/**
+ * This function expects the object defined in pobject to be already
+ * instantiated as a PurpleObject-derived class. Sets all the "o"
+ * GVariant-typed properties according to pobject.
+ *
+ * @param pobject An "(oa(sv))" GVariant defining a PurpleObject. See
+ *        purple_constructor_load_pobj() for an explanation of "oa(sv)".
+ * @returns The already instantiated object, if found, or NULL.
+ */
+void purple_constructor_reload_pobj_objpath_props(GVariant *vpobject);
+
+/**
+ * Do the same as purple_constructor_reload_pobj_objpath_props(), except that
+ * it opers an array of objects.
+ *
+ * @param pobject An "a(oa(sv))" GVariant defining an array of PurpleObjects.
+ *        See purple_constructor_load_pobj() for an explanation of "oa(sv)".
+ * @param type A GType of a class derived from PurpleObject.
+ */
+void purple_constructor_reload_pobjs_objpath_props(GVariant *pobjects);
+
+/**
  * What's get actually called when you call NewAccount over dbus.
  */
 gboolean DBUS_purple_constructor_new_account(PurpleConstructor *con, gchar* username, gchar* protocol_id, gchar **account_path, GError** error);



More information about the Commits mailing list