Skip to content

Commit

Permalink
Extend pseudo-generics system used by maps to dynarrays
Browse files Browse the repository at this point in the history
  • Loading branch information
RicardoLuis0 authored and coelckers committed Feb 9, 2023
1 parent e29011e commit 569263e
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 87 deletions.
2 changes: 2 additions & 0 deletions src/common/engine/namedef.h
Expand Up @@ -187,6 +187,8 @@ xx(Exists)
xx(SetInvalid)
xx(SetNull)
xx(Key)
xx(Index)
xx(Find)

// color channels
xx(a)
Expand Down
5 changes: 5 additions & 0 deletions src/common/scripting/backend/codegen.cpp
Expand Up @@ -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();
Expand Down
199 changes: 112 additions & 87 deletions src/common/scripting/core/types.cpp
Expand Up @@ -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);
}

//==========================================================================
Expand Down Expand Up @@ -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);
}

//==========================================================================
Expand Down Expand Up @@ -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);
}

//==========================================================================
Expand Down
2 changes: 2 additions & 0 deletions src/common/scripting/core/types.h
Expand Up @@ -512,6 +512,8 @@ class PDynArray : public PCompoundType
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;

Expand Down

0 comments on commit 569263e

Please sign in to comment.