- let skip_super use the AActor assignment operator. The blanket memcpy it used was clobbering some data.

- moved the Finalize method from PClassActor to AActor. Now that defaults get their vtbl pointer initialized this will actually work.
This commit is contained in:
Christoph Oelckers 2017-02-07 18:12:38 +01:00
parent 56024a1ebe
commit 776509e68a
10 changed files with 15 additions and 26 deletions

View file

@ -596,6 +596,7 @@ public:
AActor &operator= (const AActor &other);
~AActor ();
virtual void Finalize(FStateDefinitions &statedef);
virtual void OnDestroy() override;
virtual void Serialize(FSerializer &arc) override;
virtual void PostSerialize() override;

View file

@ -73,10 +73,10 @@ size_t PClassInventory::PointerSubstitution(DObject *oldclass, DObject *newclass
return changed;
}
void PClassInventory::Finalize(FStateDefinitions &statedef)
void AInventory::Finalize(FStateDefinitions &statedef)
{
Super::Finalize(statedef);
((AActor*)Defaults)->flags |= MF_SPECIAL;
flags |= MF_SPECIAL;
}
IMPLEMENT_CLASS(AInventory, false, true)

View file

@ -72,6 +72,7 @@ class AInventory : public AActor
HAS_OBJECT_POINTERS
public:
virtual void Finalize(FStateDefinitions &statedef) override;
virtual void Serialize(FSerializer &arc) override;
virtual void MarkPrecacheSounds() const override;
virtual void OnDestroy() override;

View file

@ -155,13 +155,14 @@ void PClassWeapon::DeriveData(PClass *newclass)
//
//===========================================================================
void PClassWeapon::Finalize(FStateDefinitions &statedef)
void AWeapon::Finalize(FStateDefinitions &statedef)
{
Super::Finalize(statedef);
FState *ready = FindState(NAME_Ready);
FState *select = FindState(NAME_Select);
FState *deselect = FindState(NAME_Deselect);
FState *fire = FindState(NAME_Fire);
auto TypeName = GetClass()->TypeName;
// Consider any weapon without any valid state abstract and don't output a warning
// This is for creating base classes for weapon groups that only set up some properties.

View file

@ -94,7 +94,6 @@ protected:
virtual void DeriveData(PClass *newclass);
public:
PClassWeapon();
void Finalize(FStateDefinitions &statedef);
int SlotNumber;
int SlotPriority;
@ -135,7 +134,8 @@ public:
virtual void MarkPrecacheSounds() const;
virtual void Serialize(FSerializer &arc) override;
void Finalize(FStateDefinitions &statedef) override;
void Serialize(FSerializer &arc) override;
void PostMorphWeapon();

View file

@ -429,20 +429,20 @@ void PClassActor::SetDropItems(DDropItem *drops)
//
//==========================================================================
void PClassActor::Finalize(FStateDefinitions &statedef)
void AActor::Finalize(FStateDefinitions &statedef)
{
AActor *defaults = (AActor*)Defaults;
AActor *defaults = this;
try
{
statedef.FinishStates(this, defaults);
statedef.FinishStates(GetClass(), defaults);
}
catch (CRecoverableError &)
{
statedef.MakeStateDefines(NULL);
throw;
}
statedef.InstallStates(this, defaults);
statedef.InstallStates(GetClass(), defaults);
statedef.MakeStateDefines(NULL);
}

View file

@ -259,7 +259,6 @@ public:
size_t PropagateMark();
bool SetReplacement(FName replaceName);
void SetDropItems(DDropItem *drops);
virtual void Finalize(FStateDefinitions &statedef);
FState *FindState(int numnames, FName *names, bool exact=false) const;
FState *FindStateByString(const char *name, bool exact=false);

View file

@ -1155,7 +1155,7 @@ static void ParseActor(FScanner &sc, PNamespace *ns)
}
try
{
info->Finalize(bag.statedef);
GetDefaultByType(info)->Finalize(bag.statedef);
}
catch (CRecoverableError &err)
{

View file

@ -560,7 +560,7 @@ DEFINE_PROPERTY(skip_super, 0, Actor)
return;
}
memcpy ((void *)defaults, (void *)GetDefault<AActor>(), sizeof(AActor));
*defaults = *GetDefault<AActor>();
ResetBaggage (&bag, RUNTIME_CLASS(AActor));
}

View file

@ -2447,19 +2447,6 @@ void ZCCCompiler::CompileStates()
continue;
}
// Same here, hack in the DVMObject as they weren't in the list originally
// TODO: process them in a non hackish way obviously
if (c->Type()->bRuntimeClass == true && c->Type()->ParentClass->bRuntimeClass == false)
{
auto vmtype = static_cast<PClassActor *>(c->Type()->ParentClass);
if (vmtype->StateList == nullptr)
{
FStateDefinitions vmstates;
vmstates.MakeStateDefines(dyn_cast<PClassActor>(vmtype->ParentClass));
vmtype->Finalize(vmstates);
}
}
FString statename; // The state builder wants the label as one complete string, not separated into tokens.
FStateDefinitions statedef;
statedef.MakeStateDefines(dyn_cast<PClassActor>(c->Type()->ParentClass));
@ -2658,7 +2645,7 @@ void ZCCCompiler::CompileStates()
}
try
{
static_cast<PClassActor *>(c->Type())->Finalize(statedef);
GetDefaultByType(c->Type())->Finalize(statedef);
}
catch (CRecoverableError &err)
{