diff --git a/.clangd b/.clangd index 35c56ef..12a9740 100644 --- a/.clangd +++ b/.clangd @@ -1,9 +1,9 @@ If: PathMatch: [.*\.h, .*\.c] CompileFlags: - Add: [-xc, -DWIN32_LEAN_AND_MEAN, -I/home/edgar/Codes/JacksEscape/easyx/include, -target, x86_64-pc-windows-gnu] + Add: [-xc, -Wall, -DWIN32_LEAN_AND_MEAN, -I/home/edgar/Codes/JacksEscape/easyx/include, -target, x86_64-pc-windows-gnu] --- If: PathMatch: [.*\.hpp, .*\.cpp] CompileFlags: - Add: [-xc++, -DWIN32_LEAN_AND_MEAN, -I/home/edgar/Codes/JacksEscape/easyx/include, -target, x86_64-pc-windows-gnu] + Add: [-xc++, -Wall, -DWIN32_LEAN_AND_MEAN, -I/home/edgar/Codes/JacksEscape/easyx/include, -target, x86_64-pc-windows-gnu] diff --git a/App.c b/App.c index ed61454..139679b 100644 --- a/App.c +++ b/App.c @@ -1,5 +1,6 @@ #include "App.h" +#include "Entity.h" #include "Input.h" #include "Physics_Component.h" #include "Player_Component.h" @@ -12,12 +13,14 @@ App *app_NewApp() { app->input = input_NewSystem(app); app->physics = physics_NewSystem(app); app->player = player_NewSystem(app); + app->entity = entity_NewSystem(app); return app; } void app_DeleteApp(App *app) { input_DeleteSystem(app->input); + entity_DeleteSystem(app->entity); physics_DeleteSystem(app->physics); player_DeleteSystem(app->player); @@ -29,4 +32,5 @@ void app_Advance(App *app, Duration deltaTime) { input_Advance(app->input); player_Advance(app->player, deltaTime); physics_Advance(app->physics, deltaTime); + entity_Advance(app->entity, deltaTime); } diff --git a/App.h b/App.h index 7ae70c4..713d451 100644 --- a/App.h +++ b/App.h @@ -11,6 +11,7 @@ typedef struct _App { System_Physics *physics; System_Player *player; System_Input *input; + System_Entity *entity; } App; App *app_NewApp(); diff --git a/App_Render.cpp b/App_Render.cpp new file mode 100644 index 0000000..4fb57d5 --- /dev/null +++ b/App_Render.cpp @@ -0,0 +1,7 @@ + +#include "App.h" +#include + + +void app_Render() { +} diff --git a/Entity.c b/Entity.c new file mode 100644 index 0000000..a9b69e1 --- /dev/null +++ b/Entity.c @@ -0,0 +1,112 @@ + +#include "Entity.h" +#include "App.h" +#include "Physics_Component.h" +#include "util/assert.h" +#include "util/tree.h" +#include "util/vector.h" +#include +#include +#include + + +System_Entity *entity_NewSystem(App *super) { + System_Entity *sys = malloc(sizeof(System_Entity)); + + sys->entities = tree_Create(sizeof(Entity)); + sys->maxID = 0; + sys->super = super; + sys->flaggedDelete = vector_Create(sizeof(uintptr_t)); + + return sys; +} + +void entity_DeleteSystem(System_Entity *sys) { + for (tree_Node *i = tree_FirstNode(sys->entities); + i != NULL; + i = tree_Node_Next(i)) { + Entity *e = (Entity *)(i->data); + + physics_DeleteEntity(sys->super->physics, e->id); + player_DeleteEntity(sys->super->player, e->id); + + if (e->position) + free(e->position); + if (e->hitbox) + free(e->hitbox); + if (e->player) + free(e->player); + if (e->name) + free(e->name); + } + + tree_Destroy(sys->entities); + vector_Destroy(sys->flaggedDelete); +} + + +Entity *entity_Create(System_Entity *sys, const char *name) { + uintptr_t id = ++sys->maxID; + + bool added = false; + Entity *e = (Entity *)(tree_Insert(sys->entities, id, &added)); + ASSERT(added && "entity ID conflict in entity_Create"); + + memset(e, 0, sizeof(Entity)); + e->id = id; + + size_t len; + if (name && (len = strlen(name)) > 0) { + e->name = malloc(len + 1); + memcpy(e->name, name, len + 1); + } + + return e; +} + + +static inline void _entity_Delete(System_Entity *sys, uintptr_t id) { + tree_Node *node = tree_FindNode(sys->entities, id); + if (!node) { + fprintf(stderr, "[entity_Delete][WARN] Missing entity ID [%d]\n", id); + return; + } + Entity *e = (Entity *)(node->data); + + fprintf(stderr, "[entity_Delete] Deleting \"%s\"[%d]\n", e->name, e->id); + + physics_DeleteEntity(sys->super->physics, e->id); + player_DeleteEntity(sys->super->player, e->id); + + if (e->position) + free(e->position); + if (e->hitbox) + free(e->hitbox); + if (e->player) + free(e->player); + if (e->name) + free(e->name); + + tree_Delete(sys->entities, node); +} + +void entity_Delete(System_Entity *sys, uintptr_t id) { + vector_Push(sys->flaggedDelete, &id); +} + + +void entity_Advance(System_Entity *sys, Duration deltaTime) { + // Delete flagged entities + for (int i = 0; i < vector_Size(sys->flaggedDelete); i++) { + _entity_Delete(sys, *(uintptr_t *)(vector_At(sys->flaggedDelete, i))); + } + + for (tree_Node *i = tree_FirstNode(sys->entities); + i != NULL; + i = tree_Node_Next(i)) { + Entity *e = (Entity *)(i->data); + + if (e->thinker) + e->thinker(e, deltaTime); + } +} diff --git a/Entity.h b/Entity.h index f61cd18..e34f0ad 100644 --- a/Entity.h +++ b/Entity.h @@ -1,7 +1,9 @@ #pragma once #include +#include "Types.h" #include "util/vector.h" +#include "util/tree.h" #include "Physics_Component.h" #include "Player_Component.h" @@ -11,17 +13,44 @@ extern "C" { #endif +typedef struct _Entity Entity; +typedef void (*entity_Thinker)(Entity *e, Duration deltaTime); // The Thinker function type assigned to Entities + + // Entity. typedef struct _Entity { uintptr_t id; - char *name; + char *name; // Allocated on the stack & copied Component_Position *position; Component_Hitbox *hitbox; Component_Player *player; + + entity_Thinker thinker; // Called by System_Entity each frame if not NULL. + void *thinkerData; // Data managed by the Thinker, if exists. } Entity; +typedef struct _App App; + +// Entity manager. +typedef struct { + App *super; + tree_Tree *entities; // Contains Entity objects on the nodes + uintptr_t maxID; + + vector_Vector *flaggedDelete; +} System_Entity; + +System_Entity *entity_NewSystem(App *super); +void entity_DeleteSystem(System_Entity *sys); + +Entity *entity_Create(System_Entity *sys, const char *name); +void entity_Delete(System_Entity *sys, uintptr_t id); + +void entity_Advance(System_Entity *sys, Duration deltaTime); + + #ifdef __cplusplus } #endif diff --git a/Input.c b/Input.c index 00660bf..2a4ef77 100644 --- a/Input.c +++ b/Input.c @@ -19,7 +19,9 @@ void input_SetDefaultKeymap(System_Input *sys) { System_Input *input_NewSystem(App *super) { System_Input *sys = malloc(sizeof(System_Input)); - sys->super = super; + memset(sys, 0, sizeof(System_Input)); + sys->super = super; + input_SetDefaultKeymap(sys); return sys; } diff --git a/Input.h b/Input.h index c30d414..79aef19 100644 --- a/Input.h +++ b/Input.h @@ -36,10 +36,10 @@ const char *input_KeyNames[input_Key_Count] = { // States a key might in typedef enum { - Pressed, - JustPressed, Released, - JustReleased + JustReleased, + Pressed, + JustPressed } input_KeyState; static inline bool input_IsPressed(input_KeyState state) { return state == Pressed || state == JustPressed; } diff --git a/Physics_Component.c b/Physics_Component.c index 89eff94..149802f 100644 --- a/Physics_Component.c +++ b/Physics_Component.c @@ -28,9 +28,8 @@ System_Physics *physics_NewSystem(App *super) { System_Physics *sys = malloc(sizeof(System_Physics)); sys->super = super; - sys->pos = tree_Create(sizeof(uintptr_t)); - sys->hit = tree_Create(sizeof(uintptr_t)); - sys->flaggedDelete = vector_Create(sizeof(uintptr_t)); + sys->pos = tree_Create(sizeof(uintptr_t)); + sys->hit = tree_Create(sizeof(uintptr_t)); return sys; } @@ -38,7 +37,6 @@ System_Physics *physics_NewSystem(App *super) { void physics_DeleteSystem(System_Physics *sys) { tree_Destroy(sys->pos); tree_Destroy(sys->hit); - vector_Destroy(sys->flaggedDelete); } @@ -52,7 +50,13 @@ void physics_AddEntity(System_Physics *sys, Entity *e) { } void physics_DeleteEntity(System_Physics *sys, uintptr_t id) { - vector_Push(sys->flaggedDelete, &id); + tree_Node *n; + n = tree_FindNode(sys->pos, id); + if (n) + tree_Delete(sys->pos, n); + n = tree_FindNode(sys->hit, id); + if (n) + tree_Delete(sys->hit, n); } @@ -82,20 +86,6 @@ static inline void _physics_AdvanceEntity(System_Physics *sys, Entity *e, Durati void physics_Advance(System_Physics *sys, Duration deltaTime) { - // Delete flagged entities - while (vector_Size(sys->flaggedDelete)) { - uintptr_t id; - vector_Pop(sys->flaggedDelete, &id); - - tree_Node *n; - n = tree_FindNode(sys->pos, id); - if (n) - tree_Delete(sys->pos, n); - n = tree_FindNode(sys->hit, id); - if (n) - tree_Delete(sys->hit, n); - } - for (tree_Node *i = tree_FirstNode(sys->pos); i != NULL; i = tree_Node_Next(i)) { diff --git a/Physics_Component.h b/Physics_Component.h index 362485d..6f7d306 100644 --- a/Physics_Component.h +++ b/Physics_Component.h @@ -53,8 +53,7 @@ typedef struct _App App; typedef struct { App *super; // Every Position & Hitbox components - tree_Tree *pos, *hit; - vector_Vector *flaggedDelete; + tree_Tree *pos, *hit; } System_Physics; // Returns an empty physics system.