- backend update from GZDoom.

This commit is contained in:
Christoph Oelckers 2022-12-04 16:51:44 +01:00
parent 4666c4a4b5
commit 1061e3e2ca
31 changed files with 2760 additions and 116 deletions

View file

@ -0,0 +1,483 @@
#include "tarray.h"
#include "dobject.h"
#include "zstring.h"
#include "vm.h"
#include "types.h"
#include "v_draw.h"
#include "maps.h"
//==========================================================================
//
// MAP_GC_WRITE_BARRIER
//
//==========================================================================
#define MAP_GC_WRITE_BARRIER(x) { \
TMapIterator<typename M::KeyType, DObject*> it(*x);\
typename M::Pair * p;\
while(it.NextPair(p)){\
GC::WriteBarrier(p->Value);\
}\
}
//==========================================================================
//
// MapCopy
//
//==========================================================================
template<typename M> void MapCopy(M * self, M * other)
{
if constexpr(std::is_same_v<typename M::ValueType,DObject*>)
{
MAP_GC_WRITE_BARRIER(other);
}
*self = *other; // how does this handle self->info? TODO double check.
self->info->rev++;
}
//==========================================================================
//
// MapMove
//
//==========================================================================
template<typename M> void MapMove(M * self, M * other)
{
if constexpr(std::is_same_v<typename M::ValueType,DObject*>)
{
MAP_GC_WRITE_BARRIER(other);
}
self->TransferFrom(*other);
self->info->rev++;
other->info->rev++;
}
//==========================================================================
//
// MapSwap
//
//==========================================================================
template<typename M> void MapSwap(M * self, M * other)
{
if constexpr(std::is_same_v<typename M::ValueType,DObject*>)
{
MAP_GC_WRITE_BARRIER(other);
}
self->Swap(*other);
self->info->rev++;
other->info->rev++;
}
//==========================================================================
//
// MapClear
//
//==========================================================================
template<typename M> void MapClear(M * self)
{
if constexpr(std::is_same_v<typename M::ValueType,DObject*>)
{
MAP_GC_WRITE_BARRIER(self);
}
self->Clear();
self->info->rev++;
}
//==========================================================================
//
//
//
//==========================================================================
template<typename T>
using expand_types_vm =
std::conditional_t<std::is_same_v<T, uint8_t> || std::is_same_v<T, uint16_t>, uint32_t , /* expand 8/16-bit to 32-bit */
std::conditional_t<std::is_same_v<T, float> , double , /* expand float to double */
std::conditional_t<std::is_same_v<T, FString> , const FString & , T>>>; /* change String to String ref */
template<typename M> unsigned int MapCountUsed(M * self)
{
return self->CountUsed();
}
template<typename M> expand_types_vm<typename M::ValueType> MapGet(M * self,expand_types_vm<typename M::KeyType> key)
{
typename M::ValueType * v = self->CheckKey(key);
if (v) {
return *v;
}
else
{
typename M::ValueType n {};
self->Insert(key,n);
return n;
}
}
template<typename M> void MapGetString(M * self,expand_types_vm<typename M::KeyType> key, FString &out)
{
FString * v = self->CheckKey(key);
if (v) {
out = *v;
}
else
{
out = FString();
self->Insert(key,out);
}
}
template<typename M> int MapCheckKey(M * self, expand_types_vm<typename M::KeyType> key)
{
return self->CheckKey(key) != nullptr;
}
//==========================================================================
//
// MapInsert
//
//==========================================================================
template<typename M> void MapInsert(M * self, expand_types_vm<typename M::KeyType> key, expand_types_vm<typename M::ValueType> value)
{
if constexpr(std::is_same_v<typename M::ValueType, DObject*>)
{
MAP_GC_WRITE_BARRIER(self);
GC::WriteBarrier(value);
}
self->Insert(key, value);
self->info->rev++; // invalidate iterators
}
//==========================================================================
//
//
//
//==========================================================================
template<typename M> void MapInsertNew(M * self, expand_types_vm<typename M::KeyType> key)
{
if constexpr(std::is_same_v<typename M::ValueType, DObject*>)
{
MAP_GC_WRITE_BARRIER(self);
}
self->Insert(key,{});
self->info->rev++; // invalidate iterators
}
template<typename M> void MapRemove(M * self, expand_types_vm<typename M::KeyType> key)
{
self->Remove(key);
self->info->rev++; // invalidate iterators
}
//==========================================================================
//
//
//
//==========================================================================
template<typename I, typename M> int MapIteratorInit(I * self, M * other)
{
return self->Init(*other);
}
template<typename I> int MapIteratorReInit(I * self)
{
return self->ReInit();
}
template<typename I> int MapIteratorValid(I * self)
{
return self->Valid();
}
template<typename I> int MapIteratorNext(I * self)
{
return self->Next();
}
template<typename I> expand_types_vm<typename I::KeyType> MapIteratorGetKey(I * self)
{
return self->GetKey();
}
template<typename I> void MapIteratorGetKeyString(I * self, FString &out)
{
out = self->GetKey();
}
template<typename I> expand_types_vm<typename I::ValueType> MapIteratorGetValue(I * self)
{
return self->GetValue();
}
template<typename I> void MapIteratorGetValueString(I * self, FString &out)
{
out = self->GetValue();
}
template<typename I> void MapIteratorSetValue(I * self, expand_types_vm<typename I::ValueType> value)
{
auto & val = self->GetValue();
if constexpr(std::is_same_v<typename I::ValueType, DObject*>)
{
GC::WriteBarrier(val);
GC::WriteBarrier(value);
}
val = value;
}
//==========================================================================
//
//
//
//==========================================================================
#define PARAM_VOIDPOINTER(X) PARAM_POINTER( X , void )
#define PARAM_OBJPOINTER(X) PARAM_OBJECT( X , DObject )
#define _DEF_MAP( name, key_type, value_type, PARAM_KEY, PARAM_VALUE ) \
typedef ZSMap<key_type , value_type> name;\
DEFINE_ACTION_FUNCTION_NATIVE( name , Copy , MapCopy< name > ) \
{ \
PARAM_SELF_STRUCT_PROLOGUE( name ); \
PARAM_POINTER( other, name ); \
MapCopy(self , other); \
return 0; \
} \
DEFINE_ACTION_FUNCTION_NATIVE( name , Move , MapMove< name > ) \
{ \
PARAM_SELF_STRUCT_PROLOGUE( name ); \
PARAM_POINTER( other, name ); \
MapMove(self , other); \
return 0; \
} \
DEFINE_ACTION_FUNCTION_NATIVE( name , Swap , MapSwap< name > ) \
{ \
PARAM_SELF_STRUCT_PROLOGUE( name ); \
PARAM_POINTER( other, name ); \
MapSwap(self , other); \
return 0; \
} \
DEFINE_ACTION_FUNCTION_NATIVE( name , Clear , MapClear< name > ) \
{ \
PARAM_SELF_STRUCT_PROLOGUE( name ); \
MapClear(self); \
return 0; \
} \
DEFINE_ACTION_FUNCTION_NATIVE( name, CountUsed, MapCountUsed< name >) \
{ \
PARAM_SELF_STRUCT_PROLOGUE( name ); \
ACTION_RETURN_INT( MapCountUsed(self) ); \
} \
DEFINE_ACTION_FUNCTION_NATIVE( name, CheckKey, MapCheckKey< name >) \
{ \
PARAM_SELF_STRUCT_PROLOGUE( name ); \
PARAM_KEY( key ); \
ACTION_RETURN_BOOL( MapCheckKey(self, key) ); \
} \
DEFINE_ACTION_FUNCTION_NATIVE( name, Insert, MapInsert< name >) \
{ \
PARAM_SELF_STRUCT_PROLOGUE( name ); \
PARAM_KEY( key ); \
PARAM_VALUE( value ); \
MapInsert(self, key, value); \
return 0; \
} \
DEFINE_ACTION_FUNCTION_NATIVE( name, InsertNew, MapInsertNew< name >) \
{ \
PARAM_SELF_STRUCT_PROLOGUE( name ); \
PARAM_KEY( key ); \
MapInsertNew(self, key); \
return 0; \
} \
DEFINE_ACTION_FUNCTION_NATIVE( name, Remove, MapRemove< name >) \
{ \
PARAM_SELF_STRUCT_PROLOGUE( name ); \
PARAM_KEY( key ); \
MapRemove(self, key); \
return 0; \
}
#define DEF_MAP_X_X( name, key_type, value_type, PARAM_KEY, PARAM_VALUE , ACTION_RETURN_VALUE ) \
_DEF_MAP( name , key_type , value_type , PARAM_KEY , PARAM_VALUE ) \
DEFINE_ACTION_FUNCTION_NATIVE( name, Get, MapGet< name >) \
{ \
PARAM_SELF_STRUCT_PROLOGUE( name ); \
PARAM_KEY( key ); \
ACTION_RETURN_VALUE( MapGet(self, key) ); \
}
#define DEF_MAP_X_S( name, key_type, PARAM_KEY ) \
_DEF_MAP( name , key_type , FString , PARAM_KEY , PARAM_STRING ) \
DEFINE_ACTION_FUNCTION_NATIVE( name, Get, MapGetString< name >) \
{ \
PARAM_SELF_STRUCT_PROLOGUE( name ); \
PARAM_KEY( key ); \
FString out; \
MapGetString(self, key, out); \
ACTION_RETURN_STRING( out ); \
}
#define COMMA ,
#define _DEF_MAP_IT( map_name , name, key_type, value_type, PARAM_VALUE ) \
typedef ZSMapIterator<key_type , value_type> name; \
DEFINE_ACTION_FUNCTION_NATIVE( name , Init , MapIteratorInit< name COMMA map_name > ) \
{ \
PARAM_SELF_STRUCT_PROLOGUE( name ); \
PARAM_POINTER( other, map_name ); \
ACTION_RETURN_BOOL( MapIteratorInit(self , other) ); \
} \
DEFINE_ACTION_FUNCTION_NATIVE( name , ReInit , MapIteratorReInit< name > ) \
{ \
PARAM_SELF_STRUCT_PROLOGUE( name ); \
ACTION_RETURN_BOOL( MapIteratorReInit(self) ); \
} \
DEFINE_ACTION_FUNCTION_NATIVE( name , Valid , MapIteratorValid< name > ) \
{ \
PARAM_SELF_STRUCT_PROLOGUE( name ); \
ACTION_RETURN_BOOL( MapIteratorValid(self) ); \
} \
DEFINE_ACTION_FUNCTION_NATIVE( name , Next , MapIteratorNext< name > ) \
{ \
PARAM_SELF_STRUCT_PROLOGUE( name ); \
ACTION_RETURN_BOOL( MapIteratorNext(self) ); \
} \
DEFINE_ACTION_FUNCTION_NATIVE( name , SetValue , MapIteratorSetValue< name > ) \
{ \
PARAM_SELF_STRUCT_PROLOGUE( name ); \
PARAM_VALUE( value ); \
MapIteratorSetValue(self, value); \
return 0; \
}
/*
DEFINE_ACTION_FUNCTION_NATIVE( name , GetKey , MapIteratorGetKey< name > ) \
{ \
PARAM_SELF_STRUCT_PROLOGUE( name ); \
ACTION_RETURN_KEY( MapIteratorGetKey(self) ); \
} \
DEFINE_ACTION_FUNCTION_NATIVE( name , GetValue , MapIteratorGetValue< name > ) \
{ \
PARAM_SELF_STRUCT_PROLOGUE( name ); \
ACTION_RETURN_VALUE( MapIteratorGetValue(self) ); \
} \
*/
#define DEF_MAP_IT_I_X( map_name , name , value_type , PARAM_VALUE , ACTION_RETURN_VALUE ) \
_DEF_MAP_IT( map_name , name , uint32_t , value_type , PARAM_VALUE ) \
DEFINE_ACTION_FUNCTION_NATIVE( name , GetKey , MapIteratorGetKey< name > ) \
{ \
PARAM_SELF_STRUCT_PROLOGUE( name ); \
ACTION_RETURN_INT( MapIteratorGetKey(self) ); \
} \
DEFINE_ACTION_FUNCTION_NATIVE( name , GetValue , MapIteratorGetValue< name > ) \
{ \
PARAM_SELF_STRUCT_PROLOGUE( name ); \
ACTION_RETURN_VALUE( MapIteratorGetValue(self) ); \
}
#define DEF_MAP_IT_S_X( map_name , name , value_type , PARAM_VALUE , ACTION_RETURN_VALUE ) \
_DEF_MAP_IT( map_name , name , FString , value_type , PARAM_VALUE ) \
DEFINE_ACTION_FUNCTION_NATIVE( name , GetKey , MapIteratorGetKeyString< name > ) \
{ \
PARAM_SELF_STRUCT_PROLOGUE( name ); \
FString out; \
MapIteratorGetKeyString(self , out); \
ACTION_RETURN_STRING( out ); \
} \
DEFINE_ACTION_FUNCTION_NATIVE( name , GetValue , MapIteratorGetValue< name > ) \
{ \
PARAM_SELF_STRUCT_PROLOGUE( name ); \
ACTION_RETURN_VALUE( MapIteratorGetValue(self) ); \
}
#define DEF_MAP_IT_I_S() \
_DEF_MAP_IT( FMap_I32_Str , FMapIterator_I32_Str , uint32_t , FString , PARAM_STRING ) \
DEFINE_ACTION_FUNCTION_NATIVE( FMapIterator_I32_Str , GetKey , MapIteratorGetKey< FMapIterator_I32_Str > ) \
{ \
PARAM_SELF_STRUCT_PROLOGUE( FMapIterator_I32_Str ); \
ACTION_RETURN_INT( MapIteratorGetKey(self) ); \
} \
DEFINE_ACTION_FUNCTION_NATIVE( FMapIterator_I32_Str , GetValue , MapIteratorGetValue< FMapIterator_I32_Str > ) \
{ \
PARAM_SELF_STRUCT_PROLOGUE( FMapIterator_I32_Str ); \
ACTION_RETURN_STRING( MapIteratorGetValue(self) ); \
}
#define DEF_MAP_IT_S_S() \
_DEF_MAP_IT( FMap_Str_Str , FMapIterator_Str_Str , FString , FString , PARAM_STRING ) \
DEFINE_ACTION_FUNCTION_NATIVE( FMapIterator_Str_Str , GetKey , MapIteratorGetKeyString< FMapIterator_Str_Str > ) \
{ \
PARAM_SELF_STRUCT_PROLOGUE( FMapIterator_Str_Str ); \
FString out; \
MapIteratorGetKeyString(self , out); \
ACTION_RETURN_STRING( out ); \
} \
DEFINE_ACTION_FUNCTION_NATIVE( FMapIterator_Str_Str , GetValue , MapIteratorGetValueString< FMapIterator_Str_Str > ) \
{ \
PARAM_SELF_STRUCT_PROLOGUE( FMapIterator_Str_Str ); \
FString out; \
MapIteratorGetValueString(self , out); \
ACTION_RETURN_STRING( out ); \
}
#define DEFINE_MAP_AND_IT_I_X( name , value_type , PARAM_VALUE , ACTION_RETURN_VALUE ) \
DEF_MAP_X_X( FMap_ ## name , uint32_t , value_type , PARAM_INT , PARAM_VALUE , ACTION_RETURN_VALUE ) \
DEF_MAP_IT_I_X( FMap_ ## name , FMapIterator_ ## name , value_type , PARAM_VALUE , ACTION_RETURN_VALUE )
#define DEFINE_MAP_AND_IT_S_X( name , value_type , PARAM_VALUE , ACTION_RETURN_VALUE ) \
DEF_MAP_X_X( FMap_ ## name , FString , value_type , PARAM_STRING , PARAM_VALUE , ACTION_RETURN_VALUE ) \
DEF_MAP_IT_S_X( FMap_ ## name , FMapIterator_ ## name , value_type , PARAM_VALUE , ACTION_RETURN_VALUE )
#define DEFINE_MAP_AND_IT_I_S() \
DEF_MAP_X_S( FMap_I32_Str , uint32_t , PARAM_INT ) \
DEF_MAP_IT_I_S()
#define DEFINE_MAP_AND_IT_S_S() \
DEF_MAP_X_S( FMap_Str_Str , FString , PARAM_STRING ) \
DEF_MAP_IT_S_S()
DEFINE_MAP_AND_IT_I_X(I32_I8 , uint8_t , PARAM_INT , ACTION_RETURN_INT);
DEFINE_MAP_AND_IT_I_X(I32_I16 , uint16_t , PARAM_INT , ACTION_RETURN_INT);
DEFINE_MAP_AND_IT_I_X(I32_I32 , uint32_t , PARAM_INT , ACTION_RETURN_INT);
DEFINE_MAP_AND_IT_I_X(I32_F32 , float , PARAM_FLOAT , ACTION_RETURN_FLOAT);
DEFINE_MAP_AND_IT_I_X(I32_F64 , double , PARAM_FLOAT , ACTION_RETURN_FLOAT);
DEFINE_MAP_AND_IT_I_X(I32_Obj , DObject* , PARAM_OBJPOINTER , ACTION_RETURN_OBJECT);
DEFINE_MAP_AND_IT_I_X(I32_Ptr , void* , PARAM_VOIDPOINTER , ACTION_RETURN_POINTER);
DEFINE_MAP_AND_IT_I_S();
DEFINE_MAP_AND_IT_S_X(Str_I8 , uint8_t , PARAM_INT , ACTION_RETURN_INT);
DEFINE_MAP_AND_IT_S_X(Str_I16 , uint16_t , PARAM_INT , ACTION_RETURN_INT);
DEFINE_MAP_AND_IT_S_X(Str_I32 , uint32_t , PARAM_INT , ACTION_RETURN_INT);
DEFINE_MAP_AND_IT_S_X(Str_F32 , float , PARAM_FLOAT , ACTION_RETURN_FLOAT);
DEFINE_MAP_AND_IT_S_X(Str_F64 , double , PARAM_FLOAT , ACTION_RETURN_FLOAT);
DEFINE_MAP_AND_IT_S_X(Str_Obj , DObject* , PARAM_OBJPOINTER , ACTION_RETURN_OBJECT);
DEFINE_MAP_AND_IT_S_X(Str_Ptr , void* , PARAM_VOIDPOINTER , ACTION_RETURN_POINTER);
DEFINE_MAP_AND_IT_S_S();

View file

@ -0,0 +1,110 @@
#pragma once
#include <memory>
#include "tarray.h"
#include "refcounted.h"
class ZSMapInfo : public RefCountedBase
{
public:
void * self = nullptr;
int rev = 0;
};
struct ZSFMap : FMap {
RefCountedPtr<RefCountedBase> info;
};
template<class KT, class VT>
class ZSMap : public TMap<KT,VT>
{
public:
RefCountedPtr<ZSMapInfo> info;
ZSMap() :
TMap<KT,VT>(), info(new ZSMapInfo)
{
info->self = this;
}
~ZSMap()
{
info->self = nullptr;
}
};
template<class KT, class VT>
struct ZSMapIterator
{
RefCountedPtr<ZSMapInfo> info;
TMapIterator<KT,VT> *it = nullptr;
typename ZSMap<KT,VT>::Pair *p = nullptr;
typedef KT KeyType;
typedef VT ValueType;
int rev = 0;
~ZSMapIterator()
{
if(it) delete it;
}
bool Valid()
{
return it && p && info.get() && info->self && info->rev == rev;
}
bool ReInit()
{
if(info.get() && info->self) {
if(it) delete it;
it = new TMapIterator<KT,VT>(*static_cast<ZSMap<KT,VT>*>(info->self));
rev = info->rev;
p = nullptr;
return true;
}
return false;
}
bool Init(ZSMap<KT,VT> &m)
{
info = m.info;
return ReInit();
}
bool Next()
{
if(it && info.get() && info->self && info->rev == rev)
{
p = nullptr;
return it->NextPair(p);
}
else
{
ThrowAbortException(X_FORMAT_ERROR,"MapIterator::Next called from invalid iterator");
}
}
VT& GetValue()
{
if(p && info.get() && info->self && info->rev == rev)
{
return p->Value;
}
else
{
ThrowAbortException(X_FORMAT_ERROR,p ? "MapIterator::GetValue called from invalid iterator" : "MapIterator::GetValue called from invalid position");
}
}
const KT& GetKey()
{
if(p && info.get() && info->self && info->rev == rev)
{
return p->Key;
}
else
{
ThrowAbortException(X_FORMAT_ERROR,p ? "MapIterator::GetKey called from invalid iterator" : "MapIterator::GetKey called from invalid position");
}
}
};

View file

@ -33,11 +33,14 @@
**
*/
#include <cinttypes>
#include "vmintern.h"
#include "s_soundinternal.h"
#include "types.h"
#include "printf.h"
#include "textureid.h"
#include "maps.h"
FTypeTable TypeTable;
@ -183,7 +186,7 @@ void PType::SetDefaultValue(void *base, unsigned offset, TArray<FTypeAndOffset>
//==========================================================================
//
// PType :: SetDefaultValue
// PType :: SetPointer*
//
//==========================================================================
@ -195,6 +198,10 @@ void PType::SetPointerArray(void *base, unsigned offset, TArray<size_t> *stroffs
{
}
void PType::SetPointerMap(void *base, unsigned offset, TArray<std::pair<size_t,PType *>> *ptrofs)
{
}
//==========================================================================
//
// PType :: InitializeValue
@ -1862,7 +1869,7 @@ void PArray::SetPointer(void *base, unsigned offset, TArray<size_t> *special)
void PArray::SetPointerArray(void *base, unsigned offset, TArray<size_t> *special)
{
if (ElementType->isStruct())
if (ElementType->isStruct() || ElementType->isDynArray())
{
for (unsigned int i = 0; i < ElementCount; ++i)
{
@ -1871,6 +1878,23 @@ void PArray::SetPointerArray(void *base, unsigned offset, TArray<size_t> *specia
}
}
//==========================================================================
//
// PArray :: SetPointerMap
//
//==========================================================================
void PArray::SetPointerMap(void *base, unsigned offset, TArray<std::pair<size_t,PType *>> *special)
{
if(ElementType->isStruct() || ElementType->isMap())
{
for (unsigned int i = 0; i < ElementCount; ++i)
{
ElementType->SetPointerMap(base, offset + ElementSize * i, special);
}
}
}
//==========================================================================
//
// NewArray
@ -2202,12 +2226,89 @@ PDynArray *NewDynArray(PType *type)
//
//==========================================================================
PMap::PMap(PType *keytype, PType *valtype)
: KeyType(keytype), ValueType(valtype)
enum OverrideFunctionRetType {
OFN_RET_VOID,
OFN_RET_VAL,
OFN_RET_KEY,
OFN_RET_BOOL,
};
enum OverrideFunctionArgType {
OFN_ARG_VOID,
OFN_ARG_KEY,
OFN_ARG_VAL,
OFN_ARG_KEY_VAL,
};
template<class MT, OverrideFunctionRetType RetType, OverrideFunctionArgType ArgType >
void CreateOverrideFunction(MT *self, FName name)
{
auto Fn = Create<PFunction>(self->BackingType, name);
auto NativeFn = FindFunction(self->BackingType, name.GetChars());
assert(NativeFn);
assert(NativeFn->VMPointer);
TArray<PType*> ret;
TArray<PType*> args;
TArray<uint32_t> argflags;
TArray<FName> argnames;
if constexpr(RetType == OFN_RET_VAL)
{
ret.Push(self->ValueType);
}
else if constexpr(RetType == OFN_RET_KEY)
{
ret.Push(self->KeyType);
}
else if constexpr(RetType == OFN_RET_BOOL)
{
ret.Push(TypeBool);
}
args.Push(NewPointer(self->BackingType));
argnames.Push(NAME_self);
argflags.Push(VARF_Implicit | VARF_ReadOnly);
if constexpr(ArgType == OFN_ARG_KEY)
{
args.Push(self->KeyType);
argflags.Push(0);
argnames.Push(NAME_Key);
}
else if constexpr(ArgType == OFN_ARG_VAL)
{
args.Push(self->ValueType);
argflags.Push(0);
argnames.Push(NAME_Value);
}
else if constexpr(ArgType == OFN_ARG_KEY_VAL)
{
args.Push(self->KeyType);
args.Push(self->ValueType);
argflags.Push(0);
argflags.Push(0);
argnames.Push(NAME_Key);
argnames.Push(NAME_Value);
}
Fn->AddVariant(NewPrototype(ret, args), argflags, argnames, *NativeFn->VMPointer, VARF_Method | VARF_Native,SUF_ACTOR | SUF_OVERLAY | SUF_WEAPON | SUF_ITEM);
self->FnOverrides.Insert(name, Fn);
}
PMap::PMap(PType *keytype, PType *valtype, PStruct *backing, int backing_class)
: KeyType(keytype), ValueType(valtype), BackingType(backing), BackingClass((decltype(BackingClass)) backing_class)
{
mDescriptiveName.Format("Map<%s, %s>", keytype->DescriptiveName(), valtype->DescriptiveName());
Size = sizeof(FMap);
Align = alignof(FMap);
Size = sizeof(ZSFMap);
Align = alignof(ZSFMap);
CreateOverrideFunction<PMap, OFN_RET_VAL, OFN_ARG_KEY>(this, NAME_Get);
CreateOverrideFunction<PMap, OFN_RET_BOOL, OFN_ARG_KEY>(this, NAME_CheckKey);
CreateOverrideFunction<PMap, OFN_RET_VOID, OFN_ARG_KEY_VAL>(this, NAME_Insert);
CreateOverrideFunction<PMap, OFN_RET_VOID, OFN_ARG_KEY>(this, NAME_InsertNew);
CreateOverrideFunction<PMap, OFN_RET_VOID, OFN_ARG_KEY>(this, NAME_Remove);
}
//==========================================================================
@ -2236,6 +2337,345 @@ void PMap::GetTypeIDs(intptr_t &id1, intptr_t &id2) const
id2 = (intptr_t)ValueType;
}
//==========================================================================
//
// PMap :: InitializeValue
//
//==========================================================================
void PMap::Construct(void * addr) const {
switch(BackingClass)
{
case MAP_I32_I8:
new(addr) ZSMap<uint32_t, uint8_t>();
break;
case MAP_I32_I16:
new(addr) ZSMap<uint32_t, uint16_t>();
break;
case MAP_I32_I32:
new(addr) ZSMap<uint32_t, uint32_t>();
break;
case MAP_I32_F32:
new(addr) ZSMap<uint32_t, float>();
break;
case MAP_I32_F64:
new(addr) ZSMap<uint32_t, double>();
break;
case MAP_I32_OBJ:
new(addr) ZSMap<uint32_t, DObject*>();
break;
case MAP_I32_PTR:
new(addr) ZSMap<uint32_t, void*>();
break;
case MAP_I32_STR:
new(addr) ZSMap<uint32_t, FString>();
break;
case MAP_STR_I8:
new(addr) ZSMap<FString, uint8_t>();
break;
case MAP_STR_I16:
new(addr) ZSMap<FString, uint16_t>();
break;
case MAP_STR_I32:
new(addr) ZSMap<FString, uint32_t>();
break;
case MAP_STR_F32:
new(addr) ZSMap<FString, float>();
break;
case MAP_STR_F64:
new(addr) ZSMap<FString, double>();
break;
case MAP_STR_OBJ:
new(addr) ZSMap<FString, DObject*>();
break;
case MAP_STR_PTR:
new(addr) ZSMap<FString, void*>();
break;
case MAP_STR_STR:
new(addr) ZSMap<FString, FString>();
break;
};
}
void PMap::InitializeValue(void *addr, const void *def) const
{
if (def != nullptr)
{
I_Error("Map cannot have default values");
}
Construct(addr);
}
//==========================================================================
//
// PMap :: DestroyValue
//
//==========================================================================
void PMap::DestroyValue(void *addr) const
{
switch(BackingClass)
{
case MAP_I32_I8:
static_cast<ZSMap<uint32_t, uint8_t>*>(addr)->~ZSMap();
break;
case MAP_I32_I16:
static_cast<ZSMap<uint32_t, uint16_t>*>(addr)->~ZSMap();
break;
case MAP_I32_I32:
static_cast<ZSMap<uint32_t, uint32_t>*>(addr)->~ZSMap();
break;
case MAP_I32_F32:
static_cast<ZSMap<uint32_t, float>*>(addr)->~ZSMap();
break;
case MAP_I32_F64:
static_cast<ZSMap<uint32_t, double>*>(addr)->~ZSMap();
break;
case MAP_I32_OBJ:
static_cast<ZSMap<uint32_t, DObject*>*>(addr)->~ZSMap();
break;
case MAP_I32_PTR:
static_cast<ZSMap<uint32_t, void*>*>(addr)->~ZSMap();
break;
case MAP_I32_STR:
static_cast<ZSMap<uint32_t, FString>*>(addr)->~ZSMap();
break;
case MAP_STR_I8:
static_cast<ZSMap<FString, uint8_t>*>(addr)->~ZSMap();
break;
case MAP_STR_I16:
static_cast<ZSMap<FString, uint16_t>*>(addr)->~ZSMap();
break;
case MAP_STR_I32:
static_cast<ZSMap<FString, uint32_t>*>(addr)->~ZSMap();
break;
case MAP_STR_F32:
static_cast<ZSMap<FString, float>*>(addr)->~ZSMap();
break;
case MAP_STR_F64:
static_cast<ZSMap<FString, double>*>(addr)->~ZSMap();
break;
case MAP_STR_OBJ:
static_cast<ZSMap<FString, DObject*>*>(addr)->~ZSMap();
break;
case MAP_STR_PTR:
static_cast<ZSMap<FString, void*>*>(addr)->~ZSMap();
break;
case MAP_STR_STR:
static_cast<ZSMap<FString, FString>*>(addr)->~ZSMap();
break;
}
}
//==========================================================================
//
// PMap :: SetDefaultValue
//
//==========================================================================
void PMap::SetDefaultValue(void *base, unsigned offset, TArray<FTypeAndOffset> *special)
{
assert(!(base && special));
if (base != nullptr)
{
Construct(((uint8_t*)base)+offset); // is this needed? string/dynarray do this initialization if base != nullptr, but their initialization doesn't need to allocate
// it might lead to double allocations (and memory leakage) for Map if both base and special != nullptr
}
if (special != nullptr)
{
special->Push(std::make_pair(this, offset));
}
else
{
I_Error("null special");
}
}
//==========================================================================
//
// PMap :: SetPointer
//
//==========================================================================
void PMap::SetPointerMap(void *base, unsigned offset, TArray<std::pair<size_t,PType *>> *special)
{
if (ValueType->isObjectPointer())
{
// Add to the list of pointer arrays for this class.
special->Push(std::make_pair(offset,KeyType));
}
}
//==========================================================================
//
// PMap :: WriteValue
//
//==========================================================================
template<typename M>
static void PMapValueWriter(FSerializer &ar, const M *map, const PMap *m)
{
TMapConstIterator<typename M::KeyType, typename M::ValueType> it(*map);
const typename M::Pair * p;
while(it.NextPair(p))
{
if constexpr(std::is_same_v<typename M::KeyType,FString>)
{
m->ValueType->WriteValue(ar,p->Key.GetChars(),static_cast<const void *>(&p->Value));
}
else if constexpr(std::is_same_v<typename M::KeyType,uint32_t>)
{
FString key;
key.Format("%u",p->Key);
m->ValueType->WriteValue(ar,key.GetChars(),static_cast<const void *>(&p->Value));
}
//else unknown key type
}
}
void PMap::WriteValue(FSerializer &ar, const char *key, const void *addr) const
{
if(ar.BeginObject(key))
{
switch(BackingClass)
{
case MAP_I32_I8:
PMapValueWriter(ar, static_cast<const ZSMap<uint32_t, uint8_t>*>(addr), this);
break;
case MAP_I32_I16:
PMapValueWriter(ar, static_cast<const ZSMap<uint32_t, uint16_t>*>(addr), this);
break;
case MAP_I32_I32:
PMapValueWriter(ar, static_cast<const ZSMap<uint32_t, uint32_t>*>(addr), this);
break;
case MAP_I32_F32:
PMapValueWriter(ar, static_cast<const ZSMap<uint32_t, float>*>(addr), this);
break;
case MAP_I32_F64:
PMapValueWriter(ar, static_cast<const ZSMap<uint32_t, double>*>(addr), this);
break;
case MAP_I32_OBJ:
PMapValueWriter(ar, static_cast<const ZSMap<uint32_t, DObject*>*>(addr), this);
break;
case MAP_I32_PTR:
PMapValueWriter(ar, static_cast<const ZSMap<uint32_t, void*>*>(addr), this);
break;
case MAP_I32_STR:
PMapValueWriter(ar, static_cast<const ZSMap<uint32_t, FString>*>(addr), this);
break;
case MAP_STR_I8:
PMapValueWriter(ar, static_cast<const ZSMap<FString, uint8_t>*>(addr), this);
break;
case MAP_STR_I16:
PMapValueWriter(ar, static_cast<const ZSMap<FString, uint16_t>*>(addr), this);
break;
case MAP_STR_I32:
PMapValueWriter(ar, static_cast<const ZSMap<FString, uint32_t>*>(addr), this);
break;
case MAP_STR_F32:
PMapValueWriter(ar, static_cast<const ZSMap<FString, float>*>(addr), this);
break;
case MAP_STR_F64:
PMapValueWriter(ar, static_cast<const ZSMap<FString, double>*>(addr), this);
break;
case MAP_STR_OBJ:
PMapValueWriter(ar, static_cast<const ZSMap<FString, DObject*>*>(addr), this);
break;
case MAP_STR_PTR:
PMapValueWriter(ar, static_cast<const ZSMap<FString, void*>*>(addr), this);
break;
case MAP_STR_STR:
PMapValueWriter(ar, static_cast<const ZSMap<FString, FString>*>(addr), this);
break;
}
ar.EndObject();
}
}
//==========================================================================
//
// PMap :: ReadValue
//
//==========================================================================
template<typename M>
static bool PMapValueReader(FSerializer &ar, M *map, const PMap *m)
{
const char * k;
while(k = ar.GetKey())
{
typename M::ValueType * val;
if constexpr(std::is_same_v<typename M::KeyType,FString>)
{
val = &map->InsertNew(k);
}
else if constexpr(std::is_same_v<typename M::KeyType,uint32_t>)
{
FString s(k);
if(!s.IsInt())
{
ar.EndObject();
return false;
}
val = &map->InsertNew(static_cast<uint32_t>(s.ToULong()));
}
if (!m->ValueType->ReadValue(ar,nullptr,static_cast<void*>(val)))
{
ar.EndObject();
return false;
}
}
ar.EndObject();
return true;
}
bool PMap::ReadValue(FSerializer &ar, const char *key, void *addr) const
{
DestroyValue(addr);
InitializeValue(addr, nullptr);
if(ar.BeginObject(key))
{
switch(BackingClass)
{
case MAP_I32_I8:
return PMapValueReader(ar, static_cast<ZSMap<uint32_t, uint8_t>*>(addr), this);
case MAP_I32_I16:
return PMapValueReader(ar, static_cast<ZSMap<uint32_t, uint16_t>*>(addr), this);
case MAP_I32_I32:
return PMapValueReader(ar, static_cast<ZSMap<uint32_t, uint32_t>*>(addr), this);
case MAP_I32_F32:
return PMapValueReader(ar, static_cast<ZSMap<uint32_t, float>*>(addr), this);
case MAP_I32_F64:
return PMapValueReader(ar, static_cast<ZSMap<uint32_t, double>*>(addr), this);
case MAP_I32_OBJ:
return PMapValueReader(ar, static_cast<ZSMap<uint32_t, DObject*>*>(addr), this);
case MAP_I32_PTR:
return PMapValueReader(ar, static_cast<ZSMap<uint32_t, void*>*>(addr), this);
case MAP_I32_STR:
return PMapValueReader(ar, static_cast<ZSMap<uint32_t, FString>*>(addr), this);
case MAP_STR_I8:
return PMapValueReader(ar, static_cast<ZSMap<FString, uint8_t>*>(addr), this);
case MAP_STR_I16:
return PMapValueReader(ar, static_cast<ZSMap<FString, uint16_t>*>(addr), this);
case MAP_STR_I32:
return PMapValueReader(ar, static_cast<ZSMap<FString, uint32_t>*>(addr), this);
case MAP_STR_F32:
return PMapValueReader(ar, static_cast<ZSMap<FString, float>*>(addr), this);
case MAP_STR_F64:
return PMapValueReader(ar, static_cast<ZSMap<FString, double>*>(addr), this);
case MAP_STR_OBJ:
return PMapValueReader(ar, static_cast<ZSMap<FString, DObject*>*>(addr), this);
case MAP_STR_PTR:
return PMapValueReader(ar, static_cast<ZSMap<FString, void*>*>(addr), this);
case MAP_STR_STR:
return PMapValueReader(ar, static_cast<ZSMap<FString, FString>*>(addr), this);
}
}
return false;
}
//==========================================================================
//
// NewMap
@ -2245,16 +2685,330 @@ void PMap::GetTypeIDs(intptr_t &id1, intptr_t &id2) const
//
//==========================================================================
PMap *NewMap(PType *keytype, PType *valuetype)
int PMapBackingClass(PType *keytype, PType *valuetype, FString &backingName) {
int backingClass;
auto key_rtype = keytype->GetRegType();
auto value_rtype = valuetype->GetRegType();
if (key_rtype == REGT_INT)
{
if(keytype->Size != 4)
{
I_Error("Unsupported map requested");
}
else
{
backingName += "I32_";
backingClass = PMap::MAP_I32_I8;
}
}
else if (key_rtype == REGT_STRING)
{
backingName += "Str_";
backingClass = PMap::MAP_STR_I8;
}
else
{
I_Error("Unsupported map requested");
}
switch (valuetype->GetRegType())
{
case REGT_INT:
backingName.AppendFormat("I%d", valuetype->Size * 8);
backingClass += (valuetype->Size >> 1);
break;
case REGT_FLOAT:
backingName.AppendFormat("F%d", valuetype->Size * 8);
backingClass += PMap::MAP_I32_F32 + (valuetype->Size == 8);
break;
case REGT_STRING:
backingName += "Str";
backingClass += PMap::MAP_I32_STR;
break;
case REGT_POINTER:
if (valuetype->isObjectPointer())
{
backingName += "Obj";
backingClass += PMap::MAP_I32_OBJ;
}
else
{
backingName += "Ptr";
backingClass += PMap::MAP_I32_PTR;
}
break;
default:
I_Error("Unsupported map requested");
break;
}
return backingClass;
}
PMap *NewMap(PType *keyType, PType *valueType)
{
size_t bucket;
PType *maptype = TypeTable.FindType(NAME_Map, (intptr_t)keytype, (intptr_t)valuetype, &bucket);
if (maptype == nullptr)
PType *mapType = TypeTable.FindType(NAME_Map, (intptr_t)keyType, (intptr_t)valueType, &bucket);
if (mapType == nullptr)
{
maptype = new PMap(keytype, valuetype);
TypeTable.AddType(maptype, NAME_Map, (intptr_t)keytype, (intptr_t)valuetype, bucket);
FString backingName = "Map_";
int backingClass = PMapBackingClass(keyType, valueType, backingName);
auto backing = NewStruct(backingName, nullptr, true);
mapType = new PMap(keyType, valueType, backing, backingClass);
TypeTable.AddType(mapType, NAME_Map, (intptr_t)keyType, (intptr_t)valueType, bucket);
}
return (PMap *)maptype;
return (PMap *)mapType;
}
/* PMap *******************************************************************/
//==========================================================================
//
// PMap - Parameterized Constructor
//
//==========================================================================
PMapIterator::PMapIterator(PType *keytype, PType *valtype, PStruct *backing, int backing_class)
: KeyType(keytype), ValueType(valtype), BackingType(backing), BackingClass((decltype(BackingClass)) backing_class)
{
mDescriptiveName.Format("MapIterator<%s, %s>", keytype->DescriptiveName(), valtype->DescriptiveName());
Size = sizeof(ZSFMap);
Align = alignof(ZSFMap);
CreateOverrideFunction<PMapIterator, OFN_RET_KEY, OFN_ARG_VOID>(this, NAME_GetKey);
CreateOverrideFunction<PMapIterator, OFN_RET_VAL, OFN_ARG_VOID>(this, NAME_GetValue);
CreateOverrideFunction<PMapIterator, OFN_RET_VOID, OFN_ARG_VAL>(this, NAME_SetValue);
}
//==========================================================================
//
// PMapIterator :: IsMatch
//
//==========================================================================
bool PMapIterator::IsMatch(intptr_t id1, intptr_t id2) const
{
const PType *keyty = (const PType *)id1;
const PType *valty = (const PType *)id2;
return keyty == KeyType && valty == ValueType;
}
//==========================================================================
//
// PMapIterator :: GetTypeIDs
//
//==========================================================================
void PMapIterator::GetTypeIDs(intptr_t &id1, intptr_t &id2) const
{
id1 = (intptr_t)KeyType;
id2 = (intptr_t)ValueType;
}
//==========================================================================
//
// PMapIterator :: InitializeValue
//
//==========================================================================
void PMapIterator::Construct(void * addr) const {
switch(BackingClass)
{
case PMap::MAP_I32_I8:
new(addr) ZSMapIterator<uint32_t, uint8_t>();
break;
case PMap::MAP_I32_I16:
new(addr) ZSMapIterator<uint32_t, uint16_t>();
break;
case PMap::MAP_I32_I32:
new(addr) ZSMapIterator<uint32_t, uint32_t>();
break;
case PMap::MAP_I32_F32:
new(addr) ZSMapIterator<uint32_t, float>();
break;
case PMap::MAP_I32_F64:
new(addr) ZSMapIterator<uint32_t, double>();
break;
case PMap::MAP_I32_OBJ:
new(addr) ZSMapIterator<uint32_t, DObject*>();
break;
case PMap::MAP_I32_PTR:
new(addr) ZSMapIterator<uint32_t, void*>();
break;
case PMap::MAP_I32_STR:
new(addr) ZSMapIterator<uint32_t, FString>();
break;
case PMap::MAP_STR_I8:
new(addr) ZSMapIterator<FString, uint8_t>();
break;
case PMap::MAP_STR_I16:
new(addr) ZSMapIterator<FString, uint16_t>();
break;
case PMap::MAP_STR_I32:
new(addr) ZSMapIterator<FString, uint32_t>();
break;
case PMap::MAP_STR_F32:
new(addr) ZSMapIterator<FString, float>();
break;
case PMap::MAP_STR_F64:
new(addr) ZSMapIterator<FString, double>();
break;
case PMap::MAP_STR_OBJ:
new(addr) ZSMapIterator<FString, DObject*>();
break;
case PMap::MAP_STR_PTR:
new(addr) ZSMapIterator<FString, void*>();
break;
case PMap::MAP_STR_STR:
new(addr) ZSMapIterator<FString, FString>();
break;
};
}
void PMapIterator::InitializeValue(void *addr, const void *def) const
{
if (def != nullptr)
{
I_Error("Map cannot have default values");
}
Construct(addr);
}
//==========================================================================
//
// PMapIterator :: DestroyValue
//
//==========================================================================
void PMapIterator::DestroyValue(void *addr) const
{
switch(BackingClass)
{
case PMap::MAP_I32_I8:
static_cast<ZSMapIterator<uint32_t, uint8_t>*>(addr)->~ZSMapIterator();
break;
case PMap::MAP_I32_I16:
static_cast<ZSMapIterator<uint32_t, uint16_t>*>(addr)->~ZSMapIterator();
break;
case PMap::MAP_I32_I32:
static_cast<ZSMapIterator<uint32_t, uint32_t>*>(addr)->~ZSMapIterator();
break;
case PMap::MAP_I32_F32:
static_cast<ZSMapIterator<uint32_t, float>*>(addr)->~ZSMapIterator();
break;
case PMap::MAP_I32_F64:
static_cast<ZSMapIterator<uint32_t, double>*>(addr)->~ZSMapIterator();
break;
case PMap::MAP_I32_OBJ:
static_cast<ZSMapIterator<uint32_t, DObject*>*>(addr)->~ZSMapIterator();
break;
case PMap::MAP_I32_PTR:
static_cast<ZSMapIterator<uint32_t, void*>*>(addr)->~ZSMapIterator();
break;
case PMap::MAP_I32_STR:
static_cast<ZSMapIterator<uint32_t, FString>*>(addr)->~ZSMapIterator();
break;
case PMap::MAP_STR_I8:
static_cast<ZSMapIterator<FString, uint8_t>*>(addr)->~ZSMapIterator();
break;
case PMap::MAP_STR_I16:
static_cast<ZSMapIterator<FString, uint16_t>*>(addr)->~ZSMapIterator();
break;
case PMap::MAP_STR_I32:
static_cast<ZSMapIterator<FString, uint32_t>*>(addr)->~ZSMapIterator();
break;
case PMap::MAP_STR_F32:
static_cast<ZSMapIterator<FString, float>*>(addr)->~ZSMapIterator();
break;
case PMap::MAP_STR_F64:
static_cast<ZSMapIterator<FString, double>*>(addr)->~ZSMapIterator();
break;
case PMap::MAP_STR_OBJ:
static_cast<ZSMapIterator<FString, DObject*>*>(addr)->~ZSMapIterator();
break;
case PMap::MAP_STR_PTR:
static_cast<ZSMapIterator<FString, void*>*>(addr)->~ZSMapIterator();
break;
case PMap::MAP_STR_STR:
static_cast<ZSMapIterator<FString, FString>*>(addr)->~ZSMapIterator();
break;
}
}
//==========================================================================
//
// PMapIterator :: SetDefaultValue
//
//==========================================================================
void PMapIterator::SetDefaultValue(void *base, unsigned offset, TArray<FTypeAndOffset> *special)
{
assert(!(base && special));
if (base != nullptr)
{
Construct(((uint8_t*)base)+offset);
}
if (special != nullptr)
{
special->Push(std::make_pair(this, offset));
}
else
{
I_Error("null special");
}
}
//==========================================================================
//
// PMapIterator :: WriteValue
//
//==========================================================================
void PMapIterator::WriteValue(FSerializer &ar, const char *key, const void *addr) const
{
ar.BeginObject(key);
ar.EndObject();
}
//==========================================================================
//
// PMapIterator :: ReadValue
//
//==========================================================================
bool PMapIterator::ReadValue(FSerializer &ar, const char *key, void *addr) const
{
DestroyValue(addr);
InitializeValue(addr, nullptr);
ar.BeginObject(key);
ar.EndObject();
return true;
}
//==========================================================================
//
// NewMapIterator
//
// Returns a PMapIterator for the given key and value types, ensuring not to create
// duplicates.
//
//==========================================================================
PMapIterator *NewMapIterator(PType *keyType, PType *valueType)
{
size_t bucket;
PType *mapIteratorType = TypeTable.FindType(NAME_MapIterator, (intptr_t)keyType, (intptr_t)valueType, &bucket);
if (mapIteratorType == nullptr)
{
FString backingName = "MapIterator_";
int backingClass = PMapBackingClass(keyType, valueType, backingName);
auto backing = NewStruct(backingName, nullptr, true);
mapIteratorType = new PMapIterator(keyType, valueType, backing, backingClass);
TypeTable.AddType(mapIteratorType, NAME_MapIterator, (intptr_t)keyType, (intptr_t)valueType, bucket);
}
return (PMapIterator *)mapIteratorType;
}
/* PStruct ****************************************************************/
@ -2333,6 +3087,26 @@ void PStruct::SetPointerArray(void *base, unsigned offset, TArray<size_t> *speci
}
}
//==========================================================================
//
// PStruct :: SetPointerMap
//
//==========================================================================
void PStruct::SetPointerMap(void *base, unsigned offset, TArray<std::pair<size_t,PType *>> *special)
{
auto it = Symbols.GetIterator();
PSymbolTable::MapType::Pair *pair;
while (it.NextPair(pair))
{
auto field = dyn_cast<PField>(pair->Value);
if (field && !(field->Flags & VARF_Transient))
{
field->Type->SetPointerMap(base, unsigned(offset + field->Offset), special);
}
}
}
//==========================================================================
//
// PStruct :: WriteValue

View file

@ -129,6 +129,7 @@ public:
virtual void SetDefaultValue(void *base, unsigned offset, TArray<FTypeAndOffset> *special=NULL);
virtual void SetPointer(void *base, unsigned offset, TArray<size_t> *ptrofs = NULL);
virtual void SetPointerArray(void *base, unsigned offset, TArray<size_t> *ptrofs = NULL);
virtual void SetPointerMap(void *base, unsigned offset, TArray<std::pair<size_t,PType *>> *ptrofs = NULL);
// Initialize the value, if needed (e.g. strings)
virtual void InitializeValue(void *addr, const void *def) const;
@ -200,6 +201,8 @@ public:
bool isArray() const { return !!(Flags & TYPE_Array); }
bool isStaticArray() const { return TypeTableType == NAME_StaticArray; }
bool isDynArray() const { return TypeTableType == NAME_DynArray; }
bool isMap() const { return TypeTableType == NAME_Map; }
bool isMapIterator() const { return TypeTableType == NAME_MapIterator; }
bool isStruct() const { return TypeTableType == NAME_Struct; }
bool isClass() const { return TypeTableType == NAME_Object; }
bool isPrototype() const { return TypeTableType == NAME_Prototype; }
@ -489,6 +492,7 @@ public:
void SetDefaultValue(void *base, unsigned offset, TArray<FTypeAndOffset> *special) override;
void SetPointer(void *base, unsigned offset, TArray<size_t> *special) override;
void SetPointerArray(void *base, unsigned offset, TArray<size_t> *ptrofs = NULL) override;
void SetPointerMap(void *base, unsigned offset, TArray<std::pair<size_t,PType *>> *ptrofs = NULL) override;
};
class PStaticArray : public PArray
@ -521,14 +525,72 @@ public:
class PMap : public PCompoundType
{
void Construct(void * addr) const;
public:
PMap(PType *keytype, PType *valtype);
PMap(PType *keytype, PType *valtype, PStruct *backing, int backing_class);
PType *KeyType;
PType *ValueType;
TMap<FName,PFunction*> FnOverrides;
PStruct *BackingType;
enum EBackingClass {
MAP_I32_I8,
MAP_I32_I16,
MAP_I32_I32,
MAP_I32_F32,
MAP_I32_F64,
MAP_I32_OBJ,
MAP_I32_PTR,
MAP_I32_STR,
MAP_STR_I8,
MAP_STR_I16,
MAP_STR_I32,
MAP_STR_F32,
MAP_STR_F64,
MAP_STR_OBJ,
MAP_STR_PTR,
MAP_STR_STR,
} BackingClass;
virtual bool IsMatch(intptr_t id1, intptr_t id2) const;
virtual void GetTypeIDs(intptr_t &id1, intptr_t &id2) const;
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) override;
void InitializeValue(void *addr, const void *def) const override;
void DestroyValue(void *addr) const override;
void SetPointerMap(void *base, unsigned offset, TArray<std::pair<size_t,PType *>> *ptrofs) override;
};
class PMapIterator : public PCompoundType
{
void Construct(void * addr) const;
public:
PMapIterator(PType *keytype, PType *valtype, PStruct *backing, int backing_class);
PType *KeyType;
PType *ValueType;
TMap<FName,PFunction*> FnOverrides;
PStruct *BackingType;
PMap::EBackingClass BackingClass;
virtual bool IsMatch(intptr_t id1, intptr_t id2) const;
virtual void GetTypeIDs(intptr_t &id1, intptr_t &id2) const;
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) override;
void InitializeValue(void *addr, const void *def) const override;
void DestroyValue(void *addr) const override;
};
class PStruct : public PContainerType
@ -550,6 +612,7 @@ public:
void SetDefaultValue(void *base, unsigned offset, TArray<FTypeAndOffset> *specials) override;
void SetPointer(void *base, unsigned offset, TArray<size_t> *specials) override;
void SetPointerArray(void *base, unsigned offset, TArray<size_t> *special) override;
void SetPointerMap(void *base, unsigned offset, TArray<std::pair<size_t,PType *>> *ptrofs) override;
};
class PPrototype : public PCompoundType
@ -586,6 +649,7 @@ inline PClass *PObjectPointer::PointedClass() const
// Returns a type from the TypeTable. Will create one if it isn't present.
PMap *NewMap(PType *keytype, PType *valuetype);
PMapIterator *NewMapIterator(PType *keytype, PType *valuetype);
PArray *NewArray(PType *type, unsigned int count);
PStaticArray *NewStaticArray(PType *type);
PDynArray *NewDynArray(PType *type);