More fixes with xyz lookup, and some cleanup and test cases.

This commit is contained in:
Jeff Hutchinson 2021-09-02 22:21:00 -04:00
parent b0549118b6
commit 7efe72aced
2 changed files with 59 additions and 64 deletions

View file

@ -164,16 +164,11 @@ namespace Con
}
}
// Gets a component of an object's field value or a variable and returns it
// in val.
static void getFieldComponent(SimObject* object, StringTableEntry field, const char* array, StringTableEntry subField, char val[], S32 currentLocalRegister)
static void getFieldComponent(StringTableEntry subField, char val[], S32 currentLocalRegister)
{
const char* prevVal = NULL;
// Grab value from object.
if (object && field)
prevVal = object->getDataField(field, array);
else if (currentLocalRegister != -1)
if (currentLocalRegister != -1)
prevVal = gEvalState.getLocalStringVariable(currentLocalRegister);
else if (gEvalState.currentVariable)
prevVal = gEvalState.getStringVariable();
@ -197,22 +192,15 @@ static void getFieldComponent(SimObject* object, StringTableEntry field, const c
StringTable->insert("a")
};
static const StringTableEntry uvw[] =
{
StringTable->insert("u"),
StringTable->insert("v"),
StringTable->insert("w")
};
// Translate xyzw and rgba into the indexed component
// of the variable or field.
if (subField == xyzw[0] || subField == rgba[0] || subField == uvw[0])
if (subField == xyzw[0] || subField == rgba[0])
dStrcpy(val, StringUnit::getUnit(prevVal, 0, " \t\n"), 128);
else if (subField == xyzw[1] || subField == rgba[1] || subField == uvw[1])
else if (subField == xyzw[1] || subField == rgba[1])
dStrcpy(val, StringUnit::getUnit(prevVal, 1, " \t\n"), 128);
else if (subField == xyzw[2] || subField == rgba[2] || subField == uvw[2])
else if (subField == xyzw[2] || subField == rgba[2])
dStrcpy(val, StringUnit::getUnit(prevVal, 2, " \t\n"), 128);
else if (subField == xyzw[3] || subField == rgba[3])
@ -225,9 +213,7 @@ static void getFieldComponent(SimObject* object, StringTableEntry field, const c
val[0] = 0;
}
// Sets a component of an object's field value based on the sub field. 'x' will
// set the first field, 'y' the second, and 'z' the third.
static void setFieldComponent(SimObject* object, StringTableEntry field, const char* array, StringTableEntry subField, S32 currentLocalRegister)
static void setFieldComponent(StringTableEntry subField, S32 currentLocalRegister)
{
// Copy the current string value
char strValue[1024];
@ -236,10 +222,7 @@ static void setFieldComponent(SimObject* object, StringTableEntry field, const c
char val[1024] = "";
const char* prevVal = NULL;
// Set the value on an object field.
if (object && field)
prevVal = object->getDataField(field, array);
else if (currentLocalRegister != -1)
if (currentLocalRegister != -1)
prevVal = gEvalState.getLocalStringVariable(currentLocalRegister);
// Set the value on a variable.
else if (gEvalState.currentVariable)
@ -282,9 +265,7 @@ static void setFieldComponent(SimObject* object, StringTableEntry field, const c
if (val[0] != 0)
{
// Update the field or variable.
if (object && field)
object->setDataField(field, 0, val);
else if (currentLocalRegister != -1)
if (currentLocalRegister != -1)
gEvalState.setLocalStringVariable(currentLocalRegister, val, dStrlen(val));
else if (gEvalState.currentVariable)
gEvalState.setStringVariable(val);
@ -740,9 +721,7 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa
} objectCreationStack[objectCreationStackSize];
SimObject* currentNewObject = 0;
StringTableEntry prevField = NULL;
StringTableEntry curField = NULL;
SimObject* prevObject = NULL;
SimObject* curObject = NULL;
SimObject* saveObject = NULL;
Namespace::Entry* nsEntry;
@ -1410,6 +1389,7 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa
case OP_INC:
reg = code[ip++];
currentRegister = reg;
gEvalState.setLocalFloatVariable(reg, gEvalState.getLocalFloatVariable(reg) + 1.0);
break;
@ -1420,8 +1400,6 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa
// If a variable is set, then these must be NULL. It is necessary
// to set this here so that the vector parser can appropriately
// identify whether it's dealing with a vector.
prevField = NULL;
prevObject = NULL;
curObject = NULL;
// Used for local variable caching of what is active...when we
@ -1442,8 +1420,6 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa
ip += 2;
// See OP_SETCURVAR
prevField = NULL;
prevObject = NULL;
curObject = NULL;
// Used for local variable caching of what is active...when we
@ -1461,8 +1437,6 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa
var = StringTable->insert(stack[_STK].getString());
// See OP_SETCURVAR
prevField = NULL;
prevObject = NULL;
curObject = NULL;
// Used for local variable caching of what is active...when we
@ -1480,8 +1454,6 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa
var = StringTable->insert(stack[_STK].getString());
// See OP_SETCURVAR
prevField = NULL;
prevObject = NULL;
curObject = NULL;
// Used for local variable caching of what is active...when we
@ -1549,25 +1521,25 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa
case OP_SAVE_LOCAL_VAR_UINT:
reg = code[ip++];
currentRegister = reg;
gEvalState.setLocalIntVariable(reg, stack[_STK].getInt());
break;
case OP_SAVE_LOCAL_VAR_FLT:
reg = code[ip++];
currentRegister = reg;
gEvalState.setLocalFloatVariable(reg, stack[_STK].getFloat());
break;
case OP_SAVE_LOCAL_VAR_STR:
reg = code[ip++];
val = stack[_STK].getString();
currentRegister = reg;
gEvalState.setLocalStringVariable(reg, val, (S32)dStrlen(val));
break;
case OP_SETCUROBJECT:
// Save the previous object for parsing vector fields.
prevObject = curObject;
val = stack[_STK].getString();
//_STK--;
// Sim::findObject will sometimes find valid objects from
// multi-component strings. This makes sure that doesn't
@ -1613,8 +1585,6 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa
break;
case OP_SETCURFIELD:
// Save the previous field for parsing vector fields.
prevField = curField;
dStrcpy(prevFieldArray, curFieldArray, 256);
curField = CodeToSTE(code, ip);
curFieldArray[0] = 0;
@ -1640,7 +1610,7 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa
// a special accessor?
char buff[FieldBufferSizeNumeric];
memset(buff, 0, sizeof(buff));
getFieldComponent(prevObject, prevField, prevFieldArray, curField, buff, currentRegister);
getFieldComponent(curField, buff, currentRegister);
stack[_STK + 1].setInt(dAtol(buff));
}
_STK++;
@ -1655,7 +1625,7 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa
// a special accessor?
char buff[FieldBufferSizeNumeric];
memset(buff, 0, sizeof(buff));
getFieldComponent(prevObject, prevField, prevFieldArray, curField, buff, currentRegister);
getFieldComponent(curField, buff, currentRegister);
stack[_STK + 1].setFloat(dAtod(buff));
}
_STK++;
@ -1673,7 +1643,7 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa
// a special accessor?
char buff[FieldBufferSizeString];
memset(buff, 0, sizeof(buff));
getFieldComponent(prevObject, prevField, prevFieldArray, curField, buff, currentRegister);
getFieldComponent(curField, buff, currentRegister);
stack[_STK + 1].setString(buff);
}
_STK++;
@ -1683,36 +1653,21 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa
if (curObject)
curObject->setDataField(curField, curFieldArray, stack[_STK].getString());
else
{
// The field is not being set on an object. Maybe it's
// a special accessor?
setFieldComponent( prevObject, prevField, prevFieldArray, curField, currentRegister );
prevObject = NULL;
}
setFieldComponent( curField, currentRegister );
break;
case OP_SAVEFIELD_FLT:
if (curObject)
curObject->setDataField(curField, curFieldArray, stack[_STK].getString());
else
{
// The field is not being set on an object. Maybe it's
// a special accessor?
setFieldComponent( prevObject, prevField, prevFieldArray, curField, currentRegister );
prevObject = NULL;
}
setFieldComponent( curField, currentRegister );
break;
case OP_SAVEFIELD_STR:
if (curObject)
curObject->setDataField(curField, curFieldArray, stack[_STK].getString());
else
{
// The field is not being set on an object. Maybe it's
// a special accessor?
setFieldComponent( prevObject, prevField, prevFieldArray, curField, currentRegister );
prevObject = NULL;
}
setFieldComponent( curField, currentRegister );
break;
case OP_POP_STK:

View file

@ -807,7 +807,6 @@ TEST(Script, Sugar_Syntax)
%extent = 10 SPC 20;
%scaling = 1;
%size = %extent.x * %scaling;
echo("%size = " @ %size @ " calculated = " @ (%extent.x * %scaling));
return %size;
}
@ -815,6 +814,25 @@ TEST(Script, Sugar_Syntax)
)");
ASSERT_EQ(valueStoreCalculated.getInt(), 10);
ConsoleValue globalValueGet = RunScript(R"(
new SimObject(AAAA);
AAAA.doSomething = false;
$vec = "1 2 3";
return $vec.x * 4;
)");
ASSERT_EQ(globalValueGet.getFloat(), 4);
ConsoleValue globalValueSet = RunScript(R"(
new SimObject(AAAAB);
AAAAB.doSomething = false;
$vec2 = "1 2 3";
$vec2.x *= 4;
return $vec2.x;
)");
ASSERT_EQ(globalValueSet.getFloat(), 4);
}
TEST(Script, InnerObjectTests)
@ -871,4 +889,26 @@ TEST(Script, InnerObjectTests)
ASSERT_EQ(nestedFuncCall.getInt(), 123);
}
TEST(Script, MiscRegressions)
{
ConsoleValue regression1 = RunScript(R"(
new SimObject(TheRegressionObject);
function doTest()
{
TheRegressionObject.hidden = false;
%previewSize = 100 SPC 100;
%previewScaleSize = 2;
%size = %previewSize.x * %previewScaleSize;
return %size;
}
return doTest();
)");
ASSERT_EQ(regression1.getInt(), 200);
}
#endif