- started moving stuff out of PClassActor into meta data.

This reinstates the old FActorInfo as part of the meta data a class can have so that the class descriptor itself can be freed from any data not directly relevant for managing the class's type information.
This commit is contained in:
Christoph Oelckers 2017-04-11 19:37:56 +02:00
parent 6a3ddaa8fa
commit 311ce2362a
8 changed files with 106 additions and 25 deletions

View file

@ -612,6 +612,12 @@ public:
return (AActor *)(this->GetClass()->Defaults); return (AActor *)(this->GetClass()->Defaults);
} }
FActorInfo *GetInfo() const
{
return ((PClassActor*)GetClass())->ActorInfo();
}
FDropItem *GetDropItems() const; FDropItem *GetDropItems() const;
// Return true if the monster should use a missile attack, false for melee // Return true if the monster should use a missile attack, false for melee

View file

@ -3051,15 +3051,15 @@ void FinishDehPatch ()
// Use the DECORATE replacement feature to redirect all spawns // Use the DECORATE replacement feature to redirect all spawns
// of the original class to the new one. // of the original class to the new one.
PClassActor *old_replacement = type->Replacement; PClassActor *old_replacement = type->ActorInfo()->Replacement;
type->Replacement = subclass; type->ActorInfo()->Replacement = subclass;
subclass->Replacee = type; subclass->ActorInfo()->Replacee = type;
// If this actor was already replaced by another actor, copy that // If this actor was already replaced by another actor, copy that
// replacement over to this item. // replacement over to this item.
if (old_replacement != NULL) if (old_replacement != NULL)
{ {
subclass->Replacement = old_replacement; subclass->ActorInfo()->Replacement = old_replacement;
} }
DPrintf (DMSG_NOTIFY, "%s replaces %s\n", subclass->TypeName.GetChars(), type->TypeName.GetChars()); DPrintf (DMSG_NOTIFY, "%s replaces %s\n", subclass->TypeName.GetChars(), type->TypeName.GetChars());

View file

@ -986,7 +986,7 @@ void FWeaponSlots::AddExtraWeapons()
} }
auto weapdef = ((AWeapon*)GetDefaultByType(cls)); auto weapdef = ((AWeapon*)GetDefaultByType(cls));
if ((cls->GameFilter == GAME_Any || (cls->GameFilter & gameinfo.gametype)) && if ((cls->GameFilter == GAME_Any || (cls->GameFilter & gameinfo.gametype)) &&
cls->Replacement == nullptr && // Replaced weapons don't get slotted. cls->ActorInfo()->Replacement == nullptr && // Replaced weapons don't get slotted.
!(weapdef->WeaponFlags & WIF_POWERED_UP) && !(weapdef->WeaponFlags & WIF_POWERED_UP) &&
!LocateWeapon(cls, nullptr, nullptr) // Don't duplicate it if it's already present. !LocateWeapon(cls, nullptr, nullptr) // Don't duplicate it if it's already present.
) )

View file

