- 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 &operator= (const AActor &other);
~AActor (); ~AActor ();
virtual void Finalize(FStateDefinitions &statedef);
virtual void OnDestroy() override; virtual void OnDestroy() override;
virtual void Serialize(FSerializer &arc) override; virtual void Serialize(FSerializer &arc) override;
virtual void PostSerialize() override; virtual void PostSerialize() override;

View file

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

View file

@ -72,6 +72,7 @@ class AInventory : public AActor
HAS_OBJECT_POINTERS HAS_OBJECT_POINTERS
public: public:
virtual void Finalize(FStateDefinitions &statedef) override;
virtual void Serialize(FSerializer &arc) override; virtual void Serialize(FSerializer &arc) override;
virtual void MarkPrecacheSounds() const override; virtual void MarkPrecacheSounds() const override;
virtual void OnDestroy() 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); Super::Finalize(statedef);
FState *ready = FindState(NAME_Ready); FState *ready = FindState(NAME_Ready);
FState *select = FindState(NAME_Select); FState *select = FindState(NAME_Select);
FState *deselect = FindState(NAME_Deselect); FState *deselect = FindState(NAME_Deselect);
FState *fire = FindState(NAME_Fire); FState *fire = FindState(NAME_Fire);
auto TypeName = GetClass()->TypeName;
// Consider any weapon without any valid state abstract and don't output a warning // 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. // 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); virtual void DeriveData(PClass *newclass);
public: public:
PClassWeapon(); PClassWeapon();
void Finalize(FStateDefinitions &statedef);
int SlotNumber; int SlotNumber;
int SlotPriority; int SlotPriority;
@ -135,7 +134,8 @@ public:
virtual void MarkPrecacheSounds() const; virtual void MarkPrecacheSounds() const;
virtual void Serialize(FSerializer &arc) override; void Finalize(FStateDefinitions &statedef) override;
void Serialize(FSerializer &arc) override;
void PostMorphWeapon(); 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 try
{ {
statedef.FinishStates(this, defaults); statedef.FinishStates(GetClass(), defaults);
} }
catch (CRecoverableError &) catch (CRecoverableError &)
{ {
statedef.MakeStateDefines(NULL); statedef.MakeStateDefines(NULL);
throw; throw;
} }
statedef.InstallStates(this, defaults); statedef.InstallStates(GetClass(), defaults);
statedef.MakeStateDefines(NULL); statedef.MakeStateDefines(NULL);
} }

View file

@ -259,7 +259,6 @@ public:
size_t PropagateMark(); size_t PropagateMark();
bool SetReplacement(FName replaceName); bool SetReplacement(FName replaceName);
void SetDropItems(DDropItem *drops); void SetDropItems(DDropItem *drops);
virtual void Finalize(FStateDefinitions &statedef);
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);

View file

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

View file

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

View file

@ -2447,19 +2447,6 @@ void ZCCCompiler::CompileStates()
continue; 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. FString statename; // The state builder wants the label as one complete string, not separated into tokens.
FStateDefinitions statedef; FStateDefinitions statedef;
statedef.MakeStateDefines(dyn_cast<PClassActor>(c->Type()->ParentClass)); statedef.MakeStateDefines(dyn_cast<PClassActor>(c->Type()->ParentClass));
@ -2658,7 +2645,7 @@ void ZCCCompiler::CompileStates()
} }
try try
{ {
static_cast<PClassActor *>(c->Type())->Finalize(statedef); GetDefaultByType(c->Type())->Finalize(statedef);
} }
catch (CRecoverableError &err) catch (CRecoverableError &err)
{ {