qzdoom-gpl/src/p_checkposition.h
Christoph Oelckers 22e8678903 - refactored P_CollectConnectedGroups to avoid frequent heap allocations for the common cases
* the temporary checking arrays are now static
 * the array that gets the returned values only starts allocating memory when the third touched sector group is found. The most common cases (no touched portal and one touched portal) can be handled without accessing the heap.

- did some streamlining of AActor::LinkToSector:

 * there's only now version of this function that can handle everything
 * moved the FIXMAPTHINGPOS stuff into a separate function.
 * removed LinkToWorldForMapThing and put all special handling this function did into P_PointInSectorBuggy.
2016-02-16 12:51:10 +01:00

110 lines
2.1 KiB
C++

#ifndef P_CHECKPOS_H
#define P_CHECKPOS_H
//============================================================================
//
// This is a dynamic array which holds its first MAX_STATIC entries in normal
// variables to avoid constant allocations which this would otherwise
// require.
//
// When collecting touched portal groups the normal cases are either
// no portals == one group or
// two portals = two groups
//
// Anything with more can happen but far less infrequently, so this
// organization helps avoiding the overhead from heap allocations
// in the vast majority of situations.
//
//============================================================================
struct FPortalGroupArray
{
enum
{
MAX_STATIC = 2
};
FPortalGroupArray()
{
varused = 0;
}
void Clear()
{
data.Clear();
varused = 0;
}
void Add(DWORD num)
{
if (varused < MAX_STATIC) entry[varused++] = num;
else data.Push(num);
}
unsigned Size()
{
return varused + data.Size();
}
DWORD operator[](unsigned index)
{
return index < MAX_STATIC ? entry[index] : data[index - MAX_STATIC];
}
private:
DWORD entry[MAX_STATIC];
unsigned varused;
TArray<DWORD> data;
};
//============================================================================
//
// Used by P_CheckPosition and P_TryMove in place of the original
// set of global variables.
//
//============================================================================
struct FCheckPosition
{
// in
AActor *thing;
fixed_t x;
fixed_t y;
fixed_t z;
// out
sector_t *sector;
fixed_t floorz;
fixed_t ceilingz;
fixed_t dropoffz;
FTextureID floorpic;
int floorterrain;
sector_t *floorsector;
FTextureID ceilingpic;
sector_t *ceilingsector;
bool touchmidtex;
bool abovemidtex;
bool floatok;
bool FromPMove;
line_t *ceilingline;
AActor *stepthing;
// [RH] These are used by PIT_CheckThing and P_XYMovement to apply
// ripping damage once per tic instead of once per move.
bool DoRipping;
TMap<AActor*, bool> LastRipped;
FPortalGroupArray Groups;
int PushTime;
FCheckPosition(bool rip=false)
{
DoRipping = rip;
PushTime = 0;
FromPMove = false;
}
};
#endif