- moved the tid hash into FLevelLocals and adjusted the interface to the iterators.

This commit is contained in:
Christoph Oelckers 2019-01-24 19:28:40 +01:00
parent 4c250a58ca
commit 0e5986769e
15 changed files with 85 additions and 79 deletions

View File

@ -1241,19 +1241,16 @@ public:
// ThingIDs
static void ClearTIDHashes ();
void AddToHash ();
void RemoveFromHash ();
private:
static AActor *TIDHash[128];
static inline int TIDHASH (int key) { return key & 127; }
public:
static FSharedStringArena mStringPropertyData;
private:
friend class FActorIterator;
friend bool P_IsTIDUsed(int tid);
bool FixMapthingPos();
@ -1496,19 +1493,21 @@ public:
class FActorIterator
{
friend struct FLevelLocals;
protected:
FActorIterator (AActor **hash, int i) : TIDHash(hash), base (nullptr), id (i)
{
}
FActorIterator (AActor **hash, int i, AActor *start) : TIDHash(hash), base (start), id (i)
{
}
public:
FActorIterator (int i) : base (NULL), id (i)
{
}
FActorIterator (int i, AActor *start) : base (start), id (i)
{
}
AActor *Next ()
{
if (id == 0)
return NULL;
return nullptr;
if (!base)
base = AActor::TIDHash[id & 127];
base = TIDHash[id & 127];
else
base = base->inext;
@ -1523,21 +1522,23 @@ public:
}
private:
AActor **TIDHash;
AActor *base;
int id;
};
class NActorIterator : public FActorIterator
{
friend struct FLevelLocals;
const PClass *type;
protected:
NActorIterator (AActor **hash, const PClass *cls, int id) : FActorIterator (hash, id) { type = cls; }
NActorIterator (AActor **hash, FName cls, int id) : FActorIterator (hash, id) { type = PClass::FindClass(cls); }
public:
NActorIterator (const PClass *cls, int id) : FActorIterator (id) { type = cls; }
NActorIterator (FName cls, int id) : FActorIterator (id) { type = PClass::FindClass(cls); }
NActorIterator (const char *cls, int id) : FActorIterator (id) { type = PClass::FindClass(cls); }
AActor *Next ()
{
AActor *actor;
if (type == NULL) return NULL;
if (type == nullptr) return nullptr;
do
{
actor = FActorIterator::Next ();
@ -1546,9 +1547,6 @@ public:
}
};
bool P_IsTIDUsed(int tid);
int P_FindUniqueTID(int start_tid, int limit);
PClassActor *ClassForSpawn(FName classname);
inline AActor *Spawn(PClassActor *type)

View File

@ -104,6 +104,7 @@ struct FLevelData
FBehaviorContainer Behaviors;
FTagManager tagManager;
AActor *TIDHash[128];
};
@ -120,6 +121,8 @@ struct FLevelLocals : public FLevelData
void FormatMapName(FString &mapname, const char *mapnamecolor);
void ClearAllSubsectorLinks();
void TranslateLineDef (line_t *ld, maplinedef_t *mld, int lineindexforid = -1);
bool IsTIDUsed(int tid);
int FindUniqueTID(int start_tid, int limit);
FSectorTagIterator GetSectorTagIterator(int tag)
{
@ -140,15 +143,15 @@ struct FLevelLocals : public FLevelData
}
FActorIterator GetActorIterator(int tid)
{
return FActorIterator(tid);
return FActorIterator(TIDHash, tid);
}
FActorIterator GetActorIterator(int tid, AActor *start)
{
return FActorIterator(tid, start);
return FActorIterator(TIDHash, tid, start);
}
NActorIterator GetActorIterator(FName type, int tid)
{
return NActorIterator(type, tid);
return NActorIterator(TIDHash, type, tid);
}
bool SectorHasTags(sector_t *sector)
{
@ -208,6 +211,12 @@ struct FLevelLocals : public FLevelData
}
void ClearTIDHashes ()
{
memset(TIDHash, 0, sizeof(TIDHash));
}
uint8_t md5[16]; // for savegame validation. If the MD5 does not match the savegame won't be loaded.
int time; // time in the hub
int maptime; // time in the map

View File

