mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-25 05:31:00 +00:00
- made GetClassName an intrinsic and expanded it to also work on class types.
This commit is contained in:
parent
1135f154b7
commit
92acbdc625
5 changed files with 87 additions and 15 deletions
|
@ -612,12 +612,6 @@ void DObject::CheckIfSerialized () const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
DEFINE_ACTION_FUNCTION(DObject, GetClassName)
|
|
||||||
{
|
|
||||||
PARAM_SELF_PROLOGUE(DObject);
|
|
||||||
ACTION_RETURN_INT(self->GetClass()->TypeName);
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_ACTION_FUNCTION(DObject, MSTime)
|
DEFINE_ACTION_FUNCTION(DObject, MSTime)
|
||||||
{
|
{
|
||||||
ACTION_RETURN_INT(I_MSTime());
|
ACTION_RETURN_INT(I_MSTime());
|
||||||
|
|
|
@ -335,6 +335,7 @@ xx(RandomPick)
|
||||||
xx(FRandomPick)
|
xx(FRandomPick)
|
||||||
xx(GetClass)
|
xx(GetClass)
|
||||||
xx(GetParentClass)
|
xx(GetParentClass)
|
||||||
|
xx(GetClassName)
|
||||||
xx(GetDefaultByType)
|
xx(GetDefaultByType)
|
||||||
xx(Exp)
|
xx(Exp)
|
||||||
xx(Log10)
|
xx(Log10)
|
||||||
|
|
|
@ -7775,6 +7775,13 @@ FxExpression *FxFunctionCall::Resolve(FCompileContext& ctx)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case NAME_GetClassName:
|
||||||
|
if (CheckArgSize(NAME_GetClassName, ArgList, 0, 0, ScriptPosition))
|
||||||
|
{
|
||||||
|
func = new FxGetClassName(new FxSelf(ScriptPosition));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case NAME_GetDefaultByType:
|
case NAME_GetDefaultByType:
|
||||||
if (CheckArgSize(NAME_GetDefaultByType, ArgList, 1, 1, ScriptPosition))
|
if (CheckArgSize(NAME_GetDefaultByType, ArgList, 1, 1, ScriptPosition))
|
||||||
{
|
{
|
||||||
|
@ -8215,14 +8222,20 @@ FxExpression *FxMemberFunctionCall::Resolve(FCompileContext& ctx)
|
||||||
if (MethodName == NAME_GetParentClass &&
|
if (MethodName == NAME_GetParentClass &&
|
||||||
(Self->IsObject() || Self->ValueType->isClassPointer()))
|
(Self->IsObject() || Self->ValueType->isClassPointer()))
|
||||||
{
|
{
|
||||||
if (ArgList.Size() > 0)
|
if (CheckArgSize(NAME_GetParentClass, ArgList, 0, 0, ScriptPosition))
|
||||||
{
|
{
|
||||||
ScriptPosition.Message(MSG_ERROR, "too many parameters in call to %s", MethodName.GetChars());
|
auto x = new FxGetParentClass(Self);
|
||||||
delete this;
|
return x->Resolve(ctx);
|
||||||
return nullptr;
|
}
|
||||||
|
}
|
||||||
|
if (MethodName == NAME_GetClassName &&
|
||||||
|
(Self->IsObject() || Self->ValueType->isClassPointer()))
|
||||||
|
{
|
||||||
|
if (CheckArgSize(NAME_GetClassName, ArgList, 0, 0, ScriptPosition))
|
||||||
|
{
|
||||||
|
auto x = new FxGetClassName(Self);
|
||||||
|
return x->Resolve(ctx);
|
||||||
}
|
}
|
||||||
auto x = new FxGetParentClass(Self);
|
|
||||||
return x->Resolve(ctx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Self->ValueType->isRealPointer())
|
if (Self->ValueType->isRealPointer())
|
||||||
|
@ -9336,11 +9349,11 @@ FxExpression *FxGetParentClass::Resolve(FCompileContext &ctx)
|
||||||
|
|
||||||
if (!Self->ValueType->isClassPointer() && !Self->IsObject())
|
if (!Self->ValueType->isClassPointer() && !Self->IsObject())
|
||||||
{
|
{
|
||||||
ScriptPosition.Message(MSG_ERROR, "GetClass() requires an object");
|
ScriptPosition.Message(MSG_ERROR, "GetParentClass() requires an object");
|
||||||
delete this;
|
delete this;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
ValueType = NewClassPointer(RUNTIME_CLASS(DObject)); //
|
ValueType = NewClassPointer(RUNTIME_CLASS(DObject));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9365,6 +9378,52 @@ ExpEmit FxGetParentClass::Emit(VMFunctionBuilder *build)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
|
FxGetClassName::FxGetClassName(FxExpression *self)
|
||||||
|
:FxExpression(EFX_GetClassName, self->ScriptPosition)
|
||||||
|
{
|
||||||
|
Self = self;
|
||||||
|
}
|
||||||
|
|
||||||
|
FxGetClassName::~FxGetClassName()
|
||||||
|
{
|
||||||
|
SAFE_DELETE(Self);
|
||||||
|
}
|
||||||
|
|
||||||
|
FxExpression *FxGetClassName::Resolve(FCompileContext &ctx)
|
||||||
|
{
|
||||||
|
SAFE_RESOLVE(Self, ctx);
|
||||||
|
|
||||||
|
if (!Self->ValueType->isClassPointer() && !Self->IsObject())
|
||||||
|
{
|
||||||
|
ScriptPosition.Message(MSG_ERROR, "GetClassName() requires an object");
|
||||||
|
delete this;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
ValueType = TypeName;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
ExpEmit FxGetClassName::Emit(VMFunctionBuilder *build)
|
||||||
|
{
|
||||||
|
ExpEmit op = Self->Emit(build);
|
||||||
|
op.Free(build);
|
||||||
|
if (Self->IsObject())
|
||||||
|
{
|
||||||
|
ExpEmit to(build, REGT_POINTER);
|
||||||
|
build->Emit(OP_CLSS, to.RegNum, op.RegNum);
|
||||||
|
op = to;
|
||||||
|
op.Free(build);
|
||||||
|
}
|
||||||
|
ExpEmit to(build, REGT_INT);
|
||||||
|
build->Emit(OP_LW, to.RegNum, op.RegNum, build->GetConstantInt(myoffsetof(PClass, TypeName)));
|
||||||
|
return to;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
FxGetDefaultByType::FxGetDefaultByType(FxExpression *self)
|
FxGetDefaultByType::FxGetDefaultByType(FxExpression *self)
|
||||||
:FxExpression(EFX_GetDefaultByType, self->ScriptPosition)
|
:FxExpression(EFX_GetDefaultByType, self->ScriptPosition)
|
||||||
{
|
{
|
||||||
|
|
|
@ -296,6 +296,7 @@ enum EFxType
|
||||||
EFX_NamedNode,
|
EFX_NamedNode,
|
||||||
EFX_GetClass,
|
EFX_GetClass,
|
||||||
EFX_GetParentClass,
|
EFX_GetParentClass,
|
||||||
|
EFX_GetClassName,
|
||||||
EFX_StrLen,
|
EFX_StrLen,
|
||||||
EFX_ColorLiteral,
|
EFX_ColorLiteral,
|
||||||
EFX_GetDefaultByType,
|
EFX_GetDefaultByType,
|
||||||
|
@ -1660,6 +1661,24 @@ public:
|
||||||
ExpEmit Emit(VMFunctionBuilder *build);
|
ExpEmit Emit(VMFunctionBuilder *build);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// FxGetClass
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
class FxGetClassName : public FxExpression
|
||||||
|
{
|
||||||
|
FxExpression *Self;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
FxGetClassName(FxExpression *self);
|
||||||
|
~FxGetClassName();
|
||||||
|
FxExpression *Resolve(FCompileContext&);
|
||||||
|
ExpEmit Emit(VMFunctionBuilder *build);
|
||||||
|
};
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// FxGetDefaultByType
|
// FxGetDefaultByType
|
||||||
|
|
|
@ -342,7 +342,6 @@ class Object native
|
||||||
native static uint MSTime();
|
native static uint MSTime();
|
||||||
native vararg static void ThrowAbortException(String fmt, ...);
|
native vararg static void ThrowAbortException(String fmt, ...);
|
||||||
|
|
||||||
native Name GetClassName();
|
|
||||||
native virtualscope void Destroy();
|
native virtualscope void Destroy();
|
||||||
|
|
||||||
// This does not call into the native method of the same name to avoid problems with objects that get garbage collected late on shutdown.
|
// This does not call into the native method of the same name to avoid problems with objects that get garbage collected late on shutdown.
|
||||||
|
|
Loading…
Reference in a new issue