r708 - trunk/game
lordhavoc at icculus.org
lordhavoc at icculus.org
Fri May 5 17:50:55 EDT 2006
Author: lordhavoc
Date: 2006-05-05 17:50:55 -0400 (Fri, 05 May 2006)
New Revision: 708
Modified:
trunk/game/g_entity.c
Log:
reworked G_Entity_New some more to fix a horrible crash and added more
comments
Modified: trunk/game/g_entity.c
===================================================================
--- trunk/game/g_entity.c 2006-05-05 21:32:26 UTC (rev 707)
+++ trunk/game/g_entity.c 2006-05-05 21:50:55 UTC (rev 708)
@@ -8,9 +8,8 @@
G_Entity *G_Entity_New(G_Entity *parent, const G_Entity_Class *eclass, const G_Entity_Position *position)
{
G_Entity *entity;
- Nbool bestfound = false;
- Nvec tbest = 0;
- NUint32 childindex = 0, bestindex = 0;
+ Nvec tbest;
+ NUint32 childindex = 0, bestindex, index;
if (!eclass)
return NULL;
if (!eclass->codeclass->name)
@@ -36,35 +35,45 @@
if (!position)
position = &GS.identityposition;
- for (entity = G.entities + G.allocentity;G.allocentity < G_MAX_ENTITIES;G.allocentity++, entity++)
+ // search for the first available entity slot in an optimized manner.
+ // G.allocentity tracks the first known gap in the G.entities array, it is
+ // incremented until a gap is found, and reset when an entity is freed
+ while (G.allocentity < G_MAX_ENTITIES && G.entities[G.allocentity].eclass)
+ G.allocentity++;
+ // if we couldn't find any at all, return NULL
+ if (G.allocentity >= G_MAX_ENTITIES)
{
+ Console_Printf("Ran out of entities (%i)\n", G_MAX_ENTITIES);
+ return NULL;
+ }
+ // now we know we're sitting at a valid free slot, but we want to choose
+ // one that hasn't been freed recently as there may still be references
+ // pointing to it (usually they will be cleared a moment later)
+ bestindex = G.allocentity;
+ tbest = G.entities[bestindex].freetime;
+ for (index = G.allocentity + 1, entity = G.entities + index;index < G_MAX_ENTITIES;index++, entity++)
+ {
if (!entity->eclass)
{
- if (G.time - entity->freetime >= FREETIMEOUT)
+ if (entity->freetime == 0 || G.time - entity->freetime >= FREETIMEOUT)
{
// this entity has not been used recently, so anything
// referencing it has probably cleared its references already,
// so it is probably safe to reuse it now
- bestfound = true;
- bestindex = G.allocentity++;
+ bestindex = index;
+ tbest = entity->freetime;
break;
}
- else if (!bestfound || (entity->freetime < tbest))
+ else if (entity->freetime < tbest)
{
// found a free slot that hasn't timed out yet, keep track of
- // which one is oldest incase we can't find one
+ // which one is oldest incase we can't find any safe ones
// (this is a dangerous situation but it's even worse to fail)
- bestfound = true;
- bestindex = G.allocentity;
+ bestindex = index;
tbest = entity->freetime;
}
}
}
- if (!bestfound)
- {
- Console_Printf("Ran out of entities (%i)\n", G_MAX_ENTITIES);
- return NULL;
- }
entity = G.entities + bestindex;
// update entity range to include this newly allocated entity
// (the entity range is used to avoid processing the entire array each
More information about the neither-commits
mailing list