@ -5751,10 +5751,10 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, int32_t *args)
break;
case ACSF_UniqueTID:
return P_FindUniqueTID(argCount > 0 ? args[0] : 0, (argCount > 1 && args[1] >= 0) ? args[1] : 0);
return level.FindUniqueTID(argCount > 0 ? args[0] : 0, (argCount > 1 && args[1] >= 0) ? args[1] : 0);
case ACSF_IsTIDUsed:
return P_IsTIDUsed(args[0]);
return level.IsTIDUsed(args[0]);
case ACSF_Sqrt:
return xs_FloorToInt(g_sqrt(double(args[0])));

View File

@ -2886,19 +2886,6 @@ void P_NightmareRespawn (AActor *mobj)
}
AActor *AActor::TIDHash[128];
//
// P_ClearTidHashes
//
// Clears the tid hashtable.
//
void AActor::ClearTIDHashes ()
{
memset(TIDHash, 0, sizeof(TIDHash));
}
//
// P_AddMobjToHash
//
@ -2916,10 +2903,11 @@ void AActor::AddToHash ()
else
{
int hash = TIDHASH (tid);
auto &slot = level.TIDHash[hash];
inext = TIDHash[hash];
iprev = &TIDHash[hash];
TIDHash[hash] = this;
inext = slot;
iprev = &slot;
slot = this;
if (inext)
{
inext->iprev = &inext;
@ -2956,9 +2944,9 @@ void AActor::RemoveFromHash ()
//
//==========================================================================
bool P_IsTIDUsed(int tid)
bool FLevelLocals::IsTIDUsed(int tid)
{
AActor *probe = AActor::TIDHash[tid & 127];
AActor *probe = TIDHash[tid & 127];
while (probe != NULL)
{
if (probe->tid == tid)
@ -2981,7 +2969,7 @@ bool P_IsTIDUsed(int tid)
//
//==========================================================================
int P_FindUniqueTID(int start_tid, int limit)
int FLevelLocals::FindUniqueTID(int start_tid, int limit)
{
int tid;
@ -2997,7 +2985,7 @@ int P_FindUniqueTID(int start_tid, int limit)
}
for (tid = start_tid; tid <= limit; ++tid)
{
if (tid != 0 && !P_IsTIDUsed(tid))
if (tid != 0 && !IsTIDUsed(tid))
{
return tid;
}
@ -3019,7 +3007,7 @@ int P_FindUniqueTID(int start_tid, int limit)
{
// Use a positive starting TID.
tid = pr_uniquetid.GenRand32() & INT_MAX;
tid = P_FindUniqueTID(tid == 0 ? 1 : tid, 5);
tid = FindUniqueTID(tid == 0 ? 1 : tid, 5);
if (tid != 0)
{
return tid;
@ -3033,7 +3021,7 @@ int P_FindUniqueTID(int start_tid, int limit)
CCMD(utid)
{
Printf("%d\n",
P_FindUniqueTID(argv.argc() > 1 ? atoi(argv[1]) : 0,
level.FindUniqueTID(argv.argc() > 1 ? atoi(argv[1]) : 0,
(argv.argc() > 2 && atoi(argv[2]) >= 0) ? atoi(argv[2]) : 0));
}

View File

@ -276,6 +276,7 @@ void FLevelLocals::ClearLevelData()
ClearPortals();
tagManager.Clear();
ClearTIDHashes();
Behaviors.UnloadModules();
SpotState = nullptr;
ACSThinker = nullptr;
@ -336,9 +337,6 @@ void P_FreeLevelData ()
R_FreePastViewers();
P_ClearUDMFKeys();
// [RH] Clear all ThingID hash chains.
AActor::ClearTIDHashes();
interpolator.ClearInterpolations(); // [RH] Nothing to interpolate on a fresh level.
level.ClearAllSubsectorLinks(); // can't be done as part of the polyobj deletion process.
SN_StopAllSequences ();

View File

@ -342,25 +342,25 @@ class DActorIterator : public DObject, public NActorIterator
DECLARE_ABSTRACT_CLASS(DActorIterator, DObject)
public:
DActorIterator(PClassActor *cls = nullptr, int tid = 0)
: NActorIterator(cls, tid)
DActorIterator(AActor **hash, PClassActor *cls = nullptr, int tid = 0)
: NActorIterator(hash, cls, tid)
{
}
};
IMPLEMENT_CLASS(DActorIterator, true, false);
static DActorIterator *CreateActI(int tid, PClassActor *type)
static DActorIterator *CreateActI(FLevelLocals *Level, int tid, PClassActor *type)
{
return Create<DActorIterator>(type, tid);
return Create<DActorIterator>(Level->TIDHash, type, tid);
}
DEFINE_ACTION_FUNCTION_NATIVE(DActorIterator, Create, CreateActI)
DEFINE_ACTION_FUNCTION_NATIVE(FLevelLocals, CreateActorIterator, CreateActI)
{
PARAM_PROLOGUE;
PARAM_SELF_STRUCT_PROLOGUE(FLevelLocals);
PARAM_INT(tid);
PARAM_CLASS(type, AActor);
ACTION_RETURN_OBJECT(Create<DActorIterator>(type, tid));
ACTION_RETURN_OBJECT(CreateActI(self, tid, type));
}
static AActor *NextActI(DActorIterator *self)

View File

@ -893,12 +893,17 @@ DEFINE_ACTION_FUNCTION_NATIVE(AActor, GetFloorTerrain, GetFloorTerrain)
ACTION_RETURN_POINTER(GetFloorTerrain(self));
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, FindUniqueTid, P_FindUniqueTID)
static int P_FindUniqueTID(FLevelLocals *Level, int start, int limit)
{
PARAM_PROLOGUE;
return Level->FindUniqueTID(start, limit);
}
DEFINE_ACTION_FUNCTION_NATIVE(FLevelLocals, FindUniqueTid, P_FindUniqueTID)
{
PARAM_SELF_STRUCT_PROLOGUE(FLevelLocals);
PARAM_INT(start);
PARAM_INT(limit);
ACTION_RETURN_INT(P_FindUniqueTID(start, limit));
ACTION_RETURN_INT(P_FindUniqueTID(self, start, limit));
}
static void RemoveFromHash(AActor *self)

View File

@ -584,7 +584,10 @@ class Actor : Thinker native
native static int ApplyDamageFactors(class<Inventory> itemcls, Name damagetype, int damage, int defdamage);
native void RemoveFromHash();
native void ChangeTid(int newtid);
native static int FindUniqueTid(int start = 0, int limit = 0);
deprecated("3.8") static int FindUniqueTid(int start = 0, int limit = 0)
{
return level.FindUniqueTid(start, limit);
}
native void SetShade(color col);
native clearscope int GetRenderStyle() const;
native clearscope bool CheckKeys(int locknum, bool remote, bool quiet = false);

View File

@ -480,8 +480,11 @@ class ThinkerIterator : Object native
}
class ActorIterator : Object native
{
native static ActorIterator Create(int tid, class<Actor> type = "Actor");
{
deprecated("3.8") static ActorIterator Create(int tid, class<Actor> type = "Actor")
{
return level.CreateActorIterator(tid, type);
}
native Actor Next();
native void Reinit();
}
@ -691,6 +694,7 @@ struct LevelLocals native
native bool IsFreelookAllowed() const;
native void StartIntermission(Name type, int state) const;
native SpotState GetSpotState(bool create = true);
native int FindUniqueTid(int start = 0, int limit = 0);
native static clearscope bool IsPointInMap(vector3 p);
@ -708,7 +712,8 @@ struct LevelLocals native
native SectorTagIterator CreateSectorTagIterator(int tag, line defline = null);
native LineIdIterator CreateLineIdIterator(int tag);
native ActorIterator CreateActorIterator(int tid, class<Actor> type = "Actor");
String TimeFormatted(bool totals = false)
{
int sec = Thinker.Tics2Seconds(totals? totaltime : time);

View File

@ -135,7 +135,7 @@ class Dragon : Actor
{
continue;
}
ActorIterator iter = ActorIterator.Create(targ.args[i]);
ActorIterator iter = Level.CreateActorIterator(targ.args[i]);
mo = iter.Next ();
if (mo == null)
{
@ -171,7 +171,7 @@ class Dragon : Actor
{
i = (random[DragonSeek]() >> 2) % 5;
} while(!targ.args[i]);
ActorIterator iter = ActorIterator.Create(targ.args[i]);
ActorIterator iter = Level.CreateActorIterator(targ.args[i]);
tracer = iter.Next ();
}
}
@ -186,7 +186,7 @@ class Dragon : Actor
void A_DragonInitFlight()
{
ActorIterator iter = ActorIterator.Create(tid);
ActorIterator iter = Level.CreateActorIterator(tid);
do
{ // find the first tid identical to the dragon's tid

View File

@ -129,7 +129,7 @@ class Korax : Actor
{
if ((!special2) && (health <= (SpawnHealth()/2)))
{
ActorIterator it = ActorIterator.Create(KORAX_FIRST_TELEPORT_TID);
ActorIterator it = Level.CreateActorIterator(KORAX_FIRST_TELEPORT_TID);
Actor spot = it.Next ();
if (spot != null)
{
@ -158,7 +158,7 @@ class Korax : Actor
{
if (random[KoraxChase]() < 10)
{
ActorIterator it = ActorIterator.Create(KORAX_TELEPORT_TID);
ActorIterator it = Level.CreateActorIterator(KORAX_TELEPORT_TID);
Actor spot;
if (tracer != null)

View File

@ -151,11 +151,11 @@ class ScriptUtil play
//
//==========================================================================
static void SetMarineWeapon(Actor activator, int tid, int marineweapontype)
static void SetMarineWeapon(LevelLocals Level, Actor activator, int tid, int marineweapontype)
{
if (tid != 0)
{
let it = ActorIterator.Create(tid, 'ScriptedMarine');
let it = Level.CreateActorIterator(tid, 'ScriptedMarine');
ScriptedMarine marine;
while ((marine = ScriptedMarine(it.Next())) != NULL)
@ -179,13 +179,13 @@ class ScriptUtil play
//
//==========================================================================
static void SetMarineSprite(Actor activator, int tid, class<Actor> type)
static void SetMarineSprite(LevelLocals Level, Actor activator, int tid, class<Actor> type)
{
if (type != NULL)
{
if (tid != 0)
{
let it = ActorIterator.Create(tid, 'ScriptedMarine');
let it = Level.CreateActorIterator(tid, 'ScriptedMarine');
ScriptedMarine marine;
while ((marine = ScriptedMarine(it.Next())) != NULL)

View File

@ -66,7 +66,7 @@ class AimingCamera : SecurityCamera
MaxPitchChange = double(changepitch / TICRATE);
Range /= TICRATE;
ActorIterator it = ActorIterator.Create(args[3]);
ActorIterator it = Level.CreateActorIterator(args[3]);
tracer = it.Next ();
if (tracer == NULL)
{
@ -82,7 +82,7 @@ class AimingCamera : SecurityCamera
{
if (tracer == NULL && args[3] != 0)
{ // Recheck, in case something with this TID was created since the last time.
ActorIterator it = ActorIterator.Create(args[3]);
ActorIterator it = Level.CreateActorIterator(args[3]);
tracer = it.Next ();
}
if (tracer != NULL)

View File

@ -74,7 +74,7 @@ class InterpolationPoint : Actor
me.bVisited = true;
let iterator = ActorIterator.Create(me.args[3] + 256 * me.args[4], "InterpolationPoint");
let iterator = Level.CreateActorIterator(me.args[3] + 256 * me.args[4], "InterpolationPoint");
me.Next = InterpolationPoint(iterator.Next ());
if (me.Next == me) // Don't link to self
@ -186,7 +186,7 @@ class PathFollower : Actor
override void PostBeginPlay ()
{
// Find first node of path
let iterator = ActorIterator.Create(args[0] + 256 * args[1], "InterpolationPoint");
let iterator = Level.CreateActorIterator(args[0] + 256 * args[1], "InterpolationPoint");
let node = InterpolationPoint(iterator.Next ());
InterpolationPoint prevnode;
@ -310,7 +310,7 @@ class PathFollower : Actor
void NewNode ()
{
let iterator = ActorIterator.Create(CurrNode.tid, "InterpolationSpecial");
let iterator = Level.CreateActorIterator(CurrNode.tid, "InterpolationSpecial");
InterpolationSpecial spec;
while ( (spec = InterpolationSpecial(iterator.Next ())) )
@ -440,7 +440,7 @@ class ActorMover : PathFollower
{
Super.PostBeginPlay ();
let iterator = ActorIterator.Create(args[3]);
let iterator = Level.CreateActorIterator(args[3]);
tracer = iterator.Next ();
if (tracer == null)
@ -552,7 +552,7 @@ class MovingCamera : PathFollower
Activator = null;
if (args[3] != 0)
{
let iterator = ActorIterator.Create(args[3]);
let iterator = Level.CreateActorIterator(args[3]);
tracer = iterator.Next ();
if (tracer == null)
{

View File

@ -109,7 +109,7 @@ class SkyPicker : Actor
}
else
{
let it = ActorIterator.Create(args[0], "SkyViewpoint");
let it = Level.CreateActorIterator(args[0], "SkyViewpoint");
box = it.Next ();
}