Fix memory leak when more groups are created than released. See patch #826
git-svn-id: svn+ssh://svn.gna.org/svn/warzone/trunk@2690 4a71c877-e1ca-e34f-864e-861f7616d084master
parent
99098a55b6
commit
bc6bd2db1e
94
src/group.c
94
src/group.c
|
@ -32,6 +32,9 @@
|
|||
|
||||
#include "multiplay.h"
|
||||
|
||||
static DROID_GROUP *firstGroup = NULL;
|
||||
static BOOL grpInitialized = FALSE;
|
||||
|
||||
// sizes for the group heap
|
||||
#define GRP_HEAP_INIT 45
|
||||
#define GRP_HEAP_EXT 15
|
||||
|
@ -39,39 +42,67 @@
|
|||
// initialise the group system
|
||||
BOOL grpInitialise(void)
|
||||
{
|
||||
firstGroup = NULL;
|
||||
grpInitialized = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
// shutdown the group system
|
||||
void grpShutDown(void)
|
||||
{
|
||||
}
|
||||
/* Since we are not very diligent removing groups after we have
|
||||
* created them; we need this hack to remove them on level end. */
|
||||
DROID_GROUP *iter = firstGroup, *psDel;
|
||||
|
||||
while (iter != NULL)
|
||||
{
|
||||
psDel = iter;
|
||||
iter = iter->psNext;
|
||||
free(psDel);
|
||||
}
|
||||
firstGroup = NULL;
|
||||
grpInitialized = FALSE;
|
||||
}
|
||||
|
||||
// create a new group
|
||||
BOOL grpCreate(DROID_GROUP **ppsGroup)
|
||||
{
|
||||
*ppsGroup = malloc(sizeof(DROID_GROUP));
|
||||
ASSERT(grpInitialized, "Group code not initialized yet");
|
||||
*ppsGroup = calloc(1, sizeof(DROID_GROUP));
|
||||
if (*ppsGroup == NULL)
|
||||
{
|
||||
debug(LOG_ERROR, "grpCreate: Out of memory");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Add node to beginning of list
|
||||
if (firstGroup != NULL)
|
||||
{
|
||||
(*ppsGroup)->psNext = firstGroup;
|
||||
(*ppsGroup)->psPrev = NULL;
|
||||
firstGroup->psPrev = *ppsGroup;
|
||||
firstGroup = *ppsGroup;
|
||||
}
|
||||
else
|
||||
{
|
||||
firstGroup = *ppsGroup;
|
||||
(*ppsGroup)->psPrev = NULL;
|
||||
(*ppsGroup)->psNext = NULL;
|
||||
}
|
||||
|
||||
(*ppsGroup)->type = GT_NORMAL;
|
||||
(*ppsGroup)->refCount = 0;
|
||||
(*ppsGroup)->psList = NULL;
|
||||
(*ppsGroup)->psCommander = NULL;
|
||||
memset(&(*ppsGroup)->sRunData, 0, sizeof(RUN_DATA));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
// add a droid to a group
|
||||
void grpJoin(DROID_GROUP *psGroup, DROID *psDroid)
|
||||
{
|
||||
ASSERT(grpInitialized, "Group code not initialized yet");
|
||||
|
||||
psGroup->refCount += 1;
|
||||
|
||||
ASSERT( psGroup != NULL,
|
||||
|
@ -117,7 +148,6 @@ void grpJoin(DROID_GROUP *psGroup, DROID *psDroid)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// add a droid to a group at the end of the list
|
||||
void grpJoinEnd(DROID_GROUP *psGroup, DROID *psDroid)
|
||||
{
|
||||
|
@ -125,6 +155,7 @@ void grpJoinEnd(DROID_GROUP *psGroup, DROID *psDroid)
|
|||
|
||||
psGroup->refCount += 1;
|
||||
|
||||
ASSERT(grpInitialized, "Group code not initialized yet");
|
||||
ASSERT( psGroup != NULL,
|
||||
"grpJoin: invalid group pointer" );
|
||||
|
||||
|
@ -172,23 +203,21 @@ void grpJoinEnd(DROID_GROUP *psGroup, DROID *psDroid)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// remove a droid from a group
|
||||
void grpLeave(DROID_GROUP *psGroup, DROID *psDroid)
|
||||
{
|
||||
DROID *psPrev, *psCurr;
|
||||
|
||||
ASSERT(grpInitialized, "Group code not initialized yet");
|
||||
ASSERT( psGroup != NULL,
|
||||
"grpLeave: invalid group pointer" );
|
||||
|
||||
if ( (psDroid != NULL )
|
||||
&& (psDroid->psGroup != psGroup) )
|
||||
if (psDroid != NULL && psDroid->psGroup != psGroup)
|
||||
{
|
||||
ASSERT( FALSE, "grpLeave: droid group does not match" );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
psGroup->refCount -= 1;
|
||||
|
||||
// if psDroid == NULL just decrease the refcount don't remove anything from the list
|
||||
|
@ -240,6 +269,18 @@ void grpLeave(DROID_GROUP *psGroup, DROID *psDroid)
|
|||
// free the group structure if necessary
|
||||
if (psGroup->refCount <= 0)
|
||||
{
|
||||
if (firstGroup == psGroup)
|
||||
{
|
||||
firstGroup = psGroup->psNext;
|
||||
}
|
||||
if (psGroup->psNext)
|
||||
{
|
||||
psGroup->psNext->psPrev = psGroup->psPrev;
|
||||
}
|
||||
if (psGroup->psPrev)
|
||||
{
|
||||
psGroup->psPrev->psNext = psGroup->psNext;
|
||||
}
|
||||
free(psGroup);
|
||||
}
|
||||
}
|
||||
|
@ -250,6 +291,7 @@ SDWORD grpNumMembers(DROID_GROUP *psGroup)
|
|||
DROID *psCurr;
|
||||
SDWORD num;
|
||||
|
||||
ASSERT(grpInitialized, "Group code not initialized yet");
|
||||
ASSERT( psGroup != NULL,
|
||||
"grpNumMembers: invalid droid group" );
|
||||
|
||||
|
@ -262,12 +304,12 @@ SDWORD grpNumMembers(DROID_GROUP *psGroup)
|
|||
return num;
|
||||
}
|
||||
|
||||
|
||||
// remove all droids from a group
|
||||
void grpReset(DROID_GROUP *psGroup)
|
||||
{
|
||||
DROID *psCurr, *psNext;
|
||||
|
||||
ASSERT(grpInitialized, "Group code not initialized yet");
|
||||
ASSERT( psGroup != NULL,
|
||||
"grpReset: invalid droid group" );
|
||||
|
||||
|
@ -278,37 +320,12 @@ void grpReset(DROID_GROUP *psGroup)
|
|||
}
|
||||
}
|
||||
|
||||
/* Give a group an order */
|
||||
//void orderGroupBase(DROID_GROUP *psGroup, DROID_ORDER_DATA *psData)
|
||||
//{
|
||||
// DROID *psCurr;
|
||||
// BOOL usedgrouporder=FALSE;
|
||||
|
||||
// ASSERT( psGroup != NULL,
|
||||
// "orderGroupBase: invalid droid group" );
|
||||
//
|
||||
// if (bMultiPlayer && SendGroupOrder( psGroup, psData->x, psData->y, psData->psObj) )
|
||||
// { // turn off multiplay messages,since we've send a group one instead.
|
||||
// bMultiPlayer =FALSE;
|
||||
// usedgrouporder = TRUE;
|
||||
// }
|
||||
//
|
||||
// for (psCurr = psGroup->psList; psCurr; psCurr=psCurr->psGrpNext)
|
||||
// {
|
||||
// orderDroidBase(psCurr, psData);
|
||||
// }
|
||||
|
||||
// if( usedgrouporder)
|
||||
// {
|
||||
// bMultiPlayer = TRUE;
|
||||
// }
|
||||
//}
|
||||
|
||||
/* Give a group an order */
|
||||
void orderGroup(DROID_GROUP *psGroup, DROID_ORDER order)
|
||||
{
|
||||
DROID *psCurr;
|
||||
|
||||
ASSERT(grpInitialized, "Group code not initialized yet");
|
||||
ASSERT( psGroup != NULL,
|
||||
"orderGroup: invalid droid group" );
|
||||
|
||||
|
@ -323,6 +340,7 @@ void orderGroupLoc(DROID_GROUP *psGroup, DROID_ORDER order, UDWORD x, UDWORD y)
|
|||
{
|
||||
DROID *psCurr;
|
||||
|
||||
ASSERT(grpInitialized, "Group code not initialized yet");
|
||||
ASSERT( psGroup != NULL,
|
||||
"orderGroupLoc: invalid droid group" );
|
||||
|
||||
|
@ -347,7 +365,6 @@ void orderGroupLoc(DROID_GROUP *psGroup, DROID_ORDER order, UDWORD x, UDWORD y)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/* Give a group of droids an order */
|
||||
void orderGroupObj(DROID_GROUP *psGroup, DROID_ORDER order, BASE_OBJECT *psObj)
|
||||
{
|
||||
|
@ -383,6 +400,7 @@ void grpSetSecondary(DROID_GROUP *psGroup, SECONDARY_ORDER sec, SECONDARY_STATE
|
|||
{
|
||||
DROID *psCurr;
|
||||
|
||||
ASSERT(grpInitialized, "Group code not initialized yet");
|
||||
ASSERT( psGroup != NULL,
|
||||
"grpSetSecondary: invalid droid group" );
|
||||
|
||||
|
|
|
@ -43,6 +43,7 @@ typedef struct _droid_group
|
|||
DROID *psList; // list of droids in the group
|
||||
DROID *psCommander; // the command droid of a command group
|
||||
RUN_DATA sRunData; // where the group should retreat to
|
||||
struct _droid_group *psNext, *psPrev; // keep linked to destroy all (a workaround hack)
|
||||
} DROID_GROUP;
|
||||
|
||||
// initialise the group system
|
||||
|
|
Loading…
Reference in New Issue