Using g_signal_connect() is traditional approach. But not best.
Only one function takes signal_id itself rather than string - g_signal_connect_closure_by_id().
This seems to be what I need, but other questions rise there.
Besides redundant signal string name parsing, there’s another issue: marshallers, which are only useful in language bindings, while in C it’s just pointless waste. Well, at least in case, when marshaller is called per each handler call rather than entire signal emission.
My solution for that would be do resind stock marshallers, placing own callback, which would take all GValue params directly. It doesn’t seem to be hard - although all those g_value_get_{type}() calls bring further level of unreadability into code, maximum 1 call seems required per argument. Also it should be no problem to define own, shorted aliases for them like:
#define int_val g_value_get_int
#define int_set g_value_set_int
But it would be way better if value inside GValue could be used directly.
Thus, question 1: is there way - may be some macroses, doing it in same way as following snippet?
typedef struct {
GType type;
union {
int v_int;
double v_double;
...
};
} GValue;
#define G_VALUE_INT(value) (value.v_int)
...
GValue var;
...
// get value
int v = G_VALUE_INT(var);
// get value address
int *p = & G_VALUE_INT(var);
// set value (not so necessary, but would be great too)
// Also need check if braces are legal around lvalue in C
G_VALUE_INT(var) = 80;
Next question (2) - about mentioned closure micromanagement. Callback at marshaller post obviously wins by performance over variant with separate useless marshaller (which does nothing but gvalue->args & return->gvalue copying), but I’m still in doubt:
Does it really make sence against gtk/gdk, gstreamer (whatever I’m going to meet) or their C code is already optimized in this way?
And side question (3).
For begining I decided to look inside existing closure, from existing connection, to see, how it’s arranged, and possibly find answer for question 2. But to my suprise, I found no way to get closure from signal+handler_func pair.
I only see function to find handlers, but it uses closure to search by, rather than to search for.
Is there any way to get closure from connection, at least if I know, what function is connected to it by g_signal_connect?
Well, perhaps I could eventually understand it, looking into gobject source code, but not expecting it to be quick.
Meanwhile I could make a proposal for gobject:
- Signals could be available not only by string/id, but by handle pointer as well. Same about handlers. Functions names to find handlers could be like:
g_signal_find_by_name(char *)
g_signal_find_by_id(unsigned)
g_signal_handler_find_by_name(char *)
g_signal_handler_find_by_id(unsigned)
g_signal_handler_get_closure(sighandler)
- Signal/handler functions should use handle pointer for object argument instead of string. Those, taking strings, would be considered as convenience wrappers.