Map<K,V> and MapIterator<K,V> for ZScript

This commit is contained in:
Ricardo Luís Vaz Silva 2022-11-25 20:39:12 -03:00 committed by Christoph Oelckers
commit 8b6a714d41
23 changed files with 2354 additions and 28 deletions

View file

@ -42,6 +42,7 @@
#include "types.h"
#include "i_time.h"
#include "printf.h"
#include "maps.h"
//==========================================================================
//
@ -342,6 +343,17 @@ DEFINE_ACTION_FUNCTION(DObject, Destroy)
//
//==========================================================================
template<typename M>
static void PropagateMarkMap(M *map)
{
TMapIterator<typename M::KeyType,DObject*> it(*map);
typename M::Pair * p;
while(it.NextPair(p))
{
GC::Mark(&p->Value);
}
}
size_t DObject::PropagateMark()
{
const PClass *info = GetClass();
@ -375,6 +387,27 @@ size_t DObject::PropagateMark()
offsets++;
}
{
const std::pair<size_t,PType *> *maps = info->MapPointers;
if (maps == NULL)
{
const_cast<PClass *>(info)->BuildMapPointers();
maps = info->MapPointers;
}
while (maps->first != ~(size_t)0)
{
if(maps->second->RegType == REGT_STRING)
{ // FString,DObject*
PropagateMarkMap((ZSMap<FString,DObject*>*)((uint8_t *)this + maps->first));
}
else
{ // uint32_t,DObject*
PropagateMarkMap((ZSMap<uint32_t,DObject*>*)((uint8_t *)this + maps->first));
}
maps++;
}
}
return info->Size;
}
return 0;

View file

@ -82,6 +82,8 @@ DEFINE_GLOBAL(WP_NOCHANGE);
// A harmless non-nullptr FlatPointer for classes without pointers.
static const size_t TheEnd = ~(size_t)0;
static const std::pair<size_t,PType *> TheMapEnd = {~(size_t)0 , nullptr};
//==========================================================================
//
// PClass :: WriteValue
@ -877,6 +879,68 @@ void PClass::BuildArrayPointers()
}
}
//==========================================================================
//
// PClass :: BuildMapPointers
//
// same as above, but creates a list to dynamic object arrays
//
//==========================================================================
void PClass::BuildMapPointers()
{
if (MapPointers != nullptr)
{ // Already built: Do nothing.
return;
}
else if (ParentClass == nullptr)
{ // No parent (i.e. DObject: FlatPointers is the same as Pointers.
MapPointers = &TheMapEnd;
}
else
{
ParentClass->BuildMapPointers();
TArray<std::pair<size_t,PType *>> ScriptPointers;
// Collect all arrays to pointers in scripted fields.
for (auto field : Fields)
{
if (!(field->Flags & VARF_Native))
{
field->Type->SetPointerMap(Defaults, unsigned(field->Offset), &ScriptPointers);
}
}
if (ScriptPointers.Size() == 0)
{ // No new pointers: Just use the same ArrayPointers as the parent.
MapPointers = ParentClass->MapPointers;
}
else
{ // New pointers: Create a new FlatPointers array and add them.
int numSuperPointers;
// Count pointers defined by superclasses.
for (numSuperPointers = 0; ParentClass->MapPointers[numSuperPointers].first != ~(size_t)0; numSuperPointers++)
{
}
// Concatenate them into a new array
std::pair<size_t,PType *> *flat = (std::pair<size_t,PType *>*)ClassDataAllocator.Alloc(sizeof(std::pair<size_t,PType *>) * (numSuperPointers + ScriptPointers.Size() + 1));
if (numSuperPointers > 0)
{
memcpy(flat, ParentClass->MapPointers, sizeof(std::pair<size_t,PType *>)*numSuperPointers);
}
if (ScriptPointers.Size() > 0)
{
memcpy(flat + numSuperPointers, &ScriptPointers[0], sizeof(std::pair<size_t,PType *>) * ScriptPointers.Size());
}
flat[numSuperPointers + ScriptPointers.Size()] = TheMapEnd;
MapPointers = flat;
}
}
}
//==========================================================================
//
// PClass :: NativeClass

View file

@ -56,6 +56,7 @@ public:
const size_t *Pointers = nullptr; // object pointers defined by this class *only*
const size_t *FlatPointers = nullptr; // object pointers defined by this class and all its superclasses; not initialized by default
const size_t *ArrayPointers = nullptr; // dynamic arrays containing object pointers.
const std::pair<size_t,PType *> *MapPointers = nullptr; // maps containing object pointers.
uint8_t *Defaults = nullptr;
uint8_t *Meta = nullptr; // Per-class static script data
unsigned Size = sizeof(DObject);
@ -84,6 +85,7 @@ public:
void InitializeActorInfo();
void BuildFlatPointers();
void BuildArrayPointers();
void BuildMapPointers();
void DestroySpecials(void *addr);
void DestroyMeta(void *addr);
const PClass *NativeClass() const;