From d1a70ee6f4b273c6721c32c1dc87d9b2ce2d2bd6 Mon Sep 17 00:00:00 2001
From: Abdelrahman Said <said.abdelrahman@flawlessai.com>
Date: Sat, 4 Jan 2025 21:48:22 +0000
Subject: [PATCH] Add EventSystem reference in Event and magic to ESInteral

---
 src/event_system.c | 49 +++++++++++++++++++++++++++++++++-------------
 src/event_system.h |  3 ++-
 src/main.c         |  4 ++--
 3 files changed, 39 insertions(+), 17 deletions(-)

diff --git a/src/event_system.c b/src/event_system.c
index 62b220e..0ed42fa 100644
--- a/src/event_system.c
+++ b/src/event_system.c
@@ -5,6 +5,10 @@
 #include <stdbool.h>
 #include <sys/mman.h>
 
+#define MAGIC 0x4556535953
+
+#define VALID_MAGIC(ESINT_PTR) (ESINT_PTR->magic == MAGIC)
+
 #define INVALID_SYSTEM ((EventSystem){ .id = 0 })
 #define INVALID_EVENT ((Event) { .id = 0 })
 #define INVALID_LISTENER ((EventListener){ .event = INVALID_EVENT, .id = 0 })
@@ -15,6 +19,7 @@
 
 typedef struct es_internal ESInternal;
 struct es_internal {
+  u64 magic;
   u64  alloc_size;
   u64  event_capacity;
   u64  event_count;
@@ -81,6 +86,7 @@ EventSystem es_init(u64 initial_event_capacity, u64 initial_listeners_capacity)
 
   ESInternal *event_system = (ESInternal *)buffer;
 
+  event_system->magic                     = MAGIC;
   event_system->alloc_size                = alloc_size;
   event_system->event_capacity            = event_capacity;
   event_system->event_count               = 0;
@@ -116,6 +122,9 @@ void es_deinit(EventSystem *event_system) {
   }
 
   ESInternal *es = get_event_system_internal(*event_system);
+	if (!VALID_MAGIC(es)) {
+		return;
+	}
 
   munmap(system, es->alloc_size);
 
@@ -129,8 +138,14 @@ Event es_register_event(EventSystem event_system) {
     goto RETURN_EVENT;
   }
 
-  ESInternal *es                = get_event_system_internal(event_system);
-  EventSlot *event_slots_array  = get_event_slots_array(es);
+  ESInternal *es = get_event_system_internal(event_system);
+	if (!VALID_MAGIC(es)) {
+		goto RETURN_EVENT;
+	}
+
+  event.system = event_system;
+
+  EventSlot *event_slots_array = get_event_slots_array(es);
 
   if (es->free_count > 0) {
     u64 *free_array = get_free_array(es);
@@ -155,35 +170,41 @@ RETURN_EVENT:
   return event;
 }
 
-void es_deregister_event(EventSystem event_system, Event event) {
-  if (IS_INVALID_SYSTEM(event_system) || IS_INVALID_EVENT(event)) {
+void es_deregister_event(EventSystem event_system, Event *event) {
+  if (IS_INVALID_SYSTEM(event_system) || IS_INVALID_EVENT((*event)) || event_system.id != event->system.id) {
     return;
   }
 
   ESInternal *es = get_event_system_internal(event_system);
-  if (event.id > es->event_count) {
+  if (!VALID_MAGIC(es) || event->id > es->event_count) {
     return;
   }
 
   EventSlot *event_slots_array = get_event_slots_array(es);
   u64 *free_array              = get_free_array(es);
 
-  event_slots_array[event.id].registered = false;
-  free_array[(es->free_count)++]         = event.id;
+  event_slots_array[event->id].registered = false;
+  free_array[(es->free_count)++]         = event->id;
 
-  if (event.id == es->event_count) {
+  if (event->id == es->event_count) {
     es->event_count -= 1;
   }
+
+  event->id = 0;
 }
 
 EventListener es_add_event_listener(EventSystem event_system, Event event, EventCallback callback) {
   EventListener listener = INVALID_LISTENER;
 
-  if (IS_INVALID_SYSTEM(event_system) || IS_INVALID_EVENT(event) || !callback) {
+  if (IS_INVALID_SYSTEM(event_system) || IS_INVALID_EVENT(event) || event_system.id != event.system.id || !callback) {
     goto RETURN_LISTENER;
   }
 
-  ESInternal *es    = get_event_system_internal(event_system);
+  ESInternal *es = get_event_system_internal(event_system);
+	if (!VALID_MAGIC(es)) {
+    goto RETURN_LISTENER;
+	}
+
   EventInternal *ev = get_event(es, event);
 
   if (ev->free_count > 0) {
@@ -215,12 +236,12 @@ RETURN_LISTENER:
 }
 
 void es_remove_event_listener(EventSystem event_system, EventListener listener) {
-  if (IS_INVALID_SYSTEM(event_system) || IS_INVALID_LISTENER(listener)) {
+  if (IS_INVALID_SYSTEM(event_system) || IS_INVALID_LISTENER(listener) || event_system.id != listener.event.system.id) {
     return;
   }
 
   ESInternal *es = get_event_system_internal(event_system);
-  if (listener.event.id > es->event_count) {
+  if (!VALID_MAGIC(es) || listener.event.id > es->event_count) {
     return;
   }
 
@@ -243,12 +264,12 @@ void es_remove_event_listener(EventSystem event_system, EventListener listener)
 }
 
 void es_emit_event(EventSystem event_system, Event event, void *data) {
-  if (IS_INVALID_SYSTEM(event_system) || IS_INVALID_EVENT(event)) {
+  if (IS_INVALID_SYSTEM(event_system) || IS_INVALID_EVENT(event) || event_system.id != event.system.id) {
     return;
   }
 
   ESInternal *es = get_event_system_internal(event_system);
-  if (event.id > es->event_count) {
+  if (!VALID_MAGIC(es) || event.id > es->event_count) {
     return;
   }
 
diff --git a/src/event_system.h b/src/event_system.h
index cfd4183..a04ad74 100644
--- a/src/event_system.h
+++ b/src/event_system.h
@@ -16,6 +16,7 @@ struct event_system {
 
 typedef struct event Event;
 struct event {
+  EventSystem system;
   u64 id;
 };
 
@@ -30,7 +31,7 @@ typedef void (*EventCallback)(void *data);
 EventSystem   es_init(u64 initial_event_capacity, u64 initial_listeners_capacity);
 void          es_deinit(EventSystem *event_system);
 Event         es_register_event(EventSystem event_system);
-void          es_deregister_event(EventSystem event_system, Event event);
+void          es_deregister_event(EventSystem event_system, Event *event);
 EventListener es_add_event_listener(EventSystem event_system, Event event, EventCallback callback);
 void          es_remove_event_listener(EventSystem event_system, EventListener listener);
 void          es_emit_event(EventSystem event_system, Event event, void *data);
diff --git a/src/main.c b/src/main.c
index ed24e01..64a5771 100644
--- a/src/main.c
+++ b/src/main.c
@@ -65,11 +65,11 @@ int main(void) {
   EventListener listener    = es_add_event_listener(es, extra_event, extra_event_handler);
   es_emit_event(es, extra_event, NULL);
   es_remove_event_listener(es, listener);
-  es_deregister_event(es, extra_event);
+  es_deregister_event(es, &extra_event);
 
   for (int i = 0; i < COUNT_EVENTS; ++i) {
     es_remove_event_listener(es, listeners[i]);
-    es_deregister_event(es, events[i]);
+    es_deregister_event(es, &events[i]);
   }
 
   es_deinit(&es);