From 7efe72aced60fa1bc30a281390d1dfab5abb32a7 Mon Sep 17 00:00:00 2001 From: Jeff Hutchinson Date: Thu, 2 Sep 2021 22:21:00 -0400 Subject: [PATCH] More fixes with xyz lookup, and some cleanup and test cases. --- Engine/source/console/compiledEval.cpp | 81 +++++------------------ Engine/source/console/test/ScriptTest.cpp | 42 +++++++++++- 2 files changed, 59 insertions(+), 64 deletions(-) diff --git a/Engine/source/console/compiledEval.cpp b/Engine/source/console/compiledEval.cpp index 99e5a633a..b3f8bebc7 100644 --- a/Engine/source/console/compiledEval.cpp +++ b/Engine/source/console/compiledEval.cpp @@ -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: diff --git a/Engine/source/console/test/ScriptTest.cpp b/Engine/source/console/test/ScriptTest.cpp index fefdf446d..cce1e6824 100644 --- a/Engine/source/console/test/ScriptTest.cpp +++ b/Engine/source/console/test/ScriptTest.cpp @@ -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