📄 gsignal.c
字号:
guint i; for (i = 0; i < node.class_closure_bsa->n_nodes; i++) { ClassClosure *cc = g_bsearch_array_get_nth (node.class_closure_bsa, &g_class_closure_bconfig, i); g_closure_unref (cc->closure); } g_bsearch_array_destroy (node.class_closure_bsa, &g_class_closure_bconfig); } g_free (node.accumulator); if (node.emission_hooks) { g_hook_list_clear (node.emission_hooks); g_free (node.emission_hooks); } SIGNAL_LOCK ();}voidg_signal_override_class_closure (guint signal_id, GType instance_type, GClosure *class_closure){ SignalNode *node; g_return_if_fail (signal_id > 0); g_return_if_fail (class_closure != NULL); SIGNAL_LOCK (); node = LOOKUP_SIGNAL_NODE (signal_id); if (!g_type_is_a (instance_type, node->itype)) g_warning ("%s: type `%s' cannot be overridden for signal id `%u'", G_STRLOC, type_debug_name (instance_type), signal_id); else { ClassClosure *cc = signal_find_class_closure (node, instance_type); if (cc && cc->instance_type == instance_type) g_warning ("%s: type `%s' is already overridden for signal id `%u'", G_STRLOC, type_debug_name (instance_type), signal_id); else signal_add_class_closure (node, instance_type, class_closure); } SIGNAL_UNLOCK ();}voidg_signal_chain_from_overridden (const GValue *instance_and_params, GValue *return_value){ GType chain_type = 0, restore_type = 0; Emission *emission = NULL; GClosure *closure = NULL; guint n_params = 0; gpointer instance; g_return_if_fail (instance_and_params != NULL); instance = g_value_peek_pointer (instance_and_params); g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance)); SIGNAL_LOCK (); emission = emission_find_innermost (instance); if (emission) { SignalNode *node = LOOKUP_SIGNAL_NODE (emission->ihint.signal_id); g_assert (node != NULL); /* paranoid */ /* we should probably do the same parameter checks as g_signal_emit() here. */ if (emission->chain_type != G_TYPE_NONE) { ClassClosure *cc = signal_find_class_closure (node, emission->chain_type); g_assert (cc != NULL); /* closure currently in call stack */ n_params = node->n_params; restore_type = cc->instance_type; cc = signal_find_class_closure (node, g_type_parent (cc->instance_type)); if (cc && cc->instance_type != restore_type) { closure = cc->closure; chain_type = cc->instance_type; } } else g_warning ("%s: signal id `%u' cannot be chained from current emission stage for instance `%p'", G_STRLOC, node->signal_id, instance); } else g_warning ("%s: no signal is currently being emitted for instance `%p'", G_STRLOC, instance); if (closure) { emission->chain_type = chain_type; SIGNAL_UNLOCK (); g_closure_invoke (closure, return_value, n_params + 1, instance_and_params, &emission->ihint); SIGNAL_LOCK (); emission->chain_type = restore_type; } SIGNAL_UNLOCK ();}GSignalInvocationHint*g_signal_get_invocation_hint (gpointer instance){ Emission *emission = NULL; g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), NULL); SIGNAL_LOCK (); emission = emission_find_innermost (instance); SIGNAL_UNLOCK (); return emission ? &emission->ihint : NULL;}gulongg_signal_connect_closure_by_id (gpointer instance, guint signal_id, GQuark detail, GClosure *closure, gboolean after){ SignalNode *node; gulong handler_seq_no = 0; g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0); g_return_val_if_fail (signal_id > 0, 0); g_return_val_if_fail (closure != NULL, 0); SIGNAL_LOCK (); node = LOOKUP_SIGNAL_NODE (signal_id); if (node) { if (detail && !(node->flags & G_SIGNAL_DETAILED)) g_warning ("%s: signal id `%u' does not support detail (%u)", G_STRLOC, signal_id, detail); else if (!g_type_is_a (G_TYPE_FROM_INSTANCE (instance), node->itype)) g_warning ("%s: signal id `%u' is invalid for instance `%p'", G_STRLOC, signal_id, instance); else { Handler *handler = handler_new (after); handler_seq_no = handler->sequential_number; handler->detail = detail; handler->closure = g_closure_ref (closure); g_closure_sink (closure); handler_insert (signal_id, instance, handler); if (node->c_marshaller && G_CLOSURE_NEEDS_MARSHAL (closure)) g_closure_set_marshal (closure, node->c_marshaller); } } else g_warning ("%s: signal id `%u' is invalid for instance `%p'", G_STRLOC, signal_id, instance); SIGNAL_UNLOCK (); return handler_seq_no;}gulongg_signal_connect_closure (gpointer instance, const gchar *detailed_signal, GClosure *closure, gboolean after){ guint signal_id; gulong handler_seq_no = 0; GQuark detail = 0; GType itype; g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0); g_return_val_if_fail (detailed_signal != NULL, 0); g_return_val_if_fail (closure != NULL, 0); SIGNAL_LOCK (); itype = G_TYPE_FROM_INSTANCE (instance); signal_id = signal_parse_name (detailed_signal, itype, &detail, TRUE); if (signal_id) { SignalNode *node = LOOKUP_SIGNAL_NODE (signal_id); if (detail && !(node->flags & G_SIGNAL_DETAILED)) g_warning ("%s: signal `%s' does not support details", G_STRLOC, detailed_signal); else if (!g_type_is_a (itype, node->itype)) g_warning ("%s: signal `%s' is invalid for instance `%p'", G_STRLOC, detailed_signal, instance); else { Handler *handler = handler_new (after); handler_seq_no = handler->sequential_number; handler->detail = detail; handler->closure = g_closure_ref (closure); g_closure_sink (closure); handler_insert (signal_id, instance, handler); if (node->c_marshaller && G_CLOSURE_NEEDS_MARSHAL (handler->closure)) g_closure_set_marshal (handler->closure, node->c_marshaller); } } else g_warning ("%s: signal `%s' is invalid for instance `%p'", G_STRLOC, detailed_signal, instance); SIGNAL_UNLOCK (); return handler_seq_no;}gulongg_signal_connect_data (gpointer instance, const gchar *detailed_signal, GCallback c_handler, gpointer data, GClosureNotify destroy_data, GConnectFlags connect_flags){ guint signal_id; gulong handler_seq_no = 0; GQuark detail = 0; GType itype; gboolean swapped, after; g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0); g_return_val_if_fail (detailed_signal != NULL, 0); g_return_val_if_fail (c_handler != NULL, 0); swapped = (connect_flags & G_CONNECT_SWAPPED) != FALSE; after = (connect_flags & G_CONNECT_AFTER) != FALSE; SIGNAL_LOCK (); itype = G_TYPE_FROM_INSTANCE (instance); signal_id = signal_parse_name (detailed_signal, itype, &detail, TRUE); if (signal_id) { SignalNode *node = LOOKUP_SIGNAL_NODE (signal_id); if (detail && !(node->flags & G_SIGNAL_DETAILED)) g_warning ("%s: signal `%s' does not support details", G_STRLOC, detailed_signal); else if (!g_type_is_a (itype, node->itype)) g_warning ("%s: signal `%s' is invalid for instance `%p'", G_STRLOC, detailed_signal, instance); else { Handler *handler = handler_new (after); handler_seq_no = handler->sequential_number; handler->detail = detail; handler->closure = g_closure_ref ((swapped ? g_cclosure_new_swap : g_cclosure_new) (c_handler, data, destroy_data)); g_closure_sink (handler->closure); handler_insert (signal_id, instance, handler); if (node->c_marshaller && G_CLOSURE_NEEDS_MARSHAL (handler->closure)) g_closure_set_marshal (handler->closure, node->c_marshaller); } } else g_warning ("%s: signal `%s' is invalid for instance `%p'", G_STRLOC, detailed_signal, instance); SIGNAL_UNLOCK (); return handler_seq_no;}voidg_signal_handler_block (gpointer instance, gulong handler_id){ Handler *handler; g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance)); g_return_if_fail (handler_id > 0); SIGNAL_LOCK (); handler = handler_lookup (instance, handler_id, NULL); if (handler) {#ifndef G_DISABLE_CHECKS if (handler->block_count >= HANDLER_MAX_BLOCK_COUNT - 1) g_error (G_STRLOC ": handler block_count overflow, %s", REPORT_BUG);#endif handler->block_count += 1; } else g_warning ("%s: instance `%p' has no handler with id `%lu'", G_STRLOC, instance, handler_id); SIGNAL_UNLOCK ();}voidg_signal_handler_unblock (gpointer instance, gulong handler_id){ Handler *handler; g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance)); g_return_if_fail (handler_id > 0); SIGNAL_LOCK (); handler = handler_lookup (instance, handler_id, NULL); if (handler) { if (handler->block_count) handler->block_count -= 1; else g_warning (G_STRLOC ": handler `%lu' of instance `%p' is not blocked", handler_id, instance); } else g_warning ("%s: instance `%p' has no handler with id `%lu'", G_STRLOC, instance, handler_id); SIGNAL_UNLOCK ();}voidg_signal_handler_disconnect (gpointer instance, gulong handler_id){ Handler *handler; guint signal_id; g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance)); g_return_if_fail (handler_id > 0); SIGNAL_LOCK (); handler = handler_lookup (instance, handler_id, &signal_id); if (handler) { handler->sequential_number = 0; handler->block_count = 1; handler_unref_R (signal_id, instance, handler); } else g_warning ("%s: instance `%p' has no handler with id `%lu'", G_STRLOC, instance, handler_id); SIGNAL_UNLOCK ();}gbooleang_signal_handler_is_connected (gpointer instance, gulong handler_id){ Handler *handler; gboolean connected; g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), FALSE); g_return_val_if_fail (handler_id > 0, FALSE); SIGNAL_LOCK (); handler = handler_lookup (instance, handler_id, NULL); connected = handler != NULL; SIGNAL_UNLOCK (); return connected;}voidg_signal_handlers_destroy (gpointer instance){ GBSearchArray *hlbsa; g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance)); SIGNAL_LOCK (); hlbsa = g_hash_table_lookup (g_handler_list_bsa_ht, instance); if (hlbsa) { guint i; /* reentrancy caution, delete instance trace first */ g_hash_table_remove (g_handler_list_bsa_ht, instance); for (i = 0; i < hlbsa->n_nodes; i++) { HandlerList *hlist = g_bsearch_array_get_nth (hlbsa, &g_signal_hlbsa_bconfig, i); Handler *handler = hlist->handlers; while (handler) { Handler *tmp = handler; handler = tmp->next; tmp->block_count = 1; /* cruel unlink, this works because _all_ handlers vanish */ tmp->next = NULL; tmp->prev = tmp; if (tmp->sequential_number) { tmp->sequential_number = 0; handler_unref_R (0, NULL, tmp); } } } g_bsearch_array_destroy (hlbsa, &g_signal_hlbsa_bconfig); } SIGNAL_UNLOCK ();}gulongg_signal_handler_find (gpointer instance, GSignalMatchType mask, guint signal_id, GQuark detail, GClosure *closure, gpointer func, gpointer data){ gulong handler_seq_no = 0; g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0); g_return_val_if_fail ((mask & ~G_SIGNAL_MATCH_MASK) == 0, 0); if (mask & G_SIGNAL_MATCH_MASK) { HandlerMatch *mlist; SIGNAL_LOCK (); mlist = handlers_find (instance, mask, signal_id, detail, closure, func, data, TRUE); if (mlist) { handler_seq_no = mlist->handler->sequential_number; handler_match_free1_R (mlist, instance); } SIGNAL_UNLOCK (); } return handler_seq_no;}static guintsignal_handlers_foreach_matched_R (gpointer instance, GSignalMatchType mask, guint signal_id, GQuark detail, GClosure *closure, gpointer func, gpointer data, void (*callback) (gpointer instance, gulong handler_seq_no)){ HandlerMatch *mlist; guint n_handlers = 0; mlist = handlers_find (instance, mask, signal_id, detail, closure, func, data, FALSE); while (mlist) { n_handlers++; if (mlist->handler->sequential_number) { SIGNAL_UNLOCK (); callback (instance, mlist->handler->sequential_number); SIGNAL_LOCK (); } mlist = handler_match_free1_R (mlist, instance); } return n_handlers;}guintg_signal_handlers_block_matched (gpointer instance, GSignalMatchType mask, guint signal_id, GQuark detail, GClosure *closure, gpointer func, gpointer data){ guint n_handlers = 0; g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), FALSE);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -