/soc/2013/ankitkv/gobjectification: d6bf29f40712: Replaced signa...

Ankit Vani a at nevitus.org
Tue Oct 8 11:02:19 EDT 2013


Changeset: d6bf29f4071291545cce9f78ea2ebe424b104c66
Author:	 Ankit Vani <a at nevitus.org>
Date:	 2013-10-08 20:26 +0530
Branch:	 soc.2013.gobjectification.signals
URL: https://hg.pidgin.im/soc/2013/ankitkv/gobjectification/rev/d6bf29f40712

Description:

Replaced signals.[ch] code with gsignal.[ch] from gobjectification branch

diffstat:

 libpurple/signals.c |  1197 +++++---------------------------------------------
 libpurple/signals.h |   340 +-------------
 2 files changed, 148 insertions(+), 1389 deletions(-)

diffs (truncated from 1607 to 300 lines):

diff --git a/libpurple/signals.c b/libpurple/signals.c
--- a/libpurple/signals.c
+++ b/libpurple/signals.c
@@ -23,1106 +23,179 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
  */
-#include "internal.h"
-
-#include "dbus-maybe.h"
-#include "debug.h"
 #include "signals.h"
 
-/* must include this to use G_VA_COPY */
-#include <string.h>
+#include "debug.h"
 
