在GObject system裡,物件(GObject)可透過g_signal_new()或g_signal_newv()註冊新的信號;並以g_signal_emit()發送信號。爾後,經由g_signal_connect()即可連結(connect)或接收某物件發出的信號。
比如,若想要加入「redrawn」事件至本系列文章中的Drawable介面,我們可以先於class_init之時註冊信號(signal);接著於繪圖完畢後,發送信號。範例如下:
static void drawable_class_init(DrawableInterface* self)
{
g_print("Drawable(0x%08x)::class::initialize\n", (guint)self);
signals[DRAW_SIGNAL] =
g_signal_newv("redrawn",
DRAWABLE_IFACE,
G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE,
NULL /* closure */,
NULL /* accumulator */,
NULL /* accumulator data */,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE /* return_type */,
0 /* n_params */,
NULL /* param_types */);
}
void draw_object(Drawable* drawable)
{
if (!IS_DRAWABLE(drawable)) {
g_print("%s(0x%08x) is not drawable.\n",
G_OBJECT_TYPE_NAME(drawable), (guint)drawable);
return;
}
DRAWABLE_GET_INTERFACE(drawable)->draw(drawable);
g_signal_emit(drawable, signals[DRAW_SIGNAL], 0 /* details */);
}
每當g_signal_emit()被喚起時,特定的事件就會被發送至GObject system,接著被派送至與其連結的物件或回呼函式(callback function)。要連結至某物件的事件只需要執行g_signal_connect()向GObject system註冊即可。static void logger(gpointer instance, gpointer user_data)
{
g_print("logger: Object(0x%08x) redrawed\n", (guint)instance);
}
int main(int argc, char** argv)
{
... ... ...
g_signal_connect(rect, "redrawn", G_CALLBACK(logger), NULL);
... ... ...
}
執行範例:
Shape(0x09c0b250)::base::initialize Shape(0x09c0b250)::class::initialize Shape(0x09c25fc0)::base::initialize Rectangle(0x09c25fc0)::base::initialize Drawable(0x09c0b1e8)::base::initialize Drawable(0x09c0b1e8)::class::initialize Drawable(0x09c26010)::base::initialize Rectangle(0x09c25fc0)::class::initialize Rectangle(0x09c26010)::Drawable::initialize Rectangle(0x09c05048)::instance::initialize Rectangle(0x09c05048)::SetProperty::Width(4) Rectangle(0x09c05048)::SetProperty::Height(5) Shape(0x09c05048)::constructor Rectangle(0x09c05048)::constructor Rectangle(0x09c05048, 4x5) is created. Rectangle(0x09c05048)::Drawable::draw +------+ | | +------+ logger: Object(0x09c05048) redrawed Rectangle(0x09c05048)::dispose Shape(0x09c05048)::dispose Rectangle(0x09c05048)::finalize Shape(0x09c05048)::finalize
完整程式碼

No comments:
Post a Comment