@ -1058,7 +1058,7 @@ void InitializeActorLights()
void *mem = ClassDataAllocator.Alloc(sizeof(FInternalLightAssociation)); void *mem = ClassDataAllocator.Alloc(sizeof(FInternalLightAssociation));
FInternalLightAssociation * iasso = new(mem) FInternalLightAssociation(&LightAssociations[i]); FInternalLightAssociation * iasso = new(mem) FInternalLightAssociation(&LightAssociations[i]);
if (iasso->Light() != nullptr) if (iasso->Light() != nullptr)
ti->LightAssociations.Push(iasso); ti->ActorInfo()->LightAssociations.Push(iasso);
} }
} }
// we don't need the parser data for the light associations anymore // we don't need the parser data for the light associations anymore
@ -1124,7 +1124,7 @@ void AActor::AttachLight(unsigned int count, const FLightDefaults *lightdef)
void AActor::SetDynamicLights() void AActor::SetDynamicLights()
{ {
TArray<FInternalLightAssociation *> & LightAssociations = GetClass()->LightAssociations; TArray<FInternalLightAssociation *> & LightAssociations = GetInfo()->LightAssociations;
unsigned int count = 0; unsigned int count = 0;
if (state == NULL) return; if (state == NULL) return;

View file

@ -65,6 +65,62 @@ FRandom FState::pr_statetics("StateTics");
cycle_t ActionCycles; cycle_t ActionCycles;
//==========================================================================
//
// special type for the native ActorInfo. This allows to let this struct
// be handled by the generic object constructors for the VM.
//
//==========================================================================
class PActorInfo : public PBasicType
{
DECLARE_CLASS(PActorInfo, PBasicType);
public:
PActorInfo()
:PBasicType(sizeof(FActorInfo), alignof(FActorInfo))
{
}
void SetDefaultValue(void *base, unsigned offset, TArray<FTypeAndOffset> *special) const override
{
if (base != nullptr) new((uint8_t *)base + offset) FActorInfo;
if (special != nullptr)
{
special->Push(std::make_pair(this, offset));
}
}
void InitializeValue(void *addr, const void *def) const override
{
if (def == nullptr)
{
new(addr) FActorInfo;
}
else
{
new(addr) FActorInfo(*(const FActorInfo*)def);
}
}
void DestroyValue(void *addr) const override
{
FActorInfo *self = (FActorInfo*)addr;
self->~FActorInfo();
}
};
IMPLEMENT_CLASS(PActorInfo, false, false)
void AddActorInfo(PClass *cls)
{
auto type = new PActorInfo;
TypeTable.AddType(type);
cls->AddField("*", type, VARF_Meta);
}
void FState::SetAction(const char *name) void FState::SetAction(const char *name)
{ {
ActionFunc = FindVMFunction(RUNTIME_CLASS(AActor), name); ActionFunc = FindVMFunction(RUNTIME_CLASS(AActor), name);
@ -245,8 +301,6 @@ PClassActor::PClassActor()
DoomEdNum = -1; DoomEdNum = -1;
OwnedStates = NULL; OwnedStates = NULL;
NumOwnedStates = 0; NumOwnedStates = 0;
Replacement = NULL;
Replacee = NULL;
StateList = NULL; StateList = NULL;
DamageFactors = NULL; DamageFactors = NULL;
PainChances = NULL; PainChances = NULL;
@ -339,8 +393,8 @@ bool PClassActor::SetReplacement(FName replaceName)
} }
if (replacee != nullptr) if (replacee != nullptr)
{ {
replacee->Replacement = this; replacee->ActorInfo()->Replacement = this;
Replacee = replacee; ActorInfo()->Replacee = replacee;
} }
} }
return true; return true;
@ -467,15 +521,15 @@ PClassActor *PClassActor::GetReplacement(bool lookskill)
lookskill = false; skillrepname = NAME_None; lookskill = false; skillrepname = NAME_None;
} }
} }
if (Replacement == NULL && (!lookskill || skillrepname == NAME_None)) auto Replacement = ActorInfo()->Replacement;
if (Replacement == nullptr && (!lookskill || skillrepname == NAME_None))
{ {
return this; return this;
} }
// The Replacement field is temporarily NULLed to prevent // The Replacement field is temporarily NULLed to prevent
// potential infinite recursion. // potential infinite recursion.
PClassActor *savedrep = Replacement; ActorInfo()->Replacement = nullptr;
Replacement = NULL; PClassActor *rep = Replacement;
PClassActor *rep = savedrep;
// Handle skill-based replacement here. It has precedence on DECORATE replacement // Handle skill-based replacement here. It has precedence on DECORATE replacement
// in that the skill replacement is applied first, followed by DECORATE replacement // in that the skill replacement is applied first, followed by DECORATE replacement
// on the actor indicated by the skill replacement. // on the actor indicated by the skill replacement.
@ -487,7 +541,7 @@ PClassActor *PClassActor::GetReplacement(bool lookskill)
// Skill replacements are not recursive, contrarily to DECORATE replacements // Skill replacements are not recursive, contrarily to DECORATE replacements
rep = rep->GetReplacement(false); rep = rep->GetReplacement(false);
// Reset the temporarily NULLed field // Reset the temporarily NULLed field
Replacement = savedrep; ActorInfo()->Replacement = Replacement;
return rep; return rep;
} }
@ -523,21 +577,21 @@ PClassActor *PClassActor::GetReplacee(bool lookskill)
lookskill = false; lookskill = false;
} }
} }
if (Replacee == NULL && (!lookskill || skillrepname == NAME_None)) PClassActor *savedrep = ActorInfo()->Replacee;
if (savedrep == nullptr && (!lookskill || skillrepname == NAME_None))
{ {
return this; return this;
} }
// The Replacee field is temporarily NULLed to prevent // The Replacee field is temporarily NULLed to prevent
// potential infinite recursion. // potential infinite recursion.
PClassActor *savedrep = Replacee; ActorInfo()->Replacee = nullptr;
Replacee = NULL;
PClassActor *rep = savedrep; PClassActor *rep = savedrep;
if (lookskill && (skillrepname != NAME_None) && (PClass::FindClass(skillrepname) != NULL)) if (lookskill && (skillrepname != NAME_None) && (PClass::FindClass(skillrepname) != NULL))
{ {
rep = PClass::FindActor(skillrepname); rep = PClass::FindActor(skillrepname);
} }
rep = rep->GetReplacee(false); rep = rep->GetReplacee(false);
Replacee = savedrep; ActorInfo()->Replacee = savedrep;
return rep; return rep;
} }

