mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-11 07:12:16 +00:00
Added code to initialize and destroy string variables in classes
- Will require being able to add strings to non-native classes to actually test this.
This commit is contained in:
parent
15208188de
commit
7c8cff64e6
5 changed files with 212 additions and 31 deletions
|
@ -257,46 +257,50 @@ DObject::DObject (PClass *inClass)
|
|||
|
||||
DObject::~DObject ()
|
||||
{
|
||||
if (!(ObjectFlags & OF_Cleanup) && !PClass::bShutdown)
|
||||
if (!PClass::bShutdown)
|
||||
{
|
||||
DObject **probe;
|
||||
PClass *type = GetClass();
|
||||
|
||||
if (!(ObjectFlags & OF_YesReallyDelete))
|
||||
if (!(ObjectFlags & OF_Cleanup) && !PClass::bShutdown)
|
||||
{
|
||||
Printf ("Warning: '%s' is freed outside the GC process.\n",
|
||||
type != NULL ? type->TypeName.GetChars() : "==some object==");
|
||||
}
|
||||
DObject **probe;
|
||||
|
||||
// Find all pointers that reference this object and NULL them.
|
||||
StaticPointerSubstitution(this, NULL);
|
||||
|
||||
// Now unlink this object from the GC list.
|
||||
for (probe = &GC::Root; *probe != NULL; probe = &((*probe)->ObjNext))
|
||||
{
|
||||
if (*probe == this)
|
||||
if (!(ObjectFlags & OF_YesReallyDelete))
|
||||
{
|
||||
*probe = ObjNext;
|
||||
if (&ObjNext == GC::SweepPos)
|
||||
{
|
||||
GC::SweepPos = probe;
|
||||
}
|
||||
break;
|
||||
Printf("Warning: '%s' is freed outside the GC process.\n",
|
||||
type != NULL ? type->TypeName.GetChars() : "==some object==");
|
||||
}
|
||||
}
|
||||
|
||||
// If it's gray, also unlink it from the gray list.
|
||||
if (this->IsGray())
|
||||
{
|
||||
for (probe = &GC::Gray; *probe != NULL; probe = &((*probe)->GCNext))
|
||||
// Find all pointers that reference this object and NULL them.
|
||||
StaticPointerSubstitution(this, NULL);
|
||||
|
||||
// Now unlink this object from the GC list.
|
||||
for (probe = &GC::Root; *probe != NULL; probe = &((*probe)->ObjNext))
|
||||
{
|
||||
if (*probe == this)
|
||||
{
|
||||
*probe = GCNext;
|
||||
*probe = ObjNext;
|
||||
if (&ObjNext == GC::SweepPos)
|
||||
{
|
||||
GC::SweepPos = probe;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If it's gray, also unlink it from the gray list.
|
||||
if (this->IsGray())
|
||||
{
|
||||
for (probe = &GC::Gray; *probe != NULL; probe = &((*probe)->GCNext))
|
||||
{
|
||||
if (*probe == this)
|
||||
{
|
||||
*probe = GCNext;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
type->DestroySpecials(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
144
src/dobjtype.cpp
144
src/dobjtype.cpp
|
@ -500,6 +500,36 @@ void PType::SkipValue(FArchive &ar, int tag)
|
|||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// PType :: SetDefaultValue
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void PType::SetDefaultValue(void *base, unsigned offset, TArray<FTypeAndOffset> *stroffs) const
|
||||
{
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// PType :: InitializeValue
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void PType::InitializeValue(void *addr, const void *def) const
|
||||
{
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// PType :: DestroyValue
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void PType::DestroyValue(void *addr) const
|
||||
{
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// PType :: SetValue
|
||||
|
@ -1497,6 +1527,43 @@ bool PString::ReadValue(FArchive &ar, void *addr) const
|
|||
return true;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// PString :: SetDefaultValue
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void PString::SetDefaultValue(void *base, unsigned offset, TArray<FTypeAndOffset> *special) const
|
||||
{
|
||||
new((BYTE *)base + offset) FString;
|
||||
if (special != NULL)
|
||||
{
|
||||
special->Push(std::make_pair(this, offset));
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// PString :: InitializeValue
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void PString::InitializeValue(void *addr, const void *def) const
|
||||
{
|
||||
new(addr) FString(*(FString *)def);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// PString :: DestroyValue
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void PString::DestroyValue(void *addr) const
|
||||
{
|
||||
((FString *)addr)->~FString();
|
||||
}
|
||||
|
||||
/* PName ******************************************************************/
|
||||
|
||||
IMPLEMENT_CLASS(PName)
|
||||
|
@ -2328,6 +2395,20 @@ bool PArray::ReadValue(FArchive &ar, void *addr) const
|
|||
return false;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// PArray :: SetDefaultValue
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void PArray::SetDefaultValue(void *base, unsigned offset, TArray<FTypeAndOffset> *special) const
|
||||
{
|
||||
for (unsigned i = 0; i < ElementCount; ++i)
|
||||
{
|
||||
ElementType->SetDefaultValue(base, offset + i*ElementSize, special);
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// NewArray
|
||||
|
@ -2581,6 +2662,23 @@ PStruct::PStruct(FName name, DObject *outer)
|
|||
{
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// PStruct :: SetDefaultValue
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void PStruct::SetDefaultValue(void *base, unsigned offset, TArray<FTypeAndOffset> *special) const
|
||||
{
|
||||
for (const PField *field : Fields)
|
||||
{
|
||||
if (!(field->Flags & VARF_Native))
|
||||
{
|
||||
field->Type->SetDefaultValue(base, offset + field->Offset, special);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// PStruct :: WriteValue
|
||||
|
@ -3287,9 +3385,50 @@ DObject *PClass::CreateNew() const
|
|||
|
||||
ConstructNative (mem);
|
||||
((DObject *)mem)->SetClass (const_cast<PClass *>(this));
|
||||
if (Defaults != NULL)
|
||||
{
|
||||
InitializeSpecials(mem);
|
||||
}
|
||||
return (DObject *)mem;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// PClass :: InitializeSpecials
|
||||
//
|
||||
// Initialize special fields of a newly-created instance (e.g. strings).
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void PClass::InitializeSpecials(void *addr) const
|
||||
{
|
||||
if (ParentClass != NULL)
|
||||
{
|
||||
ParentClass->InitializeSpecials(addr);
|
||||
}
|
||||
for (auto tao : SpecialInits)
|
||||
{
|
||||
tao.first->InitializeValue((BYTE*)addr + tao.second, Defaults + tao.second);
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// PClass :: DestroySpecials
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void PClass::DestroySpecials(void *addr) const
|
||||
{
|
||||
if (ParentClass != NULL)
|
||||
{
|
||||
ParentClass->DestroySpecials(addr);
|
||||
}
|
||||
for (auto tao : SpecialInits)
|
||||
{
|
||||
tao.first->DestroyValue((BYTE *)addr + tao.second);
|
||||
}
|
||||
}
|
||||
//==========================================================================
|
||||
//
|
||||
// PClass :: Derive
|
||||
|
@ -3388,6 +3527,11 @@ PField *PClass::AddField(FName name, PType *type, DWORD flags)
|
|||
{
|
||||
Defaults = (BYTE *)M_Realloc(Defaults, Size);
|
||||
memset(Defaults + oldsize, 0, Size - oldsize);
|
||||
// If this is a native class, then we must not initialize and
|
||||
// destroy any of its members. We do, however, initialize the
|
||||
// default instance since it's not a normal instance of the class.
|
||||
type->SetDefaultValue(Defaults, field->Offset,
|
||||
bRuntimeClass ? &SpecialInits : NULL);
|
||||
}
|
||||
return field;
|
||||
}
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
|
||||
#include "vm.h"
|
||||
|
||||
typedef std::pair<const class PType *, unsigned> FTypeAndOffset;
|
||||
|
||||
// Variable/parameter/field flags -------------------------------------------
|
||||
|
||||
// Making all these different storage types use a common set of flags seems
|
||||
|
@ -200,6 +202,22 @@ public:
|
|||
static void SkipValue(FArchive &ar);
|
||||
static void SkipValue(FArchive &ar, int tag);
|
||||
|
||||
// Sets the default value for this type at (base + offset)
|
||||
// If the default value is binary 0, then this function doesn't need
|
||||
// to do anything, because PClass::Extend() takes care of that.
|
||||
//
|
||||
// The stroffs array is so that types that need special initialization
|
||||
// and destruction (e.g. strings) can add their offsets to it for special
|
||||
// initialization when the object is created and destruction when the
|
||||
// object is destroyed.
|
||||
virtual void SetDefaultValue(void *base, unsigned offset, TArray<FTypeAndOffset> *special=NULL) const;
|
||||
|
||||
// Initialize the value, if needed (e.g. strings)
|
||||
virtual void InitializeValue(void *addr, const void *def) const;
|
||||
|
||||
// Destroy the value, if needed (e.g. strings)
|
||||
virtual void DestroyValue(void *addr) const;
|
||||
|
||||
// Sets the value of a variable of this type at (addr)
|
||||
virtual void SetValue(void *addr, int val);
|
||||
virtual void SetValue(void *addr, double val);
|
||||
|
@ -404,6 +422,9 @@ public:
|
|||
|
||||
void WriteValue(FArchive &ar, const void *addr) const override;
|
||||
bool ReadValue(FArchive &ar, void *addr) const override;
|
||||
void SetDefaultValue(void *base, unsigned offset, TArray<FTypeAndOffset> *special=NULL) const override;
|
||||
void InitializeValue(void *addr, const void *def) const override;
|
||||
void DestroyValue(void *addr) const override;
|
||||
};
|
||||
|
||||
// Variations of integer types ----------------------------------------------
|
||||
|
@ -577,6 +598,8 @@ public:
|
|||
void WriteValue(FArchive &ar, const void *addr) const override;
|
||||
bool ReadValue(FArchive &ar, void *addr) const override;
|
||||
|
||||
void SetDefaultValue(void *base, unsigned offset, TArray<FTypeAndOffset> *special) const override;
|
||||
|
||||
protected:
|
||||
PArray();
|
||||
};
|
||||
|
@ -637,6 +660,7 @@ public:
|
|||
|
||||
void WriteValue(FArchive &ar, const void *addr) const override;
|
||||
bool ReadValue(FArchive &ar, void *addr) const override;
|
||||
void SetDefaultValue(void *base, unsigned offset, TArray<FTypeAndOffset> *specials) const override;
|
||||
|
||||
static void WriteFields(FArchive &ar, const void *addr, const TArray<PField *> &fields);
|
||||
bool ReadFields(FArchive &ar, void *addr) const;
|
||||
|
@ -697,7 +721,9 @@ class PClass : public PStruct
|
|||
protected:
|
||||
// We unravel _WITH_META here just as we did for PType.
|
||||
enum { MetaClassNum = CLASSREG_PClassClass };
|
||||
TArray<FTypeAndOffset> SpecialInits;
|
||||
virtual void Derive(PClass *newclass);
|
||||
void InitializeSpecials(void *addr) const;
|
||||
public:
|
||||
typedef PClassClass MetaClass;
|
||||
MetaClass *GetClass() const;
|
||||
|
@ -728,6 +754,7 @@ public:
|
|||
PField *AddField(FName name, PType *type, DWORD flags=0) override;
|
||||
void InitializeActorInfo();
|
||||
void BuildFlatPointers();
|
||||
void DestroySpecials(void *addr) const;
|
||||
const PClass *NativeClass() const;
|
||||
|
||||
// Returns true if this type is an ancestor of (or same as) the passed type.
|
||||
|
|
14
src/tarray.h
14
src/tarray.h
|
@ -94,17 +94,23 @@ public:
|
|||
{
|
||||
return &Array[0];
|
||||
}
|
||||
|
||||
iterator end()
|
||||
const_iterator begin() const
|
||||
{
|
||||
return &Array[Count];
|
||||
return &Array[0];
|
||||
}
|
||||
|
||||
const_iterator cbegin() const
|
||||
{
|
||||
return &Array[0];
|
||||
}
|
||||
|
||||
iterator end()
|
||||
{
|
||||
return &Array[Count];
|
||||
}
|
||||
const_iterator end() const
|
||||
{
|
||||
return &Array[Count];
|
||||
}
|
||||
const_iterator cend() const
|
||||
{
|
||||
return &Array[Count];
|
||||
|
|
|
@ -3039,7 +3039,7 @@ ExpEmit FxArrayElement::Emit(VMFunctionBuilder *build)
|
|||
{
|
||||
ExpEmit indexv(index->Emit(build));
|
||||
int shiftbits = 0;
|
||||
while (1 << shiftbits < arraytype->ElementSize)
|
||||
while (1u << shiftbits < arraytype->ElementSize)
|
||||
{
|
||||
shiftbits++;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue