diff --git a/src/common/objects/dobject.cpp b/src/common/objects/dobject.cpp index 09bea79993a..6a1f8664cb5 100644 --- a/src/common/objects/dobject.cpp +++ b/src/common/objects/dobject.cpp @@ -363,54 +363,49 @@ size_t DObject::PropagateMark() const PClass *info = GetClass(); if (!PClass::bShutdown) { - const size_t *offsets = info->FlatPointers; - if (offsets == NULL) + if (info->FlatPointers == nullptr) { - const_cast(info)->BuildFlatPointers(); - offsets = info->FlatPointers; + info->BuildFlatPointers(); + assert(info->FlatPointers); } - while (*offsets != ~(size_t)0) + + for(size_t i = 0; i < info->FlatPointersSize; i++) { - GC::Mark((DObject **)((uint8_t *)this + *offsets)); - offsets++; + GC::Mark((DObject **)((uint8_t *)this + info->FlatPointers[i].first)); } - offsets = info->ArrayPointers; - if (offsets == NULL) + if (info->ArrayPointers == nullptr) { - const_cast(info)->BuildArrayPointers(); - offsets = info->ArrayPointers; + info->BuildArrayPointers(); + assert(info->ArrayPointers); } - while (*offsets != ~(size_t)0) + + for(size_t i = 0; i < info->ArrayPointersSize; i++) { - auto aray = (TArray*)((uint8_t *)this + *offsets); + auto aray = (TArray*)((uint8_t *)this + info->ArrayPointers[i].first); for (auto &p : *aray) { GC::Mark(&p); } - offsets++; } + if (info->MapPointers == nullptr) { - const std::pair *maps = info->MapPointers; - if (maps == NULL) - { - const_cast(info)->BuildMapPointers(); - maps = info->MapPointers; + info->BuildMapPointers(); + assert(info->MapPointers); + } + + for(size_t i = 0; i < info->MapPointersSize; i++) + { + PMap * type = static_cast(info->MapPointers[i].second); + if(type->KeyType->RegType == REGT_STRING) + { // FString,DObject* + PropagateMarkMap((ZSMap*)((uint8_t *)this + info->MapPointers[i].first)); } - while (maps->first != ~(size_t)0) - { - if(maps->second->RegType == REGT_STRING) - { // FString,DObject* - PropagateMarkMap((ZSMap*)((uint8_t *)this + maps->first)); - } - else - { // uint32_t,DObject* - PropagateMarkMap((ZSMap*)((uint8_t *)this + maps->first)); - } - maps++; + else + { // uint32_t,DObject* + PropagateMarkMap((ZSMap*)((uint8_t *)this + info->MapPointers[i].first)); } - } return info->Size; } @@ -423,35 +418,51 @@ size_t DObject::PropagateMark() // //========================================================================== +template +static void MapPointerSubstitution(M *map, size_t &changed, DObject *old, DObject *notOld) +{ + TMapIterator it(*map); + typename M::Pair * p; + while(it.NextPair(p)) + { + if (p->Value == old) + { + p->Value = notOld; + changed++; + } + } +} + size_t DObject::PointerSubstitution (DObject *old, DObject *notOld) { const PClass *info = GetClass(); - const size_t *offsets = info->FlatPointers; size_t changed = 0; - if (offsets == NULL) + if (info->FlatPointers == nullptr) { - const_cast(info)->BuildFlatPointers(); - offsets = info->FlatPointers; + info->BuildFlatPointers(); + assert(info->FlatPointers); } - while (*offsets != ~(size_t)0) + + for(size_t i = 0; i < info->FlatPointersSize; i++) { - if (*(DObject **)((uint8_t *)this + *offsets) == old) + size_t offset = info->FlatPointers[i].first; + + if (*(DObject **)((uint8_t *)this + offset) == old) { - *(DObject **)((uint8_t *)this + *offsets) = notOld; + *(DObject **)((uint8_t *)this + offset) = notOld; changed++; } - offsets++; } - offsets = info->ArrayPointers; - if (offsets == NULL) + if (info->ArrayPointers == nullptr) { - const_cast(info)->BuildArrayPointers(); - offsets = info->ArrayPointers; + info->BuildArrayPointers(); + assert(info->ArrayPointers); } - while (*offsets != ~(size_t)0) + + for(size_t i = 0; i < info->ArrayPointersSize; i++) { - auto aray = (TArray*)((uint8_t *)this + *offsets); + auto aray = (TArray*)((uint8_t *)this + info->ArrayPointers[i].first); for (auto &p : *aray) { if (p == old) @@ -460,9 +471,26 @@ size_t DObject::PointerSubstitution (DObject *old, DObject *notOld) changed++; } } - offsets++; } + if (info->MapPointers == nullptr) + { + info->BuildMapPointers(); + assert(info->MapPointers); + } + + for(size_t i = 0; i < info->MapPointersSize; i++) + { + PMap * type = static_cast(info->MapPointers[i].second); + if(type->KeyType->RegType == REGT_STRING) + { // FString,DObject* + MapPointerSubstitution((ZSMap*)((uint8_t *)this + info->MapPointers[i].first), changed, old, notOld); + } + else + { // uint32_t,DObject* + MapPointerSubstitution((ZSMap*)((uint8_t *)this + info->MapPointers[i].first), changed, old, notOld); + } + } return changed; } diff --git a/src/common/objects/dobjtype.cpp b/src/common/objects/dobjtype.cpp index 7b4463011c8..0d1bfdf9a87 100644 --- a/src/common/objects/dobjtype.cpp +++ b/src/common/objects/dobjtype.cpp @@ -80,9 +80,7 @@ DEFINE_GLOBAL(WP_NOCHANGE); // PRIVATE DATA DEFINITIONS ------------------------------------------------ // A harmless non-nullptr FlatPointer for classes without pointers. -static const size_t TheEnd = ~(size_t)0; - -static const std::pair TheMapEnd = {~(size_t)0 , nullptr}; +static const std::pair TheEnd = {~(size_t)0 , nullptr}; //========================================================================== // @@ -768,75 +766,81 @@ PSymbol *PClass::FindSymbol(FName symname, bool searchparents) const // //========================================================================== -void PClass::BuildFlatPointers () +void PClass::BuildFlatPointers() const { + using pairType = std::pair; + if (FlatPointers != nullptr) { // Already built: Do nothing. return; } - else if (ParentClass == nullptr) - { // No parent (i.e. DObject: FlatPointers is the same as Pointers. - if (Pointers == nullptr) - { // No pointers: Make FlatPointers a harmless non-nullptr. - FlatPointers = &TheEnd; - } - else - { - FlatPointers = Pointers; - } - } else { - ParentClass->BuildFlatPointers (); - - TArray ScriptPointers; - - // Collect all pointers in scripted fields. These are not part of the Pointers list. - for (auto field : Fields) + TArray NativePointers; + if (Pointers != nullptr) { - if (!(field->Flags & VARF_Native)) + for (size_t i = 0; Pointers[i] != ~(size_t)0; i++) { - field->Type->SetPointer(Defaults, unsigned(field->Offset), &ScriptPointers); + NativePointers.Push({Pointers[i], nullptr}); // native pointers have a null type } } - if (Pointers == nullptr && ScriptPointers.Size() == 0) - { // No new pointers: Just use the same FlatPointers as the parent. - FlatPointers = ParentClass->FlatPointers; + if (ParentClass == nullptr) + { // No parent (i.e. DObject): FlatPointers is the same as Pointers. + if (NativePointers.Size() == 0) + { // No pointers: Make FlatPointers a harmless non-nullptr. + FlatPointers = (pairType*)(&TheEnd); + FlatPointersSize = 0; + } + else + { + pairType *flat = (pairType*)ClassDataAllocator.Alloc(sizeof(pairType) * NativePointers.Size()); + memcpy(flat, NativePointers.Data(), sizeof(pairType) * NativePointers.Size()); + + FlatPointers = flat; + FlatPointersSize = NativePointers.Size(); + } } else - { // New pointers: Create a new FlatPointers array and add them. - int numPointers, numSuperPointers; + { + ParentClass->BuildFlatPointers(); - if (Pointers != nullptr) + TArray ScriptPointers; + + // Collect all pointers in scripted fields. These are not part of the Pointers list. + for (auto field : Fields) { - // Count pointers defined by this class. - for (numPointers = 0; Pointers[numPointers] != ~(size_t)0; numPointers++) + if (!(field->Flags & VARF_Native)) { + field->Type->SetPointer(Defaults, unsigned(field->Offset), &ScriptPointers); } } - 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 = (size_t*)ClassDataAllocator.Alloc(sizeof(size_t) * (numPointers + numSuperPointers + ScriptPointers.Size() + 1)); - if (numSuperPointers > 0) - { - memcpy (flat, ParentClass->FlatPointers, sizeof(size_t)*numSuperPointers); - } - if (numPointers > 0) - { - memcpy(flat + numSuperPointers, Pointers, sizeof(size_t)*numPointers); + if (NativePointers.Size() == 0 && ScriptPointers.Size() == 0) + { // No new pointers: Just use the same FlatPointers as the parent. + FlatPointers = ParentClass->FlatPointers; + FlatPointersSize = ParentClass->FlatPointersSize; } - if (ScriptPointers.Size() > 0) - { - memcpy(flat + numSuperPointers + numPointers, &ScriptPointers[0], sizeof(size_t) * ScriptPointers.Size()); + else + { // New pointers: Create a new FlatPointers array and add them. + // Concatenate them into a new array + pairType *flat = (pairType*)ClassDataAllocator.Alloc(sizeof(pairType) * (ParentClass->FlatPointersSize + NativePointers.Size() + ScriptPointers.Size())); + + if (ParentClass->FlatPointersSize > 0) + { + memcpy (flat, ParentClass->FlatPointers, sizeof(pairType) * ParentClass->FlatPointersSize); + } + if (NativePointers.Size() > 0) + { + memcpy(flat + ParentClass->FlatPointersSize, NativePointers.Data(), sizeof(pairType) * NativePointers.Size()); + } + if (ScriptPointers.Size() > 0) + { + memcpy(flat + ParentClass->FlatPointersSize + NativePointers.Size(), &ScriptPointers[0], sizeof(pairType) * ScriptPointers.Size()); + } + FlatPointers = flat; + FlatPointersSize = ParentClass->FlatPointersSize + NativePointers.Size() + ScriptPointers.Size(); } - flat[numSuperPointers + numPointers + ScriptPointers.Size()] = ~(size_t)0; - FlatPointers = flat; } } } @@ -849,21 +853,24 @@ void PClass::BuildFlatPointers () // //========================================================================== -void PClass::BuildArrayPointers() +void PClass::BuildArrayPointers() const { + using pairType = std::pair; + if (ArrayPointers != nullptr) { // Already built: Do nothing. return; } else if (ParentClass == nullptr) - { // No parent (i.e. DObject: FlatPointers is the same as Pointers. - ArrayPointers = &TheEnd; + { // No parent (i.e. DObject): Make ArrayPointers a harmless non-nullptr. + ArrayPointers = (pairType*)(&TheEnd); + ArrayPointersSize = 0; } else { ParentClass->BuildArrayPointers(); - TArray ScriptPointers; + TArray ScriptPointers; // Collect all arrays to pointers in scripted fields. for (auto field : Fields) @@ -877,28 +884,24 @@ void PClass::BuildArrayPointers() if (ScriptPointers.Size() == 0) { // No new pointers: Just use the same ArrayPointers as the parent. ArrayPointers = ParentClass->ArrayPointers; + ArrayPointersSize = ParentClass->ArrayPointersSize; } else - { // New pointers: Create a new FlatPointers array and add them. - int numSuperPointers; - - // Count pointers defined by superclasses. - for (numSuperPointers = 0; ParentClass->ArrayPointers[numSuperPointers] != ~(size_t)0; numSuperPointers++) - { - } - + { // New pointers: Create a new ArrayPointers array and add them. // Concatenate them into a new array - size_t *flat = (size_t*)ClassDataAllocator.Alloc(sizeof(size_t) * (numSuperPointers + ScriptPointers.Size() + 1)); - if (numSuperPointers > 0) + pairType *flat = (pairType*)ClassDataAllocator.Alloc(sizeof(pairType) * (ParentClass->ArrayPointersSize + ScriptPointers.Size())); + if (ParentClass->ArrayPointersSize > 0) { - memcpy(flat, ParentClass->ArrayPointers, sizeof(size_t)*numSuperPointers); + memcpy(flat, ParentClass->ArrayPointers, sizeof(pairType) * ParentClass->ArrayPointersSize); } + if (ScriptPointers.Size() > 0) { - memcpy(flat + numSuperPointers, &ScriptPointers[0], sizeof(size_t) * ScriptPointers.Size()); + memcpy(flat + ParentClass->ArrayPointersSize, ScriptPointers.Data(), sizeof(pairType) * ScriptPointers.Size()); } - flat[numSuperPointers + ScriptPointers.Size()] = ~(size_t)0; + ArrayPointers = flat; + ArrayPointersSize = ParentClass->ArrayPointersSize + ScriptPointers.Size(); } } } @@ -911,21 +914,24 @@ void PClass::BuildArrayPointers() // //========================================================================== -void PClass::BuildMapPointers() +void PClass::BuildMapPointers() const { + using pairType = std::pair; + 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; + { // No parent (i.e. DObject): Make MapPointers a harmless non-nullptr. + MapPointers = (pairType*)(&TheEnd); + MapPointersSize = 0; } else { ParentClass->BuildMapPointers(); - TArray> ScriptPointers; + TArray ScriptPointers; // Collect all arrays to pointers in scripted fields. for (auto field : Fields) @@ -939,28 +945,23 @@ void PClass::BuildMapPointers() if (ScriptPointers.Size() == 0) { // No new pointers: Just use the same ArrayPointers as the parent. MapPointers = ParentClass->MapPointers; + MapPointersSize = ParentClass->MapPointersSize; } 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++) - { - } - + { // New pointers: Create a new FlatPointers array and add them. // Concatenate them into a new array - std::pair *flat = (std::pair*)ClassDataAllocator.Alloc(sizeof(std::pair) * (numSuperPointers + ScriptPointers.Size() + 1)); - if (numSuperPointers > 0) + pairType *flat = (pairType*)ClassDataAllocator.Alloc(sizeof(pairType) * (ParentClass->MapPointersSize + ScriptPointers.Size())); + if (ParentClass->MapPointersSize > 0) { - memcpy(flat, ParentClass->MapPointers, sizeof(std::pair)*numSuperPointers); + memcpy(flat, ParentClass->MapPointers, sizeof(pairType) * ParentClass->MapPointersSize); } + if (ScriptPointers.Size() > 0) { - memcpy(flat + numSuperPointers, &ScriptPointers[0], sizeof(std::pair) * ScriptPointers.Size()); + memcpy(flat + ParentClass->MapPointersSize, ScriptPointers.Data(), sizeof(pairType) * ScriptPointers.Size()); } - flat[numSuperPointers + ScriptPointers.Size()] = TheMapEnd; MapPointers = flat; + MapPointersSize = ParentClass->MapPointersSize + ScriptPointers.Size(); } } } diff --git a/src/common/objects/dobjtype.h b/src/common/objects/dobjtype.h index 7e698a6bf8e..62e6f5ccc5d 100644 --- a/src/common/objects/dobjtype.h +++ b/src/common/objects/dobjtype.h @@ -27,6 +27,9 @@ class PClassType; struct FNamespaceManager; class PSymbol; class PField; +class PObjectPointer; +class PDynArray; +class PMap; enum { @@ -53,10 +56,15 @@ class PClass // Per-class information ------------------------------------- PClass *ParentClass = nullptr; // the class this class derives from - 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 *MapPointers = nullptr; // maps containing object pointers. + const size_t * Pointers = nullptr; // native object pointers defined by this class *only* + + mutable size_t FlatPointersSize = 0; + mutable const std::pair * FlatPointers = nullptr; // object pointers defined by this class and all its superclasses; not initialized by default. + mutable size_t ArrayPointersSize = 0; + mutable const std::pair * ArrayPointers = nullptr; // dynamic arrays containing object pointers. + mutable size_t MapPointersSize = 0; + mutable const std::pair * MapPointers = nullptr; // maps containing object pointers. + uint8_t *Defaults = nullptr; uint8_t *Meta = nullptr; // Per-class static script data unsigned Size = sizeof(DObject); @@ -86,9 +94,11 @@ class PClass PClass *CreateDerivedClass(FName name, unsigned int size, bool *newlycreated = nullptr, int fileno = 0); void InitializeActorInfo(); - void BuildFlatPointers(); - void BuildArrayPointers(); - void BuildMapPointers(); + + void BuildFlatPointers() const; + void BuildArrayPointers() const; + void BuildMapPointers() const; + void DestroySpecials(void *addr); void DestroyMeta(void *addr); const PClass *NativeClass() const; diff --git a/src/common/scripting/core/types.cpp b/src/common/scripting/core/types.cpp index 0873125f836..8e13dcc521b 100644 --- a/src/common/scripting/core/types.cpp +++ b/src/common/scripting/core/types.cpp @@ -196,15 +196,15 @@ void PType::SetDefaultValue(void *base, unsigned offset, TArray // //========================================================================== -void PType::SetPointer(void *base, unsigned offset, TArray *stroffs) +void PType::SetPointer(void *base, unsigned offset, TArray> *stroffs) { } -void PType::SetPointerArray(void *base, unsigned offset, TArray *stroffs) +void PType::SetPointerArray(void *base, unsigned offset, TArray> *stroffs) { } -void PType::SetPointerMap(void *base, unsigned offset, TArray> *ptrofs) +void PType::SetPointerMap(void *base, unsigned offset, TArray> *ptrofs) { } @@ -1575,10 +1575,10 @@ PObjectPointer::PObjectPointer(PClass *cls, bool isconst) // //========================================================================== -void PObjectPointer::SetPointer(void *base, unsigned offset, TArray *special) +void PObjectPointer::SetPointer(void *base, unsigned offset, TArray> *special) { // Add to the list of pointers for this class. - special->Push(offset); + special->Push({offset, this}); } //========================================================================== @@ -1706,7 +1706,7 @@ bool PClassPointer::isCompatible(PType *type) // //========================================================================== -void PClassPointer::SetPointer(void *base, unsigned offset, TArray *special) +void PClassPointer::SetPointer(void *base, unsigned offset, TArray> *special) { } @@ -1908,7 +1908,7 @@ void PArray::SetDefaultValue(void *base, unsigned offset, TArray // //========================================================================== -void PArray::SetPointer(void *base, unsigned offset, TArray *special) +void PArray::SetPointer(void *base, unsigned offset, TArray> *special) { for (unsigned i = 0; i < ElementCount; ++i) { @@ -1922,7 +1922,7 @@ void PArray::SetPointer(void *base, unsigned offset, TArray *special) // //========================================================================== -void PArray::SetPointerArray(void *base, unsigned offset, TArray *special) +void PArray::SetPointerArray(void *base, unsigned offset, TArray> *special) { if (ElementType->isStruct() || ElementType->isDynArray()) { @@ -1939,7 +1939,7 @@ void PArray::SetPointerArray(void *base, unsigned offset, TArray *specia // //========================================================================== -void PArray::SetPointerMap(void *base, unsigned offset, TArray> *special) +void PArray::SetPointerMap(void *base, unsigned offset, TArray> *special) { if(ElementType->isStruct() || ElementType->isMap()) { @@ -2254,12 +2254,12 @@ void PDynArray::SetDefaultValue(void *base, unsigned offset, TArray *special) +void PDynArray::SetPointerArray(void *base, unsigned offset, TArray> *special) { if (ElementType->isObjectPointer()) { // Add to the list of pointer arrays for this class. - special->Push(offset); + special->Push({offset, this}); } } @@ -2524,12 +2524,12 @@ void PMap::SetDefaultValue(void *base, unsigned offset, TArray * // //========================================================================== -void PMap::SetPointerMap(void *base, unsigned offset, TArray> *special) +void PMap::SetPointerMap(void *base, unsigned offset, TArray> *special) { if (ValueType->isObjectPointer()) { // Add to the list of pointer arrays for this class. - special->Push(std::make_pair(offset,KeyType)); + special->Push(std::make_pair(offset, this)); } } @@ -3264,7 +3264,7 @@ void PStruct::SetDefaultValue(void *base, unsigned offset, TArray *special) +void PStruct::SetPointer(void *base, unsigned offset, TArray> *special) { auto it = Symbols.GetIterator(); PSymbolTable::MapType::Pair *pair; @@ -3284,7 +3284,7 @@ void PStruct::SetPointer(void *base, unsigned offset, TArray *special) // //========================================================================== -void PStruct::SetPointerArray(void *base, unsigned offset, TArray *special) +void PStruct::SetPointerArray(void *base, unsigned offset, TArray> *special) { auto it = Symbols.GetIterator(); PSymbolTable::MapType::Pair *pair; @@ -3304,7 +3304,7 @@ void PStruct::SetPointerArray(void *base, unsigned offset, TArray *speci // //========================================================================== -void PStruct::SetPointerMap(void *base, unsigned offset, TArray> *special) +void PStruct::SetPointerMap(void *base, unsigned offset, TArray> *special) { auto it = Symbols.GetIterator(); PSymbolTable::MapType::Pair *pair; diff --git a/src/common/scripting/core/types.h b/src/common/scripting/core/types.h index e892a8b1209..a092247dea3 100644 --- a/src/common/scripting/core/types.h +++ b/src/common/scripting/core/types.h @@ -68,8 +68,11 @@ class PPointer; class PClassPointer; class PFunctionPointer; class PArray; +class PDynArray; +class PMap; class PStruct; class PClassType; +class PObjectPointer; struct ZCC_ExprConstant; class PType : public PTypeBase @@ -129,9 +132,9 @@ class PType : public PTypeBase // initialization when the object is created and destruction when the // object is destroyed. virtual void SetDefaultValue(void *base, unsigned offset, TArray *special=NULL); - virtual void SetPointer(void *base, unsigned offset, TArray *ptrofs = NULL); - virtual void SetPointerArray(void *base, unsigned offset, TArray *ptrofs = NULL); - virtual void SetPointerMap(void *base, unsigned offset, TArray> *ptrofs = NULL); + virtual void SetPointer(void *base, unsigned offset, TArray> *ptrofs = NULL); + virtual void SetPointerArray(void *base, unsigned offset, TArray> *ptrofs = NULL); + virtual void SetPointerMap(void *base, unsigned offset, TArray> *ptrofs = NULL); // Initialize the value, if needed (e.g. strings) virtual void InitializeValue(void *addr, const void *def) const; @@ -455,7 +458,7 @@ class PObjectPointer : public PPointer void WriteValue(FSerializer &ar, const char *key, const void *addr) const override; bool ReadValue(FSerializer &ar, const char *key, void *addr) const override; - void SetPointer(void *base, unsigned offset, TArray *special = NULL) override; + void SetPointer(void *base, unsigned offset, TArray> *special = NULL) override; PClass *PointedClass() const; }; @@ -471,7 +474,7 @@ class PClassPointer : public PPointer void WriteValue(FSerializer &ar, const char *key, const void *addr) const override; bool ReadValue(FSerializer &ar, const char *key, void *addr) const override; - void SetPointer(void *base, unsigned offset, TArray *special = NULL) override; + void SetPointer(void *base, unsigned offset, TArray> *special = NULL) override; bool IsMatch(intptr_t id1, intptr_t id2) const override; void GetTypeIDs(intptr_t &id1, intptr_t &id2) const override; }; @@ -503,9 +506,9 @@ class PArray : public PCompoundType bool ReadValue(FSerializer &ar, const char *key,void *addr) const override; void SetDefaultValue(void *base, unsigned offset, TArray *special) override; - void SetPointer(void *base, unsigned offset, TArray *special) override; - void SetPointerArray(void *base, unsigned offset, TArray *ptrofs = NULL) override; - void SetPointerMap(void *base, unsigned offset, TArray> *ptrofs = NULL) override; + void SetPointer(void *base, unsigned offset, TArray> *special) override; + void SetPointerArray(void *base, unsigned offset, TArray> *ptrofs = NULL) override; + void SetPointerMap(void *base, unsigned offset, TArray> *ptrofs = NULL) override; }; class PStaticArray : public PArray @@ -535,7 +538,7 @@ class PDynArray : public PCompoundType void SetDefaultValue(void *base, unsigned offset, TArray *specials) override; void InitializeValue(void *addr, const void *def) const override; void DestroyValue(void *addr) const override; - void SetPointerArray(void *base, unsigned offset, TArray *ptrofs = NULL) override; + void SetPointerArray(void *base, unsigned offset, TArray> *ptrofs = NULL) override; }; class PMap : public PCompoundType @@ -579,7 +582,7 @@ class PMap : public PCompoundType void SetDefaultValue(void *base, unsigned offset, TArray *specials) override; void InitializeValue(void *addr, const void *def) const override; void DestroyValue(void *addr) const override; - void SetPointerMap(void *base, unsigned offset, TArray> *ptrofs) override; + void SetPointerMap(void *base, unsigned offset, TArray> *ptrofs) override; }; @@ -653,9 +656,9 @@ class PStruct : public PContainerType 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 *specials) override; - void SetPointer(void *base, unsigned offset, TArray *specials) override; - void SetPointerArray(void *base, unsigned offset, TArray *special) override; - void SetPointerMap(void *base, unsigned offset, TArray> *ptrofs) override; + void SetPointer(void *base, unsigned offset, TArray> *specials) override; + void SetPointerArray(void *base, unsigned offset, TArray> *special) override; + void SetPointerMap(void *base, unsigned offset, TArray> *ptrofs) override; }; class PPrototype : public PCompoundType