mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2025-02-18 01:21:32 +00:00
- took InitializeDefaults out of PClass and moved it to PClassActor.
Like so many other parts, this created a hard dependency of the low level code on very invasive game content.
This commit is contained in:
parent
74c5f83658
commit
f02c5c0a56
8 changed files with 120 additions and 120 deletions
|
@ -39,17 +39,12 @@
|
|||
|
||||
#include "dobject.h"
|
||||
#include "serializer.h"
|
||||
#include "actor.h"
|
||||
#include "autosegs.h"
|
||||
#include "v_text.h"
|
||||
#include "a_pickups.h"
|
||||
#include "d_player.h"
|
||||
#include "fragglescript/t_fs.h"
|
||||
#include "a_keys.h"
|
||||
#include "c_cvars.h"
|
||||
#include "vm.h"
|
||||
#include "symbols.h"
|
||||
#include "types.h"
|
||||
#include "scriptutil.h"
|
||||
#include "i_system.h"
|
||||
|
||||
// MACROS ------------------------------------------------------------------
|
||||
|
||||
|
@ -217,13 +212,6 @@ void PClass::StaticInit ()
|
|||
((ClassReg *)*probe)->RegisterClass ();
|
||||
}
|
||||
probe.Reset();
|
||||
for(auto cls : AllClasses)
|
||||
{
|
||||
if (cls->IsDescendantOf(RUNTIME_CLASS(AActor)))
|
||||
{
|
||||
PClassActor::AllActorClasses.Push(static_cast<PClassActor*>(cls));
|
||||
}
|
||||
}
|
||||
|
||||
// Keep built-in classes in consistant order. I did this before, though
|
||||
// I'm not sure if this is really necessary to maintain any sort of sync.
|
||||
|
@ -255,7 +243,6 @@ void PClass::StaticShutdown ()
|
|||
{
|
||||
*p = nullptr;
|
||||
}
|
||||
ScriptUtil::Clear();
|
||||
FunctionPtrList.Clear();
|
||||
VMFunction::DeleteAll();
|
||||
|
||||
|
@ -267,10 +254,6 @@ void PClass::StaticShutdown ()
|
|||
// This flags DObject::Destroy not to call any scripted OnDestroy methods anymore.
|
||||
bVMOperational = false;
|
||||
|
||||
for (auto &p : players)
|
||||
{
|
||||
p.PendingWeapon = nullptr;
|
||||
}
|
||||
Namespaces.ReleaseSymbols();
|
||||
|
||||
// This must be done in two steps because the native classes are not ordered by inheritance,
|
||||
|
@ -282,7 +265,6 @@ void PClass::StaticShutdown ()
|
|||
TypeTable.Clear();
|
||||
ClassDataAllocator.FreeAllBlocks();
|
||||
AllClasses.Clear();
|
||||
PClassActor::AllActorClasses.Clear();
|
||||
ClassMap.Clear();
|
||||
|
||||
FAutoSegIterator probe(CRegHead, CRegTail);
|
||||
|
@ -393,10 +375,6 @@ void PClass::InsertIntoHash (bool native)
|
|||
{
|
||||
ClassMap[TypeName] = this;
|
||||
}
|
||||
if (!native && IsDescendantOf(RUNTIME_CLASS(AActor)))
|
||||
{
|
||||
PClassActor::AllActorClasses.Push(static_cast<PClassActor*>(this));
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -548,90 +526,6 @@ void PClass::Derive(PClass *newclass, FName name)
|
|||
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// PClassActor :: InitializeNativeDefaults
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void PClass::InitializeDefaults()
|
||||
{
|
||||
if (IsDescendantOf(RUNTIME_CLASS(AActor)))
|
||||
{
|
||||
assert(Defaults == nullptr);
|
||||
Defaults = (uint8_t *)M_Malloc(Size);
|
||||
|
||||
ConstructNative(Defaults);
|
||||
// We must unlink the defaults from the class list because it's just a static block of data to the engine.
|
||||
DObject *optr = (DObject*)Defaults;
|
||||
GC::Root = optr->ObjNext;
|
||||
optr->ObjNext = nullptr;
|
||||
optr->SetClass(this);
|
||||
|
||||
// Copy the defaults from the parent but leave the DObject part alone because it contains important data.
|
||||
if (ParentClass->Defaults != nullptr)
|
||||
{
|
||||
memcpy(Defaults + sizeof(DObject), ParentClass->Defaults + sizeof(DObject), ParentClass->Size - sizeof(DObject));
|
||||
if (Size > ParentClass->Size)
|
||||
{
|
||||
memset(Defaults + ParentClass->Size, 0, Size - ParentClass->Size);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(Defaults + sizeof(DObject), 0, Size - sizeof(DObject));
|
||||
}
|
||||
|
||||
assert(MetaSize >= ParentClass->MetaSize);
|
||||
if (MetaSize != 0)
|
||||
{
|
||||
Meta = (uint8_t*)M_Malloc(MetaSize);
|
||||
|
||||
// Copy the defaults from the parent but leave the DObject part alone because it contains important data.
|
||||
if (ParentClass->Meta != nullptr)
|
||||
{
|
||||
memcpy(Meta, ParentClass->Meta, ParentClass->MetaSize);
|
||||
if (MetaSize > ParentClass->MetaSize)
|
||||
{
|
||||
memset(Meta + ParentClass->MetaSize, 0, MetaSize - ParentClass->MetaSize);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(Meta, 0, MetaSize);
|
||||
}
|
||||
|
||||
if (MetaSize > 0) memcpy(Meta, ParentClass->Meta, ParentClass->MetaSize);
|
||||
else memset(Meta, 0, MetaSize);
|
||||
}
|
||||
}
|
||||
|
||||
if (VMType != nullptr) // purely internal classes have no symbol table
|
||||
{
|
||||
if (bRuntimeClass)
|
||||
{
|
||||
// Copy parent values from the parent defaults.
|
||||
assert(ParentClass != nullptr);
|
||||
if (Defaults != nullptr) ParentClass->InitializeSpecials(Defaults, ParentClass->Defaults, &PClass::SpecialInits);
|
||||
for (const PField *field : Fields)
|
||||
{
|
||||
if (!(field->Flags & VARF_Native) && !(field->Flags & VARF_Meta))
|
||||
{
|
||||
field->Type->SetDefaultValue(Defaults, unsigned(field->Offset), &SpecialInits);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Meta != nullptr) ParentClass->InitializeSpecials(Meta, ParentClass->Meta, &PClass::MetaInits);
|
||||
for (const PField *field : Fields)
|
||||
{
|
||||
if (!(field->Flags & VARF_Native) && (field->Flags & VARF_Meta))
|
||||
{
|
||||
field->Type->SetDefaultValue(Meta, unsigned(field->Offset), &MetaInits);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// PClass :: CreateDerivedClass
|
||||
|
@ -640,7 +534,7 @@ void PClass::InitializeDefaults()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
PClass *PClass::CreateDerivedClass(FName name, unsigned int size)
|
||||
PClass *PClass::CreateDerivedClass(FName name, unsigned int size, bool *newlycreated)
|
||||
{
|
||||
assert(size >= Size);
|
||||
PClass *type;
|
||||
|
@ -648,6 +542,7 @@ PClass *PClass::CreateDerivedClass(FName name, unsigned int size)
|
|||
|
||||
const PClass *existclass = FindClass(name);
|
||||
|
||||
if (newlycreated) *newlycreated = false;
|
||||
if (existclass != nullptr)
|
||||
{
|
||||
// This is a placeholder so fill it in
|
||||
|
@ -680,7 +575,7 @@ PClass *PClass::CreateDerivedClass(FName name, unsigned int size)
|
|||
if (size != TentativeClass)
|
||||
{
|
||||
NewClassType(type);
|
||||
type->InitializeDefaults();
|
||||
if (newlycreated) *newlycreated = true;
|
||||
type->Virtuals = Virtuals;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -36,12 +36,11 @@ class PClass
|
|||
{
|
||||
protected:
|
||||
void Derive(PClass *newclass, FName name);
|
||||
void InitializeSpecials(void *addr, void *defaults, TArray<FTypeAndOffset> PClass::*Inits);
|
||||
void SetSuper();
|
||||
public:
|
||||
void InitializeSpecials(void* addr, void* defaults, TArray<FTypeAndOffset> PClass::* Inits);
|
||||
void WriteAllFields(FSerializer &ar, const void *addr) const;
|
||||
bool ReadAllFields(FSerializer &ar, void *addr) const;
|
||||
void InitializeDefaults();
|
||||
int FindVirtualIndex(FName name, PFunction::Variant *variant, PFunction *parentfunc);
|
||||
PSymbol *FindSymbol(FName symname, bool searchparents) const;
|
||||
PField *AddField(FName name, PType *type, uint32_t flags);
|
||||
|
@ -77,7 +76,7 @@ public:
|
|||
~PClass();
|
||||
void InsertIntoHash(bool native);
|
||||
DObject *CreateNew();
|
||||
PClass *CreateDerivedClass(FName name, unsigned int size);
|
||||
PClass *CreateDerivedClass(FName name, unsigned int size, bool *newlycreated = nullptr);
|
||||
|
||||
void InitializeActorInfo();
|
||||
void BuildFlatPointers();
|
||||
|
|
|
@ -110,6 +110,7 @@
|
|||
#include "animations.h"
|
||||
#include "texturemanager.h"
|
||||
#include "formats/multipatchtexture.h"
|
||||
#include "scriptutil.h"
|
||||
|
||||
EXTERN_CVAR(Bool, hud_althud)
|
||||
EXTERN_CVAR(Int, vr_mode)
|
||||
|
@ -3443,6 +3444,12 @@ void D_Cleanup()
|
|||
|
||||
GC::DelSoftRootHead();
|
||||
|
||||
for (auto& p : players)
|
||||
{
|
||||
p.PendingWeapon = nullptr;
|
||||
}
|
||||
PClassActor::AllActorClasses.Clear();
|
||||
ScriptUtil::Clear();
|
||||
PClass::StaticShutdown();
|
||||
|
||||
GC::FullGC(); // perform one final garbage collection after shutdown
|
||||
|
|
|
@ -3029,7 +3029,9 @@ void FinishDehPatch ()
|
|||
{
|
||||
// Retry until we find a free name. This is unlikely to happen but not impossible.
|
||||
mysnprintf(typeNameBuilder, countof(typeNameBuilder), "DehackedPickup%d", nameindex++);
|
||||
subclass = static_cast<PClassActor *>(dehtype->CreateDerivedClass(typeNameBuilder, dehtype->Size));
|
||||
bool newlycreated;
|
||||
subclass = static_cast<PClassActor *>(dehtype->CreateDerivedClass(typeNameBuilder, dehtype->Size, &newlycreated));
|
||||
if (newlycreated) subclass->InitializeDefaults();
|
||||
}
|
||||
while (subclass == nullptr);
|
||||
NewClassType(subclass); // This needs a VM type to work as intended.
|
||||
|
|
|
@ -392,6 +392,15 @@ void PClassActor::StaticInit()
|
|||
if (!batchrun) Printf ("LoadActors: Load actor definitions.\n");
|
||||
ClearStrifeTypes();
|
||||
LoadActors ();
|
||||
|
||||
for (auto cls : AllClasses)
|
||||
{
|
||||
if (cls->IsDescendantOf(RUNTIME_CLASS(AActor)))
|
||||
{
|
||||
AllActorClasses.Push(static_cast<PClassActor*>(cls));
|
||||
}
|
||||
}
|
||||
|
||||
LoadAltHudStuff();
|
||||
InitBotStuff();
|
||||
|
||||
|
@ -444,6 +453,90 @@ bool PClassActor::SetReplacement(FName replaceName)
|
|||
return true;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// PClassActor :: InitializeNativeDefaults
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void PClassActor::InitializeDefaults()
|
||||
{
|
||||
if (IsDescendantOf(RUNTIME_CLASS(AActor)))
|
||||
{
|
||||
assert(Defaults == nullptr);
|
||||
Defaults = (uint8_t*)M_Malloc(Size);
|
||||
|
||||
ConstructNative(Defaults);
|
||||
// We must unlink the defaults from the class list because it's just a static block of data to the engine.
|
||||
DObject* optr = (DObject*)Defaults;
|
||||
GC::Root = optr->ObjNext;
|
||||
optr->ObjNext = nullptr;
|
||||
optr->SetClass(this);
|
||||
|
||||
// Copy the defaults from the parent but leave the DObject part alone because it contains important data.
|
||||
if (ParentClass->Defaults != nullptr)
|
||||
{
|
||||
memcpy(Defaults + sizeof(DObject), ParentClass->Defaults + sizeof(DObject), ParentClass->Size - sizeof(DObject));
|
||||
if (Size > ParentClass->Size)
|
||||
{
|
||||
memset(Defaults + ParentClass->Size, 0, Size - ParentClass->Size);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(Defaults + sizeof(DObject), 0, Size - sizeof(DObject));
|
||||
}
|
||||
|
||||
assert(MetaSize >= ParentClass->MetaSize);
|
||||
if (MetaSize != 0)
|
||||
{
|
||||
Meta = (uint8_t*)M_Malloc(MetaSize);
|
||||
|
||||
// Copy the defaults from the parent but leave the DObject part alone because it contains important data.
|
||||
if (ParentClass->Meta != nullptr)
|
||||
{
|
||||
memcpy(Meta, ParentClass->Meta, ParentClass->MetaSize);
|
||||
if (MetaSize > ParentClass->MetaSize)
|
||||
{
|
||||
memset(Meta + ParentClass->MetaSize, 0, MetaSize - ParentClass->MetaSize);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(Meta, 0, MetaSize);
|
||||
}
|
||||
|
||||
if (MetaSize > 0) memcpy(Meta, ParentClass->Meta, ParentClass->MetaSize);
|
||||
else memset(Meta, 0, MetaSize);
|
||||
}
|
||||
}
|
||||
|
||||
if (VMType != nullptr) // purely internal classes have no symbol table
|
||||
{
|
||||
if (bRuntimeClass)
|
||||
{
|
||||
// Copy parent values from the parent defaults.
|
||||
assert(ParentClass != nullptr);
|
||||
if (Defaults != nullptr) ParentClass->InitializeSpecials(Defaults, ParentClass->Defaults, &PClass::SpecialInits);
|
||||
for (const PField* field : Fields)
|
||||
{
|
||||
if (!(field->Flags & VARF_Native) && !(field->Flags & VARF_Meta))
|
||||
{
|
||||
field->Type->SetDefaultValue(Defaults, unsigned(field->Offset), &SpecialInits);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Meta != nullptr) ParentClass->InitializeSpecials(Meta, ParentClass->Meta, &PClass::MetaInits);
|
||||
for (const PField* field : Fields)
|
||||
{
|
||||
if (!(field->Flags & VARF_Native) && (field->Flags & VARF_Meta))
|
||||
{
|
||||
field->Type->SetDefaultValue(Meta, unsigned(field->Offset), &MetaInits);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// PClassActor :: RegisterIDs
|
||||
|
|
|
@ -307,6 +307,7 @@ public:
|
|||
void SetDamageFactor(FName type, double factor);
|
||||
void SetPainChance(FName type, int chance);
|
||||
bool SetReplacement(FName replaceName);
|
||||
void InitializeDefaults();
|
||||
|
||||
FActorInfo *ActorInfo() const
|
||||
{
|
||||
|
|
|
@ -77,7 +77,8 @@ PClassActor *DecoDerivedClass(const FScriptPosition &sc, PClassActor *parent, FN
|
|||
{
|
||||
sc.Message(MSG_ERROR, "Parent class %s of %s not accessible to DECORATE", parent->TypeName.GetChars(), typeName.GetChars());
|
||||
}
|
||||
PClassActor *type = static_cast<PClassActor *>(parent->CreateDerivedClass(typeName, parent->Size));
|
||||
bool newlycreated;
|
||||
PClassActor *type = static_cast<PClassActor *>(parent->CreateDerivedClass(typeName, parent->Size, &newlycreated));
|
||||
if (type == nullptr)
|
||||
{
|
||||
FString newname = typeName.GetChars();
|
||||
|
@ -94,14 +95,15 @@ PClassActor *DecoDerivedClass(const FScriptPosition &sc, PClassActor *parent, FN
|
|||
// Due to backwards compatibility issues this cannot be an unconditional error.
|
||||
sc.Message(MSG_WARNING, "Tried to define class '%s' more than once. Renaming class to '%s'", typeName.GetChars(), newname.GetChars());
|
||||
}
|
||||
type = static_cast<PClassActor *>(parent->CreateDerivedClass(newname, parent->Size));
|
||||
type = static_cast<PClassActor *>(parent->CreateDerivedClass(newname, parent->Size, &newlycreated));
|
||||
if (type == nullptr)
|
||||
{
|
||||
// This we cannot handle cleanly anymore. Let's just abort and forget about the odd mod out that was this careless.
|
||||
sc.Message(MSG_FATAL, "Tried to define class '%s' more than twice in the same file.", typeName.GetChars());
|
||||
}
|
||||
}
|
||||
|
||||
if (newlycreated) type->InitializeDefaults();
|
||||
|
||||
if (type != nullptr)
|
||||
{
|
||||
// [ZZ] DECORATE classes are always play
|
||||
|
|
|
@ -474,10 +474,11 @@ void LoadActors()
|
|||
I_Error("%d errors while parsing DECORATE scripts", FScriptPosition::ErrorCounter);
|
||||
}
|
||||
FScriptPosition::ResetErrorCounter();
|
||||
|
||||
for (int i = PClassActor::AllActorClasses.Size() - 1; i >= 0; i--)
|
||||
// AllActorClasses hasn'T been set up yet.
|
||||
for (int i = PClass::AllClasses.Size() - 1; i >= 0; i--)
|
||||
{
|
||||
auto ti = PClassActor::AllActorClasses[i];
|
||||
auto ti = (PClassActor*)PClass::AllClasses[i];
|
||||
if (!ti->IsDescendantOf(RUNTIME_CLASS(AActor))) continue;
|
||||
if (ti->Size == TentativeClass)
|
||||
{
|
||||
if (ti->bOptional)
|
||||
|
|
Loading…
Reference in a new issue