因为我找到了这条消息,但我并没有完全找到我的解决方案,所以我根据https://prdeving.wordpress.com/2017/04/03/event-driven-programming-with-c-89/在此处发布我的代码为他人。
事件.h
typedef struct s_Arguments {
char *name;
int value;
} Arguments; // Treat this as you please
typedef struct s_Event {
char *name;
Arguments args;
} Event;
typedef struct {
char *name;
void (*handler)(void*);
} Handler;
struct s_EventContainer {
int *exitFlag;
Event *poll;
Handler *listeners;
void (*registerEvent)(char *name, void*);
void (*emit)(char *name, Arguments args);
int listenersc;
int pollc;
};
struct s_EventContainer eventContainer;
void _registerEvent(char *name, void*);
void _emitEvent(char *name, Arguments args);
void popPoll();
void find_and_exec_handler_in_listeners(char *name, Arguments *args);
void * fn_eventsDigest(void * p_Data);
void *testFired(Arguments *args);
事件.c
#include "event.h"
int BLOCK_POP, BLOCK_EMIT;
void _registerEvent(char *name, void *cb) {
LOG("_registerEvent '%s'", name);
if (!eventContainer.listeners) eventContainer.listeners = malloc(sizeof(Handler));
Handler listener = {name, cb};
eventContainer.listeners[eventContainer.listenersc] = listener;
eventContainer.listenersc++;
eventContainer.listeners = realloc(eventContainer.listeners, sizeof(Handler) * (eventContainer.listenersc+1));
}
void _emitEvent(char *name, Arguments args) {
LOG("Emit event '%s' with args value %d", name, args.value);
while(BLOCK_EMIT) asm("nop");
BLOCK_POP = 1;
if (!eventContainer.poll) eventContainer.poll = malloc(sizeof(Event));
Event poll = {name, args};
eventContainer.poll[eventContainer.pollc] = poll;
eventContainer.pollc++;
eventContainer.poll = realloc(eventContainer.poll, sizeof(Event) * (eventContainer.pollc+1));
BLOCK_POP = 0;
}
void popPoll(){
int* temp = malloc((eventContainer.pollc - 1) * sizeof(Event));
memcpy(temp, eventContainer.poll+1, (eventContainer.pollc - 1) * sizeof(Event));
eventContainer.pollc -= 1;
eventContainer.poll = realloc(eventContainer.poll, eventContainer.pollc * sizeof(Event) + sizeof(Event));
memcpy(eventContainer.poll, temp, eventContainer.pollc * sizeof(Event));
temp = NULL;
}
void find_and_exec_handler_in_listeners(char *name, Arguments *args){
int i;
for (i=0; i < eventContainer.listenersc; i++) {
if (strcmp(eventContainer.listeners[i].name, name ) == 0 ) {
(*eventContainer.listeners[i].handler)(args);
}
}
}
void * fn_eventsDigest(void * p_Data) {
struct s_EventContainer *eventContainer = (struct s_EventContainer *)p_Data;
BLOCK_POP = 0;
BLOCK_EMIT = 0;
while(*(eventContainer->exitFlag) == 0) {
if ( eventContainer->pollc > 0 && BLOCK_POP == 0) {
BLOCK_EMIT = 1;
Event ev = eventContainer->poll[0];
find_and_exec_handler_in_listeners(ev.name, &ev.args);
popPoll();
BLOCK_EMIT = 0;
}
usleep(1*1000);
}
printf("Event Loop::exiting...\r\n"); fflush(stdout);
}
void *testFired(Arguments *args) {
LOG("test event fired with value %d \r\n", args->value);
}
主程序
#include "event.h"
#include <pthread.h>
struct s_EventContainer eventContainer = {
&Data.exitFlag, //exit loop
NULL, //poll
NULL, //listeners
_registerEvent,
_emitEvent,
0,
0
};
pthread_t events_thread;
int main(int argc, char** argv) {
eventContainer.registerEvent("test", &testFired);
int ret = pthread_create (&events_thread, NULL, fn_eventsDigest, &eventContainer);
if (ret) {
fprintf (stderr, "%s", strerror (ret));
}
pthread_setname_np(events_thread,"events_thread");
//....
sleep(2);
Arguments args;
args.name = "test";
args.value = 10;
eventContainer.emit("test", args);
pthread_join (events_thread, NULL);
return (EXIT_SUCCESS);
}
我愿意接受建议。