mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-09-27 17:52:58 +02:00
Add g_signal_set_va_marshaller
This lets you set a va_marshaller on your signal which will be propagated to all closures for the signal. Also, automatically uses the generica va_marshaller if you specify a NULL c_marshaller. https://bugzilla.gnome.org/show_bug.cgi?id=661140
This commit is contained in:
@@ -213,6 +213,7 @@ struct _SignalNode
|
|||||||
GBSearchArray *class_closure_bsa;
|
GBSearchArray *class_closure_bsa;
|
||||||
SignalAccumulator *accumulator;
|
SignalAccumulator *accumulator;
|
||||||
GSignalCMarshaller c_marshaller;
|
GSignalCMarshaller c_marshaller;
|
||||||
|
GSignalCVaMarshaller va_marshaller;
|
||||||
GHookList *emission_hooks;
|
GHookList *emission_hooks;
|
||||||
};
|
};
|
||||||
#define MAX_TEST_CLASS_OFFSET (4096) /* 2^12, 12 bits for test_class_offset */
|
#define MAX_TEST_CLASS_OFFSET (4096) /* 2^12, 12 bits for test_class_offset */
|
||||||
@@ -1492,7 +1493,11 @@ signal_add_class_closure (SignalNode *node,
|
|||||||
&key);
|
&key);
|
||||||
g_closure_sink (closure);
|
g_closure_sink (closure);
|
||||||
if (node->c_marshaller && closure && G_CLOSURE_NEEDS_MARSHAL (closure))
|
if (node->c_marshaller && closure && G_CLOSURE_NEEDS_MARSHAL (closure))
|
||||||
|
{
|
||||||
g_closure_set_marshal (closure, node->c_marshaller);
|
g_closure_set_marshal (closure, node->c_marshaller);
|
||||||
|
if (node->va_marshaller)
|
||||||
|
_g_closure_set_va_marshal (closure, node->va_marshaller);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1645,8 +1650,12 @@ g_signal_newv (const gchar *signal_name,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
node->accumulator = NULL;
|
node->accumulator = NULL;
|
||||||
|
node->va_marshaller = NULL;
|
||||||
if (c_marshaller == NULL)
|
if (c_marshaller == NULL)
|
||||||
|
{
|
||||||
c_marshaller = g_cclosure_marshal_generic;
|
c_marshaller = g_cclosure_marshal_generic;
|
||||||
|
node->va_marshaller = g_cclosure_marshal_generic_va;
|
||||||
|
}
|
||||||
node->c_marshaller = c_marshaller;
|
node->c_marshaller = c_marshaller;
|
||||||
node->emission_hooks = NULL;
|
node->emission_hooks = NULL;
|
||||||
if (class_closure)
|
if (class_closure)
|
||||||
@@ -1665,6 +1674,32 @@ g_signal_newv (const gchar *signal_name,
|
|||||||
return signal_id;
|
return signal_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
g_signal_set_va_marshaller (guint signal_id,
|
||||||
|
GType instance_type,
|
||||||
|
GSignalCVaMarshaller va_marshaller)
|
||||||
|
{
|
||||||
|
SignalNode *node;
|
||||||
|
|
||||||
|
g_return_if_fail (signal_id > 0);
|
||||||
|
g_return_if_fail (va_marshaller != NULL);
|
||||||
|
|
||||||
|
SIGNAL_LOCK ();
|
||||||
|
node = LOOKUP_SIGNAL_NODE (signal_id);
|
||||||
|
if (node)
|
||||||
|
{
|
||||||
|
node->va_marshaller = va_marshaller;
|
||||||
|
if (node->class_closure_bsa)
|
||||||
|
{
|
||||||
|
ClassClosure *cc = g_bsearch_array_get_nth (node->class_closure_bsa, &g_class_closure_bconfig, 0);
|
||||||
|
if (cc->closure->marshal == node->c_marshaller)
|
||||||
|
_g_closure_set_va_marshal (cc->closure, va_marshaller);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SIGNAL_UNLOCK ();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* g_signal_new_valist:
|
* g_signal_new_valist:
|
||||||
* @signal_name: the name for the signal
|
* @signal_name: the name for the signal
|
||||||
@@ -1741,6 +1776,7 @@ signal_destroy_R (SignalNode *signal_node)
|
|||||||
signal_node->class_closure_bsa = NULL;
|
signal_node->class_closure_bsa = NULL;
|
||||||
signal_node->accumulator = NULL;
|
signal_node->accumulator = NULL;
|
||||||
signal_node->c_marshaller = NULL;
|
signal_node->c_marshaller = NULL;
|
||||||
|
signal_node->va_marshaller = NULL;
|
||||||
signal_node->emission_hooks = NULL;
|
signal_node->emission_hooks = NULL;
|
||||||
|
|
||||||
#ifdef G_ENABLE_DEBUG
|
#ifdef G_ENABLE_DEBUG
|
||||||
@@ -2166,7 +2202,11 @@ g_signal_connect_closure_by_id (gpointer instance,
|
|||||||
g_closure_sink (closure);
|
g_closure_sink (closure);
|
||||||
handler_insert (signal_id, instance, handler);
|
handler_insert (signal_id, instance, handler);
|
||||||
if (node->c_marshaller && G_CLOSURE_NEEDS_MARSHAL (closure))
|
if (node->c_marshaller && G_CLOSURE_NEEDS_MARSHAL (closure))
|
||||||
|
{
|
||||||
g_closure_set_marshal (closure, node->c_marshaller);
|
g_closure_set_marshal (closure, node->c_marshaller);
|
||||||
|
if (node->va_marshaller)
|
||||||
|
_g_closure_set_va_marshal (closure, node->va_marshaller);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -2224,7 +2264,11 @@ g_signal_connect_closure (gpointer instance,
|
|||||||
g_closure_sink (closure);
|
g_closure_sink (closure);
|
||||||
handler_insert (signal_id, instance, handler);
|
handler_insert (signal_id, instance, handler);
|
||||||
if (node->c_marshaller && G_CLOSURE_NEEDS_MARSHAL (handler->closure))
|
if (node->c_marshaller && G_CLOSURE_NEEDS_MARSHAL (handler->closure))
|
||||||
|
{
|
||||||
g_closure_set_marshal (handler->closure, node->c_marshaller);
|
g_closure_set_marshal (handler->closure, node->c_marshaller);
|
||||||
|
if (node->va_marshaller)
|
||||||
|
_g_closure_set_va_marshal (handler->closure, node->va_marshaller);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -2318,7 +2362,11 @@ g_signal_connect_data (gpointer instance,
|
|||||||
g_closure_sink (handler->closure);
|
g_closure_sink (handler->closure);
|
||||||
handler_insert (signal_id, instance, handler);
|
handler_insert (signal_id, instance, handler);
|
||||||
if (node->c_marshaller && G_CLOSURE_NEEDS_MARSHAL (handler->closure))
|
if (node->c_marshaller && G_CLOSURE_NEEDS_MARSHAL (handler->closure))
|
||||||
|
{
|
||||||
g_closure_set_marshal (handler->closure, node->c_marshaller);
|
g_closure_set_marshal (handler->closure, node->c_marshaller);
|
||||||
|
if (node->va_marshaller)
|
||||||
|
_g_closure_set_va_marshal (handler->closure, node->va_marshaller);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@@ -43,6 +43,14 @@ typedef struct _GSignalInvocationHint GSignalInvocationHint;
|
|||||||
* signal system.
|
* signal system.
|
||||||
*/
|
*/
|
||||||
typedef GClosureMarshal GSignalCMarshaller;
|
typedef GClosureMarshal GSignalCMarshaller;
|
||||||
|
/**
|
||||||
|
* GSignalCVaMarshaller:
|
||||||
|
*
|
||||||
|
* This is the signature of va_list marshaller functions, an optional
|
||||||
|
* marshaller that can be used in some situations to avoid
|
||||||
|
* marshalling the signal argument into GValues.
|
||||||
|
*/
|
||||||
|
typedef GVaClosureMarshal GSignalCVaMarshaller;
|
||||||
/**
|
/**
|
||||||
* GSignalEmissionHook:
|
* GSignalEmissionHook:
|
||||||
* @ihint: Signal invocation hint, see #GSignalInvocationHint.
|
* @ihint: Signal invocation hint, see #GSignalInvocationHint.
|
||||||
@@ -294,6 +302,9 @@ guint g_signal_new_class_handler (const gchar *signal_name,
|
|||||||
GType return_type,
|
GType return_type,
|
||||||
guint n_params,
|
guint n_params,
|
||||||
...);
|
...);
|
||||||
|
void g_signal_set_va_marshaller (guint signal_id,
|
||||||
|
GType instance_type,
|
||||||
|
GSignalCVaMarshaller va_marshaller);
|
||||||
|
|
||||||
void g_signal_emitv (const GValue *instance_and_params,
|
void g_signal_emitv (const GValue *instance_and_params,
|
||||||
guint signal_id,
|
guint signal_id,
|
||||||
|
Reference in New Issue
Block a user