From e582796b208240a164609181c5d236cf4c4e1e87 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Fri, 8 May 2026 17:26:29 +1000 Subject: [PATCH] Fixed some most memory leaks --- Toy | 2 +- assets/main.toy | 8 ++++++-- source/actor.c | 33 +++++++++++++++++++++++++++++---- 3 files changed, 36 insertions(+), 7 deletions(-) diff --git a/Toy b/Toy index be84a8d..8b9b012 160000 --- a/Toy +++ b/Toy @@ -1 +1 @@ -Subproject commit be84a8dfe2eb80c585ab496c12ee8e0ae30725f5 +Subproject commit 8b9b012bccaa45a14b0222f7acc7a3d14dbd9e26 diff --git a/assets/main.toy b/assets/main.toy index 915abed..4e963e8 100644 --- a/assets/main.toy +++ b/assets/main.toy @@ -9,9 +9,13 @@ fn onReady() { fn onStep() { frameCounter++; - if (frameCounter % 100 == 0) { - spawnActorAt("zombie", posCounter*50, posCounter*50); +// if (frameCounter % 10 == 0) { + spawnActorAt("zombie", posCounter*5, posCounter*5); posCounter++; +// } + + if (posCounter > 150) { + posCounter = 0; } } diff --git a/source/actor.c b/source/actor.c index 8139e77..61cae6b 100644 --- a/source/actor.c +++ b/source/actor.c @@ -89,7 +89,12 @@ static void loadSprite(Toy_VM* vm) { } //insert into the table as an opaque - Toy_insertTable(&spriteTable, key, TOY_OPAQUE_FROM_POINTER(sprite)); + Toy_insertTable(&spriteTable, Toy_copyValue(&vm->memoryBucket, key), TOY_OPAQUE_FROM_POINTER(sprite)); + + Toy_freeValue(key); + Toy_freeValue(file); + Toy_freeValue(width); + Toy_freeValue(height); } static void spawnActorAt(Toy_VM* vm) { @@ -165,6 +170,11 @@ static void spawnActorAt(Toy_VM* vm) { .position = { TOY_VALUE_AS_INTEGER(xpos), TOY_VALUE_AS_INTEGER(ypos) }, .health = 10, }; + + Toy_freeValue(spriteValue); + Toy_freeValue(key); + Toy_freeValue(xpos); + Toy_freeValue(ypos); } static void setActorStep(Toy_VM* vm) { @@ -172,15 +182,17 @@ static void setActorStep(Toy_VM* vm) { if (!TOY_VALUE_IS_FUNCTION(value) && !TOY_VALUE_IS_NULL(value)) { fprintf(stderr, TOY_CC_ERROR "ERROR: Bad argument type found in 'setActorStep', exiting" TOY_CC_RESET "\n"); + Toy_freeValue(value); exit(-1); } if (TOY_VALUE_IS_FUNCTION(value)) { if (TOY_VALUE_AS_FUNCTION(value)->type != TOY_FUNCTION_CUSTOM) { fprintf(stderr, TOY_CC_ERROR "ERROR: Bad function found in 'setActorStep', exiting (only allows custom functions or null)" TOY_CC_RESET "\n"); + Toy_freeValue(value); exit(-1); } - actorStep = TOY_VALUE_AS_FUNCTION(value); + actorStep = TOY_VALUE_AS_FUNCTION(value); //do not free, it'll be needed } } @@ -234,8 +246,11 @@ void freeActorAPI(Toy_VM* vm) { Toy_freeTable(spriteTable); spriteTable = NULL; - + actorArray = Toy_resizeArray(actorArray, 0); + + Toy_freeFunction(actorStep); + actorStep = NULL; } void processActorStep(Toy_VM* vm) { @@ -264,10 +279,13 @@ void processActorStep(Toy_VM* vm) { const char* cstr = ((char*)(subVM.code + subVM.dataAddr)) + paramAddr; Toy_String* name = Toy_toStringLength(&subVM.memoryBucket, cstr, strlen(cstr)); + int ticker = 0; + //load each valid actor and process them one at a time for (unsigned int i = 0; i < actorArray->count; i++) { ActorData* actor = (ActorData*)TOY_VALUE_AS_OPAQUE(actorArray->data[i]); if (actor->health > 0) { + ticker++; subVM.scope = Toy_pushScope(&subVM.memoryBucket, subVM.scope); Toy_declareScope(subVM.scope, name, paramType, Toy_copyValue(&subVM.memoryBucket, actorArray->data[i]), true); @@ -278,6 +296,14 @@ void processActorStep(Toy_VM* vm) { } Toy_freeVM(&subVM); + + //DEBUG: "wipe" the actors if there's too many, so memory doesn't keep growing. + if (ticker >= 100) { + for (unsigned int i = 0; i < actorArray->count; i++) { + ActorData* actor = (ActorData*)TOY_VALUE_AS_OPAQUE(actorArray->data[i]); + actor->health = 0; + } + } } void drawActors(Toy_VM* vm) { @@ -340,7 +366,6 @@ Toy_Value handleActorAttributes(Toy_VM* vm, Toy_Value compound, Toy_Value attrib ActorData* actor = (ActorData*)TOY_VALUE_AS_OPAQUE(compound); - if (TOY_VALUE_AS_STRING(attribute)->info.length == 1 && strncmp(TOY_VALUE_AS_STRING(attribute)->leaf.data, "x", 1) == 0) { return TOY_VALUE_FROM_INTEGER(actor->position.x); }