Implemented the ObjectStore functionality.

This commit is contained in:
abdelrahman committed 2022-09-19 23:44:31 +01:00
1 parent 20f476c4ab
commit a0e76bc1fc
4 files changed
+259 -21

No files matched your search

+202
View File
@@ -1 +1,203 @@
#include "ObjectStore.h"
#include "Hashmap.h"
#include "constants.h"
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
struct object_store {
size_t count;
int32_t active_indices[MAX_OBJ_COUNT];
void **object_ptrs;
EventHandlerPtr *event_handlers;
UpdateFuncPtr *update_funcs;
RenderFuncPtr *render_funcs;
};
ObjectStore *create_object_store() {
init_hashmap();
bool allocation_complete = true;
ObjectStore *os = (ObjectStore *)malloc(sizeof(ObjectStore));
if (!os) {
// If allocating memory to the store fails, we still need to call the
// destroy function to make sure that the memory allocated for the
// hashmap is freed.
destroy_object_store(os);
return NULL;
}
os->count = 0;
os->object_ptrs = malloc(sizeof(void *) * MAX_OBJ_COUNT);
if (!(os->object_ptrs)) {
allocation_complete = false;
}
os->event_handlers =
(EventHandlerPtr *)malloc(sizeof(EventHandlerPtr) * MAX_OBJ_COUNT);
if (!(os->event_handlers)) {
allocation_complete = false;
}
os->update_funcs =
(UpdateFuncPtr *)malloc(sizeof(UpdateFuncPtr) * MAX_OBJ_COUNT);
if (!(os->update_funcs)) {
allocation_complete = false;
}
os->render_funcs =
(RenderFuncPtr *)malloc(sizeof(RenderFuncPtr) * MAX_OBJ_COUNT);
if (!(os->render_funcs)) {
allocation_complete = false;
}
if (!allocation_complete) {
// If any of the allocations failed, we need to call the destroy function
// to free any resources that have been allocated successfully.
destroy_object_store(os);
return NULL;
}
for (int i = 0; i < MAX_OBJ_COUNT; ++i) {
os->active_indices[i] = -1;
}
return os;
}
void add_object_to_store(ObjectStore *os, void *object, const char *object_tag,
EventHandlerPtr eh, UpdateFuncPtr uf,
RenderFuncPtr rf) {
int32_t index = add_object_to_map(object_tag);
if (index < 0) {
return;
}
os->active_indices[os->count] = index;
os->count += 1;
os->object_ptrs[index] = object;
os->event_handlers[index] = eh;
os->update_funcs[index] = uf;
os->render_funcs[index] = rf;
}
void remove_object_from_store(ObjectStore *os, const char *object_tag) {
if (os->count == 0) {
return;
}
int32_t index = delete_object_from_map(object_tag);
if (index < 0) {
return;
}
os->object_ptrs[index] = NULL;
os->event_handlers[index] = NULL;
os->update_funcs[index] = NULL;
os->render_funcs[index] = NULL;
size_t packing_start_index = 0;
for (size_t i = 0; i < os->count; ++i) {
if (os->active_indices[i] == index) {
os->active_indices[i] = -1;
packing_start_index = i;
break;
}
}
// Make sure the indices are packed in the array
for (; packing_start_index < os->count; ++packing_start_index) {
if (packing_start_index + 1 == MAX_OBJ_COUNT) {
// Make sure we don't go out of bounds if we are at the last item
os->active_indices[packing_start_index] = -1;
continue;
}
os->active_indices[packing_start_index] =
os->active_indices[packing_start_index + 1];
}
os->count -= 1;
}
void handle_all_objects_events(ObjectStore *os, const SDL_Event *event) {
if (os->count == 0) {
return;
}
for (int i = 0; i < os->count; ++i) {
int32_t index = os->active_indices[i];
void *object = os->object_ptrs[index];
(os->event_handlers[index])(event, object);
}
}
void update_all_objects(ObjectStore *os, float delta) {
if (os->count == 0) {
return;
}
for (int i = 0; i < os->count; ++i) {
int32_t index = os->active_indices[i];
void *object = os->object_ptrs[index];
(os->update_funcs[index])(delta, object);
}
}
void render_all_objects(ObjectStore *os, Renderer *renderer) {
if (os->count == 0) {
return;
}
for (int i = 0; i < os->count; ++i) {
int32_t index = os->active_indices[i];
void *object = os->object_ptrs[index];
(os->render_funcs[index])(renderer, object);
}
}
void destroy_object_store(ObjectStore *os) {
destroy_hashmap();
if (!os) {
return;
}
for (int i = 0; i < os->count; ++i) {
os->active_indices[i] = -1;
}
os->count = 0;
if (os->event_handlers) {
free(os->event_handlers);
os->event_handlers = NULL;
}
if (os->update_funcs) {
free(os->update_funcs);
os->update_funcs = NULL;
}
if (os->render_funcs) {
free(os->render_funcs);
os->render_funcs = NULL;
}
if (os->object_ptrs) {
free(os->object_ptrs);
os->object_ptrs = NULL;
}
free(os);
os = NULL;
}
#ifdef DEBUG_ENGINE
void print_objects() { print_hashmap(); }
#endif /* DEBUG_ENGINE */