|
@@ -183,13 +183,13 @@ void Dictionary::exportVariables(const char *varString, const char *fileName, bo
|
|
|
|
|
|
for (s = sortList.begin(); s != sortList.end(); s++)
|
|
|
{
|
|
|
- switch ((*s)->value.getType())
|
|
|
+ switch ((*s)->type)
|
|
|
{
|
|
|
- case ConsoleValueType::cvInteger:
|
|
|
- dSprintf(buffer, sizeof(buffer), "%s = %d;%s", (*s)->name, (*s)->value.getInt(), cat);
|
|
|
+ case Entry::TypeInternalInt:
|
|
|
+ dSprintf(buffer, sizeof(buffer), "%s = %d;%s", (*s)->name, (*s)->ival, cat);
|
|
|
break;
|
|
|
- case ConsoleValueType::cvFloat:
|
|
|
- dSprintf(buffer, sizeof(buffer), "%s = %g;%s", (*s)->name, (*s)->value.getFloat(), cat);
|
|
|
+ case Entry::TypeInternalFloat:
|
|
|
+ dSprintf(buffer, sizeof(buffer), "%s = %g;%s", (*s)->name, (*s)->fval, cat);
|
|
|
break;
|
|
|
default:
|
|
|
expandEscape(expandBuffer, (*s)->getStringValue());
|
|
@@ -243,11 +243,11 @@ void Dictionary::exportVariables(const char *varString, Vector<String> *names, V
|
|
|
|
|
|
if (values)
|
|
|
{
|
|
|
- switch ((*s)->value.getType())
|
|
|
+ switch ((*s)->type)
|
|
|
{
|
|
|
case ConsoleValueType::cvInteger:
|
|
|
case ConsoleValueType::cvFloat:
|
|
|
- values->push_back(String((*s)->value.getString()));
|
|
|
+ values->push_back(String((*s)->getStringValue()));
|
|
|
break;
|
|
|
default:
|
|
|
expandEscape(expandBuffer, (*s)->getStringValue());
|
|
@@ -473,17 +473,88 @@ Dictionary::Entry::Entry(StringTableEntry in_name)
|
|
|
mUsage = NULL;
|
|
|
mIsConstant = false;
|
|
|
mNext = NULL;
|
|
|
- // NOTE: This is data inside a nameless
|
|
|
- // union, so we don't need to init the rest.
|
|
|
- value.init();
|
|
|
+
|
|
|
+ ival = 0;
|
|
|
+ fval = 0;
|
|
|
+ sval = typeValueEmpty;
|
|
|
+ bufferLen = 0;
|
|
|
}
|
|
|
|
|
|
Dictionary::Entry::~Entry()
|
|
|
{
|
|
|
+ reset();
|
|
|
+}
|
|
|
+
|
|
|
+void Dictionary::Entry::reset()
|
|
|
+{
|
|
|
+ name = NULL;
|
|
|
+ if (type <= TypeInternalString && sval != typeValueEmpty)
|
|
|
+ dFree(sval);
|
|
|
if (notify)
|
|
|
delete notify;
|
|
|
}
|
|
|
|
|
|
+void Dictionary::Entry::setStringValue(const char* value)
|
|
|
+{
|
|
|
+ if (mIsConstant)
|
|
|
+ {
|
|
|
+ Con::errorf("Cannot assign value to constant '%s'.", name);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (type <= TypeInternalString)
|
|
|
+ {
|
|
|
+ // Let's not remove empty-string-valued global vars from the dict.
|
|
|
+ // If we remove them, then they won't be exported, and sometimes
|
|
|
+ // it could be necessary to export such a global. There are very
|
|
|
+ // few empty-string global vars so there's no performance-related
|
|
|
+ // need to remove them from the dict.
|
|
|
+ /*
|
|
|
+ if(!value[0] && name[0] == '$')
|
|
|
+ {
|
|
|
+ gEvalState.globalVars.remove(this);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ */
|
|
|
+
|
|
|
+ U32 stringLen = dStrlen(value);
|
|
|
+
|
|
|
+ // If it's longer than 256 bytes, it's certainly not a number.
|
|
|
+ //
|
|
|
+ // (This decision may come back to haunt you. Shame on you if it
|
|
|
+ // does.)
|
|
|
+ if (stringLen < 256)
|
|
|
+ {
|
|
|
+ fval = dAtof(value);
|
|
|
+ ival = dAtoi(value);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ fval = 0.f;
|
|
|
+ ival = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ type = TypeInternalString;
|
|
|
+
|
|
|
+ // may as well pad to the next cache line
|
|
|
+ U32 newLen = ((stringLen + 1) + 15) & ~15;
|
|
|
+
|
|
|
+ if (sval == typeValueEmpty)
|
|
|
+ sval = (char*)dMalloc(newLen);
|
|
|
+ else if (newLen > bufferLen)
|
|
|
+ sval = (char*)dRealloc(sval, newLen);
|
|
|
+
|
|
|
+ bufferLen = newLen;
|
|
|
+ dStrcpy(sval, value, newLen);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ Con::setData(type, dataPtr, 0, 1, &value, enumTable);
|
|
|
+
|
|
|
+ // Fire off the notification if we have one.
|
|
|
+ if (notify)
|
|
|
+ notify->trigger();
|
|
|
+}
|
|
|
+
|
|
|
const char *Dictionary::getVariable(StringTableEntry name, bool *entValid)
|
|
|
{
|
|
|
Entry *ent = lookup(name);
|
|
@@ -558,13 +629,18 @@ Dictionary::Entry* Dictionary::addVariable(const char *name,
|
|
|
}
|
|
|
|
|
|
Entry *ent = add(StringTable->insert(name));
|
|
|
+
|
|
|
+ if (ent->type <= Entry::TypeInternalString && ent->sval != typeValueEmpty)
|
|
|
+ dFree(ent->sval);
|
|
|
+
|
|
|
ent->mUsage = usage;
|
|
|
+ ent->type = type;
|
|
|
+ ent->dataPtr = dataPtr;
|
|
|
|
|
|
// Fetch enum table, if any.
|
|
|
-
|
|
|
ConsoleBaseType* conType = ConsoleBaseType::getType(type);
|
|
|
AssertFatal(conType, "Dictionary::addVariable - invalid console type");
|
|
|
- ent->value.setConsoleData(type, dataPtr, conType->getEnumTable());
|
|
|
+ ent->enumTable = conType->getEnumTable();
|
|
|
|
|
|
return ent;
|
|
|
}
|