Skip to content

Commit

Permalink
Fixed|World|Trace Intercepts: Memory leak in trace intercept node man…
Browse files Browse the repository at this point in the history
…agement

Incorrect logic in P_ClearIntercepts() resulted in the used node list
being "truncated" when the intercept nodes from the last trace were
moved to this list.
  • Loading branch information
danij-deng committed Jul 15, 2013
1 parent f3afbce commit f7c2754
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 15 deletions.
7 changes: 7 additions & 0 deletions doomsday/client/include/world/p_intercept.h
Expand Up @@ -49,6 +49,13 @@ int P_TraverseIntercepts(traverser_t callback, void *parameters);

/// @todo Find a better home for the following functions ----------------------

/**
* Looks for lines in the given block that intercept the given trace to add
* to the intercepts list.
* A line is crossed if its endpoints are on opposite sides of the trace.
*
* @return Non-zero if current iteration should stop.
*/
int PIT_AddLineIntercepts(Line *ld, void *parameters);

int PIT_AddMobjIntercepts(struct mobj_s *mobj, void *parameters);
Expand Down
2 changes: 1 addition & 1 deletion doomsday/client/src/world/map.cpp
Expand Up @@ -2128,7 +2128,7 @@ static int traversePath(divline_t &traceLine, Blockmap &bmap,
traceLine.direction[VX] = FLT2FIX(to[VX] - from[VX]);
traceLine.direction[VY] = FLT2FIX(to[VY] - from[VY]);

/**
/*
* It is possible that one or both points are outside the blockmap.
* Clip path so that 'to' is within the AABB of the blockmap (note we
* would have already abandoned if 'from' lay outside..
Expand Down
26 changes: 12 additions & 14 deletions doomsday/client/src/world/p_intercept.cpp
Expand Up @@ -31,7 +31,7 @@ struct InterceptNode
};

// Blockset from which intercepts are allocated.
static zblockset_t *interceptNodeSet = NULL;
static zblockset_t *interceptNodeSet;
// Head of the used intercept list.
static InterceptNode *interceptFirst;

Expand Down Expand Up @@ -73,7 +73,16 @@ void P_ClearIntercepts()
}

// Start reusing intercepts (may point to a sentinel but that is Ok).
interceptFirst = head.next;
if(!interceptFirst)
{
interceptFirst = head.next;
}
else if(head.next != &tail)
{
InterceptNode *existing = interceptFirst;
interceptFirst = head.next;
tail.prev->next = existing;
}

// Reset the trace.
head.next = &tail;
Expand All @@ -83,8 +92,7 @@ void P_ClearIntercepts()

InterceptNode *P_AddIntercept(intercepttype_t type, float distance, void *object)
{
if(!object)
Con_Error("P_AddIntercept: Invalid arguments (object=NULL).");
DENG_ASSERT(object != 0);

// First reject vs our sentinels
if(distance < head.intercept.distance) return NULL;
Expand Down Expand Up @@ -117,9 +125,6 @@ InterceptNode *P_AddIntercept(intercepttype_t type, float distance, void *object
case ICPT_LINE:
in->d.line = (Line *) object;
break;
default:
Con_Error("P_AddIntercept: Invalid type %i.", (int)type);
exit(1); // Unreachable.
}

// Link it in.
Expand All @@ -143,13 +148,6 @@ int P_TraverseIntercepts(traverser_t callback, void *parameters)
return false; // Continue iteration.
}

/**
* Looks for lines in the given block that intercept the given trace to add
* to the intercepts list.
* A line is crossed if its endpoints are on opposite sides of the trace.
*
* @return Non-zero if current iteration should stop.
*/
int PIT_AddLineIntercepts(Line *line, void * /*parameters*/)
{
/// @todo Do not assume line is from the current map.
Expand Down

0 comments on commit f7c2754

Please sign in to comment.