Skip to content

Commit d3d253d

Browse files
authored
Merge pull request #1823 from Azaezel/alpha41/FieldComponentFindOut
adress #1822
2 parents b5c63b1 + 4442862 commit d3d253d

2 files changed

Lines changed: 145 additions & 63 deletions

File tree

Engine/source/console/torquescript/compiledEval.cpp

Lines changed: 132 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
//------------------------------------------------------------
166200
static 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

385431
enum 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

Comments
 (0)