在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