Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

نظام الأحداث

جزء من قسم البرمجة كائنية التوجه في رحلة C على Coddy. الدرس 61 من 61.

challenge icon

التحدي

سهل

لنبنِ نظام إشعارات: بنية تعتمد على event، حيث يمكن لـ handlers متعددة الاشتراك في event والاستجابة عند fire الخاص به. يُعد هذا النمط أساس البرمجة التفاعلية وأطر عمل واجهات المستخدم الرسومية.

ستنظّم شفرتك عبر ثلاثة ملفات:

  • event.h: عرّف نوع مؤشر الدالة Handler الذي يأخذ رسالة من النوع const char*. أنشئ بنية Event تحتوي على array تضم ما يصل إلى 5 من handlers، بالإضافة إلى عدد handlers المسجّلة. صرّح بالدوال اللازمة لتهيئة event، والاشتراك باستخدام handler، وfire الخاص بـ event لإخطار جميع المشتركين.
  • event.c: نفّذ نظام event:
    • init_event: تأخذ مؤشراً إلى Event وتضبط عدد handlers على 0
    • subscribe: تأخذ مؤشراً إلى Event وHandler، وتضيف handler إلى array إذا كانت هناك مساحة (أي إن كان count أقل من 5)، ثم تزيد count
    • fire: تأخذ مؤشراً إلى Event وmessage string، ثم تستدعي كل handler مسجّلة مع تلك الرسالة بالترتيب الذي اشتركت به
  • main.c: أنشئ ثلاث دوال handlers مختلفة تستجيب للأحداث بطرق مميزة:
    • logger: تطبع [LOG] متبوعةً بالرسالة
    • alert: تطبع [ALERT] متبوعةً بالرسالة
    • counter: تستخدم متغيراً static لحساب عدد مرات استدعائها، ثم تطبع [COUNT] X حيث تمثل X العدد الحالي
    اقرأ عدداً صحيحاً يحدد عدد handlers المطلوب الاشتراك بها (1 أو 2 أو 3). اشترك في هذا العدد من handlers بالترتيب: أولاً logger، ثم alert (إذا كان العدد 2 أو أكثر)، ثم counter (إذا كان العدد 3). اقرأ message string، ثم نفّذ fire لـ event باستخدام تلك الرسالة.

سيستقبل برنامجك:

  1. عدد handlers المطلوب الاشتراك بها (1 أو 2 أو 3)
  2. الرسالة المطلوب بثّها

مثال على الخرج عندما تكون المدخلات 3 وSystem started:

[LOG] System started
[ALERT] System started
[COUNT] 1

مثال على الخرج عندما تكون المدخلات 2 وWarning detected:

[LOG] Warning detected
[ALERT] Warning detected

مثال على الخرج عندما تكون المدخلات 1 وHello:

[LOG] Hello

يوضح هذا تعدد الأشكال من خلال مؤشرات الدوال: إذ يؤدي استدعاء fire نفسه إلى تشغيل سلوكيات مختلفة تماماً اعتماداً على handlers التي تم الاشتراك بها. يستجيب كل handler بطريقته الخاصة إلى event نفسه، مما يبرز الطبيعة غير المقترنة للتصميم القائم على event.

جرّب بنفسك

#include <stdio.h>
#include <string.h>
#include "event.h"

// TODO: نفّذ معالج logger
// يطبع "[LOG] " متبوعًا بالرسالة
void logger(const char* message) {
    // TODO: نفّذ
}

// TODO: نفّذ معالج alert
// يطبع "[ALERT] " متبوعًا بالرسالة
void alert(const char* message) {
    // TODO: نفّذ
}

// TODO: نفّذ معالج counter
// يستخدم متغيرًا static لعدّ الاستدعاءات
// يطبع "[COUNT] X" حيث X هو العدد الحالي
void counter(const char* message) {
    // TODO: نفّذ باستخدام متغير static
}

int main() {
    // اقرأ عدد المعالجات للاشتراك
    int num_handlers;
    scanf("%d", &num_handlers);
    getchar(); // استهلك السطر الجديد
    
    // اقرأ الرسالة
    char message[256];
    fgets(message, sizeof(message), stdin);
    message[strcspn(message, "\n")] = '\0'; // إزالة السطر الجديد
    
    // TODO: إنشاء وتهيئة Event
    
    // TODO: الاشتراك في المعالجات بناءً على num_handlers
    // 1 معالج: logger
    // 2 معالجات: logger, alert
    // 3 معالجات: logger, alert, counter
    
    // TODO: إطلاق الحدث مع الرسالة
    
    return 0;
}
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس البرمجة كائنية التوجه

تدرّب بنفسك: مترجم C عبر الإنترنت