diff --git a/Makefile b/Makefile index 4ef078d..dc9cbbc 100644 --- a/Makefile +++ b/Makefile @@ -27,6 +27,8 @@ SRC = src/engine/engine.c \ src/utility/my_strcmp.c \ src/utility/pow.c \ src/utility/read_line.c \ + src/utility/list.c \ + src/utility/tupple.c \ src/deserializer/deserialize_entity.c \ src/deserializer/prefab.c \ src/system.c \ diff --git a/include/engine.h b/include/engine.h index 38c20b9..21e8d12 100644 --- a/include/engine.h +++ b/include/engine.h @@ -30,6 +30,7 @@ struct gc_engine gc_list *systems; void (*add_system)(gc_engine *engine, const gc_system *system); const gc_system *(*get_system)(gc_engine *engine, const char *name); + gc_list *components; void (*add_component)(gc_engine *engine, const void *component); const void *(*get_component)(gc_engine *engine, const char *name); diff --git a/include/entity.h b/include/entity.h index 217594d..c9772a6 100644 --- a/include/entity.h +++ b/include/entity.h @@ -22,13 +22,11 @@ struct gc_entity bool (*has_component)(const gc_entity *entity, const char *name); char *(*serialize)(gc_entity *entity, int fd); void (*destroy)(gc_entity *entity); - - gc_entity *next; - gc_entity *prev; }; gc_entity *entity_create(void); gc_entity *entity_create_with_id(int id); -gc_entity *entity_add(gc_entity *list, gc_entity *entity); +gc_entity *entity_get(gc_scene *scene, int id); +int entity_add(gc_scene *scene, gc_entity *entity); gc_entity *entity_add_component(gc_entity *entity, void *component); char *entity_serialize(gc_entity *entity, int fd); \ No newline at end of file diff --git a/include/list.h b/include/list.h index e4ca8c8..d471961 100644 --- a/include/list.h +++ b/include/list.h @@ -13,4 +13,6 @@ struct gc_list { void *data; gc_list *next; -}; \ No newline at end of file +}; + +gc_list *list_add(gc_list *list, void *obj); \ No newline at end of file diff --git a/include/prefab.h b/include/prefab.h index 6b84084..1681762 100644 --- a/include/prefab.h +++ b/include/prefab.h @@ -9,7 +9,6 @@ #include "entity.h" -gc_entity *prefab_load(gc_engine *engine, const char *path); - +int prefab_load(gc_engine *engine, const char *path); gc_entity *deserialize_entity(gc_engine *engine, node *n); \ No newline at end of file diff --git a/include/scene.h b/include/scene.h index bb4d860..b1ade4d 100644 --- a/include/scene.h +++ b/include/scene.h @@ -11,14 +11,20 @@ typedef struct gc_scene gc_scene; #include "engine.h" #include "entity.h" #include "texture.h" +#include "list.h" +#include "tupple.h" #include struct gc_scene { - gc_entity *entities; gc_texture **textures; - int (*add_entity)(gc_scene *scene, gc_entity *entity); void (*destroy)(gc_scene *scene); + + gc_list *entities; + gc_tupple *entities_by_cmp; + int (*add_entity)(gc_scene *scene, gc_entity *entity); + gc_entity *(*get_entity)(gc_scene *scene, int id); + gc_list *(*get_entity_by_cmp)(gc_scene *scene, const char *cmp_name); }; gc_scene *scene_create(const char **textures); diff --git a/include/tupple.h b/include/tupple.h new file mode 100644 index 0000000..47c83e0 --- /dev/null +++ b/include/tupple.h @@ -0,0 +1,22 @@ +/* +** EPITECH PROJECT, 2019 +** MUL_my_runner_2019 +** File description: +** tupple +*/ + +typedef struct gc_tupple gc_tupple; + +#pragma once + +#include "list.h" +#include "entity.h" + +struct gc_tupple +{ + char *name; + gc_list *entities; + gc_tupple *next; +}; + +gc_tupple *tupple_add(gc_tupple *list, const char *name, gc_entity *entity); \ No newline at end of file diff --git a/src/deserializer/prefab.c b/src/deserializer/prefab.c index cdda201..0d8431e 100644 --- a/src/deserializer/prefab.c +++ b/src/deserializer/prefab.c @@ -14,15 +14,22 @@ #include #include -gc_entity *prefab_load(gc_engine *engine, const char *path) +int prefab_load(gc_engine *engine, const char *path) { - gc_entity *entity = NULL; - node *n = xml_parse(path); + node *n; + gc_entity *entity; + if (!engine || !engine->scene) + return (-1); + n = xml_parse(path); if (!n) - return (NULL); - for (node *ent_n = n->child; ent_n; ent_n = ent_n->next) - entity = entity_add(entity, deserialize_entity(engine, ent_n)); + return (-1); + for (node *ent_n = n->child; ent_n; ent_n = ent_n->next) { + entity = deserialize_entity(engine, ent_n); + if (!entity) + return (-1); + engine->scene->add_entity(engine->scene, entity); + } xml_destroy(n); - return (entity); + return (0); } diff --git a/src/engine/engine.c b/src/engine/engine.c index cb39058..9b7550f 100644 --- a/src/engine/engine.c +++ b/src/engine/engine.c @@ -12,22 +12,27 @@ #include #include -void update_entity(gc_engine *engine, gc_entity *entity, float dtime) +void update_system(gc_engine *engine, gc_system *sys, float dtime) { - for (gc_list *sys = engine->systems; sys; sys = sys->next) { - if (((gc_system *)sys->data)->check_dependencies(sys->data, entity)) - ((gc_system *)sys->data)->update_entity(engine, entity, dtime); + gc_scene *scene = engine->scene; + gc_list *entities; + + if (!scene) + return; + entities = scene->get_entity_by_cmp(scene, sys->component_name); + for (gc_list *entity = entities; entity; entity = entity->next) { + if (sys->check_dependencies(sys, entity->data)) + sys->update_entity(engine, entity->data, dtime); } } int game_loop(gc_engine *engine) { - gc_entity *entities = engine->scene->entities; float dtime = sfTime_asSeconds(sfClock_restart(engine->clock)); handle_events(engine); - for (gc_entity *entity = entities; entity; entity = entity->next) - update_entity(engine, entity, dtime); + for (gc_list *sys = engine->systems; sys; sys = sys->next) + update_system(engine, sys->data, dtime); engine->draw(engine); return (0); } diff --git a/src/engine/engine_component_builder.c b/src/engine/engine_component_builder.c index 1e0abdd..c19c9f6 100644 --- a/src/engine/engine_component_builder.c +++ b/src/engine/engine_component_builder.c @@ -15,23 +15,7 @@ void engine_add_component(gc_engine *engine, const void *component) { - gc_list *components = engine->components; - - if (!components) { - engine->components = malloc(sizeof(gc_list)); - if (!engine->components) - return; - engine->components->data = (void *)component; - engine->components->next = NULL; - } else { - while (components->next) - components = components->next; - components->next = malloc(sizeof(gc_list)); - if (!components->next) - return; - components->next->data = (void *)component; - components->next->next = NULL; - } + engine->components = list_add(engine->components, (void *)component); } void engine_add_buildin_components(gc_engine *engine) diff --git a/src/engine/engine_system_builder.c b/src/engine/engine_system_builder.c index 19fd389..d68c189 100644 --- a/src/engine/engine_system_builder.c +++ b/src/engine/engine_system_builder.c @@ -13,23 +13,7 @@ void engine_add_system(gc_engine *engine, const gc_system *system) { - gc_list *systems = engine->systems; - - if (!systems) { - engine->systems = malloc(sizeof(gc_list)); - if (!engine->systems) - return; - engine->systems->data = (void *)system; - engine->systems->next = NULL; - } else { - while (systems->next) - systems = systems->next; - systems->next = malloc(sizeof(gc_list)); - if (!systems->next) - return; - systems->next->data = (void *)system; - systems->next->next = NULL; - } + engine->systems = list_add(engine->systems, (void *)system); } void engine_add_buildin_systems(gc_engine *engine) diff --git a/src/entity/entity.c b/src/entity/entity.c index e2b8205..0aff1c0 100644 --- a/src/entity/entity.c +++ b/src/entity/entity.c @@ -10,6 +10,15 @@ #include #include +gc_entity *entity_get(gc_scene *scene, int id) +{ + for (gc_list *ent = scene->entities; ent; ent = ent->next) { + if (((gc_entity *)ent->data)->id == id) + return (ent->data); + } + return (NULL); +} + void *entity_get_component(const gc_entity *entity, const char *name) { for (gc_component *cmp = entity->components; cmp; cmp = cmp->next) { @@ -58,7 +67,5 @@ const gc_entity entity_prefab = { get_component: &entity_get_component, has_component: &entity_has_component, serialize: &entity_serialize, - destroy: &destroy, - next: NULL, - prev: NULL + destroy: &destroy }; \ No newline at end of file diff --git a/src/entity/entity_factory.c b/src/entity/entity_factory.c index 4196d39..b5e4335 100644 --- a/src/entity/entity_factory.c +++ b/src/entity/entity_factory.c @@ -35,19 +35,20 @@ gc_entity *entity_create_with_id(int id) return (entity); } -gc_entity *entity_add(gc_entity *list, gc_entity *entity) +int entity_add(gc_scene *scene, gc_entity *e) { - gc_entity *list_const = list; + char *name; - if (!list) { - return (entity); - } else { - while (list->next) - list = list->next; - list->next = entity; - entity->prev = list; - return (list_const); + scene->entities = list_add(scene->entities, e); + if (!scene->entities) + return (-1); + for (gc_component *cmp = e->components; cmp; cmp = cmp->next) { + name = cmp->name; + scene->entities_by_cmp = tupple_add(scene->entities_by_cmp, name, e); + if (!scene->entities_by_cmp) + return (-1); } + return (0); } gc_entity *entity_add_component(gc_entity *entity, void *component) diff --git a/src/scene/scene.c b/src/scene/scene.c index 4dddbd7..54e01aa 100644 --- a/src/scene/scene.c +++ b/src/scene/scene.c @@ -11,12 +11,13 @@ #include "utility.h" #include -int scene_add_entity(gc_scene *scene, gc_entity *entity) +gc_list *get_entity_by_cmp(gc_scene *scene, const char *cmp_name) { - if (!scene || !entity) - return (-1); - scene->entities = entity_add(scene->entities, entity); - return (0); + for (gc_tupple *tup = scene->entities_by_cmp; tup; tup = tup->next) { + if (!my_strcmp(tup->name, cmp_name)) + return (tup->entities); + } + return (NULL); } int scene_load_textures(gc_scene *scene, const char **textures) @@ -37,11 +38,11 @@ int scene_load_textures(gc_scene *scene, const char **textures) void scene_destroy(gc_scene *scene) { - gc_entity *next = NULL; + gc_list *next = NULL; - for (gc_entity *entity = scene->entities; entity; entity = next) { + for (gc_list *entity = scene->entities; entity; entity = next) { next = entity->next; - entity->destroy(entity); + ((gc_entity *)entity->data)->destroy(entity->data); } for (int i = 0; scene->textures[i]; i++) { scene->textures[i]->destroy(scene->textures[i]); @@ -59,7 +60,10 @@ gc_scene *scene_create(const char **textures) if (textures && scene_load_textures(scene, textures) < 0) return (NULL); scene->entities = NULL; - scene->add_entity = &scene_add_entity; + scene->entities_by_cmp = NULL; + scene->add_entity = &entity_add; + scene->get_entity = &entity_get; + scene->get_entity_by_cmp = &get_entity_by_cmp; scene->destroy = &scene_destroy; return (scene); } \ No newline at end of file diff --git a/src/utility/list.c b/src/utility/list.c new file mode 100644 index 0000000..da5154a --- /dev/null +++ b/src/utility/list.c @@ -0,0 +1,29 @@ +/* +** EPITECH PROJECT, 2019 +** MUL_my_runner_2019 +** File description: +** list +*/ + +#include "list.h" +#include + +gc_list *list_add(gc_list *list, void *obj) +{ + gc_list *listconst = list; + + if (!list) { + list = malloc(sizeof(gc_list)); + listconst = list; + } else { + while (list->next) + list = list->next; + list->next = malloc(sizeof(gc_list)); + list = list->next; + } + if (!list) + return (NULL); + list->data = obj; + list->next = NULL; + return (listconst); +} \ No newline at end of file diff --git a/src/utility/tupple.c b/src/utility/tupple.c new file mode 100644 index 0000000..5e6f67f --- /dev/null +++ b/src/utility/tupple.c @@ -0,0 +1,44 @@ +/* +** EPITECH PROJECT, 2019 +** MUL_my_runner_2019 +** File description: +** tupple +*/ + +#include "tupple.h" +#include "entity.h" +#include "utility.h" +#include + +static int tupple_add_existing(gc_tupple *l, const char *name, gc_entity *ent) +{ + while (l && my_strcmp(l->name, name)) + l = l->next; + if (!l) + return (-1); + l->entities = list_add(l->entities, ent); + return (0); +} + +gc_tupple *tupple_add(gc_tupple *list, const char *name, gc_entity *entity) +{ + gc_tupple *listconst = list; + + if (!list) { + list = malloc(sizeof(gc_tupple)); + listconst = list; + } else { + if (!tupple_add_existing(list, name, entity)) + return (listconst); + while (list->next) + list = list->next; + list->next = malloc(sizeof(gc_tupple)); + list = list->next; + } + if (!list) + return (NULL); + list->name = my_strdup(name); + list->entities = list_add(NULL, entity); + list->next = NULL; + return (listconst); +} \ No newline at end of file