Initial implementation of adding and removing listeners and emitting an event
This commit is contained in:
		| @@ -110,14 +110,16 @@ RETURN_SYSTEM: | |||||||
|   return es; |   return es; | ||||||
| } | } | ||||||
|  |  | ||||||
| void es_deinit(EventSystem event_system) { | void es_deinit(EventSystem *event_system) { | ||||||
|   if (IS_INVALID_SYSTEM(event_system)) { |   if (!event_system || IS_INVALID_SYSTEM((*event_system))) { | ||||||
|     return; |     return; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   ESInternal *es = get_event_system_internal(event_system); |   ESInternal *es = get_event_system_internal(*event_system); | ||||||
|  |  | ||||||
|   munmap(system, es->alloc_size); |   munmap(system, es->alloc_size); | ||||||
|  |  | ||||||
|  |   event_system->id = 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| Event es_register_event(EventSystem event_system) { | Event es_register_event(EventSystem event_system) { | ||||||
| @@ -174,11 +176,88 @@ void es_deregister_event(EventSystem event_system, Event event) { | |||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| EventListener es_add_event_listener(EventSystem event_system, Event event, EventCallback *listener) {} | EventListener es_add_event_listener(EventSystem event_system, Event event, EventCallback callback) { | ||||||
|  |   EventListener listener = INVALID_LISTENER; | ||||||
|  |  | ||||||
| void es_remove_event_listener(EventSystem event_system, EventListener listener) {} |   if (IS_INVALID_SYSTEM(event_system) || IS_INVALID_EVENT(event) || !callback) { | ||||||
|  |     goto RETURN_LISTENER; | ||||||
|  |   } | ||||||
|  |  | ||||||
| void es_emit_event(EventSystem event_system, Event event, void *data) {} |   ESInternal *es    = get_event_system_internal(event_system); | ||||||
|  |   EventInternal *ev = get_event(es, event); | ||||||
|  |  | ||||||
|  |   if (ev->free_count > 0) { | ||||||
|  |     u64 id = ev->free[--(ev->free_count)]; | ||||||
|  |  | ||||||
|  |     ev->free[ev->free_count] = 0; | ||||||
|  |     ev->callbacks[id]        = callback; | ||||||
|  |  | ||||||
|  |     listener.id    = id; | ||||||
|  |     listener.event = event; | ||||||
|  |  | ||||||
|  |     goto RETURN_LISTENER; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if (ev->count >= ev->capacity) { | ||||||
|  |     // TODO (Abdelrahman): Handle reallocating when out of callbacks | ||||||
|  |     goto RETURN_LISTENER; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   u64 id = ++(ev->count); | ||||||
|  |  | ||||||
|  |   ev->callbacks[id] = callback; | ||||||
|  |  | ||||||
|  |   listener.id    = id; | ||||||
|  |   listener.event = event; | ||||||
|  |  | ||||||
|  | RETURN_LISTENER: | ||||||
|  |   return listener; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void es_remove_event_listener(EventSystem event_system, EventListener listener) { | ||||||
|  |   if (IS_INVALID_SYSTEM(event_system) || IS_INVALID_LISTENER(listener)) { | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   ESInternal *es    = get_event_system_internal(event_system); | ||||||
|  |   EventInternal *ev = get_event(es, listener.event); | ||||||
|  |  | ||||||
|  |   if (listener.id > ev->count) { | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if (ev->callbacks[listener.id] == NULL) { | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   ev->callbacks[listener.id]   = NULL; | ||||||
|  |   ev->free[(ev->free_count)++] = listener.id;  | ||||||
|  |  | ||||||
|  |   if (listener.id == ev->count) { | ||||||
|  |     ev->count -= 1; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void es_emit_event(EventSystem event_system, Event event, void *data) { | ||||||
|  |   if (IS_INVALID_SYSTEM(event_system) || IS_INVALID_EVENT(event)) { | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   ESInternal *es = get_event_system_internal(event_system); | ||||||
|  |   if (event.id > es->event_count) { | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   EventInternal *ev = get_event(es, event); | ||||||
|  |   EventCallback callback; | ||||||
|  |   for (int i = 0; i < ev->count; ++i) { | ||||||
|  |     callback = ev->callbacks[i + 1]; | ||||||
|  |     if (!callback) { | ||||||
|  |       continue; | ||||||
|  |     } | ||||||
|  |     callback(data); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
| // INTERNAL | // INTERNAL | ||||||
|  |  | ||||||
|   | |||||||
| @@ -25,12 +25,12 @@ struct event_listener { | |||||||
|   u64 id; |   u64 id; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| typedef void (EventCallback)(void *data); | typedef void (*EventCallback)(void *data); | ||||||
|  |  | ||||||
| EventSystem   es_init(u64 initial_event_capacity, u64 initial_listeners_capacity); | EventSystem   es_init(u64 initial_event_capacity, u64 initial_listeners_capacity); | ||||||
| void          es_deinit(EventSystem event_system); | void          es_deinit(EventSystem *event_system); | ||||||
| Event         es_register_event(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 *listener); | EventListener es_add_event_listener(EventSystem event_system, Event event, EventCallback callback); | ||||||
| void          es_remove_event_listener(EventSystem event_system, EventListener listener); | void          es_remove_event_listener(EventSystem event_system, EventListener listener); | ||||||
| void          es_emit_event(EventSystem event_system, Event event, void *data); | void          es_emit_event(EventSystem event_system, Event event, void *data); | ||||||
|   | |||||||
							
								
								
									
										76
									
								
								src/main.c
									
									
									
									
									
								
							
							
						
						
									
										76
									
								
								src/main.c
									
									
									
									
									
								
							| @@ -1,6 +1,15 @@ | |||||||
| #include "event_system.h" | #include "event_system.h" | ||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
|  |  | ||||||
|  | #define ARR_LEN(ARR) (sizeof(ARR) / sizeof(ARR[0])) | ||||||
|  |  | ||||||
|  | void callback(void *data); | ||||||
|  | void callback1(void *data); | ||||||
|  | void callback2(void *data); | ||||||
|  | void callback3(void *data); | ||||||
|  | void callback4(void *data); | ||||||
|  | void callback5(void *data); | ||||||
|  |  | ||||||
| int main(void) { | int main(void) { | ||||||
|   EventSystem es = es_init(16, 64); |   EventSystem es = es_init(16, 64); | ||||||
|  |  | ||||||
| @@ -22,7 +31,72 @@ int main(void) { | |||||||
|     printf("%lu\n", ev.id); |     printf("%lu\n", ev.id); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   es_deinit(es); |   printf("\n"); | ||||||
|  |  | ||||||
|  |   es_deregister_event(es, (Event){ .id = 10 }); | ||||||
|  |   Event ev = es_register_event(es); | ||||||
|  |   for (int i = 0; i < 10; ++i) { | ||||||
|  |     EventListener listener = es_add_event_listener(es, ev, callback); | ||||||
|  |     printf("Event: %lu, ID: %lu\n", listener.event.id, listener.id); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   printf("\n"); | ||||||
|  |  | ||||||
|  |   for (int i = 5; i < 8; ++i) { | ||||||
|  |     es_remove_event_listener(es, (EventListener){ .event = ev, .id = i }); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   for (int i = 0; i < 3; ++i) { | ||||||
|  |     EventListener listener = es_add_event_listener(es, ev, callback); | ||||||
|  |     printf("Event: %lu, ID: %lu\n", listener.event.id, listener.id); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   printf("\n"); | ||||||
|  |  | ||||||
|  |   EventCallback callbacks[] = {callback1, callback2, callback3, callback4, callback5}; | ||||||
|  |   EventListener listeners[ARR_LEN(callbacks)] = {0}; | ||||||
|  |   Event ev_with_callbacks = (Event){ .id = 20 }; | ||||||
|  |   for (int i = 0; i < ARR_LEN(callbacks); ++i) { | ||||||
|  |     listeners[i] = es_add_event_listener(es, ev_with_callbacks, callbacks[i]); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   es_emit_event(es, ev_with_callbacks, (void *)0); | ||||||
|  |  | ||||||
|  |   printf("\n"); | ||||||
|  |  | ||||||
|  |   es_remove_event_listener(es, listeners[2]); | ||||||
|  |  | ||||||
|  |   es_emit_event(es, ev_with_callbacks, (void *)0); | ||||||
|  |  | ||||||
|  |   printf("\n"); | ||||||
|  |  | ||||||
|  |   printf("SYSTEM: %lu\n", es.id); | ||||||
|  |   es_deinit(&es); | ||||||
|  |   printf("SYSTEM: %lu\n", es.id); | ||||||
|  |  | ||||||
|   return 0; |   return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void callback(void *data) { | ||||||
|  |   return; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void callback1(void *data) { | ||||||
|  |   printf("Hello from callback1\n"); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void callback2(void *data) { | ||||||
|  |   printf("Hello from callback2\n"); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void callback3(void *data) { | ||||||
|  |   printf("Hello from callback3\n"); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void callback4(void *data) { | ||||||
|  |   printf("Hello from callback4\n"); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void callback5(void *data) { | ||||||
|  |   printf("Hello from callback5\n"); | ||||||
|  | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user