- Merged FActorInfo::FindStateExact and FActorInfo::FindState into one function

because the differences are only minimal.
- Removed all the varargs FindState functions because they aren't really needed.
  The engine itself never explicitly checks for more than 2 labels and for the 
  rest a function that gets passed a FName array is more suitable anyway.


SVN r414 (trunk)
This commit is contained in:
Christoph Oelckers 2006-12-16 14:06:21 +00:00
parent 979dfdf4cf
commit 693bf96cb3
11 changed files with 103 additions and 140 deletions

View file

@ -1,4 +1,9 @@
December 16, 2006 (Changes by Graf Zahl) December 16, 2006 (Changes by Graf Zahl)
- Merged FActorInfo::FindStateExact and FActorInfo::FindState into one function
because the differences are only minimal.
- Removed all the varargs FindState functions because they aren't really needed.
The engine itself never explicitly checks for more than 2 labels and for the
rest a function that gets passed a FName array is more suitable anyway.
- Changed state label storage so that each actor owns all the state labels itself - Changed state label storage so that each actor owns all the state labels itself
and doesn't have to traverse parent lists to find them. This is required for and doesn't have to traverse parent lists to find them. This is required for
Dehacked actors that inherit states (e.g. NonsolidMeat and Spectre) but it also Dehacked actors that inherit states (e.g. NonsolidMeat and Spectre) but it also

View file

@ -749,8 +749,7 @@ public:
bool UpdateWaterLevel (fixed_t oldz); bool UpdateWaterLevel (fixed_t oldz);
FState *FindState (FName label) const; FState *FindState (FName label) const;
FState *FindState (int numnames, int first, ...) const; FState *FindState (FName label, FName sublabel, bool exact = false) const;
FState *FindState (int numnames, va_list arglist) const;
bool HasSpecialDeathStates () const; bool HasSpecialDeathStates () const;
static FState States[]; static FState States[];

View file

@ -2499,7 +2499,7 @@ static bool LoadDehSupp ()
StateMap[i].State = def->SpawnState; StateMap[i].State = def->SpawnState;
break; break;
case DeathState: case DeathState:
StateMap[i].State = type->ActorInfo->FindStateExact(1, NAME_Death); StateMap[i].State = type->ActorInfo->FindState(NAME_Death);
break; break;
} }
StateMap[i].StateSpan = supp[6+i*4+3]; StateMap[i].StateSpan = supp[6+i*4+3];

View file

