- added a compiler-side workaround for the formerly static methods of FLevelLocals.

LevelLocals on the left side of.a function call will now always be remapped to 'Level', which will either remap to the same-named instance variable or the global deprecated one.

In a few degenerate cases where there is a conflicting local variable named 'level' it may error out but that is unavoidable here but this is very unlikely.
This commit is contained in:
Christoph Oelckers 2019-01-29 02:04:31 +01:00
commit f9239f6e0f
8 changed files with 132 additions and 117 deletions

View file

@ -2607,7 +2607,7 @@ DEFINE_ACTION_FUNCTION(FLevelLocals, GetChecksum)
ACTION_RETURN_STRING((const char*)md5string);
}
static void Vec2Offset(double x, double y, double dx, double dy, bool absolute, DVector2 *result)
static void Vec2Offset(FLevelLocals *Level, double x, double y, double dx, double dy, bool absolute, DVector2 *result)
{
if (absolute)
{
@ -2615,24 +2615,24 @@ static void Vec2Offset(double x, double y, double dx, double dy, bool absolute,
}
else
{
*result = level.GetPortalOffsetPosition(x, y, dx, dy);
*result = Level->GetPortalOffsetPosition(x, y, dx, dy);
}
}
DEFINE_ACTION_FUNCTION_NATIVE(FLevelLocals, Vec2Offset, Vec2Offset)
{
PARAM_PROLOGUE;
PARAM_SELF_STRUCT_PROLOGUE(FLevelLocals);
PARAM_FLOAT(x);
PARAM_FLOAT(y);
PARAM_FLOAT(dx);
PARAM_FLOAT(dy);
PARAM_BOOL(absolute);
DVector2 result;
Vec2Offset(x, y, dx, dy, absolute, &result);
Vec2Offset(self, x, y, dx, dy, absolute, &result);
ACTION_RETURN_VEC2(result);
}
static void Vec2OffsetZ(double x, double y, double dx, double dy, double atz, bool absolute, DVector3 *result)
static void Vec2OffsetZ(FLevelLocals *Level, double x, double y, double dx, double dy, double atz, bool absolute, DVector3 *result)
{
if (absolute)
{
@ -2647,7 +2647,7 @@ static void Vec2OffsetZ(double x, double y, double dx, double dy, double atz, bo
DEFINE_ACTION_FUNCTION_NATIVE(FLevelLocals, Vec2OffsetZ, Vec2OffsetZ)
{
PARAM_PROLOGUE;
PARAM_SELF_STRUCT_PROLOGUE(FLevelLocals);
PARAM_FLOAT(x);
PARAM_FLOAT(y);
PARAM_FLOAT(dx);
@ -2655,11 +2655,11 @@ DEFINE_ACTION_FUNCTION_NATIVE(FLevelLocals, Vec2OffsetZ, Vec2OffsetZ)
PARAM_FLOAT(atz);
PARAM_BOOL(absolute);
DVector3 result;
Vec2OffsetZ(x, y, dx, dy, atz, absolute, &result);
Vec2OffsetZ(self, x, y, dx, dy, atz, absolute, &result);
ACTION_RETURN_VEC3(result);
}
static void Vec3Offset(double x, double y, double z, double dx, double dy, double dz, bool absolute, DVector3 *result)
static void Vec3Offset(FLevelLocals *Level, double x, double y, double z, double dx, double dy, double dz, bool absolute, DVector3 *result)
{
if (absolute)
{
@ -2667,14 +2667,14 @@ static void Vec3Offset(double x, double y, double z, double dx, double dy, doubl
}
else
{
DVector2 v = level.GetPortalOffsetPosition(x, y, dx, dy);
DVector2 v = Level->GetPortalOffsetPosition(x, y, dx, dy);
*result = (DVector3(v, z + dz));
}
}
DEFINE_ACTION_FUNCTION_NATIVE(FLevelLocals, Vec3Offset, Vec3Offset)
{
PARAM_PROLOGUE;
PARAM_SELF_STRUCT_PROLOGUE(FLevelLocals);
PARAM_FLOAT(x);
PARAM_FLOAT(y);
PARAM_FLOAT(z);
@ -2683,10 +2683,104 @@ DEFINE_ACTION_FUNCTION_NATIVE(FLevelLocals, Vec3Offset, Vec3Offset)
PARAM_FLOAT(dz);
PARAM_BOOL(absolute);
DVector3 result;
Vec3Offset(x, y, z, dx, dy, dz, absolute, &result);
Vec3Offset(self, x, y, z, dx, dy, dz, absolute, &result);
ACTION_RETURN_VEC3(result);
}
int IsPointInMap(FLevelLocals *Level, double x, double y, double z);
DEFINE_ACTION_FUNCTION_NATIVE(FLevelLocals, IsPointInLevel, IsPointInMap)
{
PARAM_SELF_STRUCT_PROLOGUE(FLevelLocals);
PARAM_FLOAT(x);
PARAM_FLOAT(y);
PARAM_FLOAT(z);
ACTION_RETURN_BOOL(IsPointInMap(self, x, y, z));
}
template <typename T>
inline T VecDiff(FLevelLocals *Level, const T& v1, const T& v2)
{
T result = v2 - v1;
if (Level->subsectors.Size() > 0)
{
const sector_t * sec1 = Level->PointInSector(v1);
const sector_t * sec2 = Level->PointInSector(v2);
if (nullptr != sec1 && nullptr != sec2)
{
result += Level->Displacements.getOffset(sec2->PortalGroup, sec1->PortalGroup);
}
}
return result;
}
void Vec2Diff(FLevelLocals *Level, double x1, double y1, double x2, double y2, DVector2 *result)
{
*result = VecDiff(Level, DVector2(x1, y1), DVector2(x2, y2));
}
DEFINE_ACTION_FUNCTION_NATIVE(FLevelLocals, Vec2Diff, Vec2Diff)
{
PARAM_SELF_STRUCT_PROLOGUE(FLevelLocals);
PARAM_FLOAT(x1);
PARAM_FLOAT(y1);
PARAM_FLOAT(x2);
PARAM_FLOAT(y2);
ACTION_RETURN_VEC2(VecDiff(self, DVector2(x1, y1), DVector2(x2, y2)));
}
void Vec3Diff(FLevelLocals *Level, double x1, double y1, double z1, double x2, double y2, double z2, DVector3 *result)
{
*result = VecDiff(Level, DVector3(x1, y1, z1), DVector3(x2, y2, z2));
}
DEFINE_ACTION_FUNCTION_NATIVE(FLevelLocals, Vec3Diff, Vec3Diff)
{
PARAM_SELF_STRUCT_PROLOGUE(FLevelLocals);
PARAM_FLOAT(x1);
PARAM_FLOAT(y1);
PARAM_FLOAT(z1);
PARAM_FLOAT(x2);
PARAM_FLOAT(y2);
PARAM_FLOAT(z2);
ACTION_RETURN_VEC3(VecDiff(self, DVector3(x1, y1, z1), DVector3(x2, y2, z2)));
}
void SphericalCoords(FLevelLocals *self, double vpX, double vpY, double vpZ, double tX, double tY, double tZ, double viewYaw, double viewPitch, int absolute, DVector3 *result)
{
DVector3 viewpoint(vpX, vpY, vpZ);
DVector3 target(tX, tY, tZ);
auto vecTo = absolute ? target - viewpoint : VecDiff(self, viewpoint, target);
*result = (DVector3(
deltaangle(vecTo.Angle(), viewYaw).Degrees,
deltaangle(vecTo.Pitch(), viewPitch).Degrees,
vecTo.Length()
));
}
DEFINE_ACTION_FUNCTION_NATIVE(FLevelLocals, SphericalCoords, SphericalCoords)
{
PARAM_SELF_STRUCT_PROLOGUE(FLevelLocals);
PARAM_FLOAT(viewpointX);
PARAM_FLOAT(viewpointY);
PARAM_FLOAT(viewpointZ);
PARAM_FLOAT(targetX);
PARAM_FLOAT(targetY);
PARAM_FLOAT(targetZ);
PARAM_FLOAT(viewYaw);
PARAM_FLOAT(viewPitch);
PARAM_BOOL(absolute);
DVector3 result;
SphericalCoords(self, viewpointX, viewpointY, viewpointZ, targetX, targetY, targetZ, viewYaw, viewpointZ, absolute, &result);
ACTION_RETURN_VEC3(result);
}
static int isFrozen(FLevelLocals *self)
{
return self->isFrozen();

View file

@ -3290,12 +3290,10 @@ static FxExpression *ModifyAssign(FxBinary *operation, FxExpression *left)
//
//==========================================================================
FxExpression *ZCCCompiler::ConvertNode(ZCC_TreeNode *ast)
FxExpression *ZCCCompiler::ConvertNode(ZCC_TreeNode *ast, bool substitute)
{
if (ast == nullptr) return nullptr;
// Note: Do not call 'Simplify' here because that function tends to destroy identifiers due to lack of context in which to resolve them.
// The Fx nodes created here will be better suited for that.
switch (ast->NodeType)
{
case AST_ExprFuncCall:
@ -3317,7 +3315,7 @@ FxExpression *ZCCCompiler::ConvertNode(ZCC_TreeNode *ast)
case AST_ExprMemberAccess:
{
auto ema = static_cast<ZCC_ExprMemberAccess *>(fcall->Function);
return new FxMemberFunctionCall(ConvertNode(ema->Left), ema->Right, ConvertNodeList(args, fcall->Parameters), *ast);
return new FxMemberFunctionCall(ConvertNode(ema->Left, true), ema->Right, ConvertNodeList(args, fcall->Parameters), *ast);
}
case AST_ExprBinary:
@ -3382,8 +3380,9 @@ FxExpression *ZCCCompiler::ConvertNode(ZCC_TreeNode *ast)
case AST_ExprID:
{
auto id = static_cast<ZCC_ExprID *>(ast);
return new FxIdentifier(id->Identifier, *ast);
auto id = static_cast<ZCC_ExprID *>(ast)->Identifier;
if (id == NAME_LevelLocals && substitute) id = NAME_Level; // All static methods of FLevelLocals are now non-static so remap the name right here before passing it to the backend.
return new FxIdentifier(id, *ast);
}
case AST_ExprConstant:

View file

@ -146,7 +146,7 @@ private:
void MessageV(ZCC_TreeNode *node, const char *txtcolor, const char *msg, va_list argptr);
FxExpression *ConvertAST(PContainerType *cclass, ZCC_TreeNode *ast);
FxExpression *ConvertNode(ZCC_TreeNode *node);
FxExpression *ConvertNode(ZCC_TreeNode *node, bool substitute= false);
FxExpression *ConvertImplicitScopeNode(ZCC_TreeNode *node, ZCC_Statement *nested);
FArgumentList &ConvertNodeList(FArgumentList &, ZCC_TreeNode *head);