View file

@ -236,6 +236,19 @@ private:
struct FDropItem; struct FDropItem;
struct FActorInfo
{
TArray<FInternalLightAssociation *> LightAssociations;
PClassActor *Replacement = nullptr;
PClassActor *Replacee = nullptr;
FActorInfo() {}
FActorInfo(const FActorInfo & other)
{
LightAssociations = other.LightAssociations;
}
};
class PClassActor : public PClass class PClassActor : public PClass
{ {
DECLARE_CLASS(PClassActor, PClass); DECLARE_CLASS(PClassActor, PClass);
@ -256,6 +269,11 @@ public:
bool SetReplacement(FName replaceName); bool SetReplacement(FName replaceName);
void SetDropItems(FDropItem *drops); void SetDropItems(FDropItem *drops);
FActorInfo *ActorInfo() const
{
return (FActorInfo*)Meta;
}
FState *FindState(int numnames, FName *names, bool exact=false) const; FState *FindState(int numnames, FName *names, bool exact=false) const;
FState *FindStateByString(const char *name, bool exact=false); FState *FindStateByString(const char *name, bool exact=false);
FState *FindState(FName name) const FState *FindState(FName name) const
@ -271,10 +289,7 @@ public:
PClassActor *GetReplacement(bool lookskill=true); PClassActor *GetReplacement(bool lookskill=true);
PClassActor *GetReplacee(bool lookskill=true); PClassActor *GetReplacee(bool lookskill=true);
TArray<FInternalLightAssociation *> LightAssociations;
FState *OwnedStates; FState *OwnedStates;
PClassActor *Replacement;
PClassActor *Replacee;
int NumOwnedStates; int NumOwnedStates;
uint8_t GameFilter; uint8_t GameFilter;
uint8_t DefaultStateUsage; // state flag defaults for blocks without a qualifier. uint8_t DefaultStateUsage; // state flag defaults for blocks without a qualifier.

View file

@ -1016,7 +1016,6 @@ PClassActor *CreateNewActor(const FScriptPosition &sc, FName typeName, FName par
ti = DecoDerivedClass(sc, parent, typeName); ti = DecoDerivedClass(sc, parent, typeName);
ti->bDecorateClass = true; // we only set this for 'modern' DECORATE. The original stuff is so limited that it cannot do anything that may require flagging. ti->bDecorateClass = true; // we only set this for 'modern' DECORATE. The original stuff is so limited that it cannot do anything that may require flagging.
ti->Replacee = ti->Replacement = NULL;
ti->DoomEdNum = -1; ti->DoomEdNum = -1;
return ti; return ti;
} }

View file

@ -1112,6 +1112,7 @@ ZCC_ExprTypeRef *ZCCCompiler::NodeFromSymbolType(PSymbolType *sym, ZCC_Expressio
// builds the internal structure of all classes and structs // builds the internal structure of all classes and structs
// //
//========================================================================== //==========================================================================
void AddActorInfo(PClass *cls);
void ZCCCompiler::CompileAllFields() void ZCCCompiler::CompileAllFields()
{ {
@ -1156,6 +1157,7 @@ void ZCCCompiler::CompileAllFields()
for (unsigned i = 0; i < Classes.Size(); i++) for (unsigned i = 0; i < Classes.Size(); i++)
{ {
auto type = Classes[i]->Type(); auto type = Classes[i]->Type();
if (type->Size == TentativeClass) if (type->Size == TentativeClass)
{ {
if (type->ParentClass->Size == TentativeClass) if (type->ParentClass->Size == TentativeClass)
@ -1169,7 +1171,12 @@ void ZCCCompiler::CompileAllFields()
type->Size = Classes[i]->Type()->ParentClass->Size; type->Size = Classes[i]->Type()->ParentClass->Size;
} }
} }
if (Classes[i]->Type()->ParentClass) if (type->TypeName == NAME_Actor)
{
assert(type->MetaSize == 0);
AddActorInfo(type); // AActor needs the actor info manually added to its meta data before adding any scripted fields.
}
else if (Classes[i]->Type()->ParentClass)
type->MetaSize = Classes[i]->Type()->ParentClass->MetaSize; type->MetaSize = Classes[i]->Type()->ParentClass->MetaSize;
else else
type->MetaSize = 0; type->MetaSize = 0;