From 571bb9699df2b281157a68217ea490482bccd729 Mon Sep 17 00:00:00 2001 From: Ulysse Cura Date: Mon, 10 Aug 2026 00:47:21 +0200 Subject: [PATCH] Implemented event bus. --- src/Makefile | 1 + src/event_bus.c | 118 ++++++++++++++++++++++++++++++++++++++++ src/headers/event_bus.h | 45 +++++++++++++++ 3 files changed, 164 insertions(+) create mode 100644 src/event_bus.c create mode 100644 src/headers/event_bus.h diff --git a/src/Makefile b/src/Makefile index 989fefb..9295a9c 100644 --- a/src/Makefile +++ b/src/Makefile @@ -4,6 +4,7 @@ CORE_SOURCES := \ vector2d.c \ inputs.c \ asset_manager.c \ + event_bus.c \ ecs.c \ display.c \ main.c diff --git a/src/event_bus.c b/src/event_bus.c new file mode 100644 index 0000000..daae032 --- /dev/null +++ b/src/event_bus.c @@ -0,0 +1,118 @@ +#include "event_bus.h" + +#include +#include "linked_list.h" +#include "memory_alloc.h" + +// Args : void *payload +int create_event(event_t *event, va_list args) +{ + event->payload = va_arg(args, void *); + + return EXIT_SUCCESS; +} + +int destroy_event(event_t *event) +{ + free(event->payload); + + return EXIT_SUCCESS; +} + +// Args : callback_t callback +int create_subscription(subscription_t *subscription, va_list args) +{ + subscription->callback = va_arg(args, callback_t); + + return EXIT_SUCCESS; +} + +// Args : size_t id, size_t max_history_size +int create_topic(topic_t *topic, va_list args) +{ + topic->id = va_arg(args, size_t); + topic->max_history_size = va_arg(args, size_t); + + linked_list_init(&topic->events, sizeof(event_t), (allocator_t)create_event, (deleter_t)destroy_event); + linked_list_init(&topic->subscriptions, sizeof(subscription_t), (allocator_t)create_subscription, NULL); + + if(linked_list_reserve(&topic->events, topic->max_history_size)) return EXIT_FAILURE; + + return EXIT_SUCCESS; +} + +int destroy_topic(topic_t *topic) +{ + if(linked_list_exit(&topic->events)) return EXIT_FAILURE; + if(linked_list_exit(&topic->subscriptions)) return EXIT_FAILURE; + + return EXIT_SUCCESS; +} + +int event_bus_init(event_bus_t *event_bus) +{ + linked_list_init(&event_bus->topics, sizeof(topic_t), (allocator_t)create_topic, (deleter_t)destroy_topic); + + return EXIT_SUCCESS; +} + +int event_bus_exit(event_bus_t *event_bus) +{ + if(linked_list_exit(&event_bus->topics)) return EXIT_FAILURE; + + return EXIT_SUCCESS; +} + +int event_bus_new_topic(event_bus_t *event_bus, size_t id, size_t max_history_size) +{ + if(!create_elem(&event_bus->topics, id, max_history_size)) return EXIT_FAILURE; + + return EXIT_SUCCESS; +} + +// Args : size_t id +static inline bool condition_is_topic_id(elem_t *elem, va_list args) +{ + return ((topic_t *)elem->data)->id == va_arg(args, size_t); +} + +int event_bus_remove_topic(event_bus_t *event_bus, size_t id) +{ + if(linked_list_remove_if(&event_bus->topics, condition_is_topic_id, id)) return EXIT_FAILURE; + + return EXIT_SUCCESS; +} + +// Args : void *payload +static inline int action_execute_callback(elem_t *elem, va_list args) +{ + subscription_t *subscription = elem->data; + + if(subscription->callback(va_arg(args, void *))) return EXIT_FAILURE; + + return EXIT_SUCCESS; +} + +int event_bus_publish(event_bus_t *event_bus, size_t id, void *payload) +{ + elem_t *topic_elem = linked_list_get_if(&event_bus->topics, condition_is_topic_id, id); + if(!topic_elem) return EXIT_FAILURE; + + topic_t *topic = topic_elem->data; + if(!create_elem(&topic->events, payload)) return EXIT_FAILURE; + + if(linked_list_for_each(&topic->subscriptions, action_execute_callback, payload)) return EXIT_FAILURE; + + return EXIT_SUCCESS; +} + +int event_bus_subscribe(event_bus_t *event_bus, size_t id, callback_t callback) +{ + elem_t *topic_elem = linked_list_get_if(&event_bus->topics, condition_is_topic_id, id); + if(!topic_elem) return EXIT_FAILURE; + + topic_t *topic = topic_elem->data; + if(!create_elem(&topic->subscriptions, callback)) return EXIT_FAILURE; + + return EXIT_SUCCESS; +} diff --git a/src/headers/event_bus.h b/src/headers/event_bus.h new file mode 100644 index 0000000..6cb943d --- /dev/null +++ b/src/headers/event_bus.h @@ -0,0 +1,45 @@ +#ifndef EVENT_BUS_H +#define EVENT_BUS_H + +#include +#include "linked_list.h" + +typedef int (*callback_t)(void *payload); + +typedef struct event_t { + void *payload; +} event_t; + +int create_event(event_t *event, va_list args); +int destroy_event(event_t *event); + +typedef struct subscription_t { + callback_t callback; +} subscription_t; + +int create_subscription(subscription_t *subscription, va_list args); + +typedef struct topic_t { + size_t id; + linked_list_t events; + linked_list_t subscriptions; + size_t max_history_size; +} topic_t; + +int create_topic(topic_t *topic, va_list args); +int destroy_topic(topic_t *topic); + +typedef struct event_bus_t { + linked_list_t topics; +} event_bus_t; + +int event_bus_init(event_bus_t *event_bus); +int event_bus_exit(event_bus_t *event_bus); + +int event_bus_new_topic(event_bus_t *event_bus, size_t id, size_t max_history_size); +int event_bus_remove_topic(event_bus_t *event_bus, size_t id); + +int event_bus_publish(event_bus_t *event_bus, size_t id, void *payload); +int event_bus_subscribe(event_bus_t *event_bus, size_t id, callback_t callback); + +#endif // EVENT_BUS_H \ No newline at end of file