diff --git a/src/game_world.c b/src/game_world.c new file mode 100644 index 0000000..a8fed34 --- /dev/null +++ b/src/game_world.c @@ -0,0 +1,80 @@ +#include "game_world.h" + +#include "behaviour_entity.h" +#include "list.h" +#include "program.h" + +static List _add_queue; +static List _remove_queue; +static List _game_entities; + +static inline +size_t _internal_find_index_for_entity(void* data, const List* list) { + for(size_t i = 0; i < _game_entities.len; ++i) { + BehaviourEntity* entity = list_at_as(BehaviourEntity, &_game_entities, i); + if(entity->data == entity) { + return i; + } + } + + return list->len; +} + +static inline +void _internal_clear_removed() { + list_foreach(size_t, index, &_remove_queue) { + BehaviourEntity* entity = list_at_as(BehaviourEntity, &_game_entities, *index); + entity->drop->drop(entity->data); + list_erase(&_game_entities, *index); + } + list_empty(&_remove_queue); +} + +static inline +void _internal_process_new() { + list_foreach(BehaviourEntity, entity, &_add_queue) { + list_add(&_game_entities, entity); + entity->tc->start(entity->data); + } + list_empty(&_add_queue); +} + +void game_world_init() { + _game_entities = list_from_type(BehaviourEntity); + _add_queue = list_from_type(BehaviourEntity); + _remove_queue = list_from_type(size_t); +} + +void game_world_close() { + _internal_clear_removed(); + _internal_process_new(); + list_foreach(BehaviourEntity, entity, &_game_entities) { + entity->drop->drop(entity->data); + } + list_empty(&_game_entities); +} + +void game_world_add_entity(BehaviourEntity entity) { + list_add(&_add_queue, &entity); +} + +void game_world_remove_entity(void* entity) { + size_t index = _internal_find_index_for_entity(entity, &_game_entities); + if(index != _game_entities.len) { + list_add(&_remove_queue, &index); + } +} + +void game_world_update() { + _internal_process_new(); + list_foreach(BehaviourEntity, entity, &_game_entities) { + entity->tc->update(entity->data, delta_time()); + } + _internal_clear_removed(); +} + +void game_word_draw() { + list_foreach(BehaviourEntity, entity, &_game_entities) { + entity->tc->draw(entity->data); + } +} diff --git a/src/game_world.h b/src/game_world.h new file mode 100644 index 0000000..d35c7d2 --- /dev/null +++ b/src/game_world.h @@ -0,0 +1,15 @@ +#ifndef _fencer_game_world_h +#define _fencer_game_world_h + +#include "behaviour_entity.h" + +extern void game_world_init(); +extern void game_world_close(); + +extern void game_world_add_entity(BehaviourEntity entity); +extern void game_world_remove_entity(void* entity); + +extern void game_world_update(); +extern void game_world_draw(); + +#endif // !_fencer_game_world_h