@ -715,7 +715,7 @@ bool F_CastResponder (event_t* ev)
// go into death frame // go into death frame
castdeath = true; castdeath = true;
caststate = castorder[castnum].Class->ActorInfo->FindState(1, NAME_Death); caststate = castorder[castnum].Class->ActorInfo->FindState(NAME_Death);
if (caststate != NULL) if (caststate != NULL)
{ {
casttics = caststate->GetTics(); casttics = caststate->GetTics();

View file

@ -421,29 +421,6 @@ void FStateLabels::Destroy ()
} }
//===========================================================================
//
// FindState (one name version)
//
// Finds a state with the exact specified name.
//
//===========================================================================
FState *AActor::FindState (FName label) const
{
const FActorInfo *info = GetClass()->ActorInfo;
if (info->StateList != NULL)
{
FStateLabel *slabel = info->StateList->FindLabel (label);
if (slabel != NULL)
{
return slabel->State;
}
}
return NULL;
}
//=========================================================================== //===========================================================================
// //
// HasStates // HasStates
@ -470,6 +447,58 @@ bool AActor::HasSpecialDeathStates () const
return false; return false;
} }
//===========================================================================
//
// FindState (one name version)
//
// Finds a state with the exact specified name.
//
//===========================================================================
FState *AActor::FindState (FName label) const
{
const FActorInfo *info = GetClass()->ActorInfo;
if (info->StateList != NULL)
{
FStateLabel *slabel = info->StateList->FindLabel (label);
if (slabel != NULL)
{
return slabel->State;
}
}
return NULL;
}
//===========================================================================
//
// FindState (two name version)
//
//===========================================================================
FState *AActor::FindState (FName label, FName sublabel, bool exact) const
{
const FActorInfo *info = GetClass()->ActorInfo;
if (info->StateList != NULL)
{
FStateLabel *slabel = info->StateList->FindLabel (label);
if (slabel != NULL)
{
if (slabel->Children != NULL)
{
FStateLabel *slabel2 = slabel->Children->FindLabel(sublabel);
if (slabel2 != NULL)
{
return slabel2->State;
}
}
if (!exact) return slabel->State;
}
}
return NULL;
}
//=========================================================================== //===========================================================================
// //
// FindState (multiple names version) // FindState (multiple names version)
@ -485,37 +514,18 @@ bool AActor::HasSpecialDeathStates () const
// has names, ignore it. If the argument list still has names, remember it. // has names, ignore it. If the argument list still has names, remember it.
// //
//=========================================================================== //===========================================================================
FState *FActorInfo::FindState (FName name) const
FState *AActor::FindState (int numnames, int first, ...) const // The 'first' parameter is only here to
// disambiguate from the single parameter version
// Please note that this code does *NOT* compile
// properly with VC++ when 'first' is removed!
{ {
va_list arglist; return FindState(1, &name);
va_start (arglist, numnames);
return FindState (numnames, arglist);
} }
FState *FActorInfo::FindState (int numnames, ...) const FState *FActorInfo::FindState (int numnames, FName *names, bool exact) const
{
va_list arglist;
va_start (arglist, numnames);
return FindState (numnames, arglist);
}
FState *AActor::FindState (int numnames, va_list arglist) const
{
return GetClass()->ActorInfo->FindState (numnames, arglist);
}
FState *FActorInfo::FindState (int numnames, va_list arglist) const
{ {
FStateLabels *labels = StateList; FStateLabels *labels = StateList;
FState *best = NULL; FState *best = NULL;
if (labels != NULL) if (labels != NULL)
{ {
va_list names = arglist;
int count = 0; int count = 0;
FStateLabel *slabel = NULL; FStateLabel *slabel = NULL;
FName label; FName label;
@ -523,7 +533,7 @@ FState *FActorInfo::FindState (int numnames, va_list arglist) const
// Find the best-matching label for this class. // Find the best-matching label for this class.
while (labels != NULL && count < numnames) while (labels != NULL && count < numnames)
{ {
label = ENamedName(va_arg (names, int)); label = *names++;
slabel = labels->FindLabel (label); slabel = labels->FindLabel (label);
if (slabel != NULL) if (slabel != NULL)
@ -537,62 +547,11 @@ FState *FActorInfo::FindState (int numnames, va_list arglist) const
break; break;
} }
} }
if (count < numnames && exact) return NULL;
} }
return best; return best;
} }
//===========================================================================
//
// FindStateExact
//
// This is like FindState, except it will only return states whose labels
// match the requested one exactly.
//
//===========================================================================
FState *FActorInfo::FindStateExact (int numnames, ...) const
{
va_list arglist;
va_start (arglist, numnames);
return FindStateExact (numnames, arglist);
}
FState *FActorInfo::FindStateExact (int numnames, va_list arglist) const
{
FStateLabels *labels = StateList;
if (labels != NULL)
{
va_list names = arglist;
int count = 0;
FStateLabel *slabel = NULL;
FName label;
// Look for a matching label for this class.
while (labels != NULL && count < numnames)
{
label = ENamedName(va_arg (names, int));
slabel = labels->FindLabel (label);
if (slabel != NULL)
{
count++;
labels = slabel->Children;
}
else
{
break;
}
}
// Only exact matches count.
if (slabel != NULL && count == numnames)
{
return slabel->State;
}
}
return NULL;
}
//=========================================================================== //===========================================================================
// //
// Changes a single state // Changes a single state

View file

@ -384,12 +384,11 @@ struct FActorInfo
void ApplyDefaults (BYTE *defaults); void ApplyDefaults (BYTE *defaults);
void RegisterIDs (); void RegisterIDs ();
FState *FindState (int numnames, ...) const; FState *FindState (FName name) const;
FState *FindState (int numnames, va_list arglist) const; FState *FindState (int numnames, FName *names, bool exact=false) const;
void ChangeState (FName label, FState * newstate) const; void ChangeState (FName label, FState * newstate) const;
FState *FindStateExact (int numnames, ...) const;
FState *FindStateExact (int numnames, va_list arglist) const;
FActorInfo *GetReplacement (); FActorInfo *GetReplacement ();
FActorInfo *GetReplacee (); FActorInfo *GetReplacee ();

View file