-typedef struct
-{
-	void *instance;
+/******************************************************************************
+ * Structs
+ *****************************************************************************/
+struct _PurpleSignalHandle {
+	guint signal_id;
+	gulong hook_id;
+};
 
-	GHashTable *signals;
-	size_t signal_count;
-
-	gulong next_signal_id;
-
-} PurpleInstanceData;
-
-typedef struct
-{
-	gulong id;
-
-	PurpleSignalMarshalFunc marshal;
-
-	int num_values;
-	GType *value_types;
-	GType ret_type;
-
-	GList *handlers;
-	size_t handler_count;
-
-	gulong next_handler_id;
+typedef struct {
+	GType type;
+	GCallback callback;
+	gpointer user_data;
+	GConnectFlags flags;
+	GQuark detail;
+	GType return_type;
 } PurpleSignalData;
 
-typedef struct
+/******************************************************************************
+ * Helpers
+ *****************************************************************************/
+static gboolean
+purple_signal_emission_hook(GSignalInvocationHint *hint, guint n_params,
+							  const GValue *pvalues, gpointer data)
 {
-	gulong id;
-	PurpleCallback cb;
-	void *handle;
-	void *data;
-	gboolean use_vargs;
-	int priority;
+	PurpleSignalData *sd = data;
+	GObject *obj = NULL;
+	gboolean swap = FALSE, after = FALSE;
+	GClosure *closure = NULL;
 
-} PurpleSignalHandlerData;
+	obj = g_value_get_object(pvalues);
 
-static GHashTable *instance_table = NULL;
+	if(!G_TYPE_CHECK_INSTANCE_TYPE(obj, sd->type))
+		return TRUE;
 
-static void
-destroy_instance_data(PurpleInstanceData *instance_data)
-{
-	g_hash_table_destroy(instance_data->signals);
+	swap = (sd->flags & G_CONNECT_SWAPPED);
+	after = (sd->flags & G_CONNECT_AFTER);
 
-	g_free(instance_data);
+	if(swap)
+		closure = g_cclosure_new_swap(sd->callback, sd->user_data, NULL);
+	else
+		closure = g_cclosure_new(sd->callback, sd->user_data, NULL);
+
+	g_signal_connect_closure_by_id(obj, hint->signal_id, sd->detail, closure, after);
+
+	if(sd->return_type != G_TYPE_NONE) {
+		GValue ret;
+
+		g_value_init(&ret, sd->return_type);
+
+		g_closure_invoke(closure, &ret, n_params, pvalues, hint);
+	} else {
+		g_closure_invoke(closure, NULL, n_params, pvalues, hint);
+	}
+
+	return TRUE;
 }
 
-static void
-destroy_signal_data(PurpleSignalData *signal_data)
+/******************************************************************************
+ * PurpleSignal API
+ *****************************************************************************/
+PurpleSignalHandle *
+purple_signal_connect_flags(GType type, const gchar *name,
+							  GConnectFlags flags,
+							  GCallback callback, gpointer data)
 {
-	g_list_foreach(signal_data->handlers, (GFunc)g_free, NULL);
-	g_list_free(signal_data->handlers);
+	PurpleSignalData *sd = NULL;
+	PurpleSignalHandle *handle = NULL;
+	GQuark detail = 0;
+	GSignalQuery query;
+	guint signal_id = 0;
+	gulong hook_id = 0;
+	gpointer *klass = NULL;
 
-	g_free(signal_data->value_types);
-	g_free(signal_data);
-}
+	klass = g_type_class_ref(type);
 
-gulong
-purple_signal_register(void *instance, const char *signal,
-					 PurpleSignalMarshalFunc marshal,
-					 GType ret_type, int num_values, ...)
-{
-	PurpleInstanceData *instance_data;
-	PurpleSignalData *signal_data;
-	va_list args;
+	if(!g_signal_parse_name(name, type, &signal_id, &detail, TRUE)) {
+		purple_debug_warning("gsignal",
+		                     "Failed to find information for signal '%s' on "
+		                     "type '%s'!\n",
+		                     name, g_type_name(type));
 
-	g_return_val_if_fail(instance != NULL, 0);
-	g_return_val_if_fail(signal   != NULL, 0);
-	g_return_val_if_fail(marshal  != NULL, 0);
 
-	instance_data =
-		(PurpleInstanceData *)g_hash_table_lookup(instance_table, instance);
+		g_type_class_unref(klass);
 
-	if (instance_data == NULL)
-	{
-		instance_data = g_new0(PurpleInstanceData, 1);
-
-		instance_data->instance = instance;
-		instance_data->next_signal_id = 1;
-
-		instance_data->signals =
-			g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
-								  (GDestroyNotify)destroy_signal_data);
-
-		g_hash_table_insert(instance_table, instance, instance_data);
+		return NULL;
 	}
 
-	signal_data = g_new0(PurpleSignalData, 1);
-	signal_data->id              = instance_data->next_signal_id;
-	signal_data->marshal         = marshal;
-	signal_data->next_handler_id = 1;
-	signal_data->ret_type        = ret_type;
-	signal_data->num_values      = num_values;
+	g_signal_query(signal_id, &query);
 
-	if (num_values > 0)
-	{
-		int i;
+	if(query.signal_id == 0) {
+		purple_debug_warning("gsignal",
+		                     "Failed to query signal '%s' on type '%s'!\n",
+		                     name, g_type_name(type));
 
-		signal_data->value_types = g_new0(GType, num_values);
+		g_type_class_unref(klass);
 
-		va_start(args, num_values);
-
-		for (i = 0; i < num_values; i++)
-			signal_data->value_types[i] = va_arg(args, GType);
-
-		va_end(args);
+		return NULL;
 	}
 
-	g_hash_table_insert(instance_data->signals,
-						g_strdup(signal), signal_data);
+	sd = g_new(PurpleSignalData, 1);
+	sd->callback = callback;
+	sd->user_data = data;
+	sd->flags = 0;
+	sd->detail = detail;
+	sd->type = type;
+	sd->return_type = query.return_type;
 
-	instance_data->next_signal_id++;
-	instance_data->signal_count++;
+	hook_id = g_signal_add_emission_hook(signal_id, detail,
+										 purple_signal_emission_hook,
+										 sd, g_free);
 
-	return signal_data->id;
+	g_type_class_unref(klass);
+
+	handle = purple_signal_handle_new(signal_id, hook_id);
+
+	return handle;
 }
 
 void
-purple_signal_unregister(void *instance, const char *signal)
-{
-	PurpleInstanceData *instance_data;
+purple_signal_disconnect(PurpleSignalHandle *handle) {
+	g_return_if_fail(handle);
 
-	g_return_if_fail(instance != NULL);
-	g_return_if_fail(signal   != NULL);
+	g_signal_remove_emission_hook(handle->signal_id, handle->hook_id);
 
-	instance_data =
-		(PurpleInstanceData *)g_hash_table_lookup(instance_table, instance);
+	purple_signal_handle_free(handle);
+}
 
-	g_return_if_fail(instance_data != NULL);
+/******************************************************************************
+ * PurpleSignalHandle API
+ *****************************************************************************/
+GType
+purple_signal_handle_get_type(void) {
+	static GType type = 0;
 
-	g_hash_table_remove(instance_data->signals, signal);
+	if(G_UNLIKELY(type == 0)) {
+		type =
+			g_boxed_type_register_static("PurpleSignalHandle",
+										 (GBoxedCopyFunc)purple_signal_handle_copy,
+										 (GBoxedFreeFunc)purple_signal_handle_free);
 
-	instance_data->signal_count--;
+	}
 
-	if (instance_data->signal_count == 0)
-	{
-		/* Unregister the instance. */
-		g_hash_table_remove(instance_table, instance);
-	}
+	return type;
+}
+
+PurpleSignalHandle *
+purple_signal_handle_new(guint signal_id, gulong hook_id) {
+	PurpleSignalHandle *handle = NULL;
+
+	handle = g_new(PurpleSignalHandle, 1);
+
+	handle->signal_id = signal_id;
+	handle->hook_id = hook_id;
+
+	return handle;
+}
+
+PurpleSignalHandle *
+purple_signal_handle_copy(const PurpleSignalHandle *handle) {
+	PurpleSignalHandle *copy = NULL;
+
+	g_return_val_if_fail(handle, NULL);
+
+	copy = purple_signal_handle_new(handle->signal_id, handle->hook_id);
+
+	return copy;
 }
 
 void
-purple_signals_unregister_by_instance(void *instance)
-{
-	gboolean found;
-
-	g_return_if_fail(instance != NULL);
-
-	found = g_hash_table_remove(instance_table, instance);
-



More information about the Commits mailing list