From 9800b5576ed265761999cddecc50567b93fb91de Mon Sep 17 00:00:00 2001 From: Klemen Plestenjak Date: Thu, 7 Dec 2023 10:42:53 +0100 Subject: [PATCH] Remove memory allocation in pathfinding --- engine/breeze/memory/stack_alloc.c | 2 +- game/game_state.h | 1 + game/main.c | 2 ++ game/pathfinding.c | 14 ++++++-------- game/pathfinding.h | 9 +++++---- game/systems_input.c | 6 ++++-- 6 files changed, 19 insertions(+), 15 deletions(-) diff --git a/engine/breeze/memory/stack_alloc.c b/engine/breeze/memory/stack_alloc.c index b9da496..4a569d9 100644 --- a/engine/breeze/memory/stack_alloc.c +++ b/engine/breeze/memory/stack_alloc.c @@ -21,7 +21,7 @@ void bzStackAllocDestroy(BzStackAlloc *alloc) { } void *bzStackAlloc(BzStackAlloc *alloc, size_t numBytes) { - BZ_ASSERT(alloc->size + numBytes < alloc->size); + BZ_ASSERT(alloc->allocated + numBytes < alloc->size); void *allocated = (u8 *) alloc->memory + alloc->allocated; alloc->allocated += numBytes; return allocated; diff --git a/game/game_state.h b/game/game_state.h index 6eef5ed..9a911fd 100644 --- a/game/game_state.h +++ b/game/game_state.h @@ -57,6 +57,7 @@ typedef struct Game { i64 gold; i64 pop; } resources; + BzStackAlloc stackAlloc; struct { BzObjectPool *pathData; } pools; diff --git a/game/main.c b/game/main.c index 4c7315a..c61b581 100644 --- a/game/main.c +++ b/game/main.c @@ -79,6 +79,7 @@ bool init(void *userData) { input->unitPositions = bzArrayCreate(Position, 16); + game->stackAlloc = bzStackAllocCreate(10 * 1000 * 1000); // 10 MB // init pools game->pools.pathData = bzObjectPoolCreate(&(BzObjectPoolDesc) { .objectSize=sizeof(PathData), @@ -189,6 +190,7 @@ void deinit(void *userData) { ECS = NULL; bzArrayDestroy(inputCopy.unitPositions); + bzStackAllocDestroy(&gameCopy.stackAlloc); bzObjectPoolDestroy(gameCopy.pools.pathData); bzSpatialGridDestroy(gameCopy.entityGrid); } diff --git a/game/pathfinding.c b/game/pathfinding.c index 0c78e5d..61d8e9c 100644 --- a/game/pathfinding.c +++ b/game/pathfinding.c @@ -123,6 +123,7 @@ static void heapUpdate(Heap *heap, i32 idx); bool pathfindAStar(const PathfindingDesc *desc) { BZ_ASSERT(desc->map); + BZ_ASSERT(desc->alloc); BzTileMap *map = desc->map; TilePosition start = {0}, target = {0}; @@ -133,18 +134,17 @@ bool pathfindAStar(const PathfindingDesc *desc) { i32 numTiles = map->width * map->height; - PathNodeRecord *closedSet = desc->closedSet; - if (!closedSet) closedSet = bzAlloc(sizeof(*closedSet) * numTiles); + PathNodeRecord *closedSet = bzStackAlloc(desc->alloc, sizeof(*closedSet) * numTiles); bzMemSet(closedSet, 0, sizeof(*closedSet) * numTiles); + PathNode *openSetArr = bzStackAlloc(desc->alloc, sizeof(*openSetArr) * numTiles); Heap openSet = { - .arr=desc->openSet, + .arr=openSetArr, .size=0, .capacity=numTiles, .mapWidth=map->width, .records=closedSet }; - if (!openSet.arr) openSet.arr = bzAlloc(sizeof(*openSet.arr) * numTiles); i32 toTargetCost = dst(start, target); heapPush(&openSet, (PathNode) { @@ -258,10 +258,8 @@ bool pathfindAStar(const PathfindingDesc *desc) { *desc->outPath = (Path) {pathData, 0}; } - if (!desc->closedSet) - bzFree(closedSet); - if (!desc->openSet) - bzFree(openSet.arr); + bzStackAllocFree(desc->alloc, openSet.arr); + bzStackAllocFree(desc->alloc, closedSet); return foundPath ? pathLen : -1; } diff --git a/game/pathfinding.h b/game/pathfinding.h index 9537b72..93618b8 100644 --- a/game/pathfinding.h +++ b/game/pathfinding.h @@ -23,11 +23,12 @@ typedef struct PathNodeRecord { typedef struct PathfindingDesc { Position start; Position target; - BzObjectPool *pool; + BzTileMap *map; - PathNode *openSet; // heap (size: width * height) - PathNodeRecord *closedSet; // size: width * height - Path *outPath; + Path *outPath; + + BzObjectPool *pool; + BzStackAlloc *alloc; } PathfindingDesc; bool pathfindAStar(const PathfindingDesc *desc); diff --git a/game/systems_input.c b/game/systems_input.c index 2a5e38e..820ce4b 100644 --- a/game/systems_input.c +++ b/game/systems_input.c @@ -138,7 +138,8 @@ void updatePlayerInput() { .target=target, .map=map, .outPath=&path, - .pool=game->pools.pathData + .pool=game->pools.pathData, + .alloc=&game->stackAlloc }); if (!path.paths) continue; ecs_set_ptr(ECS, entity, Path, &path); @@ -166,7 +167,8 @@ void updatePlayerInput() { .target=worldPos, .map=map, .outPath=&path, - .pool=game->pools.pathData + .pool=game->pools.pathData, + .alloc=&game->stackAlloc }); if (!path.paths) continue; ecs_set_ptr(ECS, entity, Path, &path);