- let the prediction code handle all 4 threaded lists an actor gets linked into.
This is mostly a straight refactoring of the existing code to work independently of specific member variables in the involved classes, using a bit of template magic to avoid redundancy and moving the work code into subfunctions. It still needs some testing to see if it a) helps fix the crash issues and b) doesn't break anything-
This commit is contained in:
parent
c52bc06e9b
commit
62ea83a35a
4 changed files with 173 additions and 127 deletions
|
|
@ -32,7 +32,7 @@
|
|||
// Maintain a freelist of msecnode_t's to reduce memory allocs and frees.
|
||||
//=============================================================================
|
||||
|
||||
msecnode_t *headsecnode = NULL;
|
||||
msecnode_t *headsecnode = nullptr;
|
||||
FMemArena secnodearena;
|
||||
|
||||
//=============================================================================
|
||||
|
|
@ -55,7 +55,6 @@ msecnode_t *P_GetSecnode()
|
|||
}
|
||||
else
|
||||
{
|
||||
node =
|
||||
node = (msecnode_t *)secnodearena.Alloc(sizeof(*node));
|
||||
}
|
||||
return node;
|
||||
|
|
@ -87,9 +86,10 @@ void P_PutSecnode(msecnode_t *node)
|
|||
//
|
||||
//=============================================================================
|
||||
|
||||
msecnode_t *P_AddSecnode(sector_t *s, AActor *thing, msecnode_t *nextnode, msecnode_t *&sec_thinglist)
|
||||
template<class nodetype, class linktype>
|
||||
nodetype *P_AddSecnode(linktype *s, AActor *thing, nodetype *nextnode, nodetype *&sec_thinglist)
|
||||
{
|
||||
msecnode_t *node;
|
||||
nodetype *node;
|
||||
|
||||
if (s == 0)
|
||||
{
|
||||
|
|
@ -110,21 +110,21 @@ msecnode_t *P_AddSecnode(sector_t *s, AActor *thing, msecnode_t *nextnode, msecn
|
|||
// Couldn't find an existing node for this sector. Add one at the head
|
||||
// of the list.
|
||||
|
||||
node = P_GetSecnode();
|
||||
node = (nodetype*)P_GetSecnode();
|
||||
|
||||
// killough 4/4/98, 4/7/98: mark new nodes unvisited.
|
||||
node->visited = 0;
|
||||
|
||||
node->m_sector = s; // sector
|
||||
node->m_thing = thing; // mobj
|
||||
node->m_tprev = NULL; // prev node on Thing thread
|
||||
node->m_tprev = nullptr; // prev node on Thing thread
|
||||
node->m_tnext = nextnode; // next node on Thing thread
|
||||
if (nextnode)
|
||||
nextnode->m_tprev = node; // set back link on Thing
|
||||
|
||||
// Add new node at head of sector thread starting at s->touching_thinglist
|
||||
|
||||
node->m_sprev = NULL; // prev node on sector thread
|
||||
node->m_sprev = nullptr; // prev node on sector thread
|
||||
node->m_snext = sec_thinglist; // next node on sector thread
|
||||
if (sec_thinglist)
|
||||
node->m_snext->m_sprev = node;
|
||||
|
|
@ -132,22 +132,26 @@ msecnode_t *P_AddSecnode(sector_t *s, AActor *thing, msecnode_t *nextnode, msecn
|
|||
return node;
|
||||
}
|
||||
|
||||
template msecnode_t *P_AddSecnode<msecnode_t, sector_t>(sector_t *s, AActor *thing, msecnode_t *nextnode, msecnode_t *&sec_thinglist);
|
||||
template portnode_t *P_AddSecnode<portnode_t, FLinePortal>(FLinePortal *s, AActor *thing, portnode_t *nextnode, portnode_t *&sec_thinglist);
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// P_DelSecnode
|
||||
//
|
||||
// Deletes a sector node from the list of
|
||||
// sectors this object appears in. Returns a pointer to the next node
|
||||
// on the linked list, or NULL.
|
||||
// on the linked list, or nullptr.
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
msecnode_t *P_DelSecnode(msecnode_t *node, msecnode_t *sector_t::*listhead)
|
||||
template<class nodetype, class linktype>
|
||||
nodetype *P_DelSecnode(nodetype *node, nodetype *linktype::*listhead)
|
||||
{
|
||||
msecnode_t* tp; // prev node on thing thread
|
||||
msecnode_t* tn; // next node on thing thread
|
||||
msecnode_t* sp; // prev node on sector thread
|
||||
msecnode_t* sn; // next node on sector thread
|
||||
nodetype* tp; // prev node on thing thread
|
||||
nodetype* tn; // next node on thing thread
|
||||
nodetype* sp; // prev node on sector thread
|
||||
nodetype* sn; // next node on sector thread
|
||||
|
||||
if (node)
|
||||
{
|
||||
|
|
@ -175,12 +179,15 @@ msecnode_t *P_DelSecnode(msecnode_t *node, msecnode_t *sector_t::*listhead)
|
|||
|
||||
// Return this node to the freelist
|
||||
|
||||
P_PutSecnode(node);
|
||||
P_PutSecnode((msecnode_t*)node);
|
||||
return tn;
|
||||
}
|
||||
return NULL;
|
||||
return nullptr;
|
||||
} // phares 3/13/98
|
||||
|
||||
template msecnode_t *P_DelSecnode(msecnode_t *node, msecnode_t *sector_t::*listhead);
|
||||
template portnode_t *P_DelSecnode(portnode_t *node, portnode_t *FLinePortal::*listhead);
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// P_DelSeclist
|
||||
|
|
@ -195,6 +202,13 @@ void P_DelSeclist(msecnode_t *node, msecnode_t *sector_t::*sechead)
|
|||
node = P_DelSecnode(node, sechead);
|
||||
}
|
||||
|
||||
void P_DelSeclist(portnode_t *node, portnode_t *FLinePortal::*sechead)
|
||||
{
|
||||
while (node)
|
||||
node = P_DelSecnode(node, sechead);
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// phares 3/14/98
|
||||
//
|
||||
|
|
@ -210,13 +224,13 @@ msecnode_t *P_CreateSecNodeList(AActor *thing, double radius, msecnode_t *sector
|
|||
|
||||
// First, clear out the existing m_thing fields. As each node is
|
||||
// added or verified as needed, m_thing will be set properly. When
|
||||
// finished, delete all nodes where m_thing is still NULL. These
|
||||
// finished, delete all nodes where m_thing is still nullptr. These
|
||||
// represent the sectors the Thing has vacated.
|
||||
|
||||
node = sector_list;
|
||||
while (node)
|
||||
{
|
||||
node->m_thing = NULL;
|
||||
node->m_thing = nullptr;
|
||||
node = node->m_tnext;
|
||||
}
|
||||
|
||||
|
|
@ -254,12 +268,12 @@ msecnode_t *P_CreateSecNodeList(AActor *thing, double radius, msecnode_t *sector
|
|||
sector_list = P_AddSecnode(thing->Sector, thing, sector_list, thing->Sector->*seclisthead);
|
||||
|
||||
// Now delete any nodes that won't be used. These are the ones where
|
||||
// m_thing is still NULL.
|
||||
// m_thing is still nullptr.
|
||||
|
||||
node = sector_list;
|
||||
while (node)
|
||||
{
|
||||
if (node->m_thing == NULL)
|
||||
if (node->m_thing == nullptr)
|
||||
{
|
||||
if (node == sector_list)
|
||||
sector_list = node->m_tnext;
|
||||
|
|
@ -308,7 +322,7 @@ portnode_t *P_DelPortalnode(portnode_t *node)
|
|||
if (sp)
|
||||
sp->m_snext = sn;
|
||||
else
|
||||
node->m_portal->lineportal_thinglist = sn;
|
||||
node->m_sector->lineportal_thinglist = sn;
|
||||
if (sn)
|
||||
sn->m_sprev = sp;
|
||||
|
||||
|
|
@ -316,7 +330,7 @@ portnode_t *P_DelPortalnode(portnode_t *node)
|
|||
P_PutSecnode(reinterpret_cast<msecnode_t *>(node));
|
||||
return tn;
|
||||
}
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -340,16 +354,16 @@ portnode_t *P_AddPortalnode(FLinePortal *s, AActor *thing, portnode_t *nextnode)
|
|||
// killough 4/4/98, 4/7/98: mark new nodes unvisited.
|
||||
node->visited = 0;
|
||||
|
||||
node->m_portal = s; // portal
|
||||
node->m_sector = s; // portal
|
||||
node->m_thing = thing; // mobj
|
||||
node->m_tprev = NULL; // prev node on Thing thread
|
||||
node->m_tprev = nullptr; // prev node on Thing thread
|
||||
node->m_tnext = nextnode; // next node on Thing thread
|
||||
if (nextnode)
|
||||
nextnode->m_tprev = node; // set back link on Thing
|
||||
|
||||
// Add new node at head of portal thread starting at s->touching_thinglist
|
||||
|
||||
node->m_sprev = NULL; // prev node on portal thread
|
||||
node->m_sprev = nullptr; // prev node on portal thread
|
||||
node->m_snext = s->lineportal_thinglist; // next node on portal thread
|
||||
if (s->lineportal_thinglist)
|
||||
node->m_snext->m_sprev = node;
|
||||
|
|
@ -357,7 +371,6 @@ portnode_t *P_AddPortalnode(FLinePortal *s, AActor *thing, portnode_t *nextnode)
|
|||
return node;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Handle the lists used to render actors from other portal areas
|
||||
|
|
@ -420,18 +433,12 @@ void AActor::UpdateRenderSectorList()
|
|||
|
||||
void AActor::ClearRenderSectorList()
|
||||
{
|
||||
msecnode_t *node = touching_sectorportallist;
|
||||
while (node)
|
||||
node = P_DelSecnode(node, §or_t::sectorportal_thinglist);
|
||||
touching_sectorportallist = NULL;
|
||||
P_DelSeclist(touching_sectorportallist, §or_t::sectorportal_thinglist);
|
||||
touching_sectorportallist = nullptr;
|
||||
}
|
||||
|
||||
void AActor::ClearRenderLineList()
|
||||
{
|
||||
portnode_t *node = touching_lineportallist;
|
||||
while (node)
|
||||
node = P_DelPortalnode(node);
|
||||
touching_lineportallist = NULL;
|
||||
P_DelSeclist(touching_lineportallist, &FLinePortal::lineportal_thinglist);
|
||||
touching_lineportallist = nullptr;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue