Implemented event bus.

This commit is contained in:
Ulysse Cura 2026-08-10 00:47:21 +02:00
parent c57cfea7f7
commit 571bb9699d
3 changed files with 164 additions and 0 deletions

View File

@ -4,6 +4,7 @@ CORE_SOURCES := \
vector2d.c \
inputs.c \
asset_manager.c \
event_bus.c \
ecs.c \
display.c \
main.c

118
src/event_bus.c Normal file
View File

@ -0,0 +1,118 @@
#include "event_bus.h"
#include <stdlib.h>
#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;
}

45
src/headers/event_bus.h Normal file
View File

@ -0,0 +1,45 @@
#ifndef EVENT_BUS_H
#define EVENT_BUS_H
#include <stdarg.h>
#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