mirror of
https://github.com/ZDoom/gzdoom.git
synced 2025-01-31 13:50:48 +00:00
Extend pseudo-generics system used by maps to dynarrays
This commit is contained in:
parent
e29011ecde
commit
569263efe9
4 changed files with 121 additions and 87 deletions
|
@ -187,6 +187,8 @@ xx(Exists)
|
||||||
xx(SetInvalid)
|
xx(SetInvalid)
|
||||||
xx(SetNull)
|
xx(SetNull)
|
||||||
xx(Key)
|
xx(Key)
|
||||||
|
xx(Index)
|
||||||
|
xx(Find)
|
||||||
|
|
||||||
// color channels
|
// color channels
|
||||||
xx(a)
|
xx(a)
|
||||||
|
|
|
@ -8505,6 +8505,11 @@ FxExpression *FxMemberFunctionCall::Resolve(FCompileContext& ctx)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (PFunction **Override; ctx.Version >= MakeVersion(4, 11, 0) && (Override = static_cast<PDynArray*>(Self->ValueType)->FnOverrides.CheckKey(MethodName)))
|
||||||
|
{
|
||||||
|
afd_override = *Override;
|
||||||
|
}
|
||||||
|
|
||||||
auto elementType = static_cast<PDynArray*>(Self->ValueType)->ElementType;
|
auto elementType = static_cast<PDynArray*>(Self->ValueType)->ElementType;
|
||||||
Self->ValueType = static_cast<PDynArray*>(Self->ValueType)->BackingType;
|
Self->ValueType = static_cast<PDynArray*>(Self->ValueType)->BackingType;
|
||||||
bool isDynArrayObj = elementType->isObjectPointer();
|
bool isDynArrayObj = elementType->isObjectPointer();
|
||||||
|
|
|
@ -1985,12 +1985,114 @@ PStaticArray *NewStaticArray(PType *type)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
|
enum OverrideFunctionRetType {
|
||||||
|
OFN_RET_VOID,
|
||||||
|
OFN_RET_VAL,
|
||||||
|
OFN_RET_KEY,
|
||||||
|
OFN_RET_BOOL,
|
||||||
|
OFN_RET_VAL_BOOL,
|
||||||
|
OFN_RET_INT,
|
||||||
|
};
|
||||||
|
enum OverrideFunctionArgType {
|
||||||
|
OFN_ARG_VOID,
|
||||||
|
OFN_ARG_KEY,
|
||||||
|
OFN_ARG_VAL,
|
||||||
|
OFN_ARG_KEY_VAL,
|
||||||
|
OFN_ARG_ELEM,
|
||||||
|
OFN_ARG_INT_ELEM,
|
||||||
|
};
|
||||||
|
|
||||||
|
template<OverrideFunctionRetType RetType, OverrideFunctionArgType ArgType , class MT>
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
else if constexpr(RetType == OFN_RET_VAL_BOOL)
|
||||||
|
{
|
||||||
|
ret.Push(self->ValueType);
|
||||||
|
ret.Push(TypeBool);
|
||||||
|
}
|
||||||
|
else if constexpr(RetType == OFN_RET_INT)
|
||||||
|
{
|
||||||
|
ret.Push(TypeSInt32);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
else if constexpr(ArgType == OFN_ARG_ELEM)
|
||||||
|
{
|
||||||
|
args.Push(self->ElementType);
|
||||||
|
argflags.Push(0);
|
||||||
|
argnames.Push(NAME_Item);
|
||||||
|
}
|
||||||
|
else if constexpr(ArgType == OFN_ARG_INT_ELEM)
|
||||||
|
{
|
||||||
|
args.Push(TypeSInt32);
|
||||||
|
args.Push(self->ElementType);
|
||||||
|
argflags.Push(0);
|
||||||
|
argflags.Push(0);
|
||||||
|
argnames.Push(NAME_Index);
|
||||||
|
argnames.Push(NAME_Item);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
PDynArray::PDynArray(PType *etype,PStruct *backing)
|
PDynArray::PDynArray(PType *etype,PStruct *backing)
|
||||||
: ElementType(etype), BackingType(backing)
|
: ElementType(etype), BackingType(backing)
|
||||||
{
|
{
|
||||||
mDescriptiveName.Format("DynArray<%s>", etype->DescriptiveName());
|
mDescriptiveName.Format("DynArray<%s>", etype->DescriptiveName());
|
||||||
Size = sizeof(FArray);
|
Size = sizeof(FArray);
|
||||||
Align = alignof(FArray);
|
Align = alignof(FArray);
|
||||||
|
CreateOverrideFunction<OFN_RET_INT , OFN_ARG_ELEM > (this, NAME_Find);
|
||||||
|
CreateOverrideFunction<OFN_RET_INT , OFN_ARG_ELEM > (this, NAME_Push);
|
||||||
|
CreateOverrideFunction<OFN_RET_VOID , OFN_ARG_INT_ELEM > (this, NAME_Insert);
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -2226,96 +2328,19 @@ PDynArray *NewDynArray(PType *type)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
enum OverrideFunctionRetType {
|
|
||||||
OFN_RET_VOID,
|
|
||||||
OFN_RET_VAL,
|
|
||||||
OFN_RET_KEY,
|
|
||||||
OFN_RET_BOOL,
|
|
||||||
OFN_RET_VAL_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);
|
|
||||||
}
|
|
||||||
else if constexpr(RetType == OFN_RET_VAL_BOOL)
|
|
||||||
{
|
|
||||||
ret.Push(self->ValueType);
|
|
||||||
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)
|
PMap::PMap(PType *keytype, PType *valtype, PStruct *backing, int backing_class)
|
||||||
: KeyType(keytype), ValueType(valtype), BackingType(backing), BackingClass((decltype(BackingClass)) backing_class)
|
: KeyType(keytype), ValueType(valtype), BackingType(backing), BackingClass((decltype(BackingClass)) backing_class)
|
||||||
{
|
{
|
||||||
mDescriptiveName.Format("Map<%s, %s>", keytype->DescriptiveName(), valtype->DescriptiveName());
|
mDescriptiveName.Format("Map<%s, %s>", keytype->DescriptiveName(), valtype->DescriptiveName());
|
||||||
Size = sizeof(ZSFMap);
|
Size = sizeof(ZSFMap);
|
||||||
Align = alignof(ZSFMap);
|
Align = alignof(ZSFMap);
|
||||||
CreateOverrideFunction<PMap, OFN_RET_VAL , OFN_ARG_KEY > (this, NAME_Get);
|
CreateOverrideFunction< OFN_RET_VAL , OFN_ARG_KEY > (this, NAME_Get);
|
||||||
CreateOverrideFunction<PMap, OFN_RET_VAL , OFN_ARG_KEY > (this, NAME_GetIfExists);
|
CreateOverrideFunction< OFN_RET_VAL , OFN_ARG_KEY > (this, NAME_GetIfExists);
|
||||||
CreateOverrideFunction<PMap, OFN_RET_BOOL , OFN_ARG_KEY > (this, NAME_CheckKey);
|
CreateOverrideFunction< OFN_RET_BOOL , OFN_ARG_KEY > (this, NAME_CheckKey);
|
||||||
CreateOverrideFunction<PMap, OFN_RET_VAL_BOOL , OFN_ARG_KEY > (this, NAME_CheckValue);
|
CreateOverrideFunction< OFN_RET_VAL_BOOL , OFN_ARG_KEY > (this, NAME_CheckValue);
|
||||||
CreateOverrideFunction<PMap, OFN_RET_VOID , OFN_ARG_KEY_VAL > (this, NAME_Insert);
|
CreateOverrideFunction< OFN_RET_VOID , OFN_ARG_KEY_VAL > (this, NAME_Insert);
|
||||||
CreateOverrideFunction<PMap, OFN_RET_VOID , OFN_ARG_KEY > (this, NAME_InsertNew);
|
CreateOverrideFunction< OFN_RET_VOID , OFN_ARG_KEY > (this, NAME_InsertNew);
|
||||||
CreateOverrideFunction<PMap, OFN_RET_VOID , OFN_ARG_KEY > (this, NAME_Remove);
|
CreateOverrideFunction< OFN_RET_VOID , OFN_ARG_KEY > (this, NAME_Remove);
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -2777,9 +2802,9 @@ PMapIterator::PMapIterator(PType *keytype, PType *valtype, PStruct *backing, int
|
||||||
mDescriptiveName.Format("MapIterator<%s, %s>", keytype->DescriptiveName(), valtype->DescriptiveName());
|
mDescriptiveName.Format("MapIterator<%s, %s>", keytype->DescriptiveName(), valtype->DescriptiveName());
|
||||||
Size = sizeof(ZSFMap);
|
Size = sizeof(ZSFMap);
|
||||||
Align = alignof(ZSFMap);
|
Align = alignof(ZSFMap);
|
||||||
CreateOverrideFunction<PMapIterator, OFN_RET_KEY, OFN_ARG_VOID>(this, NAME_GetKey);
|
CreateOverrideFunction<OFN_RET_KEY, OFN_ARG_VOID>(this, NAME_GetKey);
|
||||||
CreateOverrideFunction<PMapIterator, OFN_RET_VAL, OFN_ARG_VOID>(this, NAME_GetValue);
|
CreateOverrideFunction<OFN_RET_VAL, OFN_ARG_VOID>(this, NAME_GetValue);
|
||||||
CreateOverrideFunction<PMapIterator, OFN_RET_VOID, OFN_ARG_VAL>(this, NAME_SetValue);
|
CreateOverrideFunction<OFN_RET_VOID, OFN_ARG_VAL>(this, NAME_SetValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
|
@ -512,6 +512,8 @@ public:
|
||||||
PType *ElementType;
|
PType *ElementType;
|
||||||
PStruct *BackingType;
|
PStruct *BackingType;
|
||||||
|
|
||||||
|
TMap<FName,PFunction*> FnOverrides;
|
||||||
|
|
||||||
bool IsMatch(intptr_t id1, intptr_t id2) const override;
|
bool IsMatch(intptr_t id1, intptr_t id2) const override;
|
||||||
void GetTypeIDs(intptr_t &id1, intptr_t &id2) const override;
|
void GetTypeIDs(intptr_t &id1, intptr_t &id2) const override;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue