diff --git a/src/game/memory.c b/src/game/memory.c index feca24fd1..1ab2f463b 100644 --- a/src/game/memory.c +++ b/src/game/memory.c @@ -185,10 +185,41 @@ void growing_pool_free_pool(struct GrowingPool *pool) { // growing array // /////////////////// +static void growing_array_free_elements(struct GrowingArray *array) { + if (array) { + for (u32 i = 0; i != array->capacity; ++i) { + if (array->buffer[i]) { + array->free(array->buffer[i]); + array->buffer[i] = NULL; + } + } + array->count = 0; + } +} + struct GrowingArray *growing_array_init(struct GrowingArray *array, u32 capacity, GrowingArrayAllocFunc alloc, GrowingArrayFreeFunc free) { - growing_array_free(&array); - array = calloc(1, sizeof(struct GrowingArray)); - array->buffer = calloc(capacity, sizeof(void *)); + growing_array_free_elements(array); + + // reuse buffer if array was already allocated + if (array) { + if (!array->buffer || array->capacity != capacity) { + void **buffer = realloc(array->buffer, sizeof(void *) * capacity); + + // if realloc fails, destroy the array and create a new one + if (!buffer) { + growing_array_free(&array); + return growing_array_init(NULL, capacity, alloc, free); + } + + array->buffer = buffer; + array->capacity = capacity; + memset(array->buffer, 0, sizeof(void *) * array->capacity); + } + } else { + array = calloc(1, sizeof(struct GrowingArray)); + array->buffer = calloc(capacity, sizeof(void *)); + } + array->capacity = capacity; array->count = 0; array->alloc = alloc; @@ -248,11 +279,7 @@ void growing_array_move(struct GrowingArray *array, u32 from, u32 to, u32 count) void growing_array_free(struct GrowingArray **array) { if (*array) { - for (u32 i = 0; i != (*array)->capacity; ++i) { - if ((*array)->buffer[i]) { - (*array)->free((*array)->buffer[i]); - } - } + growing_array_free_elements(*array); free((*array)->buffer); free(*array); *array = NULL; diff --git a/src/pc/djui/djui_hud_utils.c b/src/pc/djui/djui_hud_utils.c index a181bb73a..6fa800b6c 100644 --- a/src/pc/djui/djui_hud_utils.c +++ b/src/pc/djui/djui_hud_utils.c @@ -175,6 +175,14 @@ static struct GrowingArray *sInterpHuds = NULL; static u32 sInterpHudCount = 0; static bool sColorAltered = false; +static void interp_hud_free(void *ptr) { + struct InterpHud *interp = ptr; + if (interp) { + growing_array_free(&interp->gfx); + free(interp); + } +} + void patch_djui_hud_before(void) { sInterpHudCount = 0; } @@ -262,10 +270,6 @@ void patch_djui_hud(f32 delta) { } static struct InterpHud *djui_hud_create_interp() { - if (!sInterpHuds) { - sInterpHuds = growing_array_init(sInterpHuds, 16, malloc, free); - } - struct InterpHud *interp = ( sInterpHudCount < sInterpHuds->count ? sInterpHuds->buffer[sInterpHudCount] : @@ -296,15 +300,7 @@ static InterpHudGfx *djui_hud_create_interp_gfx(struct InterpHud *interp, enum I } void djui_hud_clear_interp_data() { - if (sInterpHuds) { - for (u32 i = 0; i < sInterpHuds->count; ++i) { - struct InterpHud *interp = sInterpHuds->buffer[i]; - if (interp) { - growing_array_free(&interp->gfx); - } - } - growing_array_free(&sInterpHuds); - } + sInterpHuds = growing_array_init(sInterpHuds, 16, malloc, interp_hud_free); sInterpHudCount = 0; }