イベントシステム
CoddyのCジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 61/61。
チャレンジ
簡単Notification Systemを構築しましょう。これは、複数のハンドラーがイベントを購読し、イベントが発火したときに応答できるイベント駆動アーキテクチャです。このパターンは、リアクティブプログラミングやGUIフレームワークの基盤となります。
コードを3つのファイルに分けて整理します。
event.h:const char*型のmessageを受け取るHandler関数ポインタ型をDefineします。最大5個のハンドラーのarrayと、登録済みハンドラーのcountを保持するEvent構造体をCreateします。イベントを初期化し、ハンドラーを購読し、すべての購読者にNotifyするためにイベントをfireする関数を宣言します。event.c:イベントシステムをImplementします。init_event:Eventポインタを受け取り、ハンドラーのcountを0に設定しますsubscribe:EventポインタとHandlerを受け取り、空きがある場合(countが5未満の場合)にハンドラーをarrayへ追加し、countをインクリメントしますfire:Eventポインタとmessage文字列を受け取り、登録された各ハンドラーを、購読されたorderでそのmessageとともにcallsします
main.c:イベントに対してそれぞれ異なる方法で応答する3つのhandler関数をCreateします。logger:messageに続けて[LOG]をPrintsしますalert:messageに続けて[ALERT]をPrintsしますcounter:static変数を使用してcallsされた回数をcountし、その後、現在のcountをXとして[COUNT] XをPrintsします
プログラムは次の入力を受け取ります。
- 購読するハンドラーの数(1、2、または3)
- ブロードキャストするmessage
入力が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のcallsであっても、どのハンドラーが購読されているかによって、まったく異なる動作がトリガーされます。各ハンドラーは同じイベントに対して独自の方法で応答し、イベント駆動設計の疎結合な性質を示しています。
自分で試してみよう
#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;
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
自分で練習してみよう: Cオンラインコンパイラ