Map<K,V> and MapIterator<K,V> for ZScript
This commit is contained in:
parent
1e5e65546d
commit
8b6a714d41
23 changed files with 2354 additions and 28 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue