mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-01-19 20:24:49 +00:00
more changes.
This commit is contained in:
parent
960db74733
commit
93500b6ac4
|
|
@ -1657,7 +1657,7 @@ static ConsoleValue _internalExecute(SimObject *object, S32 argc, ConsoleValue a
|
|||
|
||||
if(ent == NULL)
|
||||
{
|
||||
warnf(ConsoleLogEntry::Script, "%s: undefined for object '%s' - id %d", funcName, object->getName(), object->getId());
|
||||
//warnf(ConsoleLogEntry::Script, "%s: undefined for object '%s' - id %d", funcName, object->getName(), object->getId());
|
||||
|
||||
STR.clearFunctionOffset();
|
||||
return std::move(ConsoleValue());
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -280,9 +280,18 @@ public:
|
|||
|
||||
struct Entry
|
||||
{
|
||||
friend class Dictionary;
|
||||
|
||||
enum
|
||||
{
|
||||
TypeInternalInt = -3,
|
||||
TypeInternalFloat = -2,
|
||||
TypeInternalString = -1,
|
||||
};
|
||||
|
||||
StringTableEntry name;
|
||||
ConsoleValue value;
|
||||
Entry *nextEntry;
|
||||
S32 type;
|
||||
|
||||
typedef Signal<void()> NotifySignal;
|
||||
|
||||
|
|
@ -296,6 +305,41 @@ public:
|
|||
/// Whether this is a constant that cannot be assigned to.
|
||||
bool mIsConstant;
|
||||
|
||||
protected:
|
||||
|
||||
// NOTE: This is protected to ensure no one outside
|
||||
// of this structure is messing with it.
|
||||
|
||||
#pragma warning( push )
|
||||
#pragma warning( disable : 4201 ) // warning C4201: nonstandard extension used : nameless struct/union
|
||||
|
||||
// An variable is either a real dynamic type or
|
||||
// its one exposed from C++ using a data pointer.
|
||||
//
|
||||
// We use this nameless union and struct setup
|
||||
// to optimize the memory usage.
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
char* sval;
|
||||
U32 ival; // doubles as strlen when type is TypeInternalString
|
||||
F32 fval;
|
||||
U32 bufferLen;
|
||||
};
|
||||
|
||||
struct
|
||||
{
|
||||
/// The real data pointer.
|
||||
void* dataPtr;
|
||||
|
||||
/// The enum lookup table for enumerated types.
|
||||
const EnumTable* enumTable;
|
||||
};
|
||||
};
|
||||
|
||||
#pragma warning( pop ) // C4201
|
||||
|
||||
public:
|
||||
|
||||
Entry() {
|
||||
|
|
@ -312,26 +356,34 @@ public:
|
|||
|
||||
Entry *mNext;
|
||||
|
||||
void reset() {
|
||||
name = NULL;
|
||||
value.reset();
|
||||
if (notify)
|
||||
delete notify;
|
||||
}
|
||||
void reset();
|
||||
|
||||
inline U32 getIntValue()
|
||||
{
|
||||
return value.getInt();
|
||||
if (type <= TypeInternalString)
|
||||
return ival;
|
||||
else
|
||||
return dAtoi(Con::getData(type, dataPtr, 0, enumTable));
|
||||
}
|
||||
|
||||
inline F32 getFloatValue()
|
||||
{
|
||||
return value.getFloat();
|
||||
if (type <= TypeInternalString)
|
||||
return fval;
|
||||
else
|
||||
return dAtof(Con::getData(type, dataPtr, 0, enumTable));
|
||||
}
|
||||
|
||||
inline const char *getStringValue()
|
||||
{
|
||||
return value.getString();
|
||||
if (type == TypeInternalString)
|
||||
return sval;
|
||||
if (type == TypeInternalFloat)
|
||||
return Con::getData(TypeF32, &fval, 0);
|
||||
else if (type == TypeInternalInt)
|
||||
return Con::getData(TypeS32, &ival, 0);
|
||||
else
|
||||
return Con::getData(type, dataPtr, 0, enumTable);
|
||||
}
|
||||
|
||||
void setIntValue(U32 val)
|
||||
|
|
@ -342,7 +394,22 @@ public:
|
|||
return;
|
||||
}
|
||||
|
||||
value.setInt(val);
|
||||
if (type <= TypeInternalString)
|
||||
{
|
||||
fval = (F32)val;
|
||||
ival = val;
|
||||
if (sval != typeValueEmpty)
|
||||
{
|
||||
dFree(sval);
|
||||
sval = typeValueEmpty;
|
||||
}
|
||||
type = TypeInternalInt;
|
||||
}
|
||||
else
|
||||
{
|
||||
const char* dptr = Con::getData(TypeS32, &val, 0);
|
||||
Con::setData(type, dataPtr, 0, 1, &dptr, enumTable);
|
||||
}
|
||||
|
||||
// Fire off the notification if we have one.
|
||||
if (notify)
|
||||
|
|
@ -357,27 +424,29 @@ public:
|
|||
return;
|
||||
}
|
||||
|
||||
value.setFloat(val);
|
||||
|
||||
// Fire off the notification if we have one.
|
||||
if (notify)
|
||||
notify->trigger();
|
||||
}
|
||||
|
||||
void setStringValue(const char *newValue)
|
||||
{
|
||||
if (mIsConstant)
|
||||
if (type <= TypeInternalString)
|
||||
{
|
||||
Con::errorf("Cannot assign value to constant '%s'.", name);
|
||||
return;
|
||||
fval = val;
|
||||
ival = static_cast<U32>(val);
|
||||
if (sval != typeValueEmpty)
|
||||
{
|
||||
dFree(sval);
|
||||
sval = typeValueEmpty;
|
||||
}
|
||||
type = TypeInternalFloat;
|
||||
}
|
||||
else
|
||||
{
|
||||
const char* dptr = Con::getData(TypeF32, &val, 0);
|
||||
Con::setData(type, dataPtr, 0, 1, &dptr, enumTable);
|
||||
}
|
||||
|
||||
value.setString(newValue);
|
||||
|
||||
// Fire off the notification if we have one.
|
||||
if (notify)
|
||||
notify->trigger();
|
||||
}
|
||||
|
||||
void setStringValue(const char* value);
|
||||
};
|
||||
|
||||
struct HashTableData
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ static void dumpVariable( Stream& stream,
|
|||
{
|
||||
// Skip variables defined in script.
|
||||
|
||||
if( !entry->value.isConsoleType() )
|
||||
if( entry->type <= Dictionary::Entry::TypeInternalString )
|
||||
return;
|
||||
|
||||
// Skip internals... don't export them.
|
||||
|
|
@ -149,7 +149,7 @@ static void dumpVariable( Stream& stream,
|
|||
|
||||
// Skip variables for which we can't decipher their type.
|
||||
|
||||
ConsoleBaseType* type = ConsoleBaseType::getType( entry->value.getType() );
|
||||
ConsoleBaseType* type = ConsoleBaseType::getType( entry->type );
|
||||
if( !type )
|
||||
{
|
||||
Con::errorf( "Can't find type for variable '%s'", entry->name );
|
||||
|
|
|
|||
Loading…
Reference in a new issue