/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