mirror of
https://github.com/ZDoom/gzdoom.git
synced 2025-01-19 08:01:50 +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(SetNull)
|
||||
xx(Key)
|
||||
xx(Index)
|
||||
xx(Find)
|
||||
|
||||
// color channels
|
||||
xx(a)
|
||||
|
|
|
@ -8505,6 +8505,11 @@ FxExpression *FxMemberFunctionCall::Resolve(FCompileContext& ctx)
|
|||
}
|
||||
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;
|
||||
Self->ValueType = static_cast<PDynArray*>(Self->ValueType)->BackingType;
|
||||
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)
|
||||
: ElementType(etype), BackingType(backing)
|
||||
{
|
||||
mDescriptiveName.Format("DynArray<%s>", etype->DescriptiveName());
|
||||
Size = sizeof(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)
|
||||
: KeyType(keytype), ValueType(valtype), BackingType(backing), BackingClass((decltype(BackingClass)) backing_class)
|
||||
{
|
||||
mDescriptiveName.Format("Map<%s, %s>", keytype->DescriptiveName(), valtype->DescriptiveName());
|
||||
Size = sizeof(ZSFMap);
|
||||
Align = alignof(ZSFMap);
|
||||
CreateOverrideFunction<PMap, OFN_RET_VAL , OFN_ARG_KEY > (this, NAME_Get);
|
||||
CreateOverrideFunction<PMap, OFN_RET_VAL , OFN_ARG_KEY > (this, NAME_GetIfExists);
|
||||
CreateOverrideFunction<PMap, OFN_RET_BOOL , OFN_ARG_KEY > (this, NAME_CheckKey);
|
||||
CreateOverrideFunction<PMap, OFN_RET_VAL_BOOL , OFN_ARG_KEY > (this, NAME_CheckValue);
|
||||
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);
|
||||
CreateOverrideFunction< OFN_RET_VAL , OFN_ARG_KEY > (this, NAME_Get);
|
||||
CreateOverrideFunction< OFN_RET_VAL , OFN_ARG_KEY > (this, NAME_GetIfExists);
|
||||
CreateOverrideFunction< OFN_RET_BOOL , OFN_ARG_KEY > (this, NAME_CheckKey);
|
||||
CreateOverrideFunction< OFN_RET_VAL_BOOL , OFN_ARG_KEY > (this, NAME_CheckValue);
|
||||
CreateOverrideFunction< OFN_RET_VOID , OFN_ARG_KEY_VAL > (this, NAME_Insert);
|
||||
CreateOverrideFunction< OFN_RET_VOID , OFN_ARG_KEY > (this, NAME_InsertNew);
|
||||
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());
|
||||
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);
|
||||
CreateOverrideFunction<OFN_RET_KEY, OFN_ARG_VOID>(this, NAME_GetKey);
|
||||
CreateOverrideFunction<OFN_RET_VAL, OFN_ARG_VOID>(this, NAME_GetValue);
|
||||
CreateOverrideFunction<OFN_RET_VOID, OFN_ARG_VAL>(this, NAME_SetValue);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
@ -512,6 +512,8 @@ public:
|
|||
PType *ElementType;
|
||||
PStruct *BackingType;
|
||||
|
||||
TMap<FName,PFunction*> FnOverrides;
|
||||
|
||||
bool IsMatch(intptr_t id1, intptr_t id2) const override;
|
||||
void GetTypeIDs(intptr_t &id1, intptr_t &id2) const override;
|
||||
|
||||
|
|
Loading…
Reference in a new issue