This patch just adds the psObj->refCount field, sets it, and makes the object release code check it before releasing object memory. It does not increment or decrement the refCount field in any way, but as a hack initializes it to 1 to avoid immediate garbage collection.
Now, the only reason I send this to the list in this premature state, is that it is already more stable than the existing code, and I thought that was kind of fun. Yes, the patch change means no object is garbage collected. Ever. Still, memory does not seem to be a problem. I could not notice memory increasing noticeably in a very short game I had. I do not believe it would be a very big problem in longer games. Still, leaving it like this would be rather ugly, I think... ;-) - Per
Index: src/base.h =================================================================== --- src/base.h (revision 1512) +++ src/base.h (working copy) @@ -54,7 +54,8 @@ UWORD x,y,z; /* Object's location */ \ float direction; /* Object's direction +ve rotation about y axis*/ \ SWORD pitch; /* Object's pitch +ve nose up*/ \ - SWORD roll /* Object's roll +ve left up, right down */ + SWORD roll; /* Object's roll +ve left up, right down */ \ + SWORD refCount /* Object's reference count, for safe deallocation */ #define BASE_ELEMENTS2(pointerType) \ SCREEN_DISP_DATA sDisplay; /* screen coordinate details */ \ Index: src/structure.c =================================================================== --- src/structure.c (revision 1512) +++ src/structure.c (working copy) @@ -4083,12 +4083,6 @@ psAssemblyPoint = ((REPAIR_FACILITY *)psBuilding->pFunctionality)->psDeliveryPoint; } - // remove any assembly points - if (psAssemblyPoint != NULL) - { - removeFlagPosition(psAssemblyPoint); - } - //free up the space used by the functionality array free(psBuilding->pFunctionality); } Index: src/objmem.c =================================================================== --- src/objmem.c (revision 1512) +++ src/objmem.c (working copy) @@ -37,6 +37,7 @@ #include "scripttabs.h" #include "scriptcb.h" #include "mission.h" +#include "structuredef.h" static SDWORD factoryDeliveryPointCheck[MAX_PLAYERS][NUM_FLAG_TYPES][MAX_FACTORY]; @@ -121,11 +122,8 @@ scrvUpdateBasePointers(); } - /* Go through the destroyed objects list looking for objects that - were destroyed before this turn */ - /* First remove the objects from the start of the list */ - while (psDestroyedObj != NULL && psDestroyedObj->died != gameTime) + while (psDestroyedObj != NULL && psDestroyedObj->refCount == 0) { psNext = psDestroyedObj->psNext; objmemDestroy(psDestroyedObj); @@ -137,17 +135,9 @@ for(psCurr = psPrev = psDestroyedObj; psCurr != NULL; psCurr = psNext) { psNext = psCurr->psNext; - if (psCurr->died != gameTime) + if (gameTime == psDestroyedObj->died) { - objmemDestroy(psCurr); - - /*set the linked list up - you will never be deleting the top - of the list, so don't have to check*/ - psPrev->psNext = psNext; - } - else - { - // do the object died callback + // do the object died callback now psCBObjDestroyed = psCurr; eventFireCallbackTrigger((TRIGGER_TYPE)CALL_OBJ_DESTROYED); switch (psCurr->type) @@ -168,6 +158,14 @@ psPrev = psCurr; } + if (psDestroyedObj->refCount == 0) + { + objmemDestroy(psCurr); + + /*set the linked list up - you will never be deleting the top + of the list because of the above hack, so don't have to check*/ + psPrev->psNext = psNext; + } } } @@ -217,6 +215,7 @@ objID++; newObject->player = (UBYTE)player; newObject->died = 0; + newObject->refCount = 1; /* forever */ return newObject; } @@ -462,6 +461,18 @@ "killStruct: pointer is not a droid" ); ASSERT( psDel->player < MAX_PLAYERS, "killStruct: invalid player for stucture" ); + + if (StructIsFactory(psDel)) + { + FACTORY *psFactory = (FACTORY *)psDel->pFunctionality; + + if (psFactory->psAssemblyPoint != NULL) + { + removeFlagPosition(psFactory->psAssemblyPoint); + psFactory->psAssemblyPoint = NULL; + } + } + destroyObject((BASE_OBJECT**)apsStructLists, (BASE_OBJECT*)psDel); } @@ -902,4 +913,8 @@ ASSERT( psCurr->type == OBJ_FEATURE, "objListIntegCheck: misplaced object in the feature list" ); } + for (psCurr = (BASE_OBJECT*)psDestroyedObj; psCurr; psCurr = psCurr->psNext) + { + ASSERT( psCurr->died > 0, "objListIntegCheck: Object in destroyed list but not dead!" ); + } }
_______________________________________________ Warzone-dev mailing list Warzone-dev@gna.org https://mail.gna.org/listinfo/warzone-dev