Implement system initialisation and deinitialisation
This commit is contained in:
parent
ffb666e0df
commit
1e2aa34b21
119
src/event_system.c
Normal file
119
src/event_system.c
Normal file
@ -0,0 +1,119 @@
|
||||
#include "event_system.h"
|
||||
#include "aliases.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#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;
|
||||
}
|
34
src/event_system.h
Normal file
34
src/event_system.h
Normal file
@ -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);
|
12
src/main.c
12
src/main.c
@ -1,3 +1,15 @@
|
||||
#include "event_system.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user