@@ -163,6 +163,40 @@ namespace Con
163163 }
164164}
165165
166+ // ------------------------------------------------------------
167+ // Map a suffix character to a component index.
168+ static S32 tscriptSuffixMap (char c)
169+ {
170+ // store these off for case insensitive comparison
171+ static const StringTableEntry X = StringTable->insert (" x" );
172+ static const StringTableEntry Y = StringTable->insert (" y" );
173+ static const StringTableEntry Z = StringTable->insert (" z" );
174+ static const StringTableEntry W = StringTable->insert (" w" );
175+
176+ static const StringTableEntry R = StringTable->insert (" r" );
177+ static const StringTableEntry G = StringTable->insert (" g" );
178+ static const StringTableEntry B = StringTable->insert (" b" );
179+ static const StringTableEntry A = StringTable->insert (" a" );
180+
181+ static const StringTableEntry U = StringTable->insert (" u" );
182+ static const StringTableEntry V = StringTable->insert (" v" );
183+
184+ char suffix[2 ] = { c, 0 };
185+ StringTableEntry entry = StringTable->insert (suffix);
186+ // StringTabe table of the suffixes, and their mapped indexes.
187+ if (entry == X || entry == R || entry == U)
188+ return 0 ;
189+ if (entry == Y || entry == G || entry == V)
190+ return 1 ;
191+ if (entry == Z || entry == B)
192+ return 2 ;
193+ if (entry == W || entry == A)
194+ return 3 ;
195+
196+ return -1 ;
197+ }
198+
199+ // ------------------------------------------------------------
166200static void getFieldComponent (SimObject* object, StringTableEntry field, const char * array, StringTableEntry subField, char val[], S32 currentLocalRegister)
167201{
168202 const char * prevVal = NULL ;
@@ -173,42 +207,44 @@ static void getFieldComponent(SimObject* object, StringTableEntry field, const c
173207 prevVal = Script::gEvalState .getLocalStringVariable (currentLocalRegister);
174208 else if (Script::gEvalState .currentVariable )
175209 prevVal = Script::gEvalState .getStringVariable ();
210+ else if (*Script::gEvalState .getStringRet ())
211+ prevVal = Script::gEvalState .getStringRet ();
176212
177213 // Make sure we got a value.
178214 if (prevVal && *prevVal)
179215 {
180- static const StringTableEntry xyzw[] =
181- {
182- StringTable->insert (" x" ),
183- StringTable->insert (" y" ),
184- StringTable->insert (" z" ),
185- StringTable->insert (" w" )
186- };
187-
188- static const StringTableEntry rgba[] =
216+ const char * suffix = subField;
217+ S32 suffixLen = dStrlen (suffix);
218+ if (suffixLen == 1 )
189219 {
190- StringTable->insert (" r" ),
191- StringTable->insert (" g" ),
192- StringTable->insert (" b" ),
193- StringTable->insert (" a" )
194- };
195-
196- // Translate xyzw and rgba into the indexed component
197- // of the variable or field.
198- if (subField == xyzw[0 ] || subField == rgba[0 ])
199- dStrcpy (val, StringUnit::getUnit (prevVal, 0 , " \t\n " ), 128 );
200-
201- else if (subField == xyzw[1 ] || subField == rgba[1 ])
202- dStrcpy (val, StringUnit::getUnit (prevVal, 1 , " \t\n " ), 128 );
203-
204- else if (subField == xyzw[2 ] || subField == rgba[2 ])
205- dStrcpy (val, StringUnit::getUnit (prevVal, 2 , " \t\n " ), 128 );
206-
207- else if (subField == xyzw[3 ] || subField == rgba[3 ])
208- dStrcpy (val, StringUnit::getUnit (prevVal, 3 , " \t\n " ), 128 );
209-
220+ S32 id = tscriptSuffixMap (suffix[0 ]);
221+ if (id != -1 )
222+ dStrcpy (val, StringUnit::getUnit (prevVal, id, " \t\n " ), 128 );
223+ else
224+ val[0 ] = 0 ;
225+ return ;
226+ }
210227 else
211- val[0 ] = 0 ;
228+ {
229+ char outVal[128 ];
230+ outVal[0 ] = 0 ;
231+ for (S32 i = 0 ; i < suffixLen; i++)
232+ {
233+ S32 id = tscriptSuffixMap (suffix[i]);
234+ if (id == -1 )
235+ {
236+ val[0 ] = 0 ;
237+ return ;
238+ }
239+ const char * unit = StringUnit::getUnit (prevVal, id, " \t\n " );
240+ if (i > 0 )
241+ {
242+ dStrcat (outVal, " " , 128 );
243+ }
244+ dStrcat (outVal, unit, 128 );
245+ }
246+ dStrcpy (val, outVal, 128 );
247+ }
212248 }
213249 else
214250 val[0 ] = 0 ;
@@ -235,35 +271,46 @@ static void setFieldComponent(SimObject* object, StringTableEntry field, const c
235271 if (!prevVal)
236272 return ;
237273
238- static const StringTableEntry xyzw[] =
239- {
240- StringTable->insert (" x" ),
241- StringTable->insert (" y" ),
242- StringTable->insert (" z" ),
243- StringTable->insert (" w" )
244- };
274+ const char * suffix = subField;
275+ S32 suffixLen = dStrlen (suffix);
245276
246- static const StringTableEntry rgba[] =
277+ if (suffixLen == 1 )
247278 {
248- StringTable->insert (" r" ),
249- StringTable->insert (" g" ),
250- StringTable->insert (" b" ),
251- StringTable->insert (" a" )
252- };
279+ S32 id = tscriptSuffixMap (suffix[0 ]);
280+ if (id != -1 )
281+ dStrcpy (val, StringUnit::setUnit (prevVal, id, strValue, " \t\n " ), 1024 );
282+ }
283+ else
284+ {
285+ char outVal[1024 ];
286+ dStrcpy (outVal, prevVal, 1024 );
287+
288+ S32 unitCount = StringUnit::getUnitCount (strValue, " \t\n " );
289+
290+ for (S32 i = 0 ; i < suffixLen; i++)
291+ {
292+ S32 id = tscriptSuffixMap (suffix[i]);
293+ if (id == -1 )
294+ {
295+ return ;
296+ }
253297
254- // Insert the value into the specified
255- // component of the string.
256- if (subField == xyzw[0 ] || subField == rgba[0 ])
257- dStrcpy (val, StringUnit::setUnit (prevVal, 0 , strValue, " \t\n " ), 128 );
298+ const char * unit = StringUnit::getUnit (strValue, i, " \t\n " );
299+ if (!unit || !*unit)
300+ continue ;
258301
259- else if (subField == xyzw[ 1 ] || subField == rgba[ 1 ])
260- dStrcpy (val, StringUnit::setUnit (prevVal, 1 , strValue, " \t\n " ), 128 );
302+ dStrcpy (outVal, StringUnit::setUnit (outVal, id, unit , " \t\n " ), 1024 );
303+ }
261304
262- else if (subField == xyzw[2 ] || subField == rgba[2 ])
263- dStrcpy (val, StringUnit::setUnit (prevVal, 2 , strValue, " \t\n " ), 128 );
305+ if (unitCount != suffixLen)
306+ {
307+ Con::warnf (ConsoleLogEntry::General,
308+ " setFieldComponent: component count mismatch - suffix '%s' expects %d value(s), got %d ('%s')!" ,
309+ suffix, suffixLen, unitCount, strValue);
310+ }
264311
265- else if (subField == xyzw[ 3 ] || subField == rgba[ 3 ])
266- dStrcpy (val, StringUnit::setUnit (prevVal, 3 , strValue, " \t\n " ), 128 );
312+ dStrcpy (val, outVal, 1024 );
313+ }
267314
268315 if (val[0 ] != 0 )
269316 {
@@ -379,7 +426,6 @@ void ExprEvalState::setStringVariable(const char *val)
379426 AssertFatal (currentVariable != NULL , " Invalid evaluator state - trying to set null variable!" );
380427 currentVariable->setStringValue (val);
381428}
382-
383429// -----------------------------------------------------------------------------
384430
385431enum class FloatOperation
@@ -1501,6 +1547,7 @@ Con::EvalResult CodeBlock::exec(U32 ip, const char* functionName, Namespace* thi
15011547 prevField = NULL ;
15021548 prevObject = NULL ;
15031549 curObject = NULL ;
1550+ Script::gEvalState .clearRet ();
15041551
15051552 // Used for local variable caching of what is active...when we
15061553 // set a global, we aren't active
@@ -1523,6 +1570,7 @@ Con::EvalResult CodeBlock::exec(U32 ip, const char* functionName, Namespace* thi
15231570 prevField = NULL ;
15241571 prevObject = NULL ;
15251572 curObject = NULL ;
1573+ Script::gEvalState .clearRet ();
15261574
15271575 // Used for local variable caching of what is active...when we
15281576 // set a global, we aren't active
@@ -1542,6 +1590,7 @@ Con::EvalResult CodeBlock::exec(U32 ip, const char* functionName, Namespace* thi
15421590 prevField = NULL ;
15431591 prevObject = NULL ;
15441592 curObject = NULL ;
1593+ Script::gEvalState .clearRet ();
15451594
15461595 // Used for local variable caching of what is active...when we
15471596 // set a global, we aren't active
@@ -1561,7 +1610,7 @@ Con::EvalResult CodeBlock::exec(U32 ip, const char* functionName, Namespace* thi
15611610 prevField = NULL ;
15621611 prevObject = NULL ;
15631612 curObject = NULL ;
1564-
1613+ Script:: gEvalState . clearRet ();
15651614 // Used for local variable caching of what is active...when we
15661615 // set a global, we aren't active
15671616 currentRegister = -1 ;
@@ -1611,6 +1660,7 @@ Con::EvalResult CodeBlock::exec(U32 ip, const char* functionName, Namespace* thi
16111660 prevField = NULL ;
16121661 prevObject = NULL ;
16131662 curObject = NULL ;
1663+ Script::gEvalState .clearRet ();
16141664
16151665 stack[_STK + 1 ].setInt (Script::gEvalState .getLocalIntVariable (reg));
16161666 _STK++;
@@ -1624,7 +1674,7 @@ Con::EvalResult CodeBlock::exec(U32 ip, const char* functionName, Namespace* thi
16241674 prevField = NULL ;
16251675 prevObject = NULL ;
16261676 curObject = NULL ;
1627-
1677+ Script:: gEvalState . clearRet ();
16281678 stack[_STK + 1 ].setFloat (Script::gEvalState .getLocalFloatVariable (reg));
16291679 _STK++;
16301680 break ;
@@ -1637,7 +1687,7 @@ Con::EvalResult CodeBlock::exec(U32 ip, const char* functionName, Namespace* thi
16371687 prevField = NULL ;
16381688 prevObject = NULL ;
16391689 curObject = NULL ;
1640-
1690+ Script:: gEvalState . clearRet ();
16411691 val = Script::gEvalState .getLocalStringVariable (reg);
16421692 stack[_STK + 1 ].setString (val);
16431693 _STK++;
@@ -1651,7 +1701,7 @@ Con::EvalResult CodeBlock::exec(U32 ip, const char* functionName, Namespace* thi
16511701 prevField = NULL ;
16521702 prevObject = NULL ;
16531703 curObject = NULL ;
1654-
1704+ Script:: gEvalState . clearRet ();
16551705 Script::gEvalState .setLocalIntVariable (reg, stack[_STK].getInt ());
16561706 break ;
16571707
@@ -1663,7 +1713,7 @@ Con::EvalResult CodeBlock::exec(U32 ip, const char* functionName, Namespace* thi
16631713 prevField = NULL ;
16641714 prevObject = NULL ;
16651715 curObject = NULL ;
1666-
1716+ Script:: gEvalState . clearRet ();
16671717 Script::gEvalState .setLocalFloatVariable (reg, stack[_STK].getFloat ());
16681718 break ;
16691719
@@ -1676,7 +1726,7 @@ Con::EvalResult CodeBlock::exec(U32 ip, const char* functionName, Namespace* thi
16761726 prevField = NULL ;
16771727 prevObject = NULL ;
16781728 curObject = NULL ;
1679-
1729+ Script:: gEvalState . clearRet ();
16801730 Script::gEvalState .setLocalStringVariable (reg, val, (S32 )dStrlen (val));
16811731 break ;
16821732
@@ -1697,6 +1747,10 @@ Con::EvalResult CodeBlock::exec(U32 ip, const char* functionName, Namespace* thi
16971747 }
16981748 }
16991749 curObject = Sim::findObject (val);
1750+ if (curObject)
1751+ Script::gEvalState .clearRet ();
1752+ else
1753+ Script::gEvalState .setRetVal (stack[_STK].getString ());
17001754 break ;
17011755
17021756 case OP_SETCUROBJECT_INTERNAL :
@@ -1726,6 +1780,8 @@ Con::EvalResult CodeBlock::exec(U32 ip, const char* functionName, Namespace* thi
17261780
17271781 case OP_SETCUROBJECT_NEW :
17281782 curObject = currentNewObject;
1783+ if (curObject)
1784+ Script::gEvalState .clearRet ();
17291785 break ;
17301786
17311787 case OP_SETCURFIELD :
@@ -1782,6 +1838,7 @@ Con::EvalResult CodeBlock::exec(U32 ip, const char* functionName, Namespace* thi
17821838 {
17831839 val = curObject->getDataField (curField, curFieldArray);
17841840 stack[_STK + 1 ].setString (val);
1841+ Script::gEvalState .clearRet ();
17851842 }
17861843 else
17871844 {
@@ -2050,9 +2107,13 @@ Con::EvalResult CodeBlock::exec(U32 ip, const char* functionName, Namespace* thi
20502107 {
20512108 ConsoleValue returnFromFn = nsEntry->mModule ->exec (nsEntry->mFunctionOffset , fnName, nsEntry->mNamespace , callArgc, callArgv, false , nsEntry->mPackage ).value ;
20522109 stack[_STK + 1 ] = (returnFromFn);
2110+ Script::gEvalState .setRetVal (returnFromFn.getString ());
20532111 }
2054- else // no body
2112+ else
2113+ {// no body
20552114 stack[_STK + 1 ].setEmptyString ();
2115+ Script::gEvalState .clearRet ();
2116+ }
20562117 _STK++;
20572118
20582119 gCallStack .popFrame ();
@@ -2078,6 +2139,7 @@ Con::EvalResult CodeBlock::exec(U32 ip, const char* functionName, Namespace* thi
20782139 gCallStack .popFrame ();
20792140 stack[_STK + 1 ].setString (result);
20802141 _STK++;
2142+ Script::gEvalState .setRetVal (result);
20812143 break ;
20822144 }
20832145 case Namespace::Entry::IntCallbackType:
@@ -2088,11 +2150,13 @@ Con::EvalResult CodeBlock::exec(U32 ip, const char* functionName, Namespace* thi
20882150 if (code[ip] == OP_POP_STK )
20892151 {
20902152 ip++;
2153+ Script::gEvalState .setRetVal (result);
20912154 break ;
20922155 }
20932156
20942157 stack[_STK + 1 ].setInt (result);
20952158 _STK++;
2159+ Script::gEvalState .setRetVal (result);
20962160 break ;
20972161 }
20982162 case Namespace::Entry::FloatCallbackType:
@@ -2103,11 +2167,13 @@ Con::EvalResult CodeBlock::exec(U32 ip, const char* functionName, Namespace* thi
21032167 if (code[ip] == OP_POP_STK )
21042168 {
21052169 ip++;
2170+ Script::gEvalState .setRetVal (result);
21062171 break ;
21072172 }
21082173
21092174 stack[_STK + 1 ].setFloat (result);
21102175 _STK++;
2176+ Script::gEvalState .setRetVal (result);
21112177 break ;
21122178 }
21132179 case Namespace::Entry::VoidCallbackType:
@@ -2118,6 +2184,7 @@ Con::EvalResult CodeBlock::exec(U32 ip, const char* functionName, Namespace* thi
21182184 if (code[ip] == OP_POP_STK )
21192185 {
21202186 ip++;
2187+ Script::gEvalState .clearRet ();
21212188 break ;
21222189 }
21232190
@@ -2128,7 +2195,7 @@ Con::EvalResult CodeBlock::exec(U32 ip, const char* functionName, Namespace* thi
21282195
21292196 stack[_STK + 1 ].setEmptyString ();
21302197 _STK++;
2131-
2198+ Script:: gEvalState . clearRet ();
21322199 break ;
21332200 }
21342201 case Namespace::Entry::BoolCallbackType:
@@ -2139,17 +2206,19 @@ Con::EvalResult CodeBlock::exec(U32 ip, const char* functionName, Namespace* thi
21392206 if (code[ip] == OP_POP_STK )
21402207 {
21412208 ip++;
2209+ Script::gEvalState .setRetVal (result);
21422210 break ;
21432211 }
21442212
21452213 stack[_STK + 1 ].setBool (result);
21462214 _STK++;
2147-
2215+ Script:: gEvalState . setRetVal (result);
21482216 break ;
21492217 }
21502218 }
21512219 }
21522220 }
2221+ Script::gEvalState .currentVariable = NULL ;
21532222 break ;
21542223 }
21552224
0 commit comments