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

Reply via email to