mirror of
https://github.com/DrBeef/Raze.git
synced 2025-01-19 07:31:03 +00:00
- backend update from GZDoom.
This commit is contained in:
parent
4666c4a4b5
commit
1061e3e2ca
31 changed files with 2760 additions and 116 deletions
|
@ -117,6 +117,7 @@ xx(Double)
|
|||
xx(String)
|
||||
xx(Vector)
|
||||
xx(Map)
|
||||
xx(MapIterator)
|
||||
xx(Array)
|
||||
xx(Include)
|
||||
xx(Sound)
|
||||
|
@ -162,6 +163,14 @@ xx(ToVector)
|
|||
xx(Size)
|
||||
xx(Push)
|
||||
xx(Insert)
|
||||
xx(InsertNew)
|
||||
xx(Remove)
|
||||
xx(Get)
|
||||
xx(GetValue)
|
||||
xx(GetKey)
|
||||
xx(SetValue)
|
||||
xx(CheckKey)
|
||||
xx(Value)
|
||||
xx(Copy)
|
||||
xx(Move)
|
||||
xx(Voidptr)
|
||||
|
@ -174,6 +183,7 @@ xx(IsNull)
|
|||
xx(Exists)
|
||||
xx(SetInvalid)
|
||||
xx(SetNull)
|
||||
xx(Key)
|
||||
|
||||
// color channels
|
||||
xx(a)
|
||||
|
|
|
@ -88,7 +88,7 @@ int Printf (const char *format, ...) ATTRIBUTE((format(printf,1,2)));
|
|||
int DPrintf (int level, const char *format, ...) ATTRIBUTE((format(printf,2,3)));
|
||||
|
||||
void I_DebugPrint(const char* cp);
|
||||
void debugprintf(const char* f, ...); // Prints to the debugger's log.
|
||||
void I_DebugPrintf(const char* fmt, ...); // Prints to the debugger's log.
|
||||
|
||||
// flag to silence non-error output
|
||||
extern bool batchrun;
|
||||
|
|
|
@ -167,6 +167,7 @@ std2:
|
|||
'vector2' { RET(TK_Vector2); }
|
||||
'vector3' { RET(TK_Vector3); }
|
||||
'map' { RET(TK_Map); }
|
||||
'mapiterator' { RET(TK_MapIterator); }
|
||||
'array' { RET(TK_Array); }
|
||||
'in' { RET(TK_In); }
|
||||
'sizeof' { RET(TK_SizeOf); }
|
||||
|
|
|
@ -128,6 +128,7 @@ xx(TK_Replaces, "'replaces'")
|
|||
xx(TK_Vector2, "'vector2'")
|
||||
xx(TK_Vector3, "'vector3'")
|
||||
xx(TK_Map, "'map'")
|
||||
xx(TK_MapIterator, "'mapiterator'")
|
||||
xx(TK_Array, "'array'")
|
||||
xx(TK_In, "'in'")
|
||||
xx(TK_SizeOf, "'sizeof'")
|
||||
|
|
|
@ -443,4 +443,5 @@ void LoadHexFont(const char* filename)
|
|||
auto hexfont = resf->FindLump("newconsolefont.hex");
|
||||
if (hexfont == nullptr) I_FatalError("Unable to find newconsolefont.hex in %s", filename);
|
||||
hexdata.ParseDefinition(hexfont);
|
||||
delete resf;
|
||||
}
|
||||
|
|
|
@ -544,7 +544,7 @@ inline FVector3 FOBJModel::RealignVector(FVector3 vecToRealign)
|
|||
*/
|
||||
inline FVector2 FOBJModel::FixUV(FVector2 vecToRealign)
|
||||
{
|
||||
vecToRealign.Y *= -1;
|
||||
vecToRealign.Y = 1-vecToRealign.Y;
|
||||
return vecToRealign;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -8205,6 +8205,8 @@ FxExpression *FxMemberFunctionCall::Resolve(FCompileContext& ctx)
|
|||
|
||||
PContainerType *ccls = nullptr;
|
||||
|
||||
PFunction * afd_override = nullptr;
|
||||
|
||||
if (ctx.Class == nullptr)
|
||||
{
|
||||
// There's no way that a member function call can resolve to a constant so abort right away.
|
||||
|
@ -8278,7 +8280,7 @@ FxExpression *FxMemberFunctionCall::Resolve(FCompileContext& ctx)
|
|||
if (Self->ValueType->isRealPointer())
|
||||
{
|
||||
auto pointedType = Self->ValueType->toPointer()->PointedType;
|
||||
if (pointedType && pointedType->isDynArray())
|
||||
if (pointedType && (pointedType->isDynArray() || pointedType->isMap() || pointedType->isMapIterator()))
|
||||
{
|
||||
Self = new FxOutVarDereference(Self, Self->ScriptPosition);
|
||||
SAFE_RESOLVE(Self, ctx);
|
||||
|
@ -8454,7 +8456,7 @@ FxExpression *FxMemberFunctionCall::Resolve(FCompileContext& ctx)
|
|||
if (a->ValueType->isRealPointer())
|
||||
{
|
||||
auto pointedType = a->ValueType->toPointer()->PointedType;
|
||||
if (pointedType && pointedType->isDynArray())
|
||||
if (pointedType && (pointedType->isDynArray() || pointedType->isMap() || pointedType->isMapIterator()))
|
||||
{
|
||||
a = new FxOutVarDereference(a, a->ScriptPosition);
|
||||
SAFE_RESOLVE(a, ctx);
|
||||
|
@ -8561,6 +8563,193 @@ FxExpression *FxMemberFunctionCall::Resolve(FCompileContext& ctx)
|
|||
}
|
||||
}
|
||||
}
|
||||
else if(Self->IsMap())
|
||||
{
|
||||
PMap * m = static_cast<PMap*>(Self->ValueType);
|
||||
Self->ValueType = m->BackingType;
|
||||
|
||||
auto mapKeyType = m->KeyType;
|
||||
auto mapValueType = m->ValueType;
|
||||
|
||||
bool isObjMap = mapValueType->isObjectPointer();
|
||||
|
||||
if (PFunction **Override; (Override = m->FnOverrides.CheckKey(MethodName)))
|
||||
{
|
||||
afd_override = *Override;
|
||||
}
|
||||
|
||||
// Adapted from DynArray codegen
|
||||
|
||||
int idx = 0;
|
||||
for (auto &a : ArgList)
|
||||
{
|
||||
a = a->Resolve(ctx);
|
||||
if (a == nullptr)
|
||||
{
|
||||
delete this;
|
||||
return nullptr;
|
||||
}
|
||||
if (a->ValueType->isRealPointer())
|
||||
{
|
||||
auto pointedType = a->ValueType->toPointer()->PointedType;
|
||||
if (pointedType && (pointedType->isDynArray() || pointedType->isMap() || pointedType->isMapIterator()))
|
||||
{
|
||||
a = new FxOutVarDereference(a, a->ScriptPosition);
|
||||
SAFE_RESOLVE(a, ctx);
|
||||
}
|
||||
}
|
||||
if (isObjMap && (MethodName == NAME_Insert && idx == 1))
|
||||
{
|
||||
// Null pointers are always valid.
|
||||
if (!a->isConstant() || static_cast<FxConstant*>(a)->GetValue().GetPointer() != nullptr)
|
||||
{
|
||||
if (!a->ValueType->isObjectPointer() ||
|
||||
!static_cast<PObjectPointer*>(mapValueType)->PointedClass()->IsAncestorOf(static_cast<PObjectPointer*>(a->ValueType)->PointedClass()))
|
||||
{
|
||||
ScriptPosition.Message(MSG_ERROR, "Type mismatch in function argument");
|
||||
delete this;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (a->IsMap())
|
||||
{
|
||||
// Copy and Move must turn their parameter into a pointer to the backing struct type.
|
||||
auto o = static_cast<PMap*>(a->ValueType);
|
||||
auto backingtype = o->BackingType;
|
||||
if (mapKeyType != o->KeyType || mapValueType != o->ValueType)
|
||||
{
|
||||
ScriptPosition.Message(MSG_ERROR, "Type mismatch in function argument");
|
||||
delete this;
|
||||
return nullptr;
|
||||
}
|
||||
bool writable;
|
||||
if (!a->RequestAddress(ctx, &writable))
|
||||
{
|
||||
ScriptPosition.Message(MSG_ERROR, "Unable to dereference map variable");
|
||||
delete this;
|
||||
return nullptr;
|
||||
}
|
||||
a->ValueType = NewPointer(backingtype);
|
||||
|
||||
// Also change the field's type so the code generator can work with this (actually this requires swapping out the entire field.)
|
||||
if (Self->ExprType == EFX_StructMember || Self->ExprType == EFX_ClassMember || Self->ExprType == EFX_StackVariable)
|
||||
{
|
||||
auto member = static_cast<FxMemberBase*>(Self);
|
||||
auto newfield = Create<PField>(NAME_None, backingtype, 0, member->membervar->Offset);
|
||||
member->membervar = newfield;
|
||||
}
|
||||
}
|
||||
else if (a->IsPointer() && Self->ValueType->isPointer())
|
||||
{
|
||||
// the only case which must be checked up front is for pointer arrays receiving a new element.
|
||||
// Since there is only one native backing class it uses a neutral void pointer as its argument,
|
||||
// meaning that FxMemberFunctionCall is unable to do a proper check. So we have to do it here.
|
||||
if (a->ValueType != mapValueType)
|
||||
{
|
||||
ScriptPosition.Message(MSG_ERROR, "Type mismatch in function argument. Got %s, expected %s", a->ValueType->DescriptiveName(), mapValueType->DescriptiveName());
|
||||
delete this;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
idx++;
|
||||
|
||||
}
|
||||
}
|
||||
else if(Self->IsMapIterator())
|
||||
{
|
||||
PMapIterator * mi = static_cast<PMapIterator*>(Self->ValueType);
|
||||
Self->ValueType = mi->BackingType;
|
||||
|
||||
auto mapKeyType = mi->KeyType;
|
||||
auto mapValueType = mi->ValueType;
|
||||
|
||||
bool isObjMap = mapValueType->isObjectPointer();
|
||||
|
||||
if (PFunction **Override; (Override = mi->FnOverrides.CheckKey(MethodName)))
|
||||
{
|
||||
afd_override = *Override;
|
||||
}
|
||||
|
||||
// Adapted from DynArray codegen
|
||||
|
||||
int idx = 0;
|
||||
for (auto &a : ArgList)
|
||||
{
|
||||
a = a->Resolve(ctx);
|
||||
if (a == nullptr)
|
||||
{
|
||||
delete this;
|
||||
return nullptr;
|
||||
}
|
||||
if (a->ValueType->isRealPointer())
|
||||
{
|
||||
auto pointedType = a->ValueType->toPointer()->PointedType;
|
||||
if (pointedType && (pointedType->isDynArray() || pointedType->isMap() || pointedType->isMapIterator()))
|
||||
{
|
||||
a = new FxOutVarDereference(a, a->ScriptPosition);
|
||||
SAFE_RESOLVE(a, ctx);
|
||||
}
|
||||
}
|
||||
if (isObjMap && (MethodName == NAME_SetValue && idx == 0))
|
||||
{
|
||||
// Null pointers are always valid.
|
||||
if (!a->isConstant() || static_cast<FxConstant*>(a)->GetValue().GetPointer() != nullptr)
|
||||
{
|
||||
if (!a->ValueType->isObjectPointer() ||
|
||||
!static_cast<PObjectPointer*>(mapValueType)->PointedClass()->IsAncestorOf(static_cast<PObjectPointer*>(a->ValueType)->PointedClass()))
|
||||
{
|
||||
ScriptPosition.Message(MSG_ERROR, "Type mismatch in function argument");
|
||||
delete this;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (a->IsMap())
|
||||
{
|
||||
// Copy and Move must turn their parameter into a pointer to the backing struct type.
|
||||
auto o = static_cast<PMapIterator*>(a->ValueType);
|
||||
auto backingtype = o->BackingType;
|
||||
if (mapKeyType != o->KeyType || mapValueType != o->ValueType)
|
||||
{
|
||||
ScriptPosition.Message(MSG_ERROR, "Type mismatch in function argument");
|
||||
delete this;
|
||||
return nullptr;
|
||||
}
|
||||
bool writable;
|
||||
if (!a->RequestAddress(ctx, &writable))
|
||||
{
|
||||
ScriptPosition.Message(MSG_ERROR, "Unable to dereference map variable");
|
||||
delete this;
|
||||
return nullptr;
|
||||
}
|
||||
a->ValueType = NewPointer(backingtype);
|
||||
|
||||
// Also change the field's type so the code generator can work with this (actually this requires swapping out the entire field.)
|
||||
if (Self->ExprType == EFX_StructMember || Self->ExprType == EFX_ClassMember || Self->ExprType == EFX_StackVariable)
|
||||
{
|
||||
auto member = static_cast<FxMemberBase*>(Self);
|
||||
auto newfield = Create<PField>(NAME_None, backingtype, 0, member->membervar->Offset);
|
||||
member->membervar = newfield;
|
||||
}
|
||||
}
|
||||
else if (a->IsPointer() && Self->ValueType->isPointer())
|
||||
{
|
||||
// the only case which must be checked up front is for pointer arrays receiving a new element.
|
||||
// Since there is only one native backing class it uses a neutral void pointer as its argument,
|
||||
// meaning that FxMemberFunctionCall is unable to do a proper check. So we have to do it here.
|
||||
if (a->ValueType != mapValueType)
|
||||
{
|
||||
ScriptPosition.Message(MSG_ERROR, "Type mismatch in function argument. Got %s, expected %s", a->ValueType->DescriptiveName(), mapValueType->DescriptiveName());
|
||||
delete this;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (MethodName == NAME_GetParentClass &&
|
||||
|
@ -8635,7 +8824,7 @@ FxExpression *FxMemberFunctionCall::Resolve(FCompileContext& ctx)
|
|||
|
||||
isresolved:
|
||||
bool error = false;
|
||||
PFunction *afd = FindClassMemberFunction(cls, ctx.Class, MethodName, ScriptPosition, &error, ctx.Version, !ctx.FromDecorate);
|
||||
PFunction *afd = afd_override ? afd_override : FindClassMemberFunction(cls, ctx.Class, MethodName, ScriptPosition, &error, ctx.Version, !ctx.FromDecorate);
|
||||
if (error)
|
||||
{
|
||||
delete this;
|
||||
|
@ -9034,7 +9223,7 @@ FxExpression *FxVMFunctionCall::Resolve(FCompileContext& ctx)
|
|||
if (ArgList[i] && ArgList[i]->ValueType->isRealPointer())
|
||||
{
|
||||
auto pointedType = ArgList[i]->ValueType->toPointer()->PointedType;
|
||||
if (pointedType && pointedType->isDynArray())
|
||||
if (pointedType && (pointedType->isDynArray() || pointedType->isMap() || pointedType->isMapIterator()))
|
||||
{
|
||||
ArgList[i] = new FxOutVarDereference(ArgList[i], ArgList[i]->ScriptPosition);
|
||||
SAFE_RESOLVE(ArgList[i], ctx);
|
||||
|
@ -11806,7 +11995,7 @@ FxExpression *FxOutVarDereference::Resolve(FCompileContext &ctx)
|
|||
SelfType = Self->ValueType->toPointer()->PointedType;
|
||||
ValueType = SelfType;
|
||||
|
||||
if (SelfType->GetRegType() == REGT_NIL && !SelfType->isRealPointer() && !SelfType->isDynArray())
|
||||
if (SelfType->GetRegType() == REGT_NIL && !SelfType->isRealPointer() && !SelfType->isDynArray() && !SelfType->isMap() && !SelfType->isMapIterator())
|
||||
{
|
||||
ScriptPosition.Message(MSG_ERROR, "Cannot dereference pointer");
|
||||
delete this;
|
||||
|
@ -11835,7 +12024,7 @@ ExpEmit FxOutVarDereference::Emit(VMFunctionBuilder *build)
|
|||
regType = REGT_POINTER;
|
||||
loadOp = OP_LP;
|
||||
}
|
||||
else if (SelfType->isDynArray())
|
||||
else if (SelfType->isDynArray() || SelfType->isMap() || SelfType->isMapIterator())
|
||||
{
|
||||
regType = REGT_POINTER;
|
||||
loadOp = OP_MOVEA;
|
||||
|
|
|
@ -350,6 +350,8 @@ public:
|
|||
bool IsArray() const { return ValueType->isArray() || (ValueType->isPointer() && ValueType->toPointer()->PointedType->isArray()); }
|
||||
bool isStaticArray() const { return (ValueType->isPointer() && ValueType->toPointer()->PointedType->isStaticArray()); } // can only exist in pointer form.
|
||||
bool IsDynamicArray() const { return (ValueType->isDynArray()); }
|
||||
bool IsMap() const { return ValueType->isMap(); }
|
||||
bool IsMapIterator() const { return ValueType->isMapIterator(); }
|
||||
bool IsStruct() const { return ValueType->isStruct(); }
|
||||
bool IsNativeStruct() const { return (ValueType->isStruct() && static_cast<PStruct*>(ValueType)->isNative); }
|
||||
|
||||
|
|
483
source/common/scripting/core/maps.cpp
Normal file
483
source/common/scripting/core/maps.cpp
Normal 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();
|
110
source/common/scripting/core/maps.h
Normal file
110
source/common/scripting/core/maps.h
Normal 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");
|
||||
}
|
||||
}
|
||||
};
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
#include "printf.h"
|
||||
|
||||
class FLispString;
|
||||
extern void (* const TreeNodePrinter[NUM_AST_NODE_TYPES])(FLispString &, ZCC_TreeNode *);
|
||||
using NodePrinterFunc = void (*)(FLispString &, const ZCC_TreeNode *);
|
||||
|
||||
static const char *BuiltInTypeNames[] =
|
||||
{
|
||||
|
@ -221,24 +221,11 @@ private:
|
|||
bool NeedSpace;
|
||||
};
|
||||
|
||||
static void PrintNode(FLispString &out, ZCC_TreeNode *node)
|
||||
{
|
||||
assert(TreeNodePrinter[NUM_AST_NODE_TYPES-1] != NULL);
|
||||
if (node->NodeType >= 0 && node->NodeType < NUM_AST_NODE_TYPES)
|
||||
{
|
||||
TreeNodePrinter[node->NodeType](out, node);
|
||||
}
|
||||
else
|
||||
{
|
||||
out.Open("unknown-node-type");
|
||||
out.AddInt(node->NodeType);
|
||||
out.Close();
|
||||
}
|
||||
}
|
||||
static void PrintNode(FLispString &out, const ZCC_TreeNode *node);
|
||||
|
||||
static void PrintNodes(FLispString &out, ZCC_TreeNode *node, bool newlist=true, bool addbreaks=false)
|
||||
static void PrintNodes(FLispString &out, const ZCC_TreeNode *node, bool newlist=true, bool addbreaks=false)
|
||||
{
|
||||
ZCC_TreeNode *p;
|
||||
const ZCC_TreeNode *p;
|
||||
|
||||
if (node == NULL)
|
||||
{
|
||||
|
@ -269,7 +256,7 @@ static void PrintNodes(FLispString &out, ZCC_TreeNode *node, bool newlist=true,
|
|||
|
||||
static void PrintBuiltInType(FLispString &out, EZCCBuiltinType type)
|
||||
{
|
||||
assert(ZCC_NUM_BUILT_IN_TYPES == countof(BuiltInTypeNames));
|
||||
static_assert(ZCC_NUM_BUILT_IN_TYPES == countof(BuiltInTypeNames));
|
||||
if (unsigned(type) >= unsigned(ZCC_NUM_BUILT_IN_TYPES))
|
||||
{
|
||||
char buf[30];
|
||||
|
@ -282,7 +269,7 @@ static void PrintBuiltInType(FLispString &out, EZCCBuiltinType type)
|
|||
}
|
||||
}
|
||||
|
||||
static void PrintIdentifier(FLispString &out, ZCC_TreeNode *node)
|
||||
static void PrintIdentifier(FLispString &out, const ZCC_TreeNode *node)
|
||||
{
|
||||
ZCC_Identifier *inode = (ZCC_Identifier *)node;
|
||||
out.Open("identifier");
|
||||
|
@ -317,7 +304,7 @@ static void PrintStringConst(FLispString &out, FString str)
|
|||
out.Add(outstr);
|
||||
}
|
||||
|
||||
static void PrintClass(FLispString &out, ZCC_TreeNode *node)
|
||||
static void PrintClass(FLispString &out, const ZCC_TreeNode *node)
|
||||
{
|
||||
ZCC_Class *cnode = (ZCC_Class *)node;
|
||||
out.Break();
|
||||
|
@ -330,7 +317,7 @@ static void PrintClass(FLispString &out, ZCC_TreeNode *node)
|
|||
out.Close();
|
||||
}
|
||||
|
||||
static void PrintStruct(FLispString &out, ZCC_TreeNode *node)
|
||||
static void PrintStruct(FLispString &out, const ZCC_TreeNode *node)
|
||||
{
|
||||
ZCC_Struct *snode = (ZCC_Struct *)node;
|
||||
out.Break();
|
||||
|
@ -340,7 +327,7 @@ static void PrintStruct(FLispString &out, ZCC_TreeNode *node)
|
|||
out.Close();
|
||||
}
|
||||
|
||||
static void PrintProperty(FLispString &out, ZCC_TreeNode *node)
|
||||
static void PrintProperty(FLispString &out, const ZCC_TreeNode *node)
|
||||
{
|
||||
ZCC_Property *snode = (ZCC_Property *)node;
|
||||
out.Break();
|
||||
|
@ -350,7 +337,7 @@ static void PrintProperty(FLispString &out, ZCC_TreeNode *node)
|
|||
out.Close();
|
||||
}
|
||||
|
||||
static void PrintFlagDef(FLispString &out, ZCC_TreeNode *node)
|
||||
static void PrintFlagDef(FLispString &out, const ZCC_TreeNode *node)
|
||||
{
|
||||
ZCC_FlagDef *snode = (ZCC_FlagDef *)node;
|
||||
out.Break();
|
||||
|
@ -361,7 +348,7 @@ static void PrintFlagDef(FLispString &out, ZCC_TreeNode *node)
|
|||
out.Close();
|
||||
}
|
||||
|
||||
static void PrintStaticArrayState(FLispString &out, ZCC_TreeNode *node)
|
||||
static void PrintStaticArrayState(FLispString &out, const ZCC_TreeNode *node)
|
||||
{
|
||||
auto *snode = (ZCC_StaticArrayStatement *)node;
|
||||
out.Break();
|
||||
|
@ -371,7 +358,7 @@ static void PrintStaticArrayState(FLispString &out, ZCC_TreeNode *node)
|
|||
out.Close();
|
||||
}
|
||||
|
||||
static void PrintEnum(FLispString &out, ZCC_TreeNode *node)
|
||||
static void PrintEnum(FLispString &out, const ZCC_TreeNode *node)
|
||||
{
|
||||
ZCC_Enum *enode = (ZCC_Enum *)node;
|
||||
out.Break();
|
||||
|
@ -382,13 +369,13 @@ static void PrintEnum(FLispString &out, ZCC_TreeNode *node)
|
|||
out.Close();
|
||||
}
|
||||
|
||||
static void PrintEnumTerminator(FLispString &out, ZCC_TreeNode *node)
|
||||
static void PrintEnumTerminator(FLispString &out, const ZCC_TreeNode *node)
|
||||
{
|
||||
out.Open("enum-term");
|
||||
out.Close();
|
||||
}
|
||||
|
||||
static void PrintStates(FLispString &out, ZCC_TreeNode *node)
|
||||
static void PrintStates(FLispString &out, const ZCC_TreeNode *node)
|
||||
{
|
||||
ZCC_States *snode = (ZCC_States *)node;
|
||||
out.Break();
|
||||
|
@ -398,13 +385,13 @@ static void PrintStates(FLispString &out, ZCC_TreeNode *node)
|
|||
out.Close();
|
||||
}
|
||||
|
||||
static void PrintStatePart(FLispString &out, ZCC_TreeNode *node)
|
||||
static void PrintStatePart(FLispString &out, const ZCC_TreeNode *node)
|
||||
{
|
||||
out.Open("state-part");
|
||||
out.Close();
|
||||
}
|
||||
|
||||
static void PrintStateLabel(FLispString &out, ZCC_TreeNode *node)
|
||||
static void PrintStateLabel(FLispString &out, const ZCC_TreeNode *node)
|
||||
{
|
||||
ZCC_StateLabel *snode = (ZCC_StateLabel *)node;
|
||||
out.Open("state-label");
|
||||
|
@ -412,31 +399,31 @@ static void PrintStateLabel(FLispString &out, ZCC_TreeNode *node)
|
|||
out.Close();
|
||||
}
|
||||
|
||||
static void PrintStateStop(FLispString &out, ZCC_TreeNode *node)
|
||||
static void PrintStateStop(FLispString &out, const ZCC_TreeNode *node)
|
||||
{
|
||||
out.Open("state-stop");
|
||||
out.Close();
|
||||
}
|
||||
|
||||
static void PrintStateWait(FLispString &out, ZCC_TreeNode *node)
|
||||
static void PrintStateWait(FLispString &out, const ZCC_TreeNode *node)
|
||||
{
|
||||
out.Open("state-wait");
|
||||
out.Close();
|
||||
}
|
||||
|
||||
static void PrintStateFail(FLispString &out, ZCC_TreeNode *node)
|
||||
static void PrintStateFail(FLispString &out, const ZCC_TreeNode *node)
|
||||
{
|
||||
out.Open("state-fail");
|
||||
out.Close();
|
||||
}
|
||||
|
||||
static void PrintStateLoop(FLispString &out, ZCC_TreeNode *node)
|
||||
static void PrintStateLoop(FLispString &out, const ZCC_TreeNode *node)
|
||||
{
|
||||
out.Open("state-loop");
|
||||
out.Close();
|
||||
}
|
||||
|
||||
static void PrintStateGoto(FLispString &out, ZCC_TreeNode *node)
|
||||
static void PrintStateGoto(FLispString &out, const ZCC_TreeNode *node)
|
||||
{
|
||||
ZCC_StateGoto *snode = (ZCC_StateGoto *)node;
|
||||
out.Open("state-goto");
|
||||
|
@ -446,7 +433,7 @@ static void PrintStateGoto(FLispString &out, ZCC_TreeNode *node)
|
|||
out.Close();
|
||||
}
|
||||
|
||||
static void PrintStateLine(FLispString &out, ZCC_TreeNode *node)
|
||||
static void PrintStateLine(FLispString &out, const ZCC_TreeNode *node)
|
||||
{
|
||||
ZCC_StateLine *snode = (ZCC_StateLine *)node;
|
||||
out.Open("state-line");
|
||||
|
@ -463,7 +450,7 @@ static void PrintStateLine(FLispString &out, ZCC_TreeNode *node)
|
|||
out.Close();
|
||||
}
|
||||
|
||||
static void PrintVarName(FLispString &out, ZCC_TreeNode *node)
|
||||
static void PrintVarName(FLispString &out, const ZCC_TreeNode *node)
|
||||
{
|
||||
ZCC_VarName *vnode = (ZCC_VarName *)node;
|
||||
out.Open("var-name");
|
||||
|
@ -472,7 +459,7 @@ static void PrintVarName(FLispString &out, ZCC_TreeNode *node)
|
|||
out.Close();
|
||||
}
|
||||
|
||||
static void PrintVarInit(FLispString &out, ZCC_TreeNode *node)
|
||||
static void PrintVarInit(FLispString &out, const ZCC_TreeNode *node)
|
||||
{
|
||||
ZCC_VarInit *vnode = (ZCC_VarInit *)node;
|
||||
out.Open("var-init");
|
||||
|
@ -483,7 +470,7 @@ static void PrintVarInit(FLispString &out, ZCC_TreeNode *node)
|
|||
out.Close();
|
||||
}
|
||||
|
||||
static void PrintType(FLispString &out, ZCC_TreeNode *node)
|
||||
static void PrintType(FLispString &out, const ZCC_TreeNode *node)
|
||||
{
|
||||
ZCC_Type *tnode = (ZCC_Type *)node;
|
||||
out.Open("bad-type");
|
||||
|
@ -491,7 +478,7 @@ static void PrintType(FLispString &out, ZCC_TreeNode *node)
|
|||
out.Close();
|
||||
}
|
||||
|
||||
static void PrintBasicType(FLispString &out, ZCC_TreeNode *node)
|
||||
static void PrintBasicType(FLispString &out, const ZCC_TreeNode *node)
|
||||
{
|
||||
ZCC_BasicType *tnode = (ZCC_BasicType *)node;
|
||||
out.Open("basic-type");
|
||||
|
@ -505,7 +492,7 @@ static void PrintBasicType(FLispString &out, ZCC_TreeNode *node)
|
|||
out.Close();
|
||||
}
|
||||
|
||||
static void PrintMapType(FLispString &out, ZCC_TreeNode *node)
|
||||
static void PrintMapType(FLispString &out, const ZCC_TreeNode *node)
|
||||
{
|
||||
ZCC_MapType *tnode = (ZCC_MapType *)node;
|
||||
out.Open("map-type");
|
||||
|
@ -515,7 +502,17 @@ static void PrintMapType(FLispString &out, ZCC_TreeNode *node)
|
|||
out.Close();
|
||||
}
|
||||
|
||||
static void PrintDynArrayType(FLispString &out, ZCC_TreeNode *node)
|
||||
static void PrintMapIteratorType(FLispString &out, const ZCC_TreeNode *node)
|
||||
{
|
||||
ZCC_MapIteratorType *tnode = (ZCC_MapIteratorType *)node;
|
||||
out.Open("map-iterator-type");
|
||||
PrintNodes(out, tnode->ArraySize);
|
||||
PrintNodes(out, tnode->KeyType);
|
||||
PrintNodes(out, tnode->ValueType);
|
||||
out.Close();
|
||||
}
|
||||
|
||||
static void PrintDynArrayType(FLispString &out, const ZCC_TreeNode *node)
|
||||
{
|
||||
ZCC_DynArrayType *tnode = (ZCC_DynArrayType *)node;
|
||||
out.Open("dyn-array-type");
|
||||
|
@ -524,7 +521,7 @@ static void PrintDynArrayType(FLispString &out, ZCC_TreeNode *node)
|
|||
out.Close();
|
||||
}
|
||||
|
||||
static void PrintClassType(FLispString &out, ZCC_TreeNode *node)
|
||||
static void PrintClassType(FLispString &out, const ZCC_TreeNode *node)
|
||||
{
|
||||
ZCC_ClassType *tnode = (ZCC_ClassType *)node;
|
||||
out.Open("class-type");
|
||||
|
@ -548,14 +545,14 @@ static void OpenExprType(FLispString &out, EZCCExprType type)
|
|||
out.Open(buf);
|
||||
}
|
||||
|
||||
static void PrintExpression(FLispString &out, ZCC_TreeNode *node)
|
||||
static void PrintExpression(FLispString &out, const ZCC_TreeNode *node)
|
||||
{
|
||||
ZCC_Expression *enode = (ZCC_Expression *)node;
|
||||
OpenExprType(out, enode->Operation);
|
||||
out.Close();
|
||||
}
|
||||
|
||||
static void PrintExprID(FLispString &out, ZCC_TreeNode *node)
|
||||
static void PrintExprID(FLispString &out, const ZCC_TreeNode *node)
|
||||
{
|
||||
ZCC_ExprID *enode = (ZCC_ExprID *)node;
|
||||
assert(enode->Operation == PEX_ID);
|
||||
|
@ -564,7 +561,7 @@ static void PrintExprID(FLispString &out, ZCC_TreeNode *node)
|
|||
out.Close();
|
||||
}
|
||||
|
||||
static void PrintExprTypeRef(FLispString &out, ZCC_TreeNode *node)
|
||||
static void PrintExprTypeRef(FLispString &out, const ZCC_TreeNode *node)
|
||||
{
|
||||
ZCC_ExprTypeRef *enode = (ZCC_ExprTypeRef *)node;
|
||||
assert(enode->Operation == PEX_TypeRef);
|
||||
|
@ -583,7 +580,7 @@ static void PrintExprTypeRef(FLispString &out, ZCC_TreeNode *node)
|
|||
out.Close();
|
||||
}
|
||||
|
||||
static void PrintExprConstant(FLispString &out, ZCC_TreeNode *node)
|
||||
static void PrintExprConstant(FLispString &out, const ZCC_TreeNode *node)
|
||||
{
|
||||
ZCC_ExprConstant *enode = (ZCC_ExprConstant *)node;
|
||||
assert(enode->Operation == PEX_ConstValue);
|
||||
|
@ -611,7 +608,7 @@ static void PrintExprConstant(FLispString &out, ZCC_TreeNode *node)
|
|||
out.Close();
|
||||
}
|
||||
|
||||
static void PrintExprFuncCall(FLispString &out, ZCC_TreeNode *node)
|
||||
static void PrintExprFuncCall(FLispString &out, const ZCC_TreeNode *node)
|
||||
{
|
||||
ZCC_ExprFuncCall *enode = (ZCC_ExprFuncCall *)node;
|
||||
assert(enode->Operation == PEX_FuncCall);
|
||||
|
@ -621,7 +618,7 @@ static void PrintExprFuncCall(FLispString &out, ZCC_TreeNode *node)
|
|||
out.Close();
|
||||
}
|
||||
|
||||
static void PrintExprClassCast(FLispString &out, ZCC_TreeNode *node)
|
||||
static void PrintExprClassCast(FLispString &out, const ZCC_TreeNode *node)
|
||||
{
|
||||
ZCC_ClassCast *enode = (ZCC_ClassCast *)node;
|
||||
assert(enode->Operation == PEX_ClassCast);
|
||||
|
@ -631,7 +628,7 @@ static void PrintExprClassCast(FLispString &out, ZCC_TreeNode *node)
|
|||
out.Close();
|
||||
}
|
||||
|
||||
static void PrintStaticArray(FLispString &out, ZCC_TreeNode *node)
|
||||
static void PrintStaticArray(FLispString &out, const ZCC_TreeNode *node)
|
||||
{
|
||||
ZCC_StaticArrayStatement *enode = (ZCC_StaticArrayStatement *)node;
|
||||
out.Open("static-array-stmt");
|
||||
|
@ -641,7 +638,7 @@ static void PrintStaticArray(FLispString &out, ZCC_TreeNode *node)
|
|||
out.Close();
|
||||
}
|
||||
|
||||
static void PrintExprMemberAccess(FLispString &out, ZCC_TreeNode *node)
|
||||
static void PrintExprMemberAccess(FLispString &out, const ZCC_TreeNode *node)
|
||||
{
|
||||
ZCC_ExprMemberAccess *enode = (ZCC_ExprMemberAccess *)node;
|
||||
assert(enode->Operation == PEX_MemberAccess);
|
||||
|
@ -651,7 +648,7 @@ static void PrintExprMemberAccess(FLispString &out, ZCC_TreeNode *node)
|
|||
out.Close();
|
||||
}
|
||||
|
||||
static void PrintExprUnary(FLispString &out, ZCC_TreeNode *node)
|
||||
static void PrintExprUnary(FLispString &out, const ZCC_TreeNode *node)
|
||||
{
|
||||
ZCC_ExprUnary *enode = (ZCC_ExprUnary *)node;
|
||||
OpenExprType(out, enode->Operation);
|
||||
|
@ -659,7 +656,7 @@ static void PrintExprUnary(FLispString &out, ZCC_TreeNode *node)
|
|||
out.Close();
|
||||
}
|
||||
|
||||
static void PrintExprBinary(FLispString &out, ZCC_TreeNode *node)
|
||||
static void PrintExprBinary(FLispString &out, const ZCC_TreeNode *node)
|
||||
{
|
||||
ZCC_ExprBinary *enode = (ZCC_ExprBinary *)node;
|
||||
OpenExprType(out, enode->Operation);
|
||||
|
@ -668,7 +665,7 @@ static void PrintExprBinary(FLispString &out, ZCC_TreeNode *node)
|
|||
out.Close();
|
||||
}
|
||||
|
||||
static void PrintExprTrinary(FLispString &out, ZCC_TreeNode *node)
|
||||
static void PrintExprTrinary(FLispString &out, const ZCC_TreeNode *node)
|
||||
{
|
||||
ZCC_ExprTrinary *enode = (ZCC_ExprTrinary *)node;
|
||||
OpenExprType(out, enode->Operation);
|
||||
|
@ -678,7 +675,7 @@ static void PrintExprTrinary(FLispString &out, ZCC_TreeNode *node)
|
|||
out.Close();
|
||||
}
|
||||
|
||||
static void PrintVectorInitializer(FLispString &out, ZCC_TreeNode *node)
|
||||
static void PrintVectorInitializer(FLispString &out, const ZCC_TreeNode *node)
|
||||
{
|
||||
ZCC_VectorValue *enode = (ZCC_VectorValue *)node;
|
||||
OpenExprType(out, enode->Operation);
|
||||
|
@ -689,7 +686,7 @@ static void PrintVectorInitializer(FLispString &out, ZCC_TreeNode *node)
|
|||
out.Close();
|
||||
}
|
||||
|
||||
static void PrintFuncParam(FLispString &out, ZCC_TreeNode *node)
|
||||
static void PrintFuncParam(FLispString &out, const ZCC_TreeNode *node)
|
||||
{
|
||||
ZCC_FuncParm *pnode = (ZCC_FuncParm *)node;
|
||||
out.Break();
|
||||
|
@ -699,13 +696,13 @@ static void PrintFuncParam(FLispString &out, ZCC_TreeNode *node)
|
|||
out.Close();
|
||||
}
|
||||
|
||||
static void PrintStatement(FLispString &out, ZCC_TreeNode *node)
|
||||
static void PrintStatement(FLispString &out, const ZCC_TreeNode *node)
|
||||
{
|
||||
out.Open("statement");
|
||||
out.Close();
|
||||
}
|
||||
|
||||
static void PrintCompoundStmt(FLispString &out, ZCC_TreeNode *node)
|
||||
static void PrintCompoundStmt(FLispString &out, const ZCC_TreeNode *node)
|
||||
{
|
||||
ZCC_CompoundStmt *snode = (ZCC_CompoundStmt *)node;
|
||||
out.Break();
|
||||
|
@ -714,7 +711,7 @@ static void PrintCompoundStmt(FLispString &out, ZCC_TreeNode *node)
|
|||
out.Close();
|
||||
}
|
||||
|
||||
static void PrintDefault(FLispString &out, ZCC_TreeNode *node)
|
||||
static void PrintDefault(FLispString &out, const ZCC_TreeNode *node)
|
||||
{
|
||||
ZCC_Default *snode = (ZCC_Default *)node;
|
||||
out.Break();
|
||||
|
@ -723,21 +720,21 @@ static void PrintDefault(FLispString &out, ZCC_TreeNode *node)
|
|||
out.Close();
|
||||
}
|
||||
|
||||
static void PrintContinueStmt(FLispString &out, ZCC_TreeNode *node)
|
||||
static void PrintContinueStmt(FLispString &out, const ZCC_TreeNode *node)
|
||||
{
|
||||
out.Break();
|
||||
out.Open("continue-stmt");
|
||||
out.Close();
|
||||
}
|
||||
|
||||
static void PrintBreakStmt(FLispString &out, ZCC_TreeNode *node)
|
||||
static void PrintBreakStmt(FLispString &out, const ZCC_TreeNode *node)
|
||||
{
|
||||
out.Break();
|
||||
out.Open("break-stmt");
|
||||
out.Close();
|
||||
}
|
||||
|
||||
static void PrintReturnStmt(FLispString &out, ZCC_TreeNode *node)
|
||||
static void PrintReturnStmt(FLispString &out, const ZCC_TreeNode *node)
|
||||
{
|
||||
ZCC_ReturnStmt *snode = (ZCC_ReturnStmt *)node;
|
||||
out.Break();
|
||||
|
@ -746,7 +743,7 @@ static void PrintReturnStmt(FLispString &out, ZCC_TreeNode *node)
|
|||
out.Close();
|
||||
}
|
||||
|
||||
static void PrintExpressionStmt(FLispString &out, ZCC_TreeNode *node)
|
||||
static void PrintExpressionStmt(FLispString &out, const ZCC_TreeNode *node)
|
||||
{
|
||||
ZCC_ExpressionStmt *snode = (ZCC_ExpressionStmt *)node;
|
||||
out.Break();
|
||||
|
@ -755,7 +752,7 @@ static void PrintExpressionStmt(FLispString &out, ZCC_TreeNode *node)
|
|||
out.Close();
|
||||
}
|
||||
|
||||
static void PrintIterationStmt(FLispString &out, ZCC_TreeNode *node)
|
||||
static void PrintIterationStmt(FLispString &out, const ZCC_TreeNode *node)
|
||||
{
|
||||
ZCC_IterationStmt *snode = (ZCC_IterationStmt *)node;
|
||||
out.Break();
|
||||
|
@ -770,7 +767,7 @@ static void PrintIterationStmt(FLispString &out, ZCC_TreeNode *node)
|
|||
out.Close();
|
||||
}
|
||||
|
||||
static void PrintIfStmt(FLispString &out, ZCC_TreeNode *node)
|
||||
static void PrintIfStmt(FLispString &out, const ZCC_TreeNode *node)
|
||||
{
|
||||
ZCC_IfStmt *snode = (ZCC_IfStmt *)node;
|
||||
out.Break();
|
||||
|
@ -783,7 +780,7 @@ static void PrintIfStmt(FLispString &out, ZCC_TreeNode *node)
|
|||
out.Close();
|
||||
}
|
||||
|
||||
static void PrintSwitchStmt(FLispString &out, ZCC_TreeNode *node)
|
||||
static void PrintSwitchStmt(FLispString &out, const ZCC_TreeNode *node)
|
||||
{
|
||||
ZCC_SwitchStmt *snode = (ZCC_SwitchStmt *)node;
|
||||
out.Break();
|
||||
|
@ -794,7 +791,7 @@ static void PrintSwitchStmt(FLispString &out, ZCC_TreeNode *node)
|
|||
out.Close();
|
||||
}
|
||||
|
||||
static void PrintCaseStmt(FLispString &out, ZCC_TreeNode *node)
|
||||
static void PrintCaseStmt(FLispString &out, const ZCC_TreeNode *node)
|
||||
{
|
||||
ZCC_CaseStmt *snode = (ZCC_CaseStmt *)node;
|
||||
out.Break();
|
||||
|
@ -810,7 +807,7 @@ static void BadAssignOp(FLispString &out, int op)
|
|||
out.Add(buf, len);
|
||||
}
|
||||
|
||||
static void PrintAssignStmt(FLispString &out, ZCC_TreeNode *node)
|
||||
static void PrintAssignStmt(FLispString &out, const ZCC_TreeNode *node)
|
||||
{
|
||||
ZCC_AssignStmt *snode = (ZCC_AssignStmt *)node;
|
||||
out.Open("assign-stmt");
|
||||
|
@ -819,7 +816,7 @@ static void PrintAssignStmt(FLispString &out, ZCC_TreeNode *node)
|
|||
out.Close();
|
||||
}
|
||||
|
||||
static void PrintLocalVarStmt(FLispString &out, ZCC_TreeNode *node)
|
||||
static void PrintLocalVarStmt(FLispString &out, const ZCC_TreeNode *node)
|
||||
{
|
||||
ZCC_LocalVarStmt *snode = (ZCC_LocalVarStmt *)node;
|
||||
out.Open("local-var-stmt");
|
||||
|
@ -828,7 +825,7 @@ static void PrintLocalVarStmt(FLispString &out, ZCC_TreeNode *node)
|
|||
out.Close();
|
||||
}
|
||||
|
||||
static void PrintFuncParamDecl(FLispString &out, ZCC_TreeNode *node)
|
||||
static void PrintFuncParamDecl(FLispString &out, const ZCC_TreeNode *node)
|
||||
{
|
||||
ZCC_FuncParamDecl *dnode = (ZCC_FuncParamDecl *)node;
|
||||
out.Break();
|
||||
|
@ -840,7 +837,7 @@ static void PrintFuncParamDecl(FLispString &out, ZCC_TreeNode *node)
|
|||
out.Close();
|
||||
}
|
||||
|
||||
static void PrintConstantDef(FLispString &out, ZCC_TreeNode *node)
|
||||
static void PrintConstantDef(FLispString &out, const ZCC_TreeNode *node)
|
||||
{
|
||||
ZCC_ConstantDef *dnode = (ZCC_ConstantDef *)node;
|
||||
out.Break();
|
||||
|
@ -850,7 +847,7 @@ static void PrintConstantDef(FLispString &out, ZCC_TreeNode *node)
|
|||
out.Close();
|
||||
}
|
||||
|
||||
static void PrintDeclarator(FLispString &out, ZCC_TreeNode *node)
|
||||
static void PrintDeclarator(FLispString &out, const ZCC_TreeNode *node)
|
||||
{
|
||||
ZCC_Declarator *dnode = (ZCC_Declarator *)node;
|
||||
out.Break();
|
||||
|
@ -860,7 +857,7 @@ static void PrintDeclarator(FLispString &out, ZCC_TreeNode *node)
|
|||
out.Close();
|
||||
}
|
||||
|
||||
static void PrintVarDeclarator(FLispString &out, ZCC_TreeNode *node)
|
||||
static void PrintVarDeclarator(FLispString &out, const ZCC_TreeNode *node)
|
||||
{
|
||||
ZCC_VarDeclarator *dnode = (ZCC_VarDeclarator *)node;
|
||||
out.Break();
|
||||
|
@ -871,7 +868,7 @@ static void PrintVarDeclarator(FLispString &out, ZCC_TreeNode *node)
|
|||
out.Close();
|
||||
}
|
||||
|
||||
static void PrintFuncDeclarator(FLispString &out, ZCC_TreeNode *node)
|
||||
static void PrintFuncDeclarator(FLispString &out, const ZCC_TreeNode *node)
|
||||
{
|
||||
ZCC_FuncDeclarator *dnode = (ZCC_FuncDeclarator *)node;
|
||||
out.Break();
|
||||
|
@ -885,7 +882,7 @@ static void PrintFuncDeclarator(FLispString &out, ZCC_TreeNode *node)
|
|||
out.Close();
|
||||
}
|
||||
|
||||
static void PrintDeclFlags(FLispString &out, ZCC_TreeNode *node)
|
||||
static void PrintDeclFlags(FLispString &out, const ZCC_TreeNode *node)
|
||||
{
|
||||
auto dnode = (ZCC_DeclFlags *)node;
|
||||
out.Break();
|
||||
|
@ -895,7 +892,7 @@ static void PrintDeclFlags(FLispString &out, ZCC_TreeNode *node)
|
|||
out.Close();
|
||||
}
|
||||
|
||||
static void PrintFlagStmt(FLispString &out, ZCC_TreeNode *node)
|
||||
static void PrintFlagStmt(FLispString &out, const ZCC_TreeNode *node)
|
||||
{
|
||||
auto dnode = (ZCC_FlagStmt *)node;
|
||||
out.Break();
|
||||
|
@ -905,7 +902,7 @@ static void PrintFlagStmt(FLispString &out, ZCC_TreeNode *node)
|
|||
out.Close();
|
||||
}
|
||||
|
||||
static void PrintPropertyStmt(FLispString &out, ZCC_TreeNode *node)
|
||||
static void PrintPropertyStmt(FLispString &out, const ZCC_TreeNode *node)
|
||||
{
|
||||
auto dnode = (ZCC_PropertyStmt *)node;
|
||||
out.Break();
|
||||
|
@ -915,7 +912,7 @@ static void PrintPropertyStmt(FLispString &out, ZCC_TreeNode *node)
|
|||
out.Close();
|
||||
}
|
||||
|
||||
static void PrintMixinDef(FLispString &out, ZCC_TreeNode *node)
|
||||
static void PrintMixinDef(FLispString &out, const ZCC_TreeNode *node)
|
||||
{
|
||||
ZCC_MixinDef *mdnode = (ZCC_MixinDef *)node;
|
||||
out.Break();
|
||||
|
@ -925,7 +922,7 @@ static void PrintMixinDef(FLispString &out, ZCC_TreeNode *node)
|
|||
out.Close();
|
||||
}
|
||||
|
||||
static void PrintMixinStmt(FLispString &out, ZCC_TreeNode *node)
|
||||
static void PrintMixinStmt(FLispString &out, const ZCC_TreeNode *node)
|
||||
{
|
||||
ZCC_MixinStmt *msnode = (ZCC_MixinStmt *)node;
|
||||
out.Break();
|
||||
|
@ -934,7 +931,20 @@ static void PrintMixinStmt(FLispString &out, ZCC_TreeNode *node)
|
|||
out.Close();
|
||||
}
|
||||
|
||||
void (* const TreeNodePrinter[NUM_AST_NODE_TYPES])(FLispString &, ZCC_TreeNode *) =
|
||||
static void PrintArrayIterationStmt(FLispString &out, const ZCC_TreeNode *node)
|
||||
{
|
||||
auto inode = (ZCC_ArrayIterationStmt *)node;
|
||||
out.Break();
|
||||
out.Open("array-iteration-stmt");
|
||||
PrintVarName(out, inode->ItName);
|
||||
out.Break();
|
||||
PrintNodes(out, inode->ItArray);
|
||||
out.Break();
|
||||
PrintNodes(out, inode->LoopStatement);
|
||||
out.Close();
|
||||
}
|
||||
|
||||
static const NodePrinterFunc TreeNodePrinter[] =
|
||||
{
|
||||
PrintIdentifier,
|
||||
PrintClass,
|
||||
|
@ -955,6 +965,7 @@ void (* const TreeNodePrinter[NUM_AST_NODE_TYPES])(FLispString &, ZCC_TreeNode *
|
|||
PrintType,
|
||||
PrintBasicType,
|
||||
PrintMapType,
|
||||
PrintMapIteratorType,
|
||||
PrintDynArrayType,
|
||||
PrintClassType,
|
||||
PrintExpression,
|
||||
|
@ -995,11 +1006,27 @@ void (* const TreeNodePrinter[NUM_AST_NODE_TYPES])(FLispString &, ZCC_TreeNode *
|
|||
PrintFlagDef,
|
||||
PrintMixinDef,
|
||||
PrintMixinStmt,
|
||||
PrintArrayIterationStmt,
|
||||
};
|
||||
|
||||
FString ZCC_PrintAST(ZCC_TreeNode *root)
|
||||
FString ZCC_PrintAST(const ZCC_TreeNode *root)
|
||||
{
|
||||
FLispString out;
|
||||
PrintNodes(out, root);
|
||||
return out;
|
||||
}
|
||||
|
||||
static void PrintNode(FLispString &out, const ZCC_TreeNode *node)
|
||||
{
|
||||
static_assert(countof(TreeNodePrinter) == NUM_AST_NODE_TYPES, "All AST node types should have printers defined for them");
|
||||
if (node->NodeType >= 0 && node->NodeType < NUM_AST_NODE_TYPES)
|
||||
{
|
||||
TreeNodePrinter[node->NodeType](out, node);
|
||||
}
|
||||
else
|
||||
{
|
||||
out.Open("unknown-node-type");
|
||||
out.AddInt(node->NodeType);
|
||||
out.Close();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -932,7 +932,7 @@ type_name(X) ::= DOT dottable_id(A).
|
|||
/* Type names can also be used as identifiers in contexts where type names
|
||||
* are not normally allowed. */
|
||||
%fallback IDENTIFIER
|
||||
SBYTE BYTE SHORT USHORT INT UINT BOOL FLOAT DOUBLE STRING VECTOR2 VECTOR3 VECTOR4 NAME MAP ARRAY VOID STATE COLOR SOUND UINT8 INT8 UINT16 INT16 PROPERTY.
|
||||
SBYTE BYTE SHORT USHORT INT UINT BOOL FLOAT DOUBLE STRING VECTOR2 VECTOR3 VECTOR4 NAME MAP MAPITERATOR ARRAY VOID STATE COLOR SOUND UINT8 INT8 UINT16 INT16 PROPERTY.
|
||||
|
||||
/* Aggregate types */
|
||||
%type aggregate_type {ZCC_Type *}
|
||||
|
@ -944,7 +944,7 @@ type_name(X) ::= DOT dottable_id(A).
|
|||
%type array_size{ZCC_Expression *}
|
||||
%type array_size_expr{ZCC_Expression *}
|
||||
|
||||
aggregate_type(X) ::= MAP(T) LT type_or_array(A) COMMA type_or_array(B) GT. /* Hash table */
|
||||
aggregate_type(X) ::= MAP(T) LT type_or_array(A) COMMA type_or_array(B) GT. /* ZSMap<K, V> */
|
||||
{
|
||||
NEW_AST_NODE(MapType,map,T);
|
||||
map->KeyType = A;
|
||||
|
@ -952,6 +952,14 @@ aggregate_type(X) ::= MAP(T) LT type_or_array(A) COMMA type_or_array(B) GT. /* H
|
|||
X = map;
|
||||
}
|
||||
|
||||
aggregate_type(X) ::= MAPITERATOR(T) LT type_or_array(A) COMMA type_or_array(B) GT. /* ZSMapIterator<K, V> */
|
||||
{
|
||||
NEW_AST_NODE(MapIteratorType,map_it,T);
|
||||
map_it->KeyType = A;
|
||||
map_it->ValueType = B;
|
||||
X = map_it;
|
||||
}
|
||||
|
||||
aggregate_type(X) ::= ARRAY(T) LT type_or_array(A) GT. /* TArray<type> */
|
||||
{
|
||||
NEW_AST_NODE(DynArrayType,arr,T);
|
||||
|
|
|
@ -1853,16 +1853,96 @@ PType *ZCCCompiler::DetermineType(PType *outertype, ZCC_TreeNode *field, FName n
|
|||
}
|
||||
|
||||
case AST_MapType:
|
||||
if (allowarraytypes)
|
||||
{
|
||||
if(AST.ParseVersion < MakeVersion(4, 10, 0))
|
||||
{
|
||||
Error(field, "%s: Map types not implemented yet", name.GetChars());
|
||||
// Todo: Decide what we allow here and if it makes sense to allow more complex constructs.
|
||||
auto mtype = static_cast<ZCC_MapType *>(ztype);
|
||||
retval = NewMap(DetermineType(outertype, field, name, mtype->KeyType, false, false), DetermineType(outertype, field, name, mtype->ValueType, false, false));
|
||||
Error(field, "Map not accessible to ZScript version %d.%d.%d", AST.ParseVersion.major, AST.ParseVersion.minor, AST.ParseVersion.revision);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
// Todo: Decide what we allow here and if it makes sense to allow more complex constructs.
|
||||
auto mtype = static_cast<ZCC_MapType *>(ztype);
|
||||
|
||||
auto keytype = DetermineType(outertype, field, name, mtype->KeyType, false, false);
|
||||
auto valuetype = DetermineType(outertype, field, name, mtype->ValueType, false, false);
|
||||
|
||||
if (keytype->GetRegType() == REGT_INT)
|
||||
{
|
||||
if (keytype->Size != 4)
|
||||
{
|
||||
Error(field, "Map<%s , ...> not implemented yet", keytype->DescriptiveName());
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (keytype->GetRegType() != REGT_STRING)
|
||||
{
|
||||
Error(field, "Map<%s , ...> not implemented yet", keytype->DescriptiveName());
|
||||
break;
|
||||
}
|
||||
|
||||
switch(valuetype->GetRegType())
|
||||
{
|
||||
case REGT_FLOAT:
|
||||
case REGT_INT:
|
||||
case REGT_STRING:
|
||||
case REGT_POINTER:
|
||||
if (valuetype->GetRegCount() > 1)
|
||||
{
|
||||
Error(field, "%s : Base type for map value types must be integral, but got %s", name.GetChars(), valuetype->DescriptiveName());
|
||||
break;
|
||||
}
|
||||
|
||||
retval = NewMap(keytype, valuetype);
|
||||
break;
|
||||
default:
|
||||
Error(field, "%s: Base type for map value types must be integral, but got %s", name.GetChars(), valuetype->DescriptiveName());
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case AST_MapIteratorType:
|
||||
{
|
||||
if(AST.ParseVersion < MakeVersion(4, 10, 0))
|
||||
{
|
||||
Error(field, "MapIterator not accessible to ZScript version %d.%d.%d", AST.ParseVersion.major, AST.ParseVersion.minor, AST.ParseVersion.revision);
|
||||
break;
|
||||
}
|
||||
// Todo: Decide what we allow here and if it makes sense to allow more complex constructs.
|
||||
auto mtype = static_cast<ZCC_MapIteratorType *>(ztype);
|
||||
|
||||
auto keytype = DetermineType(outertype, field, name, mtype->KeyType, false, false);
|
||||
auto valuetype = DetermineType(outertype, field, name, mtype->ValueType, false, false);
|
||||
|
||||
if (keytype->GetRegType() == REGT_INT)
|
||||
{
|
||||
if (keytype->Size != 4)
|
||||
{
|
||||
Error(field, "MapIterator<%s , ...> not implemented yet", keytype->DescriptiveName());
|
||||
}
|
||||
}
|
||||
else if (keytype->GetRegType() != REGT_STRING)
|
||||
{
|
||||
Error(field, "MapIterator<%s , ...> not implemented yet", keytype->DescriptiveName());
|
||||
}
|
||||
|
||||
switch(valuetype->GetRegType())
|
||||
{
|
||||
case REGT_FLOAT:
|
||||
case REGT_INT:
|
||||
case REGT_STRING:
|
||||
case REGT_POINTER:
|
||||
if (valuetype->GetRegCount() > 1)
|
||||
{
|
||||
Error(field, "%s : Base type for map value types must be integral, but got %s", name.GetChars(), valuetype->DescriptiveName());
|
||||
break;
|
||||
}
|
||||
retval = NewMapIterator(keytype, valuetype);
|
||||
break;
|
||||
default:
|
||||
Error(field, "%s: Base type for map value types must be integral, but got %s", name.GetChars(), valuetype->DescriptiveName());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case AST_DynArrayType:
|
||||
{
|
||||
auto atype = static_cast<ZCC_DynArrayType *>(ztype);
|
||||
|
@ -2357,7 +2437,7 @@ void ZCCCompiler::CompileFunction(ZCC_StructWork *c, ZCC_FuncDeclarator *f, bool
|
|||
{
|
||||
auto type = DetermineType(c->Type(), p, f->Name, p->Type, false, false);
|
||||
int flags = 0;
|
||||
if ((type->isStruct() && type != TypeVector2 && type != TypeVector3 && type != TypeVector4 && type != TypeQuaternion && type != TypeFVector2 && type != TypeFVector3 && type != TypeFVector4 && type != TypeFQuaternion) || type->isDynArray())
|
||||
if ((type->isStruct() && type != TypeVector2 && type != TypeVector3 && type != TypeVector4 && type != TypeQuaternion && type != TypeFVector2 && type != TypeFVector3 && type != TypeFVector4 && type != TypeFQuaternion) || type->isDynArray() || type->isMap() || type->isMapIterator())
|
||||
{
|
||||
// Structs are being passed by pointer, but unless marked 'out' that pointer must be readonly.
|
||||
type = NewPointer(type /*, !(p->Flags & ZCC_Out)*/);
|
||||
|
|
|
@ -220,6 +220,7 @@ static void InitTokenMap()
|
|||
TOKENDEF2(TK_Vector3, ZCC_VECTOR3, NAME_Vector3);
|
||||
TOKENDEF2(TK_Name, ZCC_NAME, NAME_Name);
|
||||
TOKENDEF2(TK_Map, ZCC_MAP, NAME_Map);
|
||||
TOKENDEF2(TK_MapIterator, ZCC_MAPITERATOR,NAME_MapIterator);
|
||||
TOKENDEF2(TK_Array, ZCC_ARRAY, NAME_Array);
|
||||
TOKENDEF2(TK_Include, ZCC_INCLUDE, NAME_Include);
|
||||
TOKENDEF (TK_Void, ZCC_VOID);
|
||||
|
@ -896,6 +897,19 @@ ZCC_TreeNode *TreeNodeDeepCopy_Internal(ZCC_AST *ast, ZCC_TreeNode *orig, bool c
|
|||
break;
|
||||
}
|
||||
|
||||
case AST_MapIteratorType:
|
||||
{
|
||||
TreeNodeDeepCopy_Start(MapIteratorType);
|
||||
|
||||
// ZCC_Type
|
||||
copy->ArraySize = static_cast<ZCC_Expression *>(TreeNodeDeepCopy_Internal(ast, origCasted->ArraySize, true, copiedNodesList));
|
||||
// AST_MapIteratorType
|
||||
copy->KeyType = static_cast<ZCC_Type *>(TreeNodeDeepCopy_Internal(ast, origCasted->KeyType, true, copiedNodesList));
|
||||
copy->ValueType = static_cast<ZCC_Type *>(TreeNodeDeepCopy_Internal(ast, origCasted->ValueType, true, copiedNodesList));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case AST_DynArrayType:
|
||||
{
|
||||
TreeNodeDeepCopy_Start(DynArrayType);
|
||||
|
@ -1128,7 +1142,7 @@ ZCC_TreeNode *TreeNodeDeepCopy_Internal(ZCC_AST *ast, ZCC_TreeNode *orig, bool c
|
|||
{
|
||||
TreeNodeDeepCopy_Start(ArrayIterationStmt);
|
||||
|
||||
// ZCC_IterationStmt
|
||||
// ZCC_ArrayIterationStmt
|
||||
copy->ItName = static_cast<ZCC_VarName*>(TreeNodeDeepCopy_Internal(ast, origCasted->ItName, true, copiedNodesList));
|
||||
copy->LoopStatement = static_cast<ZCC_Statement*>(TreeNodeDeepCopy_Internal(ast, origCasted->LoopStatement, true, copiedNodesList));
|
||||
copy->ItArray = static_cast<ZCC_Expression*>(TreeNodeDeepCopy_Internal(ast, origCasted->ItArray, true, copiedNodesList));
|
||||
|
|
|
@ -98,6 +98,7 @@ enum EZCCTreeNodeType
|
|||
AST_Type,
|
||||
AST_BasicType,
|
||||
AST_MapType,
|
||||
AST_MapIteratorType,
|
||||
AST_DynArrayType,
|
||||
AST_ClassType,
|
||||
AST_Expression,
|
||||
|
@ -367,6 +368,12 @@ struct ZCC_MapType : ZCC_Type
|
|||
ZCC_Type *ValueType;
|
||||
};
|
||||
|
||||
struct ZCC_MapIteratorType : ZCC_Type
|
||||
{
|
||||
ZCC_Type *KeyType;
|
||||
ZCC_Type *ValueType;
|
||||
};
|
||||
|
||||
struct ZCC_DynArrayType : ZCC_Type
|
||||
{
|
||||
ZCC_Type *ElementType;
|
||||
|
@ -601,7 +608,7 @@ struct ZCC_MixinStmt : ZCC_Statement
|
|||
ENamedName MixinName;
|
||||
};
|
||||
|
||||
FString ZCC_PrintAST(ZCC_TreeNode *root);
|
||||
FString ZCC_PrintAST(const ZCC_TreeNode *root);
|
||||
|
||||
|
||||
struct ZCC_AST
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
bool gameisdead;
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <cstdarg>
|
||||
#include <windows.h>
|
||||
#include "zstring.h"
|
||||
void I_DebugPrint(const char *cp)
|
||||
|
@ -46,10 +47,31 @@ void I_DebugPrint(const char *cp)
|
|||
OutputDebugStringW(wstr.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void I_DebugPrintf(const char *fmt,...)
|
||||
{
|
||||
if (IsDebuggerPresent())
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
|
||||
FString s;
|
||||
s.VFormat(fmt, args);
|
||||
|
||||
va_end(args);
|
||||
|
||||
auto wstr = WideString(s);
|
||||
OutputDebugStringW(wstr.c_str());
|
||||
}
|
||||
}
|
||||
#else
|
||||
void I_DebugPrint(const char *cp)
|
||||
{
|
||||
}
|
||||
|
||||
void I_DebugPrintf(const char *fmt,...)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#include "engineerrors.h"
|
||||
|
|
|
@ -916,6 +916,9 @@ public:
|
|||
typedef struct { const KT Key; VT Value; } Pair;
|
||||
typedef const Pair ConstPair;
|
||||
|
||||
typedef KT KeyType;
|
||||
typedef VT ValueType;
|
||||
|
||||
TMap() { NumUsed = 0; SetNodeVector(1); }
|
||||
TMap(hash_t size) { NumUsed = 0; SetNodeVector(size); }
|
||||
~TMap() { ClearNodeVector(); }
|
||||
|
|
|
@ -1547,6 +1547,16 @@ inline TAngle<T> interpolatedvalue(const TAngle<T> &oang, const TAngle<T> &ang,
|
|||
return oang + (deltaangle(oang, ang) * interpfrac);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline TRotator<T> interpolatedvalue(const TRotator<T> &oang, const TRotator<T> &ang, const double interpfrac)
|
||||
{
|
||||
return TRotator<T>(
|
||||
interpolatedvalue(oang.Pitch, ang.Pitch, interpfrac),
|
||||
interpolatedvalue(oang.Yaw, ang.Yaw, interpfrac),
|
||||
interpolatedvalue(oang.Roll, ang.Roll, interpfrac)
|
||||
);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline T interpolatedvalue(const T& oval, const T& val, const double interpfrac)
|
||||
{
|
||||
|
|
|
@ -430,7 +430,7 @@ void initshell(DDukeActor* actj, DDukeActor* act, bool isshell)
|
|||
ang = ps[snum].angle.ang - mapangle((krand() & 63) + 8); //Fine tune
|
||||
|
||||
act->temp_data[0] = krand() & 1;
|
||||
act->spr.pos.Z = 3 + ps[snum].pos.Z + ps[snum].pyoff + (ps[snum].horizon.sum().Tan() * 8.) + (!isshell ? 3 : 0);
|
||||
act->spr.pos.Z = 3 + ps[snum].pos.Z + ps[snum].pyoff + (ps[snum].horizon.sum().Sin() * 8.) + (!isshell ? 3 : 0);
|
||||
act->vel.Z = -krandf(1);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -14,6 +14,7 @@ version "4.10"
|
|||
#include "zscript/engine/ui/menu/menu.zs"
|
||||
#include "zscript/engine/ui/menu/menuitembase.zs"
|
||||
#include "zscript/engine/ui/menu/messagebox.zs"
|
||||
#include "zscript/engine/ui/menu/custommessagebox.zs"
|
||||
#include "zscript/engine/ui/menu/optionmenu.zs"
|
||||
#include "zscript/engine/ui/menu/optionmenuitems.zs"
|
||||
#include "zscript/engine/ui/menu/reverbedit.zs"
|
||||
|
|
|
@ -893,3 +893,16 @@ struct Translation version("2.4")
|
|||
}
|
||||
}
|
||||
|
||||
// Convenient way to attach functions to Quat
|
||||
struct QuatStruct native
|
||||
{
|
||||
native static Quat SLerp(Quat from, Quat to, double t);
|
||||
native static Quat NLerp(Quat from, Quat to, double t);
|
||||
native static Quat FromAngles(double yaw, double pitch, double roll);
|
||||
native static Quat AxisAngle(Vector3 xyz, double angle);
|
||||
native Quat Conjugate();
|
||||
native Quat Inverse();
|
||||
// native double Length();
|
||||
// native double LengthSquared();
|
||||
// native Quat Unit();
|
||||
}
|
||||
|
|
447
wadsrc/static/zscript/engine/maps.zs
Normal file
447
wadsrc/static/zscript/engine/maps.zs
Normal file
|
@ -0,0 +1,447 @@
|
|||
|
||||
struct Map_I32_I8 native
|
||||
{
|
||||
native void Copy(Map_I32_I8 other);
|
||||
native void Move(Map_I32_I8 other);
|
||||
native void Swap(Map_I32_I8 other);
|
||||
native void Clear();
|
||||
native uint CountUsed();
|
||||
|
||||
native int Get(int key);
|
||||
native bool CheckKey(int key);
|
||||
native void Insert(int key,int value);
|
||||
native void InsertNew(int key);
|
||||
native void Remove(int key);
|
||||
}
|
||||
|
||||
struct MapIterator_I32_I8 native
|
||||
{
|
||||
native bool Init(Map_I32_I8 other);
|
||||
native bool ReInit();
|
||||
|
||||
native bool Valid();
|
||||
native bool Next();
|
||||
|
||||
native int GetKey();
|
||||
native int GetValue();
|
||||
native void SetValue(int value);
|
||||
}
|
||||
|
||||
struct Map_I32_I16 native
|
||||
{
|
||||
native void Copy(Map_I32_I16 other);
|
||||
native void Move(Map_I32_I16 other);
|
||||
native void Swap(Map_I32_I16 other);
|
||||
native void Clear();
|
||||
native uint CountUsed();
|
||||
|
||||
native int Get(int key);
|
||||
native bool CheckKey(int key);
|
||||
native void Insert(int key,int value);
|
||||
native void InsertNew(int key);
|
||||
native void Remove(int key);
|
||||
}
|
||||
|
||||
struct MapIterator_I32_I16 native
|
||||
{
|
||||
native bool Init(Map_I32_I16 other);
|
||||
native bool ReInit();
|
||||
|
||||
native bool Valid();
|
||||
native bool Next();
|
||||
|
||||
native int GetKey();
|
||||
native int GetValue();
|
||||
native void SetValue(int value);
|
||||
}
|
||||
|
||||
struct Map_I32_I32 native
|
||||
{
|
||||
native void Copy(Map_I32_I32 other);
|
||||
native void Move(Map_I32_I32 other);
|
||||
native void Swap(Map_I32_I32 other);
|
||||
native void Clear();
|
||||
native uint CountUsed();
|
||||
|
||||
native int Get(int key);
|
||||
native bool CheckKey(int key);
|
||||
native void Insert(int key,int value);
|
||||
native void InsertNew(int key);
|
||||
native void Remove(int key);
|
||||
}
|
||||
|
||||
struct MapIterator_I32_I32 native
|
||||
{
|
||||
native bool Init(Map_I32_I32 other);
|
||||
native bool ReInit();
|
||||
|
||||
native bool Valid();
|
||||
native bool Next();
|
||||
|
||||
native int GetKey();
|
||||
native int GetValue();
|
||||
native void SetValue(int value);
|
||||
}
|
||||
|
||||
struct Map_I32_F32 native
|
||||
{
|
||||
native void Copy(Map_I32_F32 other);
|
||||
native void Move(Map_I32_F32 other);
|
||||
native void Swap(Map_I32_F32 other);
|
||||
native void Clear();
|
||||
native uint CountUsed();
|
||||
|
||||
native double Get(int key);
|
||||
native bool CheckKey(int key);
|
||||
native void Insert(int key,double value);
|
||||
native void InsertNew(int key);
|
||||
native void Remove(int key);
|
||||
}
|
||||
|
||||
struct MapIterator_I32_F32 native
|
||||
{
|
||||
native bool Init(Map_I32_F32 other);
|
||||
native bool ReInit();
|
||||
|
||||
native bool Valid();
|
||||
native bool Next();
|
||||
|
||||
native int GetKey();
|
||||
native double GetValue();
|
||||
native void SetValue(double value);
|
||||
}
|
||||
|
||||
struct Map_I32_F64 native
|
||||
{
|
||||
native void Copy(Map_I32_F64 other);
|
||||
native void Move(Map_I32_F64 other);
|
||||
native void Swap(Map_I32_F64 other);
|
||||
native void Clear();
|
||||
native uint CountUsed();
|
||||
|
||||
native double Get(int key);
|
||||
native bool CheckKey(int key);
|
||||
native void Insert(int key,double value);
|
||||
native void InsertNew(int key);
|
||||
native void Remove(int key);
|
||||
}
|
||||
|
||||
struct MapIterator_I32_F64 native
|
||||
{
|
||||
native bool Init(Map_I32_F64 other);
|
||||
native bool ReInit();
|
||||
|
||||
native bool Valid();
|
||||
native bool Next();
|
||||
|
||||
native int GetKey();
|
||||
native double GetValue();
|
||||
native void SetValue(double value);
|
||||
}
|
||||
|
||||
struct Map_I32_Obj native
|
||||
{
|
||||
native void Copy(Map_I32_Obj other);
|
||||
native void Move(Map_I32_Obj other);
|
||||
native void Swap(Map_I32_Obj other);
|
||||
native void Clear();
|
||||
native uint CountUsed();
|
||||
|
||||
native Object Get(int key);
|
||||
native bool CheckKey(int key);
|
||||
native void Insert(int key,Object value);
|
||||
native void InsertNew(int key);
|
||||
native void Remove(int key);
|
||||
}
|
||||
|
||||
struct MapIterator_I32_Obj native
|
||||
{
|
||||
native bool Init(Map_I32_Obj other);
|
||||
native bool ReInit();
|
||||
|
||||
native bool Valid();
|
||||
native bool Next();
|
||||
|
||||
native int GetKey();
|
||||
native Object GetValue();
|
||||
native void SetValue(Object value);
|
||||
}
|
||||
|
||||
struct Map_I32_Ptr native
|
||||
{
|
||||
native void Copy(Map_I32_Ptr other);
|
||||
native void Move(Map_I32_Ptr other);
|
||||
native void Swap(Map_I32_Ptr other);
|
||||
native void Clear();
|
||||
native uint CountUsed();
|
||||
|
||||
native voidptr Get(int key);
|
||||
native bool CheckKey(int key);
|
||||
native void Insert(int key,voidptr value);
|
||||
native void InsertNew(int key);
|
||||
native void Remove(int key);
|
||||
}
|
||||
|
||||
struct MapIterator_I32_Ptr native
|
||||
{
|
||||
native bool Init(Map_I32_Ptr other);
|
||||
native bool Next();
|
||||
|
||||
native int GetKey();
|
||||
native voidptr GetValue();
|
||||
native void SetValue(voidptr value);
|
||||
}
|
||||
|
||||
struct Map_I32_Str native
|
||||
{
|
||||
native void Copy(Map_I32_Str other);
|
||||
native void Move(Map_I32_Str other);
|
||||
native void Swap(Map_I32_Str other);
|
||||
native void Clear();
|
||||
native uint CountUsed();
|
||||
|
||||
native String Get(int key);
|
||||
native bool CheckKey(int key);
|
||||
native void Insert(int key,String value);
|
||||
native void InsertNew(int key);
|
||||
native void Remove(int key);
|
||||
}
|
||||
|
||||
struct MapIterator_I32_Str native
|
||||
{
|
||||
native bool Init(Map_I32_Str other);
|
||||
native bool ReInit();
|
||||
|
||||
native bool Valid();
|
||||
native bool Next();
|
||||
|
||||
native int GetKey();
|
||||
native String GetValue();
|
||||
native void SetValue(String value);
|
||||
}
|
||||
|
||||
// ---------------
|
||||
|
||||
struct Map_Str_I8 native
|
||||
{
|
||||
native void Copy(Map_Str_I8 other);
|
||||
native void Move(Map_Str_I8 other);
|
||||
native void Swap(Map_Str_I8 other);
|
||||
native void Clear();
|
||||
native uint CountUsed();
|
||||
|
||||
native int Get(String key);
|
||||
native bool CheckKey(String key);
|
||||
native void Insert(String key,int value);
|
||||
native void InsertNew(String key);
|
||||
native void Remove(String key);
|
||||
}
|
||||
|
||||
struct MapIterator_Str_I8 native
|
||||
{
|
||||
native bool Init(Map_Str_I8 other);
|
||||
native bool ReInit();
|
||||
|
||||
native bool Valid();
|
||||
native bool Next();
|
||||
|
||||
native String GetKey();
|
||||
native int GetValue();
|
||||
native void SetValue(int value);
|
||||
}
|
||||
|
||||
struct Map_Str_I16 native
|
||||
{
|
||||
native void Copy(Map_Str_I16 other);
|
||||
native void Move(Map_Str_I16 other);
|
||||
native void Swap(Map_Str_I16 other);
|
||||
native void Clear();
|
||||
native uint CountUsed();
|
||||
|
||||
native int Get(String key);
|
||||
native bool CheckKey(String key);
|
||||
native void Insert(String key,int value);
|
||||
native void InsertNew(String key);
|
||||
native void Remove(String key);
|
||||
}
|
||||
|
||||
struct MapIterator_Str_I16 native
|
||||
{
|
||||
native bool Init(Map_Str_I16 other);
|
||||
native bool ReInit();
|
||||
|
||||
native bool Valid();
|
||||
native bool Next();
|
||||
|
||||
native String GetKey();
|
||||
native int GetValue();
|
||||
native void SetValue(int value);
|
||||
}
|
||||
|
||||
struct Map_Str_I32 native
|
||||
{
|
||||
native void Copy(Map_Str_I32 other);
|
||||
native void Move(Map_Str_I32 other);
|
||||
native void Swap(Map_Str_I32 other);
|
||||
native void Clear();
|
||||
native uint CountUsed();
|
||||
|
||||
native int Get(String key);
|
||||
native bool CheckKey(String key);
|
||||
native void Insert(String key,int value);
|
||||
native void InsertNew(String key);
|
||||
native void Remove(String key);
|
||||
}
|
||||
|
||||
struct MapIterator_Str_I32 native
|
||||
{
|
||||
native bool Init(Map_Str_I32 other);
|
||||
native bool ReInit();
|
||||
|
||||
native bool Valid();
|
||||
native bool Next();
|
||||
|
||||
native String GetKey();
|
||||
native int GetValue();
|
||||
native void SetValue(int value);
|
||||
}
|
||||
|
||||
struct Map_Str_F32 native
|
||||
{
|
||||
native void Copy(Map_Str_F32 other);
|
||||
native void Move(Map_Str_F32 other);
|
||||
native void Swap(Map_Str_F32 other);
|
||||
native void Clear();
|
||||
native uint CountUsed();
|
||||
|
||||
native double Get(String key);
|
||||
native bool CheckKey(String key);
|
||||
native void Insert(String key,double value);
|
||||
native void InsertNew(String key);
|
||||
native void Remove(String key);
|
||||
}
|
||||
|
||||
struct MapIterator_Str_F32 native
|
||||
{
|
||||
native bool Init(Map_Str_F32 other);
|
||||
native bool ReInit();
|
||||
|
||||
native bool Valid();
|
||||
native bool Next();
|
||||
|
||||
native String GetKey();
|
||||
native double GetValue();
|
||||
native void SetValue(double value);
|
||||
}
|
||||
|
||||
struct Map_Str_F64 native
|
||||
{
|
||||
native void Copy(Map_Str_F64 other);
|
||||
native void Move(Map_Str_F64 other);
|
||||
native void Swap(Map_Str_F64 other);
|
||||
native void Clear();
|
||||
native uint CountUsed();
|
||||
|
||||
native double Get(String key);
|
||||
native bool CheckKey(String key);
|
||||
native void Insert(String key,double value);
|
||||
native void InsertNew(String key);
|
||||
native void Remove(String key);
|
||||
}
|
||||
|
||||
struct MapIterator_Str_F64 native
|
||||
{
|
||||
native bool Init(Map_Str_F64 other);
|
||||
native bool ReInit();
|
||||
|
||||
native bool Valid();
|
||||
native bool Next();
|
||||
|
||||
native String GetKey();
|
||||
native double GetValue();
|
||||
native void SetValue(double value);
|
||||
}
|
||||
|
||||
struct Map_Str_Obj native
|
||||
{
|
||||
native void Copy(Map_Str_Obj other);
|
||||
native void Move(Map_Str_Obj other);
|
||||
native void Swap(Map_Str_Obj other);
|
||||
native void Clear();
|
||||
native uint CountUsed();
|
||||
|
||||
native Object Get(String key);
|
||||
native bool CheckKey(String key);
|
||||
native void Insert(String key,Object value);
|
||||
native void InsertNew(String key);
|
||||
native void Remove(String key);
|
||||
}
|
||||
|
||||
struct MapIterator_Str_Obj native
|
||||
{
|
||||
native bool Init(Map_Str_Obj other);
|
||||
native bool ReInit();
|
||||
|
||||
native bool Valid();
|
||||
native bool Next();
|
||||
|
||||
native String GetKey();
|
||||
native Object GetValue();
|
||||
native void SetValue(Object value);
|
||||
}
|
||||
|
||||
struct Map_Str_Ptr native
|
||||
{
|
||||
native void Copy(Map_Str_Ptr other);
|
||||
native void Move(Map_Str_Ptr other);
|
||||
native void Swap(Map_Str_Ptr other);
|
||||
native void Clear();
|
||||
native uint CountUsed();
|
||||
|
||||
native voidptr Get(String key);
|
||||
native bool CheckKey(String key);
|
||||
native void Insert(String key,voidptr value);
|
||||
native void InsertNew(String key);
|
||||
native void Remove(String key);
|
||||
}
|
||||
|
||||
struct MapIterator_Str_Ptr native
|
||||
{
|
||||
native bool Init(Map_Str_Ptr other);
|
||||
native bool ReInit();
|
||||
|
||||
native bool Valid();
|
||||
native bool Next();
|
||||
|
||||
native String GetKey();
|
||||
native voidptr GetValue();
|
||||
native void SetValue(voidptr value);
|
||||
}
|
||||
|
||||
struct Map_Str_Str native
|
||||
{
|
||||
native void Copy(Map_Str_Str other);
|
||||
native void Move(Map_Str_Str other);
|
||||
native void Swap(Map_Str_Str other);
|
||||
native void Clear();
|
||||
native uint CountUsed();
|
||||
|
||||
native String Get(String key);
|
||||
native bool CheckKey(String key);
|
||||
native void Insert(String key,String value);
|
||||
native void InsertNew(String key);
|
||||
native void Remove(String key);
|
||||
}
|
||||
|
||||
struct MapIterator_Str_Str native
|
||||
{
|
||||
native bool Init(Map_Str_Str other);
|
||||
native bool ReInit();
|
||||
|
||||
native bool Valid();
|
||||
native bool Next();
|
||||
|
||||
native String GetKey();
|
||||
native String GetValue();
|
||||
native void SetValue(String value);
|
||||
}
|
264
wadsrc/static/zscript/engine/ui/menu/custommessagebox.zs
Normal file
264
wadsrc/static/zscript/engine/ui/menu/custommessagebox.zs
Normal file
|
@ -0,0 +1,264 @@
|
|||
/*
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 2010-2017 Christoph Oelckers
|
||||
** Copyright 2022 Ricardo Luis Vaz Silva
|
||||
**
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions
|
||||
** are met:
|
||||
**
|
||||
** 1. Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** 2. Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** 3. The name of the author may not be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**---------------------------------------------------------------------------
|
||||
**
|
||||
*/
|
||||
|
||||
class CustomMessageBoxMenuBase : Menu abstract
|
||||
{
|
||||
BrokenLines mMessage;
|
||||
uint messageSelection;
|
||||
int mMouseLeft, mMouseRight, mMouseY;
|
||||
|
||||
Font textFont, arrowFont;
|
||||
int destWidth, destHeight;
|
||||
String selector;
|
||||
|
||||
abstract uint OptionCount();
|
||||
abstract String OptionName(uint index);
|
||||
abstract int OptionXOffset(uint index);
|
||||
|
||||
abstract int OptionForShortcut(int char_key, out bool activate); // -1 for no shortcut, activate = true if this executes the option immediately
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
virtual void Init(Menu parent, String message, bool playsound = false)
|
||||
{
|
||||
Super.Init(parent);
|
||||
messageSelection = 0;
|
||||
mMouseLeft = 140;
|
||||
mMouseY = 0x80000000;
|
||||
textFont = null;
|
||||
|
||||
if (!generic_ui)
|
||||
{
|
||||
if (SmallFont && SmallFont.CanPrint(message) && SmallFont.CanPrint("$TXT_YES") && SmallFont.CanPrint("$TXT_NO")) textFont = SmallFont;
|
||||
else if (OriginalSmallFont && OriginalSmallFont.CanPrint(message) && OriginalSmallFont.CanPrint("$TXT_YES") && OriginalSmallFont.CanPrint("$TXT_NO")) textFont = OriginalSmallFont;
|
||||
}
|
||||
|
||||
if (!textFont)
|
||||
{
|
||||
arrowFont = textFont = NewSmallFont;
|
||||
int factor = (CleanXfac+1) / 2;
|
||||
destWidth = screen.GetWidth() / factor;
|
||||
destHeight = screen.GetHeight() / factor;
|
||||
selector = "▶";
|
||||
}
|
||||
else
|
||||
{
|
||||
arrowFont = ConFont;
|
||||
destWidth = CleanWidth;
|
||||
destHeight = CleanHeight;
|
||||
selector = "\xd";
|
||||
}
|
||||
|
||||
int mr1 = destWidth/2 + 10 + textFont.StringWidth(Stringtable.Localize("$TXT_YES"));
|
||||
int mr2 = destWidth/2 + 10 + textFont.StringWidth(Stringtable.Localize("$TXT_NO"));
|
||||
mMouseRight = MAX(mr1, mr2);
|
||||
mParentMenu = parent;
|
||||
mMessage = textFont.BreakLines(Stringtable.Localize(message), int(300/NotifyFontScale));
|
||||
if (playsound)
|
||||
{
|
||||
MenuSound ("menu/prompt");
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
override void Drawer ()
|
||||
{
|
||||
int i;
|
||||
double y;
|
||||
let fontheight = textFont.GetHeight() * NotifyFontScale;
|
||||
|
||||
y = destHeight / 2;
|
||||
|
||||
int c = mMessage.Count();
|
||||
y -= c * fontHeight / 2;
|
||||
|
||||
for (i = 0; i < c; i++)
|
||||
{
|
||||
screen.DrawText (textFont, Font.CR_UNTRANSLATED, destWidth/2 - mMessage.StringWidth(i)*NotifyFontScale/2, y, mMessage.StringAt(i), DTA_VirtualWidth, destWidth, DTA_VirtualHeight, destHeight, DTA_KeepRatio, true,
|
||||
DTA_ScaleX, NotifyFontScale, DTA_ScaleY, NotifyFontScale);
|
||||
y += fontheight;
|
||||
}
|
||||
|
||||
y += fontheight;
|
||||
mMouseY = int(y);
|
||||
|
||||
let n = optionCount();
|
||||
for(uint i = 0; i < n; i++)
|
||||
{
|
||||
screen.DrawText(textFont, messageSelection == i? OptionMenuSettings.mFontColorSelection : OptionMenuSettings.mFontColor, (destWidth / 2) + OptionXOffset(i), y + (fontheight * i), Stringtable.Localize(optionName(i)), DTA_VirtualWidth, destWidth, DTA_VirtualHeight, destHeight, DTA_KeepRatio, true, DTA_ScaleX, NotifyFontScale, DTA_ScaleY, NotifyFontScale);
|
||||
}
|
||||
|
||||
if (messageSelection >= 0)
|
||||
{
|
||||
if ((MenuTime() % 8) < 6)
|
||||
{
|
||||
screen.DrawText(arrowFont, OptionMenuSettings.mFontColorSelection,
|
||||
(destWidth/2 - 11) + OptionXOffset(messageSelection), y + fontheight * messageSelection, selector, DTA_VirtualWidth, destWidth, DTA_VirtualHeight, destHeight, DTA_KeepRatio, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
protected void CloseSound()
|
||||
{
|
||||
MenuSound (GetCurrentMenu() != NULL? "menu/backup" : "menu/dismiss");
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
abstract void HandleResult(int index); // -1 = escape
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
override bool OnUIEvent(UIEvent ev)
|
||||
{
|
||||
if (ev.type == UIEvent.Type_KeyDown)
|
||||
{
|
||||
// tolower
|
||||
int ch = ev.KeyChar;
|
||||
ch = ch >= 65 && ch <91? ch + 32 : ch;
|
||||
|
||||
bool activate;
|
||||
int opt = optionForShortcut(ch,activate);
|
||||
|
||||
if(opt >= 0){
|
||||
if(activate || opt == messageSelection) {
|
||||
HandleResult(messageSelection);
|
||||
} else {
|
||||
messageSelection = opt;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return Super.OnUIEvent(ev);
|
||||
}
|
||||
|
||||
override bool OnInputEvent(InputEvent ev)
|
||||
{
|
||||
if (ev.type == InputEvent.Type_KeyDown)
|
||||
{
|
||||
Close();
|
||||
return true;
|
||||
}
|
||||
return Super.OnInputEvent(ev);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
override bool MenuEvent(int mkey, bool fromcontroller)
|
||||
{
|
||||
if (mkey == MKEY_Up)
|
||||
{
|
||||
MenuSound("menu/cursor");
|
||||
if (messageSelection == 0) messageSelection = optionCount();
|
||||
messageSelection--;
|
||||
return true;
|
||||
}
|
||||
else if (mkey == MKEY_Down)
|
||||
{
|
||||
MenuSound("menu/cursor");
|
||||
messageSelection++;
|
||||
if (messageSelection == optionCount()) messageSelection = 0;
|
||||
return true;
|
||||
}
|
||||
else if (mkey == MKEY_Enter)
|
||||
{
|
||||
HandleResult(messageSelection);
|
||||
return true;
|
||||
}
|
||||
else if (mkey == MKEY_Back)
|
||||
{
|
||||
HandleResult(-1);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
override bool MouseEvent(int type, int x, int y)
|
||||
{
|
||||
int fh = textFont.GetHeight() + 1;
|
||||
|
||||
// convert x/y from screen to virtual coordinates, according to CleanX/Yfac use in DrawTexture
|
||||
x = x * destWidth / screen.GetWidth();
|
||||
y = y * destHeight / screen.GetHeight();
|
||||
|
||||
int n = OptionCount();
|
||||
|
||||
if (x >= mMouseLeft && x <= mMouseRight && y >= mMouseY && y < mMouseY + (n * fh))
|
||||
{
|
||||
messageSelection = (y - mMouseY) / fh;
|
||||
}
|
||||
if (type == MOUSE_Release)
|
||||
{
|
||||
return MenuEvent(MKEY_Enter, true);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -41,6 +41,8 @@ class ImageScrollerDescriptor : MenuDescriptor native
|
|||
native double textScale;
|
||||
native bool mAnimatedTransition;
|
||||
native bool mAnimated;
|
||||
native bool mDontBlur;
|
||||
native bool mDontDim;
|
||||
native int virtWidth, virtHeight;
|
||||
}
|
||||
|
||||
|
@ -168,8 +170,10 @@ class ImageScrollerMenu : Menu
|
|||
mParentMenu = parent;
|
||||
index = 0;
|
||||
mDesc = desc;
|
||||
AnimatedTransition = desc.mAnimatedTransition;
|
||||
Animated = desc.mAnimated;
|
||||
AnimatedTransition = mDesc.mAnimatedTransition;
|
||||
Animated = mDesc.mAnimated;
|
||||
DontBlur = mDesc.mDontBlur;
|
||||
DontDim = mDesc.mDontDim;
|
||||
current = mDesc.mItems[0];
|
||||
current.onStartPage();
|
||||
previous = null;
|
||||
|
|
|
@ -57,6 +57,8 @@ class ListMenuDescriptor : MenuDescriptor native
|
|||
native bool mCenter;
|
||||
native bool mAnimatedTransition;
|
||||
native bool mAnimated;
|
||||
native bool mDontBlur;
|
||||
native bool mDontDim;
|
||||
native int mVirtWidth, mVirtHeight;
|
||||
|
||||
native void Reset();
|
||||
|
@ -89,6 +91,8 @@ class ListMenu : Menu
|
|||
mDesc = desc;
|
||||
AnimatedTransition = mDesc.mAnimatedTransition;
|
||||
Animated = mDesc.mAnimated;
|
||||
DontBlur = mDesc.mDontBlur;
|
||||
DontDim = mDesc.mDontDim;
|
||||
if (desc.mCenter)
|
||||
{
|
||||
double center = 160;
|
||||
|
|
|
@ -55,6 +55,9 @@ class OptionMenuDescriptor : MenuDescriptor native
|
|||
native int mIndent;
|
||||
native int mPosition;
|
||||
native bool mDontDim;
|
||||
native bool mDontBlur;
|
||||
native bool mAnimatedTransition;
|
||||
native bool mAnimated;
|
||||
native Font mFont;
|
||||
|
||||
void Reset()
|
||||
|
@ -106,6 +109,9 @@ class OptionMenu : Menu
|
|||
mParentMenu = parent;
|
||||
mDesc = desc;
|
||||
DontDim = desc.mDontDim;
|
||||
DontBlur = desc.mDontBlur;
|
||||
AnimatedTransition = desc.mAnimatedTransition;
|
||||
Animated = desc.mAnimated;
|
||||
|
||||
let itemCount = mDesc.mItems.size();
|
||||
if (itemCount > 0)
|
||||
|
|
Loading…
Reference in a new issue