- fixed: Script defined pointers were not added to the FlatPointers array.

This commit is contained in:
Christoph Oelckers 2016-11-17 22:21:08 +01:00
parent e4dfb13d25
commit 6461f5995b
2 changed files with 98 additions and 14 deletions

View file

@ -419,6 +419,16 @@ void PType::SetDefaultValue(void *base, unsigned offset, TArray<FTypeAndOffset>
{
}
//==========================================================================
//
// PType :: SetDefaultValue
//
//==========================================================================
void PType::SetPointer(void *base, unsigned offset, TArray<size_t> *stroffs) const
{
}
//==========================================================================
//
// PType :: InitializeValue
@ -1550,6 +1560,21 @@ void PPointer::GetTypeIDs(intptr_t &id1, intptr_t &id2) const
id2 = 0;
}
//==========================================================================
//
// PPointer :: SetDefaultValue
//
//==========================================================================
void PPointer::SetPointer(void *base, unsigned offset, TArray<size_t> *special) const
{
if (PointedType != nullptr && PointedType->IsKindOf(RUNTIME_CLASS(PClass)))
{
// Add to the list of pointers for this class.
special->Push(offset);
}
}
//==========================================================================
//
// PPointer :: WriteValue
@ -1869,6 +1894,20 @@ void PArray::SetDefaultValue(void *base, unsigned offset, TArray<FTypeAndOffset>
}
}
//==========================================================================
//
// PArray :: SetDefaultValue
//
//==========================================================================
void PArray::SetPointer(void *base, unsigned offset, TArray<size_t> *special) const
{
for (unsigned i = 0; i < ElementCount; ++i)
{
ElementType->SetPointer(base, offset + i*ElementSize, special);
}
}
//==========================================================================
//
// NewArray
@ -2104,6 +2143,23 @@ void PStruct::SetDefaultValue(void *base, unsigned offset, TArray<FTypeAndOffset
}
}
//==========================================================================
//
// PStruct :: SetPointer
//
//==========================================================================
void PStruct::SetPointer(void *base, unsigned offset, TArray<size_t> *special) const
{
for (const PField *field : Fields)
{
if (!(field->Flags & VARF_Native))
{
field->Type->SetPointer(base, unsigned(offset + field->Offset), special);
}
}
}
//==========================================================================
//
// PStruct :: WriteValue
@ -3045,14 +3101,9 @@ void PClass::InitializeDefaults()
assert(ParentClass != NULL);
ParentClass->InitializeSpecials(Defaults);
// and initialize our own special values.
auto it = Symbols.GetIterator();
PSymbolTable::MapType::Pair *pair;
while (it.NextPair(pair))
for (const PField *field : Fields)
{
auto field = dyn_cast<PField>(pair->Value);
if (field != nullptr && !(field->Flags & VARF_Native))
if (!(field->Flags & VARF_Native))
{
field->Type->SetDefaultValue(Defaults, unsigned(field->Offset), &SpecialInits);
}
@ -3270,7 +3321,7 @@ void PClass::BuildFlatPointers ()
return;
}
else if (ParentClass == NULL)
{ // No parent: FlatPointers is the same as Pointers.
{ // No parent (i.e. DObject: FlatPointers is the same as Pointers.
if (Pointers == NULL)
{ // No pointers: Make FlatPointers a harmless non-NULL.
FlatPointers = &TheEnd;
@ -3283,7 +3334,19 @@ void PClass::BuildFlatPointers ()
else
{
ParentClass->BuildFlatPointers ();
if (Pointers == NULL)
TArray<size_t> ScriptPointers;
// Collect all pointers in scripted fields. These are not part of the Pointers list.
for (auto field : Fields)
{
if (!(field->Flags & VARF_Native))
{
field->Type->SetPointer(Defaults, unsigned(field->Offset), &ScriptPointers);
}
}
if (Pointers == nullptr && ScriptPointers.Size() == 0)
{ // No new pointers: Just use the same FlatPointers as the parent.
FlatPointers = ParentClass->FlatPointers;
}
@ -3291,20 +3354,34 @@ void PClass::BuildFlatPointers ()
{ // New pointers: Create a new FlatPointers array and add them.
int numPointers, numSuperPointers;
// Count pointers defined by this class.
for (numPointers = 0; Pointers[numPointers] != ~(size_t)0; numPointers++)
{ }
if (Pointers != nullptr)
{
// Count pointers defined by this class.
for (numPointers = 0; Pointers[numPointers] != ~(size_t)0; numPointers++)
{
}
}
else numPointers = 0;
// Count pointers defined by superclasses.
for (numSuperPointers = 0; ParentClass->FlatPointers[numSuperPointers] != ~(size_t)0; numSuperPointers++)
{ }
// Concatenate them into a new array
size_t *flat = new size_t[numPointers + numSuperPointers + 1];
size_t *flat = new size_t[numPointers + numSuperPointers + ScriptPointers.Size() + 1];
if (numSuperPointers > 0)
{
memcpy (flat, ParentClass->FlatPointers, sizeof(size_t)*numSuperPointers);
}
memcpy (flat + numSuperPointers, Pointers, sizeof(size_t)*(numPointers+1));
if (numPointers > 0)
{
memcpy(flat + numSuperPointers, Pointers, sizeof(size_t)*numPointers);
}
if (ScriptPointers.Size() > 0)
{
memcpy(flat + numSuperPointers + numPointers, &ScriptPointers[0], sizeof(size_t) * ScriptPointers.Size());
}
flat[numSuperPointers + numPointers + ScriptPointers.Size()] = ~(size_t)0;
FlatPointers = flat;
}
}

View file

@ -252,6 +252,7 @@ public:
// 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;
virtual void SetPointer(void *base, unsigned offset, TArray<size_t> *ptrofs = NULL) const;
// Initialize the value, if needed (e.g. strings)
virtual void InitializeValue(void *addr, const void *def) const;
@ -552,6 +553,7 @@ public:
virtual bool IsMatch(intptr_t id1, intptr_t id2) const;
virtual void GetTypeIDs(intptr_t &id1, intptr_t &id2) const;
void SetPointer(void *base, unsigned offset, TArray<size_t> *special = NULL) const override;
void WriteValue(FSerializer &ar, const char *key,const void *addr) const override;
bool ReadValue(FSerializer &ar, const char *key,void *addr) const override;
@ -569,6 +571,9 @@ public:
class PClass *ClassRestriction;
// this is only here to block PPointer's implementation
void SetPointer(void *base, unsigned offset, TArray<size_t> *special = NULL) const override {}
virtual bool IsMatch(intptr_t id1, intptr_t id2) const;
virtual void GetTypeIDs(intptr_t &id1, intptr_t &id2) const;
protected:
@ -626,6 +631,7 @@ public:
bool ReadValue(FSerializer &ar, const char *key,void *addr) const override;
void SetDefaultValue(void *base, unsigned offset, TArray<FTypeAndOffset> *special) const override;
void SetPointer(void *base, unsigned offset, TArray<size_t> *special) const override;
protected:
PArray();
@ -679,6 +685,7 @@ public:
void WriteValue(FSerializer &ar, const char *key,const void *addr) const override;
bool ReadValue(FSerializer &ar, const char *key,void *addr) const override;
void SetDefaultValue(void *base, unsigned offset, TArray<FTypeAndOffset> *specials) const override;
void SetPointer(void *base, unsigned offset, TArray<size_t> *specials) const override;
static void WriteFields(FSerializer &ar, const void *addr, const TArray<PField *> &fields);
bool ReadFields(FSerializer &ar, void *addr) const;