Menu
Coddy logo textTech

Система событий

Часть раздела Объектно-ориентированное программирование путешествия по C на Coddy. Урок 61 из 61.

challenge icon

Задание

Легко

Давайте создадим систему уведомлений: архитектуру, управляемую событиями, в которой несколько обработчиков могут подписаться на событие и реагировать, когда оно срабатывает. Этот шаблон лежит в основе реактивного программирования и GUI-фреймворков.

Вы организуете код в трёх файлах:

  • event.h: Define тип указателя на функцию Handler, которая принимает сообщение const char*. Создайте структуру Event, содержащую массив максимум из 5 обработчиков и количество зарегистрированных обработчиков. Объявите функции для инициализации события, подписки обработчика и срабатывания события для уведомления всех подписчиков.
  • event.c: Реализуйте систему событий:
    • init_event: принимает указатель Event и устанавливает количество обработчиков равным 0
    • subscribe: принимает указатель Event и Handler, добавляет обработчик в массив, если есть место (count меньше 5), и увеличивает count
    • fire: принимает указатель Event и строку сообщения, затем вызывает каждый зарегистрированный обработчик с этим сообщением в порядке их подписки
  • main.c: Создайте три разные функции-обработчика, которые уникальным образом реагируют на события:
    • logger: выводит [LOG] , за которым следует сообщение
    • alert: выводит [ALERT] , за которым следует сообщение
    • counter: использует статическую переменную для подсчёта количества вызовов, затем выводит [COUNT] X, где X — текущее количество
    Считайте целое число, указывающее, сколько обработчиков нужно подписать (1, 2 или 3). Подписывайте это количество обработчиков по порядку: сначала logger, затем alert (если 2 или больше), затем counter (если 3). Считайте строку сообщения, затем вызовите fire для события с этим сообщением.

Ваша программа получит:

  1. Количество обработчиков для подписки (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 запускает совершенно разное поведение в зависимости от того, на какие обработчики выполнена подписка. Каждый обработчик по-своему реагирует на одно и то же событие, демонстрируя слабосвязанную природу архитектуры, управляемой событиями.

Попробуйте сами

#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
// Использует статическую переменную для подсчёта вызовов
// Выводит "[COUNT] X", где X — текущее значение счётчика
void counter(const char* message) {
    // TODO: Реализовать со статической переменной
}

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