From 1e2aa34b21be08e3633bc891d03c600b39d9e04c Mon Sep 17 00:00:00 2001 From: Abdelrahman Date: Sun, 29 Dec 2024 01:47:30 +0000 Subject: [PATCH] Implement system initialisation and deinitialisation --- src/event_system.c | 119 +++++++++++++++++++++++++++++++++++++++++++++ src/event_system.h | 34 +++++++++++++ src/main.c | 12 +++++ 3 files changed, 165 insertions(+) create mode 100644 src/event_system.c create mode 100644 src/event_system.h diff --git a/src/event_system.c b/src/event_system.c new file mode 100644 index 0000000..03a70f2 --- /dev/null +++ b/src/event_system.c @@ -0,0 +1,119 @@ +#include "event_system.h" +#include "aliases.h" +#include +#include +#include + +#define INVALID_EVENT ((Event){ .id = 0 }) +#define INVALID_LISTENER ((EventListener){ .event = INVALID_EVENT, .id = 0 }) + +#define IS_INVALID_EVENT(EV) (EV.id == 0) +#define IS_INVALID_LISTENER(LS) (LS.id == 0) + +struct event_system { + EventCallback *callbacks; + u64 *callback_count; + u64 *free; + u64 free_count; + u64 event_count; + u64 event_capacity; + u64 max_listeners_count; +}; + +void *alloc(u64 size); +void alloc_members(EventSystem *es, u64 event_capacity); +void default_init_event_system(EventSystem *es); +bool is_default_initialised(const EventSystem *es); +bool member_allocation_failed(const EventSystem *es); + +u32 es_init(EventSystem **es, u64 initial_event_capacity, u64 max_event_listeners) { + if (!es) { + return ES_INIT_NULL_POINTER; + } + + if (*es) { + return ES_INIT_ALREADY_INITIALISED; + } + + *es = (EventSystem *)alloc(sizeof(EventSystem)); + if (!*es) { + return ES_INIT_SYSTEM_ALLOC_FAILED; + } + + EventSystem *system = *es; + + // Add extra event to account for keeping zero index free + u64 event_capacity = initial_event_capacity + 1; + system->free_count = 0; + system->event_count = 0; + system->event_capacity = initial_event_capacity; + system->max_listeners_count = max_event_listeners; + + alloc_members(system, event_capacity); + if (member_allocation_failed(system)) { + default_init_event_system(system); + return ES_INIT_MEMBER_ALLOC_FAILED; + } + + return ES_INIT_SUCCESS; +} + +void es_deinit(EventSystem **es) { + if (!es || !*es) { + return; + } + + EventSystem *system = *es; + + if (!is_default_initialised(system)) { + u64 event_capacity = system->event_capacity + 1; + munmap(system->callbacks, event_capacity * system->max_listeners_count * sizeof(EventCallback)); + munmap(system->callback_count, event_capacity * sizeof(u64)); + munmap(system->free, event_capacity * sizeof(u64)); + } + + munmap(system, sizeof(EventSystem)); + *es = NULL; +} + +Event es_register_event(EventSystem *es) { + // TODO (Abdelrahman): Incomplete implementation + if (!es || is_default_initialised(es)) { + return INVALID_EVENT; + } + + return (Event){ .id = ++(es->event_count) }; +} + +void es_deregister_event(EventSystem *es, Event event) {} + +EventListener es_add_event_listener(EventSystem *es, Event event, EventCallback *listener) {} + +void es_remove_event_listener(EventSystem *es, EventListener listener) {} + +void es_emit_event(EventSystem *es, Event event, void *data) {} + +void *alloc(u64 size) { + return mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_NORESERVE, -1, 0); +} + +void alloc_members(EventSystem *es, u64 event_capacity) { + es->callbacks = (EventCallback *)alloc(event_capacity * es->max_listeners_count * sizeof(EventCallback)); + es->callback_count = (u64 *)alloc(event_capacity * sizeof(u64)); + es->free = (u64 *)alloc(event_capacity * sizeof(u64)); +} + +void default_init_event_system(EventSystem *es) { + *es = (EventSystem){0}; + es->callbacks = (EventCallback *)es; + es->callback_count = (u64 *)es; + es->free = (u64 *)es; +} + +bool is_default_initialised(const EventSystem *es) { + return es->callbacks == (EventCallback *)es || es->callback_count == (u64 *)es || es->free == (u64 *)es; +} + +bool member_allocation_failed(const EventSystem *es) { + return es->callbacks == NULL || es->callback_count == NULL || es->free == NULL; +} diff --git a/src/event_system.h b/src/event_system.h new file mode 100644 index 0000000..680e613 --- /dev/null +++ b/src/event_system.h @@ -0,0 +1,34 @@ +#pragma once + +#include "aliases.h" + +enum { + ES_INIT_SUCCESS = 0, + ES_INIT_NULL_POINTER, + ES_INIT_ALREADY_INITIALISED, + ES_INIT_SYSTEM_ALLOC_FAILED, + ES_INIT_MEMBER_ALLOC_FAILED, +}; + +typedef struct event Event; +struct event { + u64 id; +}; + +typedef struct event_listener EventListener; +struct event_listener { + Event event; + u64 id; +}; + +typedef struct event_system EventSystem; + +typedef void (EventCallback)(void *data); + +u32 es_init(EventSystem **es, u64 initial_event_capacity, u64 max_event_listeners); +void es_deinit(EventSystem **es); +Event es_register_event(EventSystem *es); +void es_deregister_event(EventSystem *es, Event event); +EventListener es_add_event_listener(EventSystem *es, Event event, EventCallback *listener); +void es_remove_event_listener(EventSystem *es, EventListener listener); +void es_emit_event(EventSystem *es, Event event, void *data); diff --git a/src/main.c b/src/main.c index 03b2213..b647214 100644 --- a/src/main.c +++ b/src/main.c @@ -1,3 +1,15 @@ +#include "event_system.h" +#include +#include + int main(void) { + EventSystem *es = NULL; + if (es_init(&es, 32, 64) != ES_INIT_SUCCESS) { + printf("INITIALISATION FAILED\n"); + return 1; + } + + es_deinit(&es); + return 0; }