Signals in GObject are used to support a event-driven programming. Signals can be connected to callback handlers. When they are emitted, these handlers are invoked. To add signals to a type, notice following lines of code:
NOTE : PLEASE READ ALL COMMENT CAREFULLY.
static void fake_base_class_init ( FakeBaseClass * klass , gpointer data ) {
// ...
/* signals */
g_signal_new ( "base-signal-int" , FAKE_TYPE_BASE , G_SIGNAL_RUN_LAST , 0 ,
NULL , NULL , g_cclosure_marshal_VOID__INT , G_TYPE_NONE , 1 , G_TYPE_INT , NULL ) ;
g_signal_new ( "base-signal-string" , FAKE_TYPE_BASE , G_SIGNAL_RUN_LAST , 0 ,
NULL , NULL , g_cclosure_marshal_VOID__STRING , G_TYPE_NONE , 1 , G_TYPE_STRING , NULL ) ;
// ...
}
Like properties, signals can be inherited too. Use signals like:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
int main ( ) {
// ...
FakeBase * base = ( FakeBase * ) g_object_new ( FAKE_TYPE_BASE , NULL ) ;
FakeDerived * derived = ( FakeDerived * ) g_object_new ( FAKE_TYPE_DERIVED , NULL ) ;
/* Test for signals */
/* 1 <-> 1 */
g_signal_connect ( base , "base-signal-int" , G_CALLBACK ( print_int1 ) , NULL ) ;
g_signal_connect ( base , "base-signal-string" , G_CALLBACK ( print_string1 ) , NULL ) ;
g_signal_emit_by_name ( base , "base-signal-int" , 12345 ) ;
g_signal_emit_by_name ( base , "base-signal-string" , "abcde" ) ;
/* 1 <-> 1+ */
g_signal_connect ( base , "base-signal-int" , G_CALLBACK ( print_int2 ) , NULL ) ;
g_signal_emit_by_name ( base , "base-signal-int" , 123456 ) ;
/* signal inheritance */
g_signal_connect ( derived , "base-signal-int" , G_CALLBACK ( print_int1 ) , NULL ) ;
g_signal_connect ( derived , "base-signal-string" , G_CALLBACK ( print_string1 ) , NULL ) ;
g_signal_connect ( derived , "derived-signal-int" , G_CALLBACK ( print_int2 ) , NULL ) ;
g_signal_connect ( derived , "derived-signal-string" , G_CALLBACK ( print_string2 ) , NULL ) ;
g_signal_emit_by_name ( derived , "base-signal-int" , 1234567 ) ;
g_signal_emit_by_name ( derived , "base-signal-string" , "abcdefg" ) ;
g_signal_emit_by_name ( derived , "derived-signal-int" , 1234567 ) ;
g_signal_emit_by_name ( derived , "derived-signal-string" , "abcdefg" ) ;
// ...
}
The callback functions are defined simply like:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
void print_int1 ( GObject * sender , int i , gpointer data ) {
if ( FAKE_IS_DERIVED ( sender ) ) {
g_print ( "Invoking print_int1(): derived.i=%d\n" , i ) ;
} else if ( FAKE_IS_BASE ( sender ) ) {
g_print ( "Invoking print_int1(): base.i=%d\n" , i ) ;
}
}
void print_int2 ( GObject * sender , int i , gpointer data ) {
if ( FAKE_IS_DERIVED ( sender ) ) {
g_print ( "Invoking print_int2(): derived.i=%d\n" , i ) ;
} else if ( FAKE_IS_BASE ( sender ) ) {
g_print ( "Invoking print_int2(): base.i=%d\n" , i ) ;
}
}
void print_string1 ( GObject * sender , gchar * str , gpointer data ) {
if ( FAKE_IS_DERIVED ( sender ) ) {
g_print ( "Invoking print_string1(): derived.str=\"%s\"\n" , str ) ;
} else if ( FAKE_IS_BASE ( sender ) ) {
g_print ( "Invoking print_string1(): base.str=\"%s\"\n" , str ) ;
}
}
void print_string2 ( GObject * sender , gchar * str , gpointer data ) {
if ( FAKE_IS_DERIVED ( sender ) ) {
g_print ( "Invoking print_string2(): derived.str=\"%s\"\n" , str ) ;
} else if ( FAKE_IS_BASE ( sender ) ) {
g_print ( "Invoking print_string2(): base.str=\"%s\"\n" , str ) ;
}
}
All source code is available in my skydrive: http://cid-481cbe104492a3af.office.live.com/browse.aspx/share/dev/TestOO . In the TestGObject-{date}.zip/TestGObject5 folder.