嵌入式事件框架

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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IoT_H2

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值