From cc66f15131e337bf6737af24c0c8be84fb7dac10 Mon Sep 17 00:00:00 2001 From: Klemen Plestenjak Date: Fri, 29 Dec 2023 17:18:06 +0100 Subject: [PATCH] Move system initialization in systems.c, properly delete all entities when unloading map --- CMakeLists.txt | 1 + game/buildings.c | 2 +- game/components.c | 4 +++ game/components.h | 9 +++++++ game/main.c | 58 ++++-------------------------------------- game/map_init.c | 10 ++++---- game/systems/systems.c | 56 ++++++++++++++++++++++++++++++++++++++++ game/systems/systems.h | 26 +++---------------- 8 files changed, 84 insertions(+), 82 deletions(-) create mode 100644 game/systems/systems.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 64668ac..4d45e51 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,6 +15,7 @@ add_executable(PixelDefense game/systems/s_event.c game/systems/s_input.c game/systems/s_ui.c + game/systems/systems.c game/systems/systems.h game/buildings.c diff --git a/game/buildings.c b/game/buildings.c index 7e9baf8..96b073b 100644 --- a/game/buildings.c +++ b/game/buildings.c @@ -55,7 +55,7 @@ ecs_entity_t placeBuilding(BzTileMap *map, BuildingType type, BzTile tileX, BzTi BZ_ASSERT(buildingTile != -1); // Create entity - ecs_entity_t e = ecs_new_id(ECS); + ecs_entity_t e = entityCreate(ECS); ecs_set(ECS, e, TilePosition, { .x = tileX, .y = tileY }); ecs_set(ECS, e, TileSize, { .sizeX = sizeX, .sizeY = sizeY }); diff --git a/game/components.c b/game/components.c index 81d5681..be2786c 100644 --- a/game/components.c +++ b/game/components.c @@ -3,6 +3,8 @@ #include "unit_ai.h" #include "unit_actions.h" +ECS_TAG_DECLARE(GameEntity); + ECS_COMPONENT_DECLARE(Resource); ECS_COMPONENT_DECLARE(TilePosition); @@ -38,6 +40,8 @@ ECS_TAG_DECLARE(Workable); ECS_TAG_DECLARE(Attackable); void initComponentIDs(ecs_world_t *ecs) { + ECS_TAG_DEFINE(ecs, GameEntity); + ECS_COMPONENT_DEFINE(ecs, Resource); ECS_COMPONENT_DEFINE(ecs, TilePosition); diff --git a/game/components.h b/game/components.h index 76a671b..2811c10 100644 --- a/game/components.h +++ b/game/components.h @@ -6,6 +6,9 @@ #include "game_tileset.h" +// Needed, so we can clean up all game created entities +extern ECS_TAG_DECLARE(GameEntity); + typedef enum ResourceType { RES_IRON, RES_WOOD, @@ -190,5 +193,11 @@ extern ECS_TAG_DECLARE(Attackable); void initComponentIDs(ecs_world_t *ecs); +static ecs_entity_t entityCreate(ecs_world_t *ecs) { + ecs_entity_t entity = ecs_new_id(ecs); + ecs_add_id(ecs, entity, GameEntity); + return entity; +} + #endif //PIXELDEFENSE_COMPONENTS_H diff --git a/game/main.c b/game/main.c index 347b9ca..9ba55ab 100644 --- a/game/main.c +++ b/game/main.c @@ -25,9 +25,6 @@ ECS_COMPONENT_DECLARE(InputState); BzUI *UI = NULL; ecs_world_t *ECS = NULL; -static ecs_entity_t renderCollidersSystem; -static ecs_entity_t renderDebugPathSystem; - bool init(void *userData); void deinit(void *userData); @@ -86,6 +83,7 @@ void terrainRender(BzTileMap *map, BzTileLayer *layer) { } void unloadMap(Game *game) { + ecs_delete_with(ECS, GameEntity); if (game->map.isValid) { bzTileMapDestroy(&game->map); game->map.isValid = false; @@ -134,21 +132,6 @@ void loadMap(Game *game, const char *path) { bzTileMapOverrideObjectGroup(&game->map, OBJECTS_ENTITIES, initEntityObjectsLayer); } -ECS_DTOR(SpatialGridID, gridID, { - Game *game = ecs_singleton_get_mut(ECS, Game); - bzSpatialGridRemove(game->entityGrid, *gridID); -}) -ECS_DTOR(Path, path, { - Game *game = ecs_singleton_get_mut(ECS, Game); - BzObjectPool *pool = game->pools.pathData; - - PathData *cur = path[i].paths; - while (cur) { - bzObjectPoolRelease(pool, cur); - cur = cur->next; - } -}) - int cmpDrawData(const void *a, const void *b) { const DrawData *lhs = (DrawData *) a; const DrawData *rhs = (DrawData *) b; @@ -221,42 +204,9 @@ bool init(void *userData) { .texturePath="assets/game.png" }); - - ecs_set_hooks(ECS, SpatialGridID, { - .dtor = ecs_dtor(SpatialGridID) - }); - ecs_set_hooks(ECS, Path, { - .dtor = ecs_dtor(Path) - }); - - //setupSystems(ECS) - - ECS_OBSERVER(ECS, entityPathRemove, EcsOnRemove, Path); - - ECS_SYSTEM(ECS, entityUpdateSpatialID, EcsOnUpdate, Position, Size, Velocity, SpatialGridID); - ECS_SYSTEM(ECS, entityUpdateKinematic, EcsOnUpdate, Position, Rotation, Velocity, Steering); - - ECS_SYSTEM(ECS, entityMoveToTarget, EcsOnUpdate, Position, Rotation, Velocity, TargetPosition, Steering); - ECS_SYSTEM(ECS, entityFollowPath, EcsOnUpdate, Path); - - ECS_SYSTEM(ECS, handleUnitActionsSystem, EcsOnUpdate, UnitAction); - ECS_SYSTEM(ECS, updateUnitAISystem, EcsOnUpdate, UnitAI, UnitAction); - // Needs to be called after AI update, since it removes finished actions - ECS_SYSTEM(ECS, updateUnitActionsSystem, EcsOnUpdate, UnitAction); - - ECS_SYSTEM(ECS, updateAnimationState, EcsOnUpdate, Animation, TextureRegion); - ECS_SYSTEM(ECS, updateAnimation, EcsOnUpdate, Animation, TextureRegion); - ECS_SYSTEM(ECS, updateEasingSystem, EcsOnUpdate, Easing, Position, Size, Rotation); - - ECS_SYSTEM(ECS, renderDebugPath, EcsOnUpdate, Path); - - ECS_SYSTEM(ECS, renderColliders, EcsOnUpdate, Position, Size); - ECS_SYSTEM(ECS, renderRotationDirection, EcsOnUpdate, Position, Rotation); - + setupSystems(); loadMap(game, "assets/maps/main_menu_01.tmj"); - renderDebugPathSystem = renderDebugPath; - renderCollidersSystem = renderColliders; game->debugDraw.mapColliders = true; game->debugDraw.spatialGrid = true; @@ -269,6 +219,8 @@ void deinit(void *userData) { Game *game = ecs_singleton_get_mut(ECS, Game); InputState *input = ecs_singleton_get_mut(ECS, InputState); + unloadMap(game); + // Destroy queries ecs_query_fini(input->queries.selected); ecs_query_fini(game->drawQuery); @@ -283,7 +235,6 @@ void deinit(void *userData) { game = &gameCopy; input = &inputCopy; - unloadMap(game); bzTilesetDestroy(&game->tileset); bzStackAllocDestroy(&game->stackAlloc); @@ -454,6 +405,7 @@ static void renderMainMenu(Game *game, float dt) { }); if (uiMainMenuButton("Play") || true) { game->screen = SCREEN_GAME; + unloadMap(game); loadMap(game, "assets/maps/map_01.tmj"); } if (uiMainMenuButton("Settings")) { diff --git a/game/map_init.c b/game/map_init.c index 6efec6c..0756320 100644 --- a/game/map_init.c +++ b/game/map_init.c @@ -44,8 +44,8 @@ bool initEntityObjectsLayer(BzTileMap *map, BzTileObjectGroup *objectGroup) { */ bzLogInfo("%d %.2f %.2f", object.gid, object.shape.sizeX, object.shape.sizeY); //EntityArms arms = { - // .left=ecs_new_id(ECS), - // .right=ecs_new_id(ECS), + // .left=createEntity(ECS), + // .right=createEntity(ECS), //}; //ecs_set_ptr(ECS, e, EntityArms, &arms); } @@ -76,7 +76,7 @@ bool initBuildingsLayer(BzTileMap *map, BzTileLayer *layer) { const i32 tileWidth = map->tileWidth; const i32 tileHeight = map->tileHeight; - ecs_entity_t e = ecs_new_id(ECS); + ecs_entity_t e = entityCreate(ECS); Size size = {.x = tileSize.sizeX * tileWidth, .y = tileSize.sizeY * tileHeight }; ecs_set_ptr(ECS, e, Size, &size); ecs_set(ECS, e, Position, { @@ -117,7 +117,7 @@ bool initTreesLayer(BzTileMap *map, BzTileLayer *layer) { f32 sizeY = tileset->tileHeight; f32 posX = layer->offsetX + x * sizeX; f32 posY = layer->offsetY + y * sizeY; - ecs_entity_t e = ecs_new_id(ECS); + ecs_entity_t e = entityCreate(ECS); SpatialGridID gridID = bzSpatialGridInsert(game->entityGrid, &e, posX, posY, sizeX, sizeY); ecs_set(ECS, e, SpatialGridID, {gridID}); posX += sizeX * 0.5f; @@ -137,7 +137,7 @@ bool initTreesLayer(BzTileMap *map, BzTileLayer *layer) { } ecs_entity_t createWorker(Position position, Size size, BzSpatialGrid *grid, BzTileset *tileset, BzTile gid) { - ecs_entity_t e = ecs_new_id(ECS); + ecs_entity_t e = entityCreate(ECS); ecs_set_ptr(ECS, e, Position, &position); ecs_set_ptr(ECS, e, Size, &size); BzSpatialGridID spatialID = bzSpatialGridInsert(grid, &e, diff --git a/game/systems/systems.c b/game/systems/systems.c new file mode 100644 index 0000000..8a2a0b1 --- /dev/null +++ b/game/systems/systems.c @@ -0,0 +1,56 @@ +#include "systems.h" + +#include "../game_state.h" + +ecs_entity_t renderCollidersSystem; +ecs_entity_t renderDebugPathSystem; + +ECS_DTOR(SpatialGridID, gridID, { + Game *game = ecs_singleton_get_mut(ECS, Game); + bzSpatialGridRemove(game->entityGrid, *gridID); +}) +ECS_DTOR(Path, path, { + Game *game = ecs_singleton_get_mut(ECS, Game); + BzObjectPool *pool = game->pools.pathData; + + PathData *cur = path[i].paths; + while (cur) { + bzObjectPoolRelease(pool, cur); + cur = cur->next; + } +}) + +void setupSystems() { + ecs_set_hooks(ECS, SpatialGridID, { + .dtor = ecs_dtor(SpatialGridID) + }); + ecs_set_hooks(ECS, Path, { + .dtor = ecs_dtor(Path) + }); + + ECS_OBSERVER(ECS, entityPathRemove, EcsOnRemove, Path); + + ECS_SYSTEM(ECS, entityUpdateSpatialID, EcsOnUpdate, Position, Size, Velocity, SpatialGridID); + ECS_SYSTEM(ECS, entityUpdateKinematic, EcsOnUpdate, Position, Rotation, Velocity, Steering); + + ECS_SYSTEM(ECS, entityMoveToTarget, EcsOnUpdate, Position, Rotation, Velocity, TargetPosition, Steering); + ECS_SYSTEM(ECS, entityFollowPath, EcsOnUpdate, Path); + + ECS_SYSTEM(ECS, handleUnitActionsSystem, EcsOnUpdate, UnitAction); + ECS_SYSTEM(ECS, updateUnitAISystem, EcsOnUpdate, UnitAI, UnitAction); + // Needs to be called after AI update, since it removes finished actions + ECS_SYSTEM(ECS, updateUnitActionsSystem, EcsOnUpdate, UnitAction); + + ECS_SYSTEM(ECS, updateAnimationState, EcsOnUpdate, Animation, TextureRegion); + ECS_SYSTEM(ECS, updateAnimation, EcsOnUpdate, Animation, TextureRegion); + ECS_SYSTEM(ECS, updateEasingSystem, EcsOnUpdate, Easing, Position, Size, Rotation); + + ECS_SYSTEM(ECS, renderDebugPath, EcsOnUpdate, Path); + + ECS_SYSTEM(ECS, renderColliders, EcsOnUpdate, Position, Size); + ECS_SYSTEM(ECS, renderRotationDirection, EcsOnUpdate, Position, Rotation); + + renderDebugPathSystem = renderDebugPath; + renderCollidersSystem = renderColliders; + +} diff --git a/game/systems/systems.h b/game/systems/systems.h index 6825b77..d04b0ec 100644 --- a/game/systems/systems.h +++ b/game/systems/systems.h @@ -163,29 +163,9 @@ void drawPlayerInputUI(); * MISC **********************************/ -static void setupSystems(ecs_world_t *ecs) { +extern ecs_entity_t renderCollidersSystem; +extern ecs_entity_t renderDebugPathSystem; - ECS_OBSERVER(ecs, entityPathRemove, EcsOnRemove, Path); - - ECS_SYSTEM(ecs, entityUpdateSpatialID, EcsOnUpdate, Position, Size, Velocity, SpatialGridID); - ECS_SYSTEM(ecs, entityUpdateKinematic, EcsOnUpdate, Position, Rotation, Velocity, Steering); - - ECS_SYSTEM(ecs, entityMoveToTarget, EcsOnUpdate, Position, Rotation, Velocity, TargetPosition, Steering); - ECS_SYSTEM(ecs, entityFollowPath, EcsOnUpdate, Path); - - ECS_SYSTEM(ecs, handleUnitActionsSystem, EcsOnUpdate, UnitAction); - ECS_SYSTEM(ecs, updateUnitAISystem, EcsOnUpdate, UnitAI, UnitAction); - // Needs to be called after AI update, since it removes finished actions - ECS_SYSTEM(ecs, updateUnitActionsSystem, EcsOnUpdate, UnitAction); - - ECS_SYSTEM(ecs, updateAnimationState, EcsOnUpdate, Animation, TextureRegion); - ECS_SYSTEM(ecs, updateAnimation, EcsOnUpdate, Animation, TextureRegion); - ECS_SYSTEM(ecs, updateEasingSystem, EcsOnUpdate, Easing, Position, Size, Rotation); - - ECS_SYSTEM(ecs, renderDebugPath, EcsOnUpdate, Path); - - ECS_SYSTEM(ecs, renderColliders, EcsOnUpdate, Position, Size); - ECS_SYSTEM(ecs, renderRotationDirection, EcsOnUpdate, Position, Rotation); -} +void setupSystems(); #endif //PIXELDEFENSE_SYSTEMS_H