对于glib,我们经常用到信号通知机制来触发事件,在GObject中,可以自己定义signal信号,用于事件触发中。
一般在class_init时,由g_signal_new配合一些参数生成一个新信号句柄,然后使用g_signal_connect连接对象和处理方式(回调函数),最后由g_signal_emit发出信号触发。
一,其中最关键的是就g_signal_new,在这个过程中,我们应该先了解下相关的参数,其一般模型如下:
guint
g_signal_new (const gchar *signal_name,
GType itype,
GSignalFlags signal_flags,
guint class_offset,
GSignalAccumulator accumulator,
gpointer accu_data,
GSignalCMarshaller c_marshaller,
GType return_type,
guint n_params,
...)
通过上面的函数模型可以看出,其参数个数是可变的。而这些参数有些是必须的,有些可设为NULL,下面可以结合一个基于clutter的实例来解释一下各个参数的含义(SECTION 1和2是从clutter源代码中提取出来的定义示例):
1, const gchar *signal_name: 该参数是定义信号的名字,它由分隔符以及ASCII码中的字母和数字构成,且第一个字符必须是字母,实例中定义的名字为"myself-signal"。(分隔符可以是"-"或"_"——事实上,系统会先调用g_strdelimit把"_"转化为"-"再存储signal_name。因此,在调用g_singal_emit_by_name时,detailed_signal参数中的分隔符必须是"-");
2, GType itype:该参数是signal所依附的类的在GType类型系统中注册时得到的ID,也就是*_get_type()函数的返回值。而在clutter工程中,class_init时可使用G_OBJECT_CLASS_TYPE(klass)来获得,实例中使用CLUTTER_TYPE_ACTOR获取。(clutter _actor应该才是stage和texture、text的基类);
3, GSignalFlags signal_flags:该参数是信号的属性标记,共有七种,其中有提到"per-object handler",将在下面class_offset中介绍:
· G_SIGNAL_RUN_FIRST:调用回调函数时,"per-object handler"对应的回调函数将第一个调用;
· G_SIGNAL_RUN_LAST:调用回调函数时,"per-object handler"对应的回调函数将在用户用g_signal_connect连接的回调函数之后调用,并在用户用g_signal_connect _after连接的回调函数之前调用;
· G_SIGNAL_RUN_CLEANUP:调用回调函数时,"per-object handler"对应的回调函数将最后一个调用;
· G_SIGNAL_NO_RECURSE:信号发射时,如果信号的上次发射还没有结束,那么本次信号发射将不再进行,而只是使上次的信号发射重新开始。[wyj1]
· G_SIGNAL_DETAILED:信号名字可以使用"signal_name::detailed"的形式。
· G_SIGNAL_ACTION:程序员可以在代码中自由地调用g_signal_emit族的函数来发射信号,而不需要把g_signal_emit族的函数放在一段代码中再来调用。