r703 - trunk/game
lordhavoc at icculus.org
lordhavoc at icculus.org
Fri May 5 12:23:34 EDT 2006
Author: lordhavoc
Date: 2006-05-05 12:23:34 -0400 (Fri, 05 May 2006)
New Revision: 703
Modified:
trunk/game/g_entity.c
trunk/game/g_main.h
Log:
thanks to painQuin for a patch to handle freed entity timeouts (to give
other entities a chance to notice that their reference is dead)
Modified: trunk/game/g_entity.c
===================================================================
--- trunk/game/g_entity.c 2006-05-04 23:09:55 UTC (rev 702)
+++ trunk/game/g_entity.c 2006-05-05 16:23:34 UTC (rev 703)
@@ -8,7 +8,9 @@
G_Entity *G_Entity_New(G_Entity *parent, const G_Entity_Class *eclass, const G_Entity_Position *position)
{
G_Entity *entity;
- NUint32 childindex = 0;
+ Nbool bestfound = false;
+ Nvec tbest = 0;
+ NUint32 childindex = 0, bestindex = 0;
if (!eclass)
return NULL;
if (!eclass->codeclass->name)
@@ -33,32 +35,56 @@
}
if (!position)
position = &GS.identityposition;
- // TODO: add a timeout after freeing an entity before it will be reused? (if so this will need to scan twice if it can't find one with the timeout)
+
for (entity = G.entities + G.allocentity;G.allocentity < G_MAX_ENTITIES;G.allocentity++, entity++)
{
if (!entity->eclass)
{
- G.allocentity++;
- G.numentities = Max(G.numentities, G.allocentity);
- memset(entity, 0, sizeof(G_Entity));
- entity->eclass = eclass;
- // mark this entity as not being a network related entity
- // (if it really is, the network code will change this)
- entity->networkindex = -1;
- if (parent)
+ if (G.time - entity->freetime >= FREETIMEOUT)
{
- entity->owner = parent;
- parent->children[childindex] = entity;
+ // 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++;
+ break;
}
- entity->position = *position;
- if (entity->eclass->modelname && entity->eclass->modelname[0])
- G_Entity_SetModel(entity, entity->eclass->modelname);
- entity->lifetime = entity->eclass->lifetime;
- return entity;
+ else if (!foundbest || (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
+ // (this is a dangerous situation but it's even worse to fail)
+ foundbest = true;
+ bestindex = G.allocentity;
+ tbest = entity->freetime;
+ }
}
}
- Console_Printf("Ran out of entities (%i)\n", G_MAX_ENTITIES);
- return NULL;
+ 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
+ // frame)
+ G.numentities = Max(G.numentities, bestindex);
+ memset(entity, 0, sizeof(G_Entity));
+ entity->eclass = eclass;
+ // mark this entity as not being a network related entity
+ // (if it really is, the network code will change this)
+ entity->networkindex = -1;
+ if (parent)
+ {
+ entity->owner = parent;
+ parent->children[childindex] = entity;
+ }
+ entity->position = *position;
+ if (entity->eclass->modelname && entity->eclass->modelname[0])
+ G_Entity_SetModel(entity, entity->eclass->modelname);
+ entity->lifetime = entity->eclass->lifetime;
+ return entity;
}
void G_Entity_Spawn(G_Entity *entity)
@@ -115,6 +141,7 @@
memset(entity, 0, sizeof(*entity));
// reset allocentity to a level that will find this freshly freed entity
G.allocentity = Min(G.allocentity, entitynum);
+ entity->freetime = G.time;
}
void G_Entity_RemoveChildren(G_Entity *entity)
Modified: trunk/game/g_main.h
===================================================================
--- trunk/game/g_main.h 2006-05-04 23:09:55 UTC (rev 702)
+++ trunk/game/g_main.h 2006-05-05 16:23:34 UTC (rev 703)
@@ -541,9 +541,14 @@
Nvec lifetime;
// weapons
Nvec attackdelay;
+
+ Nvec freetime;
}
G_Entity;
+// number of seconds before an entity slot will be reused (unless overloaded, in which case the least recently freed entity will be chosen)
+#define FREETIMEOUT 0.2
+
typedef struct G_Trace
{
G_Entity *moveentity;
More information about the neither-commits
mailing list