Compare commits

..

No commits in common. "95167c91e8713cf05e9bade6c978903e9f0bdb39" and "4a93ca2a9d77eeb65ac51bba13560258d83fe772" have entirely different histories.

10 changed files with 131 additions and 97 deletions

View File

@ -2,7 +2,6 @@
#include <stdarg.h>
#include <string.h>
#include "game.h"
#include "linked_list.h"
#include "texture.h"
#include "memory_alloc.h"
@ -23,7 +22,7 @@ int destroy_asset(asset_t *asset)
switch(asset->type)
{
case ASSET_TEXTURE:
destroy_texture(asset->data);
SDL_DestroyTexture(asset->data);
break;
default:
@ -41,63 +40,67 @@ int destroy_asset_header_def(asset_header_def_t *asset_header_def)
return EXIT_SUCCESS;
}
int asset_manager_init(void)
int asset_manager_init(asset_manager_t *asset_manager)
{
linked_list_init(&game.asset_manager.assets, sizeof(asset_t), (allocator_t)create_asset, (deleter_t)destroy_asset);
linked_list_init(&game.asset_manager.assets_header_defs, sizeof(asset_header_def_t), NULL, (deleter_t)destroy_asset_header_def);
assert("Asset manager cannot be NULL" && asset_manager);
game.asset_manager.asset_file = fopen(ASSET_FILE_NAME, "rb");
if(!game.asset_manager.asset_file)
linked_list_init(&asset_manager->assets, sizeof(asset_t), (allocator_t)create_asset, (deleter_t)destroy_asset);
linked_list_init(&asset_manager->assets_header_defs, sizeof(asset_header_def_t), NULL, (deleter_t)destroy_asset_header_def);
asset_manager->asset_file = fopen(ASSET_FILE_NAME, "rb");
if(!asset_manager->asset_file)
{
error_printf("Failed to open asset file : %d", errno);
return EXIT_FAILURE;
}
size_t nb_assets;
size_t ret = fread(&nb_assets, sizeof(nb_assets), 1, game.asset_manager.asset_file);
size_t ret = fread(&nb_assets, sizeof(nb_assets), 1, asset_manager->asset_file);
if(ret != 1)
{
error_printf("Failed to read asset file.");
return EXIT_FAILURE;
}
if(linked_list_reserve(&game.asset_manager.assets_header_defs, nb_assets + 1)) return_failure_int;
if(linked_list_reserve(&asset_manager->assets_header_defs, nb_assets + 1)) return_failure_int;
for(size_t i = 0; i < nb_assets; i++)
{
elem_t *asset_header_def_elem = create_elem(&game.asset_manager.assets_header_defs);
elem_t *asset_header_def_elem = create_elem(&asset_manager->assets_header_defs);
if(!asset_header_def_elem) return_failure_int;
asset_header_def_t *asset_header_def = asset_header_def_elem->data;
size_t cap = 0;
ret = getdelim(&asset_header_def->name, &cap, '\0', game.asset_manager.asset_file);
ret = getdelim(&asset_header_def->name, &cap, '\0', asset_manager->asset_file);
if(ret == SIZE_MAX)
{
error_printf("Failed to read asset file.");
return EXIT_FAILURE;
}
ret = fread(&asset_header_def->start, sizeof(asset_header_def->start), 1, game.asset_manager.asset_file);
ret = fread(&asset_header_def->start, sizeof(asset_header_def->start), 1, asset_manager->asset_file);
if(ret != 1)
{
error_printf("Failed to read asset file.");
return EXIT_FAILURE;
}
linked_list_push_back(&game.asset_manager.assets_header_defs, asset_header_def_elem);
linked_list_push_back(&asset_manager->assets_header_defs, asset_header_def_elem);
}
debug_printf("Initialized asset manager.");
return EXIT_SUCCESS;
}
int asset_manager_exit(void)
int asset_manager_exit(asset_manager_t *asset_manager)
{
if(linked_list_exit(&game.asset_manager.assets_header_defs)) return_failure_int;
if(linked_list_exit(&game.asset_manager.assets)) return_failure_int;
assert("Asset manager cannot be NULL" && asset_manager);
if(fclose(game.asset_manager.asset_file))
if(linked_list_exit(&asset_manager->assets_header_defs)) return_failure_int;
if(linked_list_exit(&asset_manager->assets)) return_failure_int;
if(fclose(asset_manager->asset_file))
{
error_printf("Failed to close asset file : %d", errno);
return EXIT_FAILURE;
@ -114,9 +117,11 @@ static inline bool condition_is_asset_unused(elem_t *elem, va_list args __attrib
return !((asset_t *)elem->data)->nb_refs;
}
inline int asset_manager_collect_garbage(void)
inline int asset_manager_collect_garbage(asset_manager_t *asset_manager)
{
if(linked_list_remove_if(&game.asset_manager.assets, condition_is_asset_unused)) return_failure_int;
assert("Asset manager cannot be NULL" && asset_manager);
if(linked_list_remove_if(&asset_manager->assets, condition_is_asset_unused)) return_failure_int;
return EXIT_SUCCESS;
}
@ -135,10 +140,12 @@ static inline bool condition_is_asset_header_def_name(elem_t *elem, va_list args
return !strcmp(((asset_header_def_t *)elem->data)->name, va_arg(args, const char *));
}
asset_t *asset_manager_load_asset(const char *asset_name, asset_type_t asset_type)
asset_t *asset_manager_load_asset(asset_manager_t *asset_manager, const char *asset_name, asset_type_t asset_type)
{
assert("Asset manager cannot be NULL" && asset_manager);
// Check if asset has alread been loaded.
elem_t *asset_elem = linked_list_get_if(&game.asset_manager.assets, condition_is_asset_name, asset_name);
elem_t *asset_elem = linked_list_get_if(&asset_manager->assets, condition_is_asset_name, asset_name);
if(asset_elem)
{
((asset_t *)asset_elem->data)->nb_refs++;
@ -148,7 +155,7 @@ asset_t *asset_manager_load_asset(const char *asset_name, asset_type_t asset_typ
else
{
// If it didn't, load it
elem_t *asset_header_def_elem = linked_list_get_if(&game.asset_manager.assets_header_defs, condition_is_asset_header_def_name, asset_name);
elem_t *asset_header_def_elem = linked_list_get_if(&asset_manager->assets_header_defs, condition_is_asset_header_def_name, asset_name);
if(!asset_header_def_elem)
{
error_printf("Asset doesn't exist in asset file : %s", asset_name);
@ -156,7 +163,7 @@ asset_t *asset_manager_load_asset(const char *asset_name, asset_type_t asset_typ
}
asset_header_def_t *asset_header_def = asset_header_def_elem->data;
asset_elem = create_elem(&game.asset_manager.assets, asset_type);
asset_elem = create_elem(&asset_manager->assets, asset_type);
if(!asset_elem) return_failure_ptr;
asset_t *asset = asset_elem->data;
@ -170,7 +177,7 @@ asset_t *asset_manager_load_asset(const char *asset_name, asset_type_t asset_typ
strcpy(asset->name, asset_name);
asset->type = asset_type;
if(fseek(game.asset_manager.asset_file, asset_header_def->start, SEEK_SET))
if(fseek(asset_manager->asset_file, asset_header_def->start, SEEK_SET))
{
error_printf("Failed to seek in asset file : %d", errno);
return NULL;
@ -179,7 +186,7 @@ asset_t *asset_manager_load_asset(const char *asset_name, asset_type_t asset_typ
switch(asset_type)
{
case ASSET_TEXTURE:
asset->data = texture_load(game.asset_manager.asset_file);
asset->data = texture_load(asset_manager->asset_file);
if(!asset->data) return_failure_ptr;
break;
@ -191,7 +198,7 @@ asset_t *asset_manager_load_asset(const char *asset_name, asset_type_t asset_typ
asset->nb_refs++;
linked_list_push_back(&game.asset_manager.assets, asset_elem);
linked_list_push_back(&asset_manager->assets, asset_elem);
debug_printf("Asset \"%s\" has been loaded.", asset->name);
}
@ -199,9 +206,11 @@ asset_t *asset_manager_load_asset(const char *asset_name, asset_type_t asset_typ
return asset_elem->data;
}
int asset_manager_let_go_asset(const char *asset_name)
int asset_manager_let_go_asset(asset_manager_t *asset_manager, const char *asset_name)
{
elem_t *asset_elem = linked_list_get_if(&game.asset_manager.assets, condition_is_asset_name, asset_name);
assert("Asset manager cannot be NULL" && asset_manager);
elem_t *asset_elem = linked_list_get_if(&asset_manager->assets, condition_is_asset_name, asset_name);
if(!asset_elem)
{
error_printf("Asset doesn't exists : %s", asset_name);
@ -217,9 +226,11 @@ int asset_manager_let_go_asset(const char *asset_name)
return EXIT_SUCCESS;
}
asset_t *asset_manager_get_asset(const char *texture_name)
asset_t *asset_manager_get_asset(asset_manager_t *asset_manager, const char *texture_name)
{
elem_t *asset_elem = linked_list_get_if(&game.asset_manager.assets, condition_is_asset_name, texture_name);
assert("Asset manager cannot be NULL" && asset_manager);
elem_t *asset_elem = linked_list_get_if(&asset_manager->assets, condition_is_asset_name, texture_name);
if(!asset_elem)
{
error_printf("Asset \"%s\" hasn't been loaded yet.", texture_name);

View File

@ -1,9 +1,7 @@
#include "ecs.h"
#include <stdarg.h>
#include "game.h"
#include "components.h"
#include "memory_alloc.h"
#include "ecs.h"
#include "components.h"
#include "errors.h"
int create_component(component_t *component, va_list args)
@ -128,19 +126,23 @@ inline int draw_entity(entity_t *entity)
return EXIT_SUCCESS;
}
inline void entity_manager_init(void)
inline void entity_manager_init(entity_manager_t *entity_manager)
{
linked_list_init(&game.entity_manager.entities, sizeof(entity_t), (allocator_t)create_entity, (deleter_t)destroy_entity);
assert("Entity manager cannot be NULL" && entity_manager);
linked_list_init(&entity_manager->entities, sizeof(entity_t), (allocator_t)create_entity, (deleter_t)destroy_entity);
debug_printf("Initialized entity manager.");
}
inline entity_t *entity_manager_new_entity(size_t id)
inline entity_t *entity_manager_new_entity(entity_manager_t *entity_manager, size_t id)
{
elem_t *entity_elem = create_elem(&game.entity_manager.entities, id);
assert("Entity manager cannot be NULL" && entity_manager);
elem_t *entity_elem = create_elem(&entity_manager->entities, id);
if(!entity_elem) return_failure_ptr;
linked_list_push_back(&game.entity_manager.entities, entity_elem);
linked_list_push_back(&entity_manager->entities, entity_elem);
debug_printf("Added entity %lu to entity manager.", id);
@ -153,9 +155,11 @@ static inline int action_update_entity(elem_t *elem, va_list args __attribute__(
return update_entity((entity_t *)elem->data);
}
inline int entity_manager_update(void)
inline int entity_manager_update(entity_manager_t *entity_manager)
{
if(linked_list_for_each(&game.entity_manager.entities, action_update_entity)) return_failure_int;
assert("Entity manager cannot be NULL" && entity_manager);
if(linked_list_for_each(&entity_manager->entities, action_update_entity)) return_failure_int;
return EXIT_SUCCESS;
}
@ -173,11 +177,13 @@ static inline bool condition_is_draw_priority_higher(elem_t *elem, va_list args
return ((entity_t *)elem->data)->draw_priority > ((entity_t *)elem->next->data)->draw_priority;
}
inline int entity_manager_draw(void)
inline int entity_manager_draw(entity_manager_t *entity_manager)
{
linked_list_insertion_sort(&game.entity_manager.entities, condition_is_draw_priority_higher);
assert("Entity manager cannot be NULL" && entity_manager);
if(linked_list_for_each(&game.entity_manager.entities, action_draw_entity)) return_failure_int;
linked_list_insertion_sort(&entity_manager->entities, condition_is_draw_priority_higher);
if(linked_list_for_each(&entity_manager->entities, action_draw_entity)) return_failure_int;
return EXIT_SUCCESS;
}
@ -189,16 +195,20 @@ static inline bool condition_is_entity_name(elem_t *elem, va_list args)
return ((entity_t *)elem->data)->id == va_arg(args, unsigned int);
}
inline int entity_manager_remove_entity(unsigned int id)
inline int entity_manager_remove_entity(entity_manager_t *entity_manager, unsigned int id)
{
if(linked_list_remove_if(&game.entity_manager.entities, condition_is_entity_name, id)) return_failure_int;
assert("Entity manager cannot be NULL" && entity_manager);
if(linked_list_remove_if(&entity_manager->entities, condition_is_entity_name, id)) return_failure_int;
return EXIT_SUCCESS;
}
inline int entity_manager_exit(void)
inline int entity_manager_exit(entity_manager_t *entity_manager)
{
if(linked_list_exit(&game.entity_manager.entities)) return_failure_int;
assert("Entity manager cannot be NULL" && entity_manager);
if(linked_list_exit(&entity_manager->entities)) return_failure_int;
debug_printf("Exited entity manager.");

View File

@ -1,7 +1,6 @@
#include "event_bus.h"
#include <stdlib.h>
#include "game.h"
#include "linked_list.h"
#include "memory_alloc.h"
#include "errors.h"
@ -32,27 +31,27 @@ inline int destroy_topic(topic_t *topic)
return EXIT_SUCCESS;
}
inline void event_bus_init(void)
inline void event_bus_init(event_bus_t *event_bus)
{
linked_list_init(&game.event_bus.topics, sizeof(topic_t), (allocator_t)create_topic, (deleter_t)destroy_topic);
linked_list_init(&event_bus->topics, sizeof(topic_t), (allocator_t)create_topic, (deleter_t)destroy_topic);
debug_printf("Initialized event bus.");
}
inline int event_bus_exit(void)
inline int event_bus_exit(event_bus_t *event_bus)
{
if(linked_list_exit(&game.event_bus.topics)) return_failure_int;
if(linked_list_exit(&event_bus->topics)) return_failure_int;
debug_printf("Exited event bus.");
return EXIT_SUCCESS;
}
int event_bus_new_topic(size_t id)
int event_bus_new_topic(event_bus_t *event_bus, size_t id)
{
elem_t *topic_elem = create_elem(&game.event_bus.topics, id);
elem_t *topic_elem = create_elem(&event_bus->topics, id);
if(!topic_elem) return_failure_int;
linked_list_push_back(&game.event_bus.topics, topic_elem);
linked_list_push_back(&event_bus->topics, topic_elem);
debug_printf("Created new topic with id : %lu", id);
@ -65,16 +64,16 @@ static inline bool condition_is_topic_id(elem_t *elem, va_list args)
return ((topic_t *)elem->data)->id == va_arg(args, size_t);
}
inline int event_bus_remove_topic(size_t id)
inline int event_bus_remove_topic(event_bus_t *event_bus, size_t id)
{
if(linked_list_remove_if(&game.event_bus.topics, condition_is_topic_id, id)) return_failure_int;
if(linked_list_remove_if(&event_bus->topics, condition_is_topic_id, id)) return_failure_int;
return EXIT_SUCCESS;
}
int event_bus_change_topic_id(size_t old_id, size_t new_id)
int event_bus_change_topic_id(event_bus_t *event_bus, size_t old_id, size_t new_id)
{
elem_t *topic_elem = linked_list_get_if(&game.event_bus.topics, condition_is_topic_id, old_id);
elem_t *topic_elem = linked_list_get_if(&event_bus->topics, condition_is_topic_id, old_id);
if(!topic_elem) return_failure_int;
topic_t *topic = topic_elem->data;
@ -98,9 +97,9 @@ static int action_execute_callback(elem_t *elem, va_list args)
return EXIT_SUCCESS;
}
int event_bus_publish(size_t id, ...)
int event_bus_publish(event_bus_t *event_bus, size_t id, ...)
{
elem_t *topic_elem = linked_list_get_if(&game.event_bus.topics, condition_is_topic_id, id);
elem_t *topic_elem = linked_list_get_if(&event_bus->topics, condition_is_topic_id, id);
if(!topic_elem) return_failure_int;
topic_t *topic = topic_elem->data;
@ -119,9 +118,9 @@ int event_bus_publish(size_t id, ...)
return EXIT_SUCCESS;
}
int event_bus_subscribe(size_t id, callback_t callback, void *data)
int event_bus_subscribe(event_bus_t *event_bus, size_t id, callback_t callback, void *data)
{
elem_t *topic_elem = linked_list_get_if(&game.event_bus.topics, condition_is_topic_id, id);
elem_t *topic_elem = linked_list_get_if(&event_bus->topics, condition_is_topic_id, id);
if(!topic_elem) return_failure_int;
topic_t *topic = topic_elem->data;
@ -142,9 +141,9 @@ static inline bool condition_is_callback(elem_t *elem, va_list args)
return ((subscription_t *)elem->data)->callback == va_arg(args, callback_t);
}
int event_bus_unsubscribe(size_t id, callback_t callback)
int event_bus_unsubscribe(event_bus_t *event_bus, size_t id, callback_t callback)
{
elem_t *topic_elem = linked_list_get_if(&game.event_bus.topics, condition_is_topic_id, id);
elem_t *topic_elem = linked_list_get_if(&event_bus->topics, condition_is_topic_id, id);
if(!topic_elem) return_failure_int;
topic_t *topic = topic_elem->data;

View File

@ -19,6 +19,7 @@ typedef struct asset_t {
} asset_t;
int create_asset(asset_t *asset, va_list args);
int destroy_asset(asset_t *asset);
typedef struct asset_header_def_t {
@ -34,12 +35,13 @@ typedef struct asset_manager_t {
FILE *asset_file;
} asset_manager_t;
int asset_manager_init(void);
int asset_manager_exit(void);
int asset_manager_collect_garbage(void);
int asset_manager_init(asset_manager_t *asset_manager);
int asset_manager_exit(asset_manager_t *asset_manager);
int asset_manager_collect_garbage(asset_manager_t *asset_manager);
asset_t *asset_manager_load_asset(const char *asset_name, asset_type_t asset_type);
int asset_manager_let_go_asset(const char *asset_name);
asset_t *asset_manager_get_asset(const char *asset_name);
asset_t *asset_manager_load_asset(asset_manager_t *asset_manager, const char *asset_name, asset_type_t asset_type);
int asset_manager_let_go_asset(asset_manager_t *asset_manager, const char *asset_name);
asset_t *asset_manager_get_asset(asset_manager_t *asset_manager, const char *asset_name);
#endif // ASSET_MANAGER_H

View File

@ -38,6 +38,7 @@ typedef struct component_t {
} component_t;
int create_component(component_t *component, va_list args);
int destroy_component(component_t *component);
typedef struct entity_t {
@ -47,23 +48,31 @@ typedef struct entity_t {
} entity_t;
int create_entity(entity_t *entity, va_list args);
int destroy_entity(entity_t *entity);
component_t *entity_new_component(entity_t *entity, component_type_t component_type);
int update_entity(entity_t *entity);
int draw_entity(entity_t *entity);
component_t *entity_get_component(const entity_t *entity, component_type_t component_type);
int update_entity(entity_t *entity);
int draw_entity(entity_t *entity);
typedef struct entity_manager_t {
linked_list_t entities;
} entity_manager_t;
void entity_manager_init(void);
int entity_manager_exit(void);
void entity_manager_init(entity_manager_t *entity_manager);
entity_t *entity_manager_new_entity(size_t id);
int entity_manager_update(void);
int entity_manager_draw(void);
int entity_manager_remove_entity(const unsigned int id);
entity_t *entity_manager_new_entity(entity_manager_t *entity_manager, size_t id);
int entity_manager_update(entity_manager_t *entity_manager);
int entity_manager_draw(entity_manager_t *entity_manager);
int entity_manager_remove_entity(entity_manager_t *entity_manager, const unsigned int id);
int entity_manager_exit(entity_manager_t *entity_manager);
#endif // ECS_H

View File

@ -12,11 +12,11 @@
#if DEBUG > 0
#define debug_printf(...) \
do { \
fprintf(stderr, "\033[32mINFO\033[m: " __VA_ARGS__); \
fprintf(stderr, "\033[33mINFO\033[m: " __VA_ARGS__); \
fputc('\n', stderr); \
} while (0)
#else
#define debug_printf(...)
#define debug_printf(...) do {} while (0)
#endif
#define warning_printf(...) \

View File

@ -25,15 +25,15 @@ typedef struct event_bus_t {
linked_list_t topics;
} event_bus_t;
void event_bus_init(void);
int event_bus_exit(void);
void event_bus_init(event_bus_t *event_bus);
int event_bus_exit(event_bus_t *event_bus);
int event_bus_new_topic(size_t id);
int event_bus_remove_topic(size_t id);
int event_bus_change_topic_id(size_t old_id, size_t new_id);
int event_bus_new_topic(event_bus_t *event_bus, size_t id);
int event_bus_remove_topic(event_bus_t *event_bus, size_t id);
int event_bus_change_topic_id(event_bus_t *event_bus, size_t old_id, size_t new_id);
int event_bus_publish(size_t id, ...);
int event_bus_subscribe(size_t id, callback_t callback, void *data);
int event_bus_unsubscribe(size_t id, callback_t callback);
int event_bus_publish(event_bus_t *event_bus, size_t id, ...);
int event_bus_subscribe(event_bus_t *event_bus, size_t id, callback_t callback, void *data);
int event_bus_unsubscribe(event_bus_t *event_bus, size_t id, callback_t callback);
#endif // EVENT_BUS_H

View File

@ -27,13 +27,22 @@ typedef struct game_t {
bool is_running;
} game_t;
// Global game instance
extern game_t game;
// Initialise game
int game_init(void);
int game_exit(void);
// Handle event like inputs
void game_handle_event(void);
// Update game
int game_update(void);
// Render game
int game_render(void);
// Free game instance
int game_exit(void);
#endif // GAME_H

View File

@ -7,6 +7,5 @@
typedef SDL_Texture texture_t;
texture_t *texture_load(FILE *asset_file);
void destroy_texture(texture_t *texture);
#endif // TEXTURE_H

View File

@ -60,8 +60,3 @@ texture_t *texture_load(FILE *asset_file)
return texture;
}
void destroy_texture(texture_t *texture)
{
SDL_DestroyTexture(texture);
}