Content
- 0x00 前言
- 0x01 不带优先级
- 0x02 区分优先级
0x00 前言
事件是系统中发生的某种情况或状态变化,通常由用户操作(如点击按钮、键盘输入)或系统状态变化(如传感器数据更新)引发。
事件可以有多种类型,例如用户输入事件(按钮按下、鼠标移动)、系统事件(定时器超时、数据接收)等任何可以产生的。
事件处理器是响应特定事件的函数或方法。当事件发生时,框架会调用相应的事件处理器来处理该事件。
事件框架通常使用事件队列来存储待处理的事件。事件可以按发生的顺序或优先级存储在队列中,确保它们在适当的时机被处理。
事件循环是框架的核心部分,它不断检查事件队列,处理待处理的事件,并调用相应的事件处理器。事件循环通常在主线程中运行,确保系统能够实时响应事件。
举个通俗的例子,正在玩电脑游戏的一名同学,按下了向左移动的按键,那么这就是"事件发生",随后会将这个事件添加到"事件队列",再随后事件处理器会根据"事件类型"去进行不同的反应,比如左键右键要分别对应向左向右移动。
事件框架将事件的生成和处理分离,使得系统的各个部分可以独立开发和维护。并且可以轻松添加新的事件类型和处理器,而不需要修改现有代码。通过事件驱动的方式,系统可以在事件发生时立即响应,而不是通过轮询等方式。由于事件处理函数是独立的,可以单独测试每个事件处理函数,简化了调试和测试过程。
0x01 不带优先级
以下是一个无优先级区分的框架,如果功能并无先后之分,可以使用以下案例来实现
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_EVENTS 100
#define MAX_HANDLERS 10
// 事件类型枚举
typedef enum {
EVENT_BUTTON_PRESS,
EVENT_MOUSE_MOVE,
EVENT_KEYBOARD_INPUT,
} EventType;
// 事件结构体
typedef struct {
EventType type;
void* data;
} Event;
// 事件队列
Event eventQueue[MAX_EVENTS];
int eventCount = 0;
// 事件处理函数类型
typedef void (*EventHandler)(Event*);
// 事件处理器数组
EventHandler handlers[MAX_HANDLERS];
int handlerCount = 0;
// 添加事件到队列
void addEvent(EventType type, void* data) {
if (eventCount < MAX_EVENTS) {
eventQueue[eventCount].type = type;
eventQueue[eventCount].data = data;
eventCount++;
} else {
printf("EVENT QUEUE IS FULL\n");
}
}
// 注册事件处理函数
void registerHandler(EventHandler handler) {
if (handlerCount < MAX_HANDLERS) {
handlers[handlerCount++] = handler;
} else {
printf("HANDLER COUNT IS MAX\n");
}
}
// 处理所有事件
void processEvents() {
for (int i = 0; i < eventCount; i++) {
for (int j = 0; j < handlerCount; j++) {
handlers[j](&eventQueue[i]);
}
}
eventCount = 0; // 清空事件队列
}
// 示例事件处理函数
void handleButtonPress(Event* event) {
if (event->type == EVENT_BUTTON_PRESS) {
printf("BUTTON IS PRESS\n");
}
}
void handleMouseMove(Event* event) {
if (event->type == EVENT_MOUSE_MOVE) {
printf("MOUSE IS MOVE\n");
}
}
int main() {
// 注册事件处理函数
registerHandler(handleButtonPress);
registerHandler(handleMouseMove);
// 模拟添加事件
addEvent(EVENT_BUTTON_PRESS, NULL);
addEvent(EVENT_MOUSE_MOVE, NULL);
// 主循环
while (1) {
// 事件发生
// 处理所有待处理的事件
processEvents();
addEvent(EVENT_MOUSE_MOVE, NULL);
addEvent(EVENT_MOUSE_MOVE, NULL);
addEvent(EVENT_MOUSE_MOVE, NULL);
addEvent(EVENT_MOUSE_MOVE, NULL);
}
return 0;
}
0x02 区分优先级
那么接下来就是一个带优先级的框架了,这个框架与以上框架不同的是,以上代码是先到先处理的方式去做,顺序执行,与轮询不同的是响应会更加即时,并且会限制事件发生数,可以限制内存的使用。
而以下这段代码,在执行之前会先对队列中的优先级进行扫描,从而先处理优先级较高的事件。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_EVENTS 100
#define MAX_HANDLERS 10
#define PRIORITY_LEVELS 3
// 事件类型枚举
typedef enum {
EVENT_BUTTON_PRESS,
EVENT_MOUSE_MOVE,
EVENT_KEYBOARD_INPUT,
} EventType;
// 事件结构体
typedef struct {
EventType type;
void* data;
int priority; // 新增:优先级字段
} Event;
// 事件队列
Event eventQueue[PRIORITY_LEVELS][MAX_EVENTS];
int eventCount[PRIORITY_LEVELS] = {0};
// 事件处理函数类型
typedef void (*EventHandler)(Event*);
// 事件处理器数组
EventHandler handlers[MAX_HANDLERS];
int handlerCount = 0;
// 添加事件到队列
void addEvent(EventType type, void* data, int priority) {
if (priority < 0 || priority >= PRIORITY_LEVELS) {
printf("Invalid priority level\n");
return;
}
if (eventCount[priority] < MAX_EVENTS) {
eventQueue[priority][eventCount[priority]].type = type;
eventQueue[priority][eventCount[priority]].data = data;
eventQueue[priority][eventCount[priority]].priority = priority;
eventCount[priority]++;
} else {
printf("Event queue is full for priority %d\n", priority);
}
}
// 注册事件处理函数
void registerHandler(EventHandler handler) {
if (handlerCount < MAX_HANDLERS) {
handlers[handlerCount++] = handler;
} else {
printf("HANDLER COUNT IS MAX\n");
}
}
// 处理所有事件
void processEvents() {
for (int p = PRIORITY_LEVELS - 1; p >= 0; p--) { // 从高优先级到低优先级处理
for (int i = 0; i < eventCount[p]; i++) {
for (int j = 0; j < handlerCount; j++) {
handlers[j](&eventQueue[p][i]);
}
}
eventCount[p] = 0; // 清空该优先级的事件队列
}
}
// 示例事件处理函数
void handleButtonPress(Event* event) {
if (event->type == EVENT_BUTTON_PRESS) {
printf("BUTTON IS PRESS\n");
}
}
void handleMouseMove(Event* event) {
if (event->type == EVENT_MOUSE_MOVE) {
printf("MOUSE IS MOVE\n");
}
}
int main() {
// 注册事件处理函数
registerHandler(handleButtonPress);
registerHandler(handleMouseMove);
// 模拟添加事件及优先级
addEvent(EVENT_MOUSE_MOVE, NULL, 0); // 低优先级
addEvent(EVENT_BUTTON_PRESS, NULL, 2); // 高优先级
// 主循环
while (1) {
//处理所有待处理的事件
processEvents();
}
return 0;
}