Modified the ObjectStore and the Hashmap and added the ObjectStore to
the GameManager
This commit is contained in:
1 parent
a0e76bc1fc
commit
79f28100bd
8 files changed
+181
-73
No files matched your search
+2
-2
@@ -22,7 +22,7 @@ set(CMAKE_INSTALL_RPATH "$ORIGIN;$ORIGIN/../lib")
|
||||
|
||||
# TARGETS
|
||||
add_library(${PROJECT_NAME} SHARED
|
||||
src/Game.c
|
||||
src/GameManager.c
|
||||
src/Window.c
|
||||
src/Renderer.c
|
||||
src/ObjectStore.c
|
||||
@@ -47,7 +47,7 @@ target_link_libraries(${PROJECT_NAME} PUBLIC
|
||||
install(FILES
|
||||
${CMAKE_CURRENT_BINARY_DIR}/engine_build_config.h
|
||||
include/constants.h
|
||||
include/Game.h
|
||||
include/GameManager.h
|
||||
include/Window.h
|
||||
include/Renderer.h
|
||||
include/ObjectStore.h
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
#ifndef GAME_H
|
||||
#define GAME_H
|
||||
|
||||
#include "ObjectStore.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
bool init_game(const char *game_name, int window_width, int window_height,
|
||||
bool full_screen);
|
||||
bool game_running();
|
||||
void add_object(void *object, const char *object_tag, EventHandlerPtr eh,
|
||||
UpdateFuncPtr uf, RenderFuncPtr rf);
|
||||
void remove_object(const char *object_tag);
|
||||
void handle_events();
|
||||
void update();
|
||||
void render();
|
||||
+9
-7
@@ -9,15 +9,17 @@
|
||||
#include <stdio.h>
|
||||
#endif /* DEBUG_ENGINE */
|
||||
|
||||
void init_hashmap();
|
||||
int32_t add_object_to_map(const char *key);
|
||||
int32_t get_object_index(const char *key);
|
||||
int32_t delete_object_from_map(const char *key);
|
||||
void destroy_hashmap();
|
||||
typedef struct hashmap Hashmap;
|
||||
|
||||
Hashmap *create_hashmap();
|
||||
int32_t add_object_to_map(Hashmap *map, const char *key);
|
||||
int32_t get_object_index(Hashmap *map, const char *key);
|
||||
int32_t delete_object_from_map(Hashmap *map, const char *key);
|
||||
void destroy_hashmap(Hashmap *map);
|
||||
|
||||
#ifdef DEBUG_ENGINE
|
||||
void print_hashmap();
|
||||
void print_non_empty();
|
||||
void print_hashmap(Hashmap *map);
|
||||
void print_non_empty(Hashmap *map);
|
||||
#endif // DEBUG_ENGINE
|
||||
|
||||
#endif // !HASHMAP_H
|
||||
@@ -22,7 +22,7 @@ void render_all_objects(ObjectStore *os, Renderer *renderer);
|
||||
void destroy_object_store(ObjectStore *os);
|
||||
|
||||
#ifdef DEBUG_ENGINE
|
||||
void print_objects();
|
||||
void print_objects(ObjectStore *os);
|
||||
#endif /* DEBUG_ENGINE */
|
||||
|
||||
#endif // !OBJECT_STORE_H
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "Game.h"
|
||||
#include "GameManager.h"
|
||||
#include "ObjectStore.h"
|
||||
#include "SDL.h"
|
||||
#include "SDL_error.h"
|
||||
#include "SDL_events.h"
|
||||
@@ -14,12 +15,16 @@
|
||||
|
||||
INTERNAL struct game {
|
||||
bool running;
|
||||
float delta;
|
||||
Window window;
|
||||
SDL_Event event;
|
||||
ObjectStore *object_store;
|
||||
} Game;
|
||||
|
||||
bool init_game(const char *game_name, int window_width, int window_height,
|
||||
bool full_screen) {
|
||||
bool initialisation_complete = true;
|
||||
|
||||
if (SDL_Init(SDL_INIT_EVERYTHING) != 0) {
|
||||
#ifdef DEBUG_ENGINE
|
||||
printf("Failed to initialise SDL. Error: %s\n", SDL_GetError());
|
||||
@@ -34,10 +39,23 @@ bool init_game(const char *game_name, int window_width, int window_height,
|
||||
printf("Failed to initialise window\n");
|
||||
#endif /* DEBUG_ENGINE */
|
||||
|
||||
initialisation_complete = false;
|
||||
}
|
||||
|
||||
Game.object_store = create_object_store();
|
||||
|
||||
if (!(Game.object_store)) {
|
||||
initialisation_complete = false;
|
||||
}
|
||||
|
||||
if (!initialisation_complete) {
|
||||
close_game();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Game.running = true;
|
||||
Game.delta = 0.0f;
|
||||
|
||||
#ifdef DEBUG_ENGINE
|
||||
printf("Game initialised successfully\n");
|
||||
@@ -48,27 +66,75 @@ bool init_game(const char *game_name, int window_width, int window_height,
|
||||
|
||||
bool game_running() { return Game.running; }
|
||||
|
||||
void add_object(void *object, const char *object_tag,
|
||||
EventHandlerPtr event_handler, UpdateFuncPtr update_func,
|
||||
RenderFuncPtr render_func) {
|
||||
if (!(Game.running) || !(Game.object_store)) {
|
||||
return;
|
||||
}
|
||||
|
||||
add_object_to_store(Game.object_store, object, object_tag, event_handler,
|
||||
update_func, render_func);
|
||||
}
|
||||
|
||||
void remove_object(const char *object_tag) {
|
||||
if (!(Game.running) || !(Game.object_store)) {
|
||||
return;
|
||||
}
|
||||
|
||||
remove_object_from_store(Game.object_store, object_tag);
|
||||
}
|
||||
|
||||
void handle_events() {
|
||||
if (!(Game.running)) {
|
||||
return;
|
||||
}
|
||||
|
||||
while (SDL_PollEvent(&(Game.event))) {
|
||||
switch (Game.event.type) {
|
||||
case SDL_QUIT:
|
||||
Game.running = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!Game.object_store) {
|
||||
break;
|
||||
}
|
||||
|
||||
handle_all_objects_events(Game.object_store, &(Game.event));
|
||||
}
|
||||
}
|
||||
|
||||
void update() {}
|
||||
void update() {
|
||||
if (!(Game.running) || !(Game.object_store)) {
|
||||
return;
|
||||
}
|
||||
|
||||
update_all_objects(Game.object_store, Game.delta);
|
||||
}
|
||||
|
||||
void render() {
|
||||
if (!(Game.running)) {
|
||||
return;
|
||||
}
|
||||
|
||||
fill_window_with_color(&(Game.window), (SDL_Color){255, 255, 255, 255});
|
||||
|
||||
if (Game.object_store) {
|
||||
render_all_objects(Game.object_store, Game.window.renderer);
|
||||
}
|
||||
|
||||
swap_render_buffers(&(Game.window));
|
||||
}
|
||||
|
||||
void close_game() {
|
||||
destroy_object_store(Game.object_store);
|
||||
Game.object_store = NULL;
|
||||
|
||||
destroy_window(&(Game.window));
|
||||
|
||||
Game.delta = 0.0f;
|
||||
|
||||
Game.running = false;
|
||||
|
||||
SDL_Quit();
|
||||
+59
-44
@@ -11,16 +11,24 @@
|
||||
#include <stdio.h>
|
||||
#endif /* DEBUG_ENGINE */
|
||||
|
||||
INTERNAL struct objects_hashmap {
|
||||
struct hashmap {
|
||||
size_t count;
|
||||
char *keys[MAX_OBJ_COUNT];
|
||||
int32_t active_indices[MAX_OBJ_COUNT];
|
||||
} map = {};
|
||||
};
|
||||
|
||||
Hashmap *create_hashmap() {
|
||||
Hashmap *map = malloc(sizeof(Hashmap));
|
||||
|
||||
map->count = 0;
|
||||
|
||||
memset(map->keys, 0, MAX_OBJ_COUNT);
|
||||
|
||||
void init_hashmap() {
|
||||
for (int i = 0; i < MAX_OBJ_COUNT; ++i) {
|
||||
map.active_indices[i] = -1;
|
||||
map->active_indices[i] = -1;
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
size_t hash_key(const char *key) {
|
||||
@@ -35,8 +43,8 @@ size_t hash_key(const char *key) {
|
||||
return i;
|
||||
}
|
||||
|
||||
int32_t add_object_to_map(const char *key) {
|
||||
if (map.count + 1 == MAX_OBJ_COUNT) {
|
||||
int32_t add_object_to_map(Hashmap *map, const char *key) {
|
||||
if (map->count + 1 == MAX_OBJ_COUNT) {
|
||||
#ifdef DEBUG_ENGINE
|
||||
printf("Map full\n");
|
||||
#endif /* DEBUG_ENGINE */
|
||||
@@ -46,8 +54,8 @@ int32_t add_object_to_map(const char *key) {
|
||||
|
||||
size_t index = hash_key(key);
|
||||
|
||||
if (map.keys[index]) {
|
||||
if (strcmp(map.keys[index], key) == 0) {
|
||||
if (map->keys[index]) {
|
||||
if (strcmp(map->keys[index], key) == 0) {
|
||||
#ifdef DEBUG_ENGINE
|
||||
printf("Key \"%s\" already exists\n", key);
|
||||
#endif /* DEBUG_ENGINE */
|
||||
@@ -56,23 +64,23 @@ int32_t add_object_to_map(const char *key) {
|
||||
// multiple keys
|
||||
#ifdef DEBUG_ENGINE
|
||||
printf("Collision detected. Key \"%s\" collides with key \"%s\"\n", key,
|
||||
map.keys[index]);
|
||||
map->keys[index]);
|
||||
#endif /* DEBUG_ENGINE */
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
map.keys[index] = malloc(strlen(key) + 1);
|
||||
strcpy(map.keys[index], key);
|
||||
map.active_indices[map.count] = index;
|
||||
map.count += 1;
|
||||
map->keys[index] = malloc(strlen(key) + 1);
|
||||
strcpy(map->keys[index], key);
|
||||
map->active_indices[map->count] = index;
|
||||
map->count += 1;
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
int32_t get_object_index(const char *key) {
|
||||
if (map.count == 0) {
|
||||
int32_t get_object_index(Hashmap *map, const char *key) {
|
||||
if (map->count == 0) {
|
||||
#ifdef DEBUG_ENGINE
|
||||
printf("Key \"%s\" doesn't exist\n", key);
|
||||
#endif /* DEBUG_ENGINE */
|
||||
@@ -82,7 +90,7 @@ int32_t get_object_index(const char *key) {
|
||||
|
||||
size_t index = hash_key(key);
|
||||
|
||||
if (!(map.keys[index]) || strcmp(map.keys[index], key) != 0) {
|
||||
if (!(map->keys[index]) || strcmp(map->keys[index], key) != 0) {
|
||||
#ifdef DEBUG_ENGINE
|
||||
printf("Key \"%s\" doesn't exist\n", key);
|
||||
#endif /* DEBUG_ENGINE */
|
||||
@@ -93,8 +101,8 @@ int32_t get_object_index(const char *key) {
|
||||
return (int32_t)index;
|
||||
}
|
||||
|
||||
int32_t delete_object_from_map(const char *key) {
|
||||
if (map.count == 0) {
|
||||
int32_t delete_object_from_map(Hashmap *map, const char *key) {
|
||||
if (map->count == 0) {
|
||||
#ifdef DEBUG_ENGINE
|
||||
printf("Key \"%s\" doesn't exist\n", key);
|
||||
#endif /* DEBUG_ENGINE */
|
||||
@@ -104,7 +112,7 @@ int32_t delete_object_from_map(const char *key) {
|
||||
|
||||
size_t index = hash_key(key);
|
||||
|
||||
if (!(map.keys[index]) || strcmp(map.keys[index], key) != 0) {
|
||||
if (!(map->keys[index]) || strcmp(map->keys[index], key) != 0) {
|
||||
#ifdef DEBUG_ENGINE
|
||||
printf("Key \"%s\" doesn't exist\n", key);
|
||||
#endif /* DEBUG_ENGINE */
|
||||
@@ -112,70 +120,77 @@ int32_t delete_object_from_map(const char *key) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
free(map.keys[index]);
|
||||
map.keys[index] = NULL;
|
||||
free(map->keys[index]);
|
||||
map->keys[index] = NULL;
|
||||
|
||||
size_t packing_start_index = 0;
|
||||
|
||||
for (size_t i = 0; i < map.count; ++i) {
|
||||
if (map.active_indices[i] == index) {
|
||||
map.active_indices[i] = -1;
|
||||
for (size_t i = 0; i < map->count; ++i) {
|
||||
if (map->active_indices[i] == index) {
|
||||
map->active_indices[i] = -1;
|
||||
packing_start_index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure the indices are packed in the array
|
||||
for (; packing_start_index < map.count; ++packing_start_index) {
|
||||
for (; packing_start_index < map->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
|
||||
map.active_indices[packing_start_index] = -1;
|
||||
map->active_indices[packing_start_index] = -1;
|
||||
continue;
|
||||
}
|
||||
|
||||
map.active_indices[packing_start_index] =
|
||||
map.active_indices[packing_start_index + 1];
|
||||
map->active_indices[packing_start_index] =
|
||||
map->active_indices[packing_start_index + 1];
|
||||
}
|
||||
|
||||
map.count -= 1;
|
||||
map->count -= 1;
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
void destroy_hashmap() {
|
||||
for (size_t i = 0; i < map.count; ++i) {
|
||||
size_t index = map.active_indices[i];
|
||||
void destroy_hashmap(Hashmap *map) {
|
||||
if (!map) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < map->count; ++i) {
|
||||
size_t index = map->active_indices[i];
|
||||
|
||||
if (index == -1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (map.keys[index]) {
|
||||
free(map.keys[index]);
|
||||
map.keys[index] = NULL;
|
||||
if (map->keys[index]) {
|
||||
free(map->keys[index]);
|
||||
map->keys[index] = NULL;
|
||||
}
|
||||
|
||||
map.active_indices[i] = -1;
|
||||
map->active_indices[i] = -1;
|
||||
}
|
||||
|
||||
map.count = 0;
|
||||
map->count = 0;
|
||||
|
||||
free(map);
|
||||
map = NULL;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_ENGINE
|
||||
void print_hashmap() {
|
||||
if (map.count == 0) {
|
||||
void print_hashmap(Hashmap *map) {
|
||||
if (map->count == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < map.count; ++i) {
|
||||
size_t index = map.active_indices[i];
|
||||
printf("%d: %s\n", i, map.keys[index]);
|
||||
for (int i = 0; i < map->count; ++i) {
|
||||
size_t index = map->active_indices[i];
|
||||
printf("%d: %s\n", i, map->keys[index]);
|
||||
}
|
||||
}
|
||||
|
||||
void print_non_empty() {
|
||||
void print_non_empty(Hashmap *map) {
|
||||
for (int i = 0; i < MAX_OBJ_COUNT; ++i) {
|
||||
if (map.active_indices[i] != -1) {
|
||||
if (map->active_indices[i] != -1) {
|
||||
printf("%d is not set to -1\n", i);
|
||||
}
|
||||
}
|
||||
|
||||
+33
-17
@@ -5,9 +5,12 @@
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
struct object_store {
|
||||
size_t count;
|
||||
int32_t active_indices[MAX_OBJ_COUNT];
|
||||
Hashmap *map;
|
||||
void **object_ptrs;
|
||||
EventHandlerPtr *event_handlers;
|
||||
UpdateFuncPtr *update_funcs;
|
||||
@@ -15,19 +18,20 @@ struct object_store {
|
||||
};
|
||||
|
||||
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);
|
||||
// If allocating memory to the store fails, we just return NULL. No need to
|
||||
// continue with the rest of the function or to call any cleanup functions
|
||||
return NULL;
|
||||
}
|
||||
|
||||
os->map = create_hashmap();
|
||||
if (!(os->map)) {
|
||||
allocation_complete = false;
|
||||
}
|
||||
|
||||
os->count = 0;
|
||||
|
||||
os->object_ptrs = malloc(sizeof(void *) * MAX_OBJ_COUNT);
|
||||
@@ -70,7 +74,7 @@ ObjectStore *create_object_store() {
|
||||
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);
|
||||
int32_t index = add_object_to_map(os->map, object_tag);
|
||||
|
||||
if (index < 0) {
|
||||
return;
|
||||
@@ -89,7 +93,7 @@ void remove_object_from_store(ObjectStore *os, const char *object_tag) {
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t index = delete_object_from_map(object_tag);
|
||||
int32_t index = delete_object_from_map(os->map, object_tag);
|
||||
|
||||
if (index < 0) {
|
||||
return;
|
||||
@@ -132,8 +136,11 @@ void handle_all_objects_events(ObjectStore *os, const SDL_Event *event) {
|
||||
|
||||
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);
|
||||
|
||||
if (os->event_handlers[index]) {
|
||||
void *object = os->object_ptrs[index];
|
||||
(os->event_handlers[index])(event, object);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,8 +151,11 @@ void update_all_objects(ObjectStore *os, float delta) {
|
||||
|
||||
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);
|
||||
|
||||
if (os->update_funcs[index]) {
|
||||
void *object = os->object_ptrs[index];
|
||||
(os->update_funcs[index])(delta, object);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -156,14 +166,15 @@ void render_all_objects(ObjectStore *os, Renderer *renderer) {
|
||||
|
||||
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);
|
||||
|
||||
if (os->render_funcs[index]) {
|
||||
void *object = os->object_ptrs[index];
|
||||
(os->render_funcs[index])(renderer, object);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void destroy_object_store(ObjectStore *os) {
|
||||
destroy_hashmap();
|
||||
|
||||
if (!os) {
|
||||
return;
|
||||
}
|
||||
@@ -194,10 +205,15 @@ void destroy_object_store(ObjectStore *os) {
|
||||
os->object_ptrs = NULL;
|
||||
}
|
||||
|
||||
if (os->map) {
|
||||
destroy_hashmap(os->map);
|
||||
os->map = NULL;
|
||||
}
|
||||
|
||||
free(os);
|
||||
os = NULL;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_ENGINE
|
||||
void print_objects() { print_hashmap(); }
|
||||
void print_objects(ObjectStore *os) { print_hashmap(os->map); }
|
||||
#endif /* DEBUG_ENGINE */
|
||||
@@ -49,9 +49,14 @@ void fill_window_with_color(const Window *wnd, SDL_Color color) {
|
||||
void swap_render_buffers(const Window *wnd) { swap_buffers(wnd->renderer); }
|
||||
|
||||
void destroy_window(Window *wnd) {
|
||||
if (!wnd) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (wnd->SDL_base_window) {
|
||||
if (wnd->renderer) {
|
||||
destroy_renderer(wnd->renderer);
|
||||
wnd->renderer = NULL;
|
||||
}
|
||||
|
||||
SDL_DestroyWindow(wnd->SDL_base_window);
|
||||
|
||||
Reference in new issue
Block a user