/* * events.cpp * * Created on: Jan 7, 2018 * Author: Philipp Hinz */ #include #include #include #include #include "events.h" #include "logger.h" /** * Struct for subscribers, contains the pointer to the handler */ struct subscriber_t { void (*handler)(event_t *); subscriber_t *next = NULL; }; /** * Struct for the event list */ struct events_t { char event[EVENT_LENGTH]; subscriber_t *subscribers = NULL; events_t *next = NULL; }; events_t *firstEvent = NULL; /**< The first element in the event list */ /** * Finds the specific event in the list and returns it * @param event Event name * @return Pointer to event, NULL if not found */ events_t * event_find(char *event) { events_t *tmp = firstEvent; while (tmp) { if (!strcmp(tmp->event, event)) return tmp; tmp = tmp->next; } return NULL; } /** * Finds the last event in the list and returns it * @return Pointer to event, NULL if no event in list */ events_t * event_findlast() { events_t *tmp = firstEvent; while (tmp) { if (!tmp->next) return tmp; tmp = tmp->next; } return NULL; } /** * Adds a subscriber to an event * @param event Target event * @param handler Event handler */ void addSubscriber(events_t *event, void (*handler)(event_t *)) { subscriber_t *newSub = (subscriber_t *) malloc(sizeof(subscriber_t)); // Cast is neccesarry in c++ if (!newSub) logger_error("Not enough memory\n"); newSub->handler = handler; newSub->next = NULL; if (event->subscribers) { subscriber_t *tmp = event->subscribers; while (tmp->next) { tmp = tmp->next; } tmp->next = newSub; } else { event->subscribers = newSub; } } /** * Adds a subscriber to an event * @param event Target event name * @param handler Event handler */ void event_subscribe(const char *event, void (*handler)(event_t *)) { //TODO change event name to a typedef enum or similar events_t *newEvent = (events_t *) malloc(sizeof(events_t)); if (!newEvent) logger_error("Not enough memory\n"); newEvent->next = NULL; newEvent->subscribers = NULL; strcpy(newEvent->event, event); addSubscriber(newEvent, handler); events_t *tmp = event_findlast(); if (tmp) tmp->next = newEvent; else firstEvent = newEvent; logger(V_HAL, "New subscriber to event \"%s\"\n", event); } /** * Triggers a specific event * @param event Event data */ void event_trigger(event_t *event) { events_t *tmp = event_find(event->event); if (!tmp) { logger(V_HAL, "No subscribers to event \"%s\"\n", event->event); return; } subscriber_t *sub = tmp->subscribers; while (sub) { sub->handler(event); sub = sub->next; } logger(V_HAL, "Triggered event \"%s\"\n", event->event); } /** * Triggers a specific event * @param event Name of event */ void event_trigger(char *event) { event_t e; e.event = event; event_trigger(&e); } /** * Triggers a specific event * @param event Name of event */ void event_trigger(const char *event) { event_t e; e.event = (char*)event; event_trigger(&e); } /** * Triggers a specific event * @param event Name of event * @param data Pointer to some data * @param len Length of data */ void event_trigger(char *event, void *data, int len) { event_t e; e.event = event; e.data = data; e.len = len; event_trigger(&e); } /** * Triggers a specific event * @param event Name of event * @param data Pointer to some data * @param len Length of data */ void event_trigger(const char *event, void *data, int len) { event_trigger((char *) event, data, len); }