@ -613,7 +613,7 @@ void AActor::Die (AActor *source, AActor *inflictor)
if (DamageType != NAME_None) if (DamageType != NAME_None)
{ {
diestate = GetClass()->ActorInfo->FindStateExact (2, NAME_Death, int(DamageType)); diestate = FindState (NAME_Death, DamageType, true);
if (diestate == NULL) if (diestate == NULL)
{ {
if (DamageType == NAME_Ice) if (DamageType == NAME_Ice)
@ -641,7 +641,7 @@ void AActor::Die (AActor *source, AActor *inflictor)
if ((health<gibhealth || flags4 & MF4_EXTREMEDEATH) && !(flags4 & MF4_NOEXTREMEDEATH)) if ((health<gibhealth || flags4 & MF4_EXTREMEDEATH) && !(flags4 & MF4_NOEXTREMEDEATH))
{ // Extreme death { // Extreme death
diestate = GetClass()->ActorInfo->FindStateExact (2, NAME_Death, NAME_Extreme); diestate = FindState (NAME_Death, NAME_Extreme, true);
// if a non-player mark as extremely dead for the crash state. // if a non-player mark as extremely dead for the crash state.
if (diestate != NULL && player == NULL && health >= gibhealth) health = gibhealth-1; if (diestate != NULL && player == NULL && health >= gibhealth) health = gibhealth-1;
} }
@ -1086,7 +1086,7 @@ void P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage
return; return;
} }
FState * woundstate = target->FindState(2,NAME_Wound, (int)mod); FState * woundstate = target->FindState(NAME_Wound, mod);
if (woundstate != NULL) if (woundstate != NULL)
{ {
int woundhealth = RUNTIME_TYPE(target)->Meta.GetMetaInt (AMETA_WoundHealth, 6); int woundhealth = RUNTIME_TYPE(target)->Meta.GetMetaInt (AMETA_WoundHealth, 6);
@ -1104,7 +1104,7 @@ void P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage
if (pr_lightning() < 96) if (pr_lightning() < 96)
{ {
target->flags |= MF_JUSTHIT; // fight back! target->flags |= MF_JUSTHIT; // fight back!
FState * painstate = target->FindState(2,NAME_Pain, (int)mod); FState * painstate = target->FindState(NAME_Pain, mod);
if (painstate != NULL) target->SetState (painstate); if (painstate != NULL) target->SetState (painstate);
} }
else else
@ -1119,7 +1119,7 @@ void P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage
else else
{ {
target->flags |= MF_JUSTHIT; // fight back! target->flags |= MF_JUSTHIT; // fight back!
FState * painstate = target->FindState(2,NAME_Pain, (int)mod); FState * painstate = target->FindState(NAME_Pain, mod);
if (painstate != NULL) target->SetState (painstate); if (painstate != NULL) target->SetState (painstate);
if (inflictor && inflictor->IsKindOf (RUNTIME_CLASS(APoisonCloud))) if (inflictor && inflictor->IsKindOf (RUNTIME_CLASS(APoisonCloud)))
{ {
@ -1311,7 +1311,7 @@ void P_PoisonDamage (player_t *player, AActor *source, int damage,
} }
if (!(level.time&63) && playPainSound) if (!(level.time&63) && playPainSound)
{ {
FState * painstate = target->FindState(2,NAME_Pain, (int)target->DamageType); FState * painstate = target->FindState(NAME_Pain, target->DamageType);
if (painstate != NULL) target->SetState (painstate); if (painstate != NULL) target->SetState (painstate);
} }
/* /*

View file

@ -1014,7 +1014,7 @@ void P_ExplodeMissile (AActor *mo, line_t *line, AActor *target)
if (target != NULL && target->flags & (MF_SHOOTABLE|MF_CORPSE)) if (target != NULL && target->flags & (MF_SHOOTABLE|MF_CORPSE))
{ {
if (target->flags & MF_NOBLOOD) nextstate = mo->FindState(NAME_Crash); if (target->flags & MF_NOBLOOD) nextstate = mo->FindState(NAME_Crash);
if (nextstate == NULL) nextstate = mo->FindState(2, NAME_Death, NAME_Extreme); if (nextstate == NULL) nextstate = mo->FindState(NAME_Death, NAME_Extreme);
} }
if (nextstate == NULL) nextstate = mo->FindState(NAME_Death); if (nextstate == NULL) nextstate = mo->FindState(NAME_Death);
mo->SetState (nextstate); mo->SetState (nextstate);
@ -4711,7 +4711,7 @@ int AActor::TakeSpecialDamage (AActor *inflictor, AActor *source, int damage, FN
target = source; target = source;
if (pr_takedamage() < PainChance) if (pr_takedamage() < PainChance)
{ {
FState * painstate = FindState(2,NAME_Pain, (int)damagetype); FState * painstate = FindState(NAME_Pain, damagetype);
if (painstate != NULL) SetState (painstate); if (painstate != NULL) SetState (painstate);
} }
return -1; return -1;
@ -4729,7 +4729,7 @@ int AActor::TakeSpecialDamage (AActor *inflictor, AActor *source, int damage, FN
} }
if (damagetype == NAME_Ice) if (damagetype == NAME_Ice)
{ {
death = GetClass()->ActorInfo->FindStateExact (2, NAME_Death, NAME_Ice); death = FindState (NAME_Death, NAME_Ice, true);
if (death == NULL && !deh.NoAutofreeze && !(flags4 & MF4_NOICEDEATH) && if (death == NULL && !deh.NoAutofreeze && !(flags4 & MF4_NOICEDEATH) &&
(player || (flags3 & MF3_ISMONSTER))) (player || (flags3 & MF3_ISMONSTER)))
{ {
@ -4738,7 +4738,7 @@ int AActor::TakeSpecialDamage (AActor *inflictor, AActor *source, int damage, FN
} }
else else
{ {
death = FindState (2, NAME_Death, int(damagetype)); death = FindState (NAME_Death, damagetype);
} }
return (death == NULL) ? -1 : damage; return (death == NULL) ? -1 : damage;
} }
@ -4753,7 +4753,7 @@ void AActor::Crash()
if (DamageType != NAME_None) if (DamageType != NAME_None)
{ {
crashstate = GetClass()->ActorInfo->FindStateExact(2, NAME_Crash, int(DamageType)); crashstate = FindState(NAME_Crash, DamageType, true);
} }
if (crashstate == NULL) if (crashstate == NULL)
{ {
@ -4762,7 +4762,7 @@ void AActor::Crash()
if (health<gibhealth) if (health<gibhealth)
{ // Extreme death { // Extreme death
crashstate = FindState (2, NAME_Crash, NAME_Extreme); crashstate = FindState (NAME_Crash, NAME_Extreme);
} }
else else
{ // Normal death { // Normal death

View file

@ -79,7 +79,7 @@ extern TArray<FActorInfo *> Decorations;
TArray<char*> DecalNames; TArray<char*> DecalNames;
// all state parameters // all state parameters
TArray<int> StateParameters; TArray<int> StateParameters;
TArray<int> JumpParameters; TArray<FName> JumpParameters;
//========================================================================== //==========================================================================
// //
@ -917,7 +917,7 @@ FState * FindStateInClass(AActor * actor, const PClass * type, const char * name
MakeStateNameList(name, &namelist); MakeStateNameList(name, &namelist);
FActorInfo * info = type->ActorInfo; FActorInfo * info = type->ActorInfo;
if (info) return info->FindStateExact(namelist.Size(), (va_list)&namelist[0]); if (info) return info->FindState(namelist.Size(), &namelist[0], true);
return NULL; return NULL;
} }
@ -1014,12 +1014,12 @@ void InstallStates(FActorInfo *info, AActor *defaults)
info->StateList = CreateStateLabelList(StateLabels); info->StateList = CreateStateLabelList(StateLabels);
// Cache these states as member veriables. // Cache these states as member veriables.
defaults->SpawnState = info->FindStateExact(1,NAME_Spawn); defaults->SpawnState = info->FindState(NAME_Spawn);
defaults->SeeState = info->FindStateExact(1,NAME_See); defaults->SeeState = info->FindState(NAME_See);
// Melee and Missile states are manipulated by the scripted marines so they // Melee and Missile states are manipulated by the scripted marines so they
// have to be stored locally // have to be stored locally
defaults->MeleeState = info->FindStateExact(1,NAME_Melee); defaults->MeleeState = info->FindState(NAME_Melee);
defaults->MissileState = info->FindStateExact(1,NAME_Missile); defaults->MissileState = info->FindState(NAME_Missile);
} }
@ -1637,7 +1637,7 @@ do_stop:
} }
else else
{ {
if (JumpParameters.Size()==0) JumpParameters.Push(0); if (JumpParameters.Size()==0) JumpParameters.Push(NAME_None);
v = -(int)JumpParameters.Size(); v = -(int)JumpParameters.Size();
FString statestring = ParseStateString(); FString statestring = ParseStateString();
@ -1675,20 +1675,20 @@ do_stop:
// labels in subclasses. // labels in subclasses.
// It also means that the validity of the given state cannot // It also means that the validity of the given state cannot
// be checked here. // be checked here.
JumpParameters.Push(0); JumpParameters.Push(NAME_None);
} }
TArray<FName> names; TArray<FName> names;
MakeStateNameList(statestring, &names); MakeStateNameList(statestring, &names);
if (stype != NULL) if (stype != NULL)
{ {
if (!stype->ActorInfo->FindState(names.Size(), (va_list)&names[0])) if (!stype->ActorInfo->FindState(names.Size(), &names[0]))
{ {
SC_ScriptError("Jump to unknown state '%s' in class '%s'", SC_ScriptError("Jump to unknown state '%s' in class '%s'",
statestring.GetChars(), stype->TypeName.GetChars()); statestring.GetChars(), stype->TypeName.GetChars());
} }
} }
JumpParameters.Push(names.Size()); JumpParameters.Push((ENamedName)names.Size());
for(unsigned i=0;i<names.Size();i++) for(unsigned i=0;i<names.Size();i++)
{ {
JumpParameters.Push(names[i]); JumpParameters.Push(names[i]);
@ -2003,7 +2003,7 @@ static FState *CheckState(PClass *type)
if (info != NULL) if (info != NULL)
{ {
state = info->FindStateExact(1, (int)FName(sc_String)); state = info->FindState(FName(sc_String));
} }
if (SC_GetString ()) if (SC_GetString ())
@ -4249,10 +4249,10 @@ void FinishThingdef()
if (isRuntimeActor) if (isRuntimeActor)
{ {
// Do some consistency checks. If these states are undefined the weapon cannot work! // Do some consistency checks. If these states are undefined the weapon cannot work!
if (!ti->ActorInfo->FindState(1, NAME_Ready)) I_Error("Weapon %s doesn't define a ready state.\n", ti->TypeName.GetChars()); if (!ti->ActorInfo->FindState(NAME_Ready)) I_Error("Weapon %s doesn't define a ready state.\n", ti->TypeName.GetChars());
if (!ti->ActorInfo->FindState(1, NAME_Select)) I_Error("Weapon %s doesn't define a select state.\n", ti->TypeName.GetChars()); if (!ti->ActorInfo->FindState(NAME_Select)) I_Error("Weapon %s doesn't define a select state.\n", ti->TypeName.GetChars());
if (!ti->ActorInfo->FindState(1, NAME_Deselect)) I_Error("Weapon %s doesn't define a deselect state.\n", ti->TypeName.GetChars()); if (!ti->ActorInfo->FindState(NAME_Deselect)) I_Error("Weapon %s doesn't define a deselect state.\n", ti->TypeName.GetChars());
if (!ti->ActorInfo->FindState(1, NAME_Fire)) I_Error("Weapon %s doesn't define a fire state.\n", ti->TypeName.GetChars()); if (!ti->ActorInfo->FindState(NAME_Fire)) I_Error("Weapon %s doesn't define a fire state.\n", ti->TypeName.GetChars());
} }
} }

View file

@ -23,7 +23,7 @@ public:
// All state parameters are stored in this array now. // All state parameters are stored in this array now.
extern TArray<int> StateParameters; extern TArray<int> StateParameters;
extern TArray<int> JumpParameters; extern TArray<FName> JumpParameters;
int ParseExpression (bool _not, PClass *cls); int ParseExpression (bool _not, PClass *cls);

View file

@ -391,20 +391,21 @@ static void DoJump(AActor * self, FState * CallingState, int offset)
{ {
offset = -offset; offset = -offset;
int classname = JumpParameters[offset]; FName classname = JumpParameters[offset];
const PClass *cls; const PClass *cls;
cls = classname==NAME_None? RUNTIME_TYPE(self) : PClass::FindClass((ENamedName)classname); cls = classname==NAME_None? RUNTIME_TYPE(self) : PClass::FindClass(classname);
if (cls==NULL || cls->ActorInfo==NULL) return; // shouldn't happen if (cls==NULL || cls->ActorInfo==NULL) return; // shouldn't happen
jumpto = cls->ActorInfo->FindState(JumpParameters[offset+1], (va_list)&JumpParameters[offset+2]); int numnames = (int)JumpParameters[offset+1];
jumpto = cls->ActorInfo->FindState(numnames, &JumpParameters[offset+2]);
if (jumpto == NULL) if (jumpto == NULL)
{ {
char * dot=""; char * dot="";
Printf("Jump target '"); Printf("Jump target '");
if (classname != NAME_None) Printf("%s::", ((FName)(ENamedName)classname).GetChars()); if (classname != NAME_None) Printf("%s::", classname.GetChars());
for (int i=0;i<JumpParameters[offset+1];i++) for (int i=0;i<numnames;i++)
{ {
Printf("%s%s", dot, ((FName)(ENamedName)JumpParameters[offset+2+i]).GetChars()); Printf("%s%s", dot, JumpParameters[offset+2+i].GetChars());
} }
Printf("not found in %s\n", self->GetClass()->TypeName.GetChars()); Printf("not found in %s\n", self->GetClass()->TypeName.GetChars());
return; return;