Skip to content

Commit

Permalink
Optimize: Reworked XG_Ticker so that thinking for extended lines and …
Browse files Browse the repository at this point in the history
…sectors is handled in thinkers rather than iterating every linedef and sector in the map, every frame.
  • Loading branch information
danij committed Jun 28, 2008
1 parent 1d15884 commit 5e399b8
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 72 deletions.
16 changes: 9 additions & 7 deletions doomsday/plugins/common/include/p_xgline.h
Expand Up @@ -58,7 +58,6 @@
// class dofuncs use it to determine when a REAL activator isn't present
#define XLE_FUNC 0x100


// Time conversion.
#define FLT2TIC(x) ( (int) ((x)*35) )
#define TIC2FLT(x) ( (x)/35.0f )
Expand Down Expand Up @@ -323,6 +322,11 @@ enum // Line.data references
#define CHSF_DEACTIVATE_WHEN_DONE 0x1
#define CHSF_LOOP 0x2

typedef struct {
thinker_t thinker;
linedef_t* line;
} xlthinker_t;

// State data for each line.
typedef struct {
linetype_t info; // Type definition.
Expand All @@ -343,18 +347,16 @@ extern struct xgclass_s xgClasses[];
// Used as the activator if there is no real activator.
extern struct mobj_s dummything;

// Initialize extended lines for the map.
void XL_Init(void);

// Register the XG classnames for XGdev
void XG_Register(void);

// Think for each extended line.
void XL_Ticker(void);

// Initialize extended lines for the map.
void XL_Init(void);
// Called when reseting engine state.
void XL_Update(void);

void XL_Thinker(xlthinker_t* xl);

void XL_SetLineType(struct linedef_s *line, int id);

linetype_t *XL_GetType(int id);
Expand Down
8 changes: 7 additions & 1 deletion doomsday/plugins/common/include/p_xgsec.h
Expand Up @@ -122,6 +122,11 @@ enum {
XGSP_BLUE
};

typedef struct {
thinker_t thinker;
sector_t* sector;
} xsthinker_t;

typedef struct {
boolean disabled;
function_t rgb[3]; // Don't move the functions around in the struct.
Expand Down Expand Up @@ -156,9 +161,10 @@ typedef struct {
} xgplanemover_t;

void XS_Init(void);
void XS_Ticker(void);
void XS_Update(void);

void XS_Thinker(xsthinker_t* xs);

float XS_Gravity(struct sector_s *sector);
float XS_Friction(struct sector_s *sector);
float XS_ThrustMul(struct sector_s *sector);
Expand Down
74 changes: 36 additions & 38 deletions doomsday/plugins/common/src/p_xgline.c
Expand Up @@ -451,13 +451,7 @@ void XG_Init(void)

void XG_Ticker(void)
{
XS_Ticker(); // Think for sectors.

// Clients rely on the server, they don't do XG themselves.
if(IS_CLIENT)
return;

XL_Ticker(); // Think for lines.
// Nothing to do.
}

/**
Expand Down Expand Up @@ -607,6 +601,16 @@ float XG_RandomPercentFloat(float value, int percent)
return value * (1 + i);
}

boolean findXLThinker(thinker_t* th, void* context)
{
xlthinker_t* xl = (xlthinker_t*) th;

if(xl->line == (linedef_t*) context)
return false; // Stop iteration, we've found it.

return true; // Continue iteration.
}

/**
* Looks for line type definition and sets the line type if one is found.
*/
Expand Down Expand Up @@ -635,6 +639,14 @@ void XL_SetLineType(linedef_t *line, int id)
XG_Dev("XL_SetLineType: Line %i (%s), ID %i.", P_ToIndex(line),
xgClasses[xline->xg->info.lineClass].className, id);

// If there is not already an xlthinker for this line, create one.
if(P_IterateThinkers(XL_Thinker, findXLThinker, line))
{ // Not created one yet.
xlthinker_t* xl = Z_Calloc(sizeof(*xl), PU_LEVSPEC, 0);

xl->thinker.function = XL_Thinker;
P_ThinkerAdd(&xl->thinker);
}
}
else if(id)
{
Expand Down Expand Up @@ -2142,7 +2154,7 @@ void XL_ActivateLine(boolean activating, linetype_t *info, linedef_t *line,
XL_ChangeMaterial(line, sidenum, info->wallSection,
info->deactMaterial, BM_NORMAL, rgba, 0);

// Change the class of the line if asked to
// Change the class of the line if asked to.
if(info->deactLineType)
XL_SetLineType(line, info->deactLineType);
}
Expand Down Expand Up @@ -2547,23 +2559,22 @@ void XL_DoChain(linedef_t *line, int chain, boolean activating,
}

/**
* Called once a tic for each 'real' line on the map (i.e. not dummys).
* XG lines get to think.
*/
void XL_Think(uint idx)
void XL_Thinker(xlthinker_t* xl)
{
float levtime;
linedef_t *line = NULL;
xline_t *xline = P_GetXLine(idx);
xgline_t *xg;
linetype_t *info;
float levtime;
linedef_t* line = xl->line;
xline_t* xline = P_ToXLine(line);
xgline_t* xg;
linetype_t* info;

// Clients rely on the server, they don't do XG themselves.
if(IS_CLIENT)
return;

if(!xline)
{
#if _DEBUG
Con_Message("XL_Think: Index (%i) not xline!\n", idx);
#endif
return; // Not an xline? Perhaps we were passed a dummy index??
}
return; // Not an xline? Most perculiar...

xg = xline->xg;
if(!xg)
Expand All @@ -2572,7 +2583,6 @@ Con_Message("XL_Think: Index (%i) not xline!\n", idx);
if(xg->disabled)
return; // Disabled, do nothing.

line = P_ToPtr(DMU_LINEDEF, idx);
info = &xg->info;
levtime = TIC2FLT(levelTime);

Expand Down Expand Up @@ -2618,7 +2628,8 @@ Con_Message("XL_Think: Index (%i) not xline!\n", idx);
// If the counter goes to zero, it's time to execute the chain.
if(xg->chTimer < 0)
{
XG_Dev("XL_ChainSequenceThink: Line %i, executing...", idx);
XG_Dev("XL_ChainSequenceThink: Line %i, executing...",
P_ToIndex(line));

// Are there any more chains?
if(xg->chIdx < DDLT_MAX_PARAMS && info->iparm[xg->chIdx])
Expand Down Expand Up @@ -2694,7 +2705,7 @@ Con_Message("XL_Think: Index (%i) not xline!\n", idx);
*/

// Front side.
side = P_GetPtr(DMU_LINEDEF, idx, DMU_SIDEDEF0);
side = P_GetPtrp(line, DMU_SIDEDEF0);
if(side)
{
P_GetFloatpv(side, DMU_TOP_MATERIAL_OFFSET_XY, current);
Expand All @@ -2714,7 +2725,7 @@ Con_Message("XL_Think: Index (%i) not xline!\n", idx);
}

// Back side.
side = P_GetPtr(DMU_LINEDEF, idx, DMU_SIDEDEF1);
side = P_GetPtrp(line, DMU_SIDEDEF1);
if(side)
{
P_GetFloatpv(side, DMU_TOP_MATERIAL_OFFSET_XY, current);
Expand All @@ -2735,19 +2746,6 @@ Con_Message("XL_Think: Index (%i) not xline!\n", idx);
}
}

/**
* Think for each extended line.
*/
void XL_Ticker(void)
{
uint i;

for(i = 0; i < numlines; ++i)
{
XL_Think(i);
}
}

/**
* During update, definitions are re-read, so the pointers need to be
* updated. However, this is a bit messy operation, prone to errors.
Expand Down
71 changes: 45 additions & 26 deletions doomsday/plugins/common/src/p_xgsec.c
Expand Up @@ -284,6 +284,29 @@ int C_DECL XLTrav_LineAngle(linedef_t* line, boolean dummy, void* context,
return false; // Stop looking after first hit.
}

boolean findXSThinker(thinker_t* th, void* context)
{
xsthinker_t* xs = (xsthinker_t*) th;

if(xs->sector == (sector_t*) context)
return false; // Stop iteration, we've found it.

return true; // Continue iteration.
}

boolean destroyXSThinker(thinker_t* th, void* context)
{
xsthinker_t* xs = (xsthinker_t*) th;

if(xs->sector == (sector_t*) context)
{
P_ThinkerRemove(&xs->thinker);
return false; // Stop iteration, we're done.
}

return true; // Continue iteration.
}

void XS_SetSectorType(struct sector_s* sec, int special)
{
int i;
Expand Down Expand Up @@ -358,12 +381,24 @@ void XS_SetSectorType(struct sector_s* sec, int special)
info->windAngle = angle / (float) ANGLE_MAX *360;
}
}

// If there is not already an xsthinker for this sector, create one.
if(P_IterateThinkers(XS_Thinker, findXSThinker, sec))
{ // Not created one yet.
xsthinker_t* xs = Z_Calloc(sizeof(*xs), PU_LEVSPEC, 0);

xs->thinker.function = XS_Thinker;
P_ThinkerAdd(&xs->thinker);
}
}
else
{
XG_Dev("XS_SetSectorType: Sector %i, NORMAL TYPE %i", P_ToIndex(sec),
special);

// If there is an xsthinker for this, destroy it.
P_IterateThinkers(XS_Thinker, destroyXSThinker, sec);

// Free previously allocated XG data.
if(xsec->xg)
Z_Free(xsec->xg);
Expand Down Expand Up @@ -2837,25 +2872,20 @@ void XS_ConstrainPlaneOffset(float *offset)
}

/**
* Called for Extended Generalized sectors.
* XG sectors get to think.
*/
void XS_Think(uint idx)
void XS_Thinker(xsthinker_t* xs)
{
int i;
float ang;
float floorOffset[2], ceilOffset[2];
sector_t *sector;
xsector_t *xsector = P_GetXSector(idx);
xgsector_t *xg;
sectortype_t *info;
int i;
float ang;
float floorOffset[2], ceilOffset[2];
sector_t* sector = xs->sector;
xsector_t* xsector = P_ToXSector(sector);
xgsector_t* xg;
sectortype_t* info;

if(!xsector)
{
#if _DEBUG
Con_Message("XS_Think: Index (%i) not xsector!\n", idx);
#endif
return; // Not an xsector? Perhaps we were passed a dummy index??
}
return; // Not an xsector? Most perculiar...

xg = xsector->xg;
if(!xg)
Expand All @@ -2864,7 +2894,6 @@ Con_Message("XS_Think: Index (%i) not xsector!\n", idx);
if(xg->disabled)
return; // This sector is disabled.

sector = P_ToPtr(DMU_SECTOR, idx);
info = &xg->info;

if(!IS_CLIENT)
Expand Down Expand Up @@ -2987,16 +3016,6 @@ Con_Message("XS_Think: Index (%i) not xsector!\n", idx);
}
}

void XS_Ticker(void)
{
uint i;

for(i = 0; i < numsectors; ++i)
{
XS_Think(i);
}
}

float XS_Gravity(struct sector_s *sector)
{
if(!P_ToXSector(sector)->xg ||
Expand Down

0 comments on commit 5e399b8

Please sign in to comment.