mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-07-11 14:44:36 +00:00
Fix stack balancing problems by refactoring execution calls
- Con::executef now uses a template - All public execution functions now restore the console stack upon return - Fixed bad parameters on some callbacks - Reverts get*Arg behavior
This commit is contained in:
parent
b1ad72692c
commit
f44a3f27d6
43 changed files with 1781 additions and 358 deletions
|
|
@ -103,9 +103,7 @@ S32 QSORT_CALLBACK ArrayObject::_keyFunctionCompare( const void* a, const void*
|
|||
ArrayObject::Element* ea = ( ArrayObject::Element* )( a );
|
||||
ArrayObject::Element* eb = ( ArrayObject::Element* )( b );
|
||||
|
||||
ConsoleValueRef argv[] = { smCompareFunction, ea->key, eb->key };
|
||||
|
||||
S32 result = dAtoi( Con::execute( 3, argv ) );
|
||||
S32 result = dAtoi( Con::executef( (const char*)smCompareFunction, ea->value, eb->key ) );
|
||||
S32 res = result < 0 ? -1 : ( result > 0 ? 1 : 0 );
|
||||
return ( smDecreasing ? -res : res );
|
||||
}
|
||||
|
|
@ -115,9 +113,7 @@ S32 QSORT_CALLBACK ArrayObject::_valueFunctionCompare( const void* a, const void
|
|||
ArrayObject::Element* ea = ( ArrayObject::Element* )( a );
|
||||
ArrayObject::Element* eb = ( ArrayObject::Element* )( b );
|
||||
|
||||
ConsoleValueRef argv[] = { smCompareFunction, ea->value, eb->value };
|
||||
|
||||
S32 result = dAtoi( Con::execute( 3, argv ) );
|
||||
S32 result = dAtoi( Con::executef( (const char*)smCompareFunction, ea->value, eb->value ) );
|
||||
S32 res = result < 0 ? -1 : ( result > 0 ? 1 : 0 );
|
||||
return ( smDecreasing ? -res : res );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -570,7 +570,7 @@ bool CodeBlock::compile(const char *codeFileName, StringTableEntry fileName, con
|
|||
|
||||
}
|
||||
|
||||
const char *CodeBlock::compileExec(StringTableEntry fileName, const char *inString, bool noCalls, S32 setFrame)
|
||||
ConsoleValueRef CodeBlock::compileExec(StringTableEntry fileName, const char *inString, bool noCalls, S32 setFrame)
|
||||
{
|
||||
AssertFatal(Con::isMainThread(), "Compiling code on a secondary thread");
|
||||
|
||||
|
|
@ -635,7 +635,7 @@ const char *CodeBlock::compileExec(StringTableEntry fileName, const char *inStri
|
|||
if(!gStatementList)
|
||||
{
|
||||
delete this;
|
||||
return "";
|
||||
return ConsoleValueRef();
|
||||
}
|
||||
|
||||
resetTables();
|
||||
|
|
|
|||
|
|
@ -129,7 +129,7 @@ public:
|
|||
/// with, zero being the top of the stack. If the the index is
|
||||
/// -1 a new frame is created. If the index is out of range the
|
||||
/// top stack frame is used.
|
||||
const char *compileExec(StringTableEntry fileName, const char *script,
|
||||
ConsoleValueRef compileExec(StringTableEntry fileName, const char *script,
|
||||
bool noCalls, S32 setFrame = -1 );
|
||||
|
||||
/// Executes the existing code in the CodeBlock. The return string is any
|
||||
|
|
|
|||
|
|
@ -195,18 +195,20 @@ namespace Con
|
|||
return STR.getArgBuffer(bufferSize);
|
||||
}
|
||||
|
||||
ConsoleValueRef getFloatArg(F64 arg)
|
||||
char *getFloatArg(F64 arg)
|
||||
{
|
||||
ConsoleValueRef ref = arg;
|
||||
return ref;
|
||||
char *ret = STR.getArgBuffer(32);
|
||||
dSprintf(ret, 32, "%g", arg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ConsoleValueRef getIntArg(S32 arg)
|
||||
char *getIntArg(S32 arg)
|
||||
{
|
||||
ConsoleValueRef ref = arg;
|
||||
return ref;
|
||||
char *ret = STR.getArgBuffer(32);
|
||||
dSprintf(ret, 32, "%d", arg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
char *getStringArg( const char *arg )
|
||||
{
|
||||
U32 len = dStrlen( arg ) + 1;
|
||||
|
|
@ -432,6 +434,8 @@ ConsoleValueRef CodeBlock::exec(U32 ip, const char *functionName, Namespace *thi
|
|||
U32 consoleStackStart = CSTK.mStackPos;
|
||||
#endif
|
||||
|
||||
//Con::printf("CodeBlock::exec(%s,%u)", functionName ? functionName : "??", ip);
|
||||
|
||||
static char traceBuffer[1024];
|
||||
S32 i;
|
||||
|
||||
|
|
@ -441,7 +445,7 @@ ConsoleValueRef CodeBlock::exec(U32 ip, const char *functionName, Namespace *thi
|
|||
F64 *curFloatTable;
|
||||
char *curStringTable;
|
||||
S32 curStringTableLen = 0; //clint to ensure we dont overwrite it
|
||||
STR.clearFunctionOffset();
|
||||
STR.clearFunctionOffset(); // ensures arg buffer offset is back to 0
|
||||
StringTableEntry thisFunctionName = NULL;
|
||||
bool popFrame = false;
|
||||
if(argv)
|
||||
|
|
@ -533,17 +537,6 @@ ConsoleValueRef CodeBlock::exec(U32 ip, const char *functionName, Namespace *thi
|
|||
}
|
||||
}
|
||||
|
||||
bool doResetValueStack = !gEvalState.mResetLocked;
|
||||
gEvalState.mResetLocked = true;
|
||||
|
||||
if (gEvalState.mShouldReset)
|
||||
{
|
||||
// Ensure all stacks are clean in case anything became unbalanced during the previous execution
|
||||
STR.clearFrames();
|
||||
CSTK.clearFrames();
|
||||
gEvalState.mShouldReset = false;
|
||||
}
|
||||
|
||||
// Grab the state of the telenet debugger here once
|
||||
// so that the push and pop frames are always balanced.
|
||||
const bool telDebuggerOn = TelDebugger && TelDebugger->isConnected();
|
||||
|
|
@ -1847,7 +1840,7 @@ breakContinue:
|
|||
|
||||
// This will clear everything including returnValue
|
||||
CSTK.popFrame();
|
||||
STR.clearFunctionOffset();
|
||||
//STR.clearFunctionOffset();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -2234,18 +2227,11 @@ execFinished:
|
|||
Con::gCurrentRoot = saveCodeBlock->modPath;
|
||||
}
|
||||
|
||||
// Mark the reset flag for the next run if we've finished execution
|
||||
if (doResetValueStack)
|
||||
{
|
||||
gEvalState.mShouldReset = true;
|
||||
gEvalState.mResetLocked = false;
|
||||
}
|
||||
|
||||
decRefCount();
|
||||
|
||||
#ifdef TORQUE_DEBUG
|
||||
AssertFatal(!(STR.mStartStackSize > stackStart), "String stack not popped enough in script exec");
|
||||
AssertFatal(!(STR.mStartStackSize < stackStart), "String stack popped too much in script exec");
|
||||
//AssertFatal(!(STR.mStartStackSize > stackStart), "String stack not popped enough in script exec");
|
||||
//AssertFatal(!(STR.mStartStackSize < stackStart), "String stack popped too much in script exec");
|
||||
#endif
|
||||
|
||||
return returnValue;
|
||||
|
|
|
|||
|
|
@ -1138,8 +1138,11 @@ void addCommand( const char *name,BoolCallback cb,const char *usage, S32 minArgs
|
|||
Namespace::global()->addCommand( StringTable->insert(name), cb, usage, minArgs, maxArgs, isToolOnly, header );
|
||||
}
|
||||
|
||||
const char *evaluate(const char* string, bool echo, const char *fileName)
|
||||
ConsoleValueRef evaluate(const char* string, bool echo, const char *fileName)
|
||||
{
|
||||
ConsoleStackFrameSaver stackSaver;
|
||||
stackSaver.save();
|
||||
|
||||
if (echo)
|
||||
{
|
||||
if (string[0] == '%')
|
||||
|
|
@ -1156,8 +1159,11 @@ const char *evaluate(const char* string, bool echo, const char *fileName)
|
|||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
const char *evaluatef(const char* string, ...)
|
||||
ConsoleValueRef evaluatef(const char* string, ...)
|
||||
{
|
||||
ConsoleStackFrameSaver stackSaver;
|
||||
stackSaver.save();
|
||||
|
||||
char buffer[4096];
|
||||
va_list args;
|
||||
va_start(args, string);
|
||||
|
|
@ -1166,26 +1172,34 @@ const char *evaluatef(const char* string, ...)
|
|||
return newCodeBlock->compileExec(NULL, buffer, false, 0);
|
||||
}
|
||||
|
||||
const char *execute(S32 argc, ConsoleValueRef argv[])
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// Internal execute for global function which does not save the stack
|
||||
ConsoleValueRef _internalExecute(S32 argc, ConsoleValueRef argv[])
|
||||
{
|
||||
Namespace::Entry *ent;
|
||||
StringTableEntry funcName = StringTable->insert(argv[0]);
|
||||
ent = Namespace::global()->lookup(funcName);
|
||||
|
||||
if(!ent)
|
||||
{
|
||||
warnf(ConsoleLogEntry::Script, "%s: Unknown command.", (const char*)argv[0]);
|
||||
|
||||
STR.clearFunctionOffset();
|
||||
return ConsoleValueRef();
|
||||
}
|
||||
return ent->execute(argc, argv, &gEvalState);
|
||||
}
|
||||
|
||||
ConsoleValueRef execute(S32 argc, ConsoleValueRef argv[])
|
||||
{
|
||||
#ifdef TORQUE_MULTITHREAD
|
||||
if(isMainThread())
|
||||
{
|
||||
#endif
|
||||
Namespace::Entry *ent;
|
||||
StringTableEntry funcName = StringTable->insert(argv[0]);
|
||||
ent = Namespace::global()->lookup(funcName);
|
||||
|
||||
if(!ent)
|
||||
{
|
||||
warnf(ConsoleLogEntry::Script, "%s: Unknown command.", (const char*)argv[0]);
|
||||
|
||||
// Clean up arg buffers, if any.
|
||||
STR.clearFunctionOffset();
|
||||
CSTK.resetFrame();
|
||||
return "";
|
||||
}
|
||||
return ent->execute(argc, argv, &gEvalState);
|
||||
ConsoleStackFrameSaver stackSaver;
|
||||
stackSaver.save();
|
||||
return _internalExecute(argc, argv);
|
||||
#ifdef TORQUE_MULTITHREAD
|
||||
}
|
||||
else
|
||||
|
|
@ -1199,17 +1213,24 @@ const char *execute(S32 argc, ConsoleValueRef argv[])
|
|||
#endif
|
||||
}
|
||||
|
||||
const char *execute(S32 argc, const char *argv[])
|
||||
ConsoleValueRef execute(S32 argc, const char *argv[])
|
||||
{
|
||||
ConsoleStackFrameSaver stackSaver;
|
||||
stackSaver.save();
|
||||
StringStackConsoleWrapper args(argc, argv);
|
||||
return execute(args.count(), args);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
const char *execute(SimObject *object, S32 argc, ConsoleValueRef argv[], bool thisCallOnly)
|
||||
|
||||
// Internal execute for object method which does not save the stack
|
||||
ConsoleValueRef _internalExecute(SimObject *object, S32 argc, ConsoleValueRef argv[], bool thisCallOnly)
|
||||
{
|
||||
if(argc < 2)
|
||||
return "";
|
||||
{
|
||||
STR.clearFunctionOffset();
|
||||
return ConsoleValueRef();
|
||||
}
|
||||
|
||||
// [neo, 10/05/2007 - #3010]
|
||||
// Make sure we don't get recursive calls, respect the flag!
|
||||
|
|
@ -1229,10 +1250,8 @@ const char *execute(SimObject *object, S32 argc, ConsoleValueRef argv[], bool th
|
|||
|
||||
if(object->getNamespace())
|
||||
{
|
||||
ConsoleValueRef internalArgv[StringStack::MaxArgs];
|
||||
|
||||
U32 ident = object->getId();
|
||||
ConsoleValueRef oldIdent = argv[1];
|
||||
U32 ident = object->getId();
|
||||
ConsoleValueRef oldIdent = argv[1];
|
||||
|
||||
StringTableEntry funcName = StringTable->insert(argv[0]);
|
||||
Namespace::Entry *ent = object->getNamespace()->lookup(funcName);
|
||||
|
|
@ -1241,10 +1260,8 @@ const char *execute(SimObject *object, S32 argc, ConsoleValueRef argv[], bool th
|
|||
{
|
||||
//warnf(ConsoleLogEntry::Script, "%s: undefined for object '%s' - id %d", funcName, object->getName(), object->getId());
|
||||
|
||||
// Clean up arg buffers, if any.
|
||||
STR.clearFunctionOffset();
|
||||
CSTK.resetFrame();
|
||||
return "";
|
||||
return ConsoleValueRef();
|
||||
}
|
||||
|
||||
// Twiddle %this argument
|
||||
|
|
@ -1252,7 +1269,7 @@ const char *execute(SimObject *object, S32 argc, ConsoleValueRef argv[], bool th
|
|||
|
||||
SimObject *save = gEvalState.thisObject;
|
||||
gEvalState.thisObject = object;
|
||||
const char *ret = ent->execute(argc, argv, &gEvalState);
|
||||
ConsoleValueRef ret = ent->execute(argc, argv, &gEvalState);
|
||||
gEvalState.thisObject = save;
|
||||
|
||||
// Twiddle it back
|
||||
|
|
@ -1260,17 +1277,52 @@ const char *execute(SimObject *object, S32 argc, ConsoleValueRef argv[], bool th
|
|||
|
||||
return ret;
|
||||
}
|
||||
|
||||
warnf(ConsoleLogEntry::Script, "Con::execute - %d has no namespace: %s", object->getId(), (const char*)argv[0]);
|
||||
return "";
|
||||
STR.clearFunctionOffset();
|
||||
return ConsoleValueRef();
|
||||
}
|
||||
|
||||
const char *execute(SimObject *object, S32 argc, const char *argv[], bool thisCallOnly)
|
||||
|
||||
ConsoleValueRef execute(SimObject *object, S32 argc, ConsoleValueRef argv[], bool thisCallOnly)
|
||||
{
|
||||
if(argc < 2)
|
||||
{
|
||||
STR.clearFunctionOffset();
|
||||
return ConsoleValueRef();
|
||||
}
|
||||
|
||||
ConsoleStackFrameSaver stackSaver;
|
||||
stackSaver.save();
|
||||
|
||||
if (object->getNamespace() || !thisCallOnly)
|
||||
{
|
||||
if (isMainThread())
|
||||
{
|
||||
return _internalExecute(object, argc, argv, thisCallOnly);
|
||||
}
|
||||
else
|
||||
{
|
||||
SimConsoleThreadExecCallback cb;
|
||||
SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(argc, argv, true, &cb);
|
||||
Sim::postEvent(object, evt, Sim::getCurrentTime());
|
||||
}
|
||||
}
|
||||
|
||||
warnf(ConsoleLogEntry::Script, "Con::execute - %d has no namespace: %s", object->getId(), (const char*)argv[0]);
|
||||
STR.clearFunctionOffset();
|
||||
return ConsoleValueRef();
|
||||
}
|
||||
|
||||
ConsoleValueRef execute(SimObject *object, S32 argc, const char *argv[], bool thisCallOnly)
|
||||
{
|
||||
ConsoleStackFrameSaver stackSaver;
|
||||
stackSaver.save();
|
||||
StringStackConsoleWrapper args(argc, argv);
|
||||
return execute(object, args.count(), args, thisCallOnly);
|
||||
}
|
||||
|
||||
inline const char*_executef(SimObject *obj, S32 checkArgc, S32 argc, ConsoleValueRef *argv)
|
||||
inline ConsoleValueRef _executef(SimObject *obj, S32 checkArgc, S32 argc, ConsoleValueRef *argv)
|
||||
{
|
||||
const U32 maxArg = 12;
|
||||
AssertWarn(checkArgc == argc, "Incorrect arg count passed to Con::executef(SimObject*)");
|
||||
|
|
@ -1278,42 +1330,14 @@ inline const char*_executef(SimObject *obj, S32 checkArgc, S32 argc, ConsoleValu
|
|||
return execute(obj, argc, argv);
|
||||
}
|
||||
|
||||
#define A ConsoleValueRef
|
||||
#define OBJ SimObject* obj
|
||||
const char *executef(OBJ, A a) { ConsoleValueRef params[] = {a,ConsoleValueRef()}; return _executef(obj, 2, 2, params); }
|
||||
const char *executef(OBJ, A a, A b) { ConsoleValueRef params[] = {a,ConsoleValueRef(),b}; return _executef(obj, 3, 3, params); }
|
||||
const char *executef(OBJ, A a, A b, A c) { ConsoleValueRef params[] = {a,ConsoleValueRef(),b,c}; return _executef(obj, 4, 4, params); }
|
||||
const char *executef(OBJ, A a, A b, A c, A d) { ConsoleValueRef params[] = {a,ConsoleValueRef(),b,c,d}; return _executef(obj, 5, 5, params); }
|
||||
const char *executef(OBJ, A a, A b, A c, A d, A e) { ConsoleValueRef params[] = {a,ConsoleValueRef(),b,c,d,e}; return _executef(obj, 6, 6, params); }
|
||||
const char *executef(OBJ, A a, A b, A c, A d, A e, A f) { ConsoleValueRef params[] = {a,ConsoleValueRef(),b,c,d,e,f}; return _executef(obj, 7, 7, params); }
|
||||
const char *executef(OBJ, A a, A b, A c, A d, A e, A f, A g) { ConsoleValueRef params[] = {a,ConsoleValueRef(),b,c,d,e,f,g}; return _executef(obj, 8, 8, params); }
|
||||
const char *executef(OBJ, A a, A b, A c, A d, A e, A f, A g, A h) { ConsoleValueRef params[] = {a,ConsoleValueRef(),b,c,d,e,f,g,h}; return _executef(obj, 9, 9, params); }
|
||||
const char *executef(OBJ, A a, A b, A c, A d, A e, A f, A g, A h, A i) { ConsoleValueRef params[] = {a,ConsoleValueRef(),b,c,d,e,f,g,h,i}; return _executef(obj, 10, 10, params); }
|
||||
const char *executef(OBJ, A a, A b, A c, A d, A e, A f, A g, A h, A i, A j) { ConsoleValueRef params[] = {a,ConsoleValueRef(),b,c,d,e,f,g,h,i,j}; return _executef(obj, 11, 11, params); }
|
||||
const char *executef(OBJ, A a, A b, A c, A d, A e, A f, A g, A h, A i, A j, A k) { ConsoleValueRef params[] = {a,ConsoleValueRef(),b,c,d,e,f,g,h,i,j,k}; return _executef(obj, 12, 12, params); }
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
inline const char*_executef(S32 checkArgc, S32 argc, ConsoleValueRef *argv)
|
||||
inline ConsoleValueRef _executef(S32 checkArgc, S32 argc, ConsoleValueRef *argv)
|
||||
{
|
||||
const U32 maxArg = 10;
|
||||
AssertFatal(checkArgc == argc, "Incorrect arg count passed to Con::executef()");
|
||||
AssertFatal(argc <= maxArg, "Too many args passed to Con::_executef(). Please update the function to handle more.");
|
||||
return execute(argc, argv);
|
||||
}
|
||||
|
||||
#define A ConsoleValueRef
|
||||
const char *executef(A a) { ConsoleValueRef params[] = {a}; return _executef(1, 1, params); }
|
||||
const char *executef(A a, A b) { ConsoleValueRef params[] = {a,b}; return _executef(2, 2, params); }
|
||||
const char *executef(A a, A b, A c) { ConsoleValueRef params[] = {a,b,c}; return _executef(3, 3, params); }
|
||||
const char *executef(A a, A b, A c, A d) { ConsoleValueRef params[] = {a,b,c,d}; return _executef(4, 4, params); }
|
||||
const char *executef(A a, A b, A c, A d, A e) { ConsoleValueRef params[] = {a,b,c,d,e}; return _executef(5, 5, params); }
|
||||
const char *executef(A a, A b, A c, A d, A e, A f) { ConsoleValueRef params[] = {a,b,c,d,e,f}; return _executef(1, 1, params); }
|
||||
const char *executef(A a, A b, A c, A d, A e, A f, A g) { ConsoleValueRef params[] = {a,b,c,d,e,f,g}; return _executef(1, 1, params); }
|
||||
const char *executef(A a, A b, A c, A d, A e, A f, A g, A h) { ConsoleValueRef params[] = {a,b,c,d,e,f,g,h}; return _executef(1, 1, params); }
|
||||
const char *executef(A a, A b, A c, A d, A e, A f, A g, A h, A i) { ConsoleValueRef params[] = {a,b,c,d,e,f,g,h,i}; return _executef(1, 1, params); }
|
||||
const char *executef(A a, A b, A c, A d, A e, A f, A g, A h, A i, A j) { ConsoleValueRef params[] = {a,b,c,d,e,f,g,h,i,j}; return _executef(1, 1, params); }
|
||||
#undef A
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool isFunction(const char *fn)
|
||||
|
|
@ -1576,10 +1600,13 @@ DefineEngineFunction( logWarning, void, ( const char* message ),,
|
|||
Con::warnf( "%s", message );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
extern ConsoleValueStack CSTK;
|
||||
|
||||
ConsoleValueRef::ConsoleValueRef(const ConsoleValueRef &ref)
|
||||
{
|
||||
value = ref.value;
|
||||
stringStackValue = ref.stringStackValue;
|
||||
value = ref.value;
|
||||
}
|
||||
|
||||
ConsoleValueRef::ConsoleValueRef(const char *newValue) : value(NULL)
|
||||
|
|
@ -1612,6 +1639,49 @@ ConsoleValueRef::ConsoleValueRef(F64 newValue) : value(NULL)
|
|||
*this = newValue;
|
||||
}
|
||||
|
||||
ConsoleValueRef& ConsoleValueRef::operator=(const ConsoleValueRef &newValue)
|
||||
{
|
||||
value = newValue.value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ConsoleValueRef& ConsoleValueRef::operator=(const char *newValue)
|
||||
{
|
||||
AssertFatal(value, "value should not be NULL");
|
||||
value->setStringValue(newValue);
|
||||
return *this;
|
||||
}
|
||||
|
||||
ConsoleValueRef& ConsoleValueRef::operator=(S32 newValue)
|
||||
{
|
||||
AssertFatal(value, "value should not be NULL");
|
||||
value->setIntValue(newValue);
|
||||
return *this;
|
||||
}
|
||||
|
||||
ConsoleValueRef& ConsoleValueRef::operator=(U32 newValue)
|
||||
{
|
||||
AssertFatal(value, "value should not be NULL");
|
||||
value->setIntValue(newValue);
|
||||
return *this;
|
||||
}
|
||||
|
||||
ConsoleValueRef& ConsoleValueRef::operator=(F32 newValue)
|
||||
{
|
||||
AssertFatal(value, "value should not be NULL");
|
||||
value->setFloatValue(newValue);
|
||||
return *this;
|
||||
}
|
||||
|
||||
ConsoleValueRef& ConsoleValueRef::operator=(F64 newValue)
|
||||
{
|
||||
AssertFatal(value, "value should not be NULL");
|
||||
value->setFloatValue(newValue);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
StringStackWrapper::StringStackWrapper(int targc, ConsoleValueRef targv[])
|
||||
{
|
||||
argv = new const char*[targc];
|
||||
|
|
@ -1636,10 +1706,13 @@ StringStackWrapper::~StringStackWrapper()
|
|||
StringStackConsoleWrapper::StringStackConsoleWrapper(int targc, const char** targ)
|
||||
{
|
||||
argv = new ConsoleValueRef[targc];
|
||||
argvValue = new ConsoleValue[targc];
|
||||
argc = targc;
|
||||
|
||||
for (int i=0; i<targc; i++) {
|
||||
argv[i] = ConsoleValueRef(targ[i]);
|
||||
argvValue[i].init();
|
||||
argv[i].value = &argvValue[i];
|
||||
argvValue[i].setStackStringValue(targ[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1650,8 +1723,11 @@ StringStackConsoleWrapper::~StringStackConsoleWrapper()
|
|||
argv[i] = 0;
|
||||
}
|
||||
delete[] argv;
|
||||
delete[] argvValue;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
S32 ConsoleValue::getSignedIntValue()
|
||||
{
|
||||
if(type <= TypeInternalString)
|
||||
|
|
@ -1752,70 +1828,49 @@ void ConsoleValue::setFloatValue(F32 val)
|
|||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
const char *ConsoleValueRef::getStringArgValue()
|
||||
ConsoleValueRef _BaseEngineConsoleCallbackHelper::_exec()
|
||||
{
|
||||
if (value)
|
||||
ConsoleValueRef returnValue;
|
||||
if( mThis )
|
||||
{
|
||||
if (stringStackValue == NULL)
|
||||
stringStackValue = Con::getStringArg(value->getStringValue());
|
||||
return stringStackValue;
|
||||
// Cannot invoke callback until object has been registered
|
||||
if (mThis->isProperlyAdded()) {
|
||||
returnValue = Con::_internalExecute( mThis, mArgc, mArgv, false );
|
||||
} else {
|
||||
STR.clearFunctionOffset();
|
||||
returnValue = ConsoleValueRef();
|
||||
}
|
||||
}
|
||||
else
|
||||
returnValue = Con::_internalExecute( mArgc, mArgv );
|
||||
|
||||
mArgc = mInitialArgc; // reset args
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
ConsoleValueRef _BaseEngineConsoleCallbackHelper::_execLater(SimConsoleThreadExecEvent *evt)
|
||||
{
|
||||
mArgc = mInitialArgc; // reset args
|
||||
Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
|
||||
return evt->getCB().waitForResult();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void ConsoleStackFrameSaver::save()
|
||||
{
|
||||
CSTK.pushFrame();
|
||||
STR.pushFrame();
|
||||
mSaved = true;
|
||||
}
|
||||
|
||||
void ConsoleStackFrameSaver::restore()
|
||||
{
|
||||
if (mSaved)
|
||||
{
|
||||
return "";
|
||||
CSTK.popFrame();
|
||||
STR.popFrame();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
extern ConsoleValueStack CSTK;
|
||||
|
||||
ConsoleValueRef& ConsoleValueRef::operator=(const ConsoleValueRef &newValue)
|
||||
{
|
||||
value = newValue.value;
|
||||
stringStackValue = newValue.stringStackValue;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ConsoleValueRef& ConsoleValueRef::operator=(const char *newValue)
|
||||
{
|
||||
value = CSTK.pushStackString(newValue);
|
||||
stringStackValue = NULL;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ConsoleValueRef& ConsoleValueRef::operator=(S32 newValue)
|
||||
{
|
||||
value = CSTK.pushFLT(newValue);
|
||||
stringStackValue = NULL;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ConsoleValueRef& ConsoleValueRef::operator=(U32 newValue)
|
||||
{
|
||||
value = CSTK.pushUINT(newValue);
|
||||
stringStackValue = NULL;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ConsoleValueRef& ConsoleValueRef::operator=(F32 newValue)
|
||||
{
|
||||
value = CSTK.pushFLT(newValue);
|
||||
stringStackValue = NULL;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ConsoleValueRef& ConsoleValueRef::operator=(F64 newValue)
|
||||
{
|
||||
value = CSTK.pushFLT(newValue);
|
||||
stringStackValue = NULL;
|
||||
return *this;
|
||||
}
|
||||
|
||||
namespace Con
|
||||
{
|
||||
void resetStackFrame()
|
||||
{
|
||||
CSTK.resetFrame();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -181,6 +181,7 @@ public:
|
|||
fval = 0;
|
||||
sval = typeValueEmpty;
|
||||
bufferLen = 0;
|
||||
type = TypeInternalString;
|
||||
}
|
||||
|
||||
void cleanup()
|
||||
|
|
@ -203,9 +204,8 @@ class ConsoleValueRef
|
|||
{
|
||||
public:
|
||||
ConsoleValue *value;
|
||||
const char *stringStackValue;
|
||||
|
||||
ConsoleValueRef() : value(0), stringStackValue(0) { ; }
|
||||
ConsoleValueRef() : value(0) { ; }
|
||||
~ConsoleValueRef() { ; }
|
||||
|
||||
ConsoleValueRef(const ConsoleValueRef &ref);
|
||||
|
|
@ -216,8 +216,9 @@ public:
|
|||
ConsoleValueRef(F32 value);
|
||||
ConsoleValueRef(F64 value);
|
||||
|
||||
static ConsoleValueRef fromValue(ConsoleValue *value) { ConsoleValueRef ref; ref.value = value; return ref; }
|
||||
|
||||
const char *getStringValue() { return value ? value->getStringValue() : ""; }
|
||||
const char *getStringArgValue();
|
||||
|
||||
inline U32 getIntValue() { return value ? value->getIntValue() : 0; }
|
||||
inline S32 getSignedIntValue() { return value ? value->getSignedIntValue() : 0; }
|
||||
|
|
@ -229,6 +230,7 @@ public:
|
|||
inline operator U32() { return getIntValue(); }
|
||||
inline operator S32() { return getSignedIntValue(); }
|
||||
inline operator F32() { return getFloatValue(); }
|
||||
inline operator bool() { return getBoolValue(); }
|
||||
|
||||
inline bool isString() { return value ? value->type >= ConsoleValue::TypeInternalStackString : true; }
|
||||
inline bool isInt() { return value ? value->type == ConsoleValue::TypeInternalInt : false; }
|
||||
|
|
@ -281,6 +283,7 @@ public:
|
|||
class StringStackConsoleWrapper
|
||||
{
|
||||
public:
|
||||
ConsoleValue *argvValue;
|
||||
ConsoleValueRef *argv;
|
||||
int argc;
|
||||
|
||||
|
|
@ -753,23 +756,9 @@ namespace Con
|
|||
/// char* argv[] = {"abs", "-9"};
|
||||
/// char* result = execute(2, argv);
|
||||
/// @endcode
|
||||
const char *execute(S32 argc, const char* argv[]);
|
||||
const char *execute(S32 argc, ConsoleValueRef argv[]);
|
||||
|
||||
/// @see execute(S32 argc, const char* argv[])
|
||||
// Note: this can't be ConsoleValueRef& since the compiler will confuse it with SimObject*
|
||||
#define ARG ConsoleValueRef
|
||||
const char *executef( ARG);
|
||||
const char *executef( ARG, ARG);
|
||||
const char *executef( ARG, ARG, ARG);
|
||||
const char *executef( ARG, ARG, ARG, ARG);
|
||||
const char *executef( ARG, ARG, ARG, ARG, ARG);
|
||||
const char *executef( ARG, ARG, ARG, ARG, ARG, ARG);
|
||||
const char *executef( ARG, ARG, ARG, ARG, ARG, ARG, ARG);
|
||||
const char *executef( ARG, ARG, ARG, ARG, ARG, ARG, ARG, ARG);
|
||||
const char *executef( ARG, ARG, ARG, ARG, ARG, ARG, ARG, ARG, ARG);
|
||||
const char *executef( ARG, ARG, ARG, ARG, ARG, ARG, ARG, ARG, ARG, ARG);
|
||||
#undef ARG
|
||||
/// NOTE: this function restores the console stack on return.
|
||||
ConsoleValueRef execute(S32 argc, const char* argv[]);
|
||||
ConsoleValueRef execute(S32 argc, ConsoleValueRef argv[]);
|
||||
|
||||
/// Call a Torque Script member function of a SimObject from C/C++ code.
|
||||
/// @param object Object on which to execute the method call.
|
||||
|
|
@ -783,35 +772,23 @@ namespace Con
|
|||
/// char* argv[] = {"setMode", "", "2"};
|
||||
/// char* result = execute(mysimobject, 3, argv);
|
||||
/// @endcode
|
||||
const char *execute(SimObject *object, S32 argc, const char *argv[], bool thisCallOnly = false);
|
||||
const char *execute(SimObject *object, S32 argc, ConsoleValueRef argv[], bool thisCallOnly = false);
|
||||
|
||||
/// @see execute(SimObject *, S32 argc, ConsoleValueRef argv[])
|
||||
#define ARG ConsoleValueRef
|
||||
const char *executef(SimObject *, ARG);
|
||||
const char *executef(SimObject *, ARG, ARG);
|
||||
const char *executef(SimObject *, ARG, ARG, ARG);
|
||||
const char *executef(SimObject *, ARG, ARG, ARG, ARG);
|
||||
const char *executef(SimObject *, ARG, ARG, ARG, ARG, ARG);
|
||||
const char *executef(SimObject *, ARG, ARG, ARG, ARG, ARG, ARG);
|
||||
const char *executef(SimObject *, ARG, ARG, ARG, ARG, ARG, ARG, ARG);
|
||||
const char *executef(SimObject *, ARG, ARG, ARG, ARG, ARG, ARG, ARG, ARG);
|
||||
const char *executef(SimObject *, ARG, ARG, ARG, ARG, ARG, ARG, ARG, ARG, ARG);
|
||||
const char *executef(SimObject *, ARG, ARG, ARG, ARG, ARG, ARG, ARG, ARG, ARG, ARG);
|
||||
const char *executef(SimObject *, ARG, ARG, ARG, ARG, ARG, ARG, ARG, ARG, ARG, ARG, ARG);
|
||||
#undef ARG
|
||||
/// NOTE: this function restores the console stack on return.
|
||||
ConsoleValueRef execute(SimObject *object, S32 argc, const char* argv[], bool thisCallOnly = false);
|
||||
ConsoleValueRef execute(SimObject *object, S32 argc, ConsoleValueRef argv[], bool thisCallOnly = false);
|
||||
|
||||
/// Evaluate an arbitrary chunk of code.
|
||||
///
|
||||
/// @param string Buffer containing code to execute.
|
||||
/// @param echo Should we echo the string to the console?
|
||||
/// @param fileName Indicate what file this code is coming from; used in error reporting and such.
|
||||
const char *evaluate(const char* string, bool echo = false, const char *fileName = NULL);
|
||||
/// NOTE: This function restores the console stack on return.
|
||||
ConsoleValueRef evaluate(const char* string, bool echo = false, const char *fileName = NULL);
|
||||
|
||||
/// Evaluate an arbitrary line of script.
|
||||
///
|
||||
/// This wraps dVsprintf(), so you can substitute parameters into the code being executed.
|
||||
const char *evaluatef(const char* string, ...);
|
||||
/// NOTE: This function restores the console stack on return.
|
||||
ConsoleValueRef evaluatef(const char* string, ...);
|
||||
|
||||
/// @}
|
||||
|
||||
|
|
@ -831,14 +808,12 @@ namespace Con
|
|||
char* getReturnBuffer( const StringBuilder& str );
|
||||
|
||||
char* getArgBuffer(U32 bufferSize);
|
||||
ConsoleValueRef getFloatArg(F64 arg);
|
||||
ConsoleValueRef getIntArg (S32 arg);
|
||||
char* getStringArg( const char *arg );
|
||||
char* getFloatArg(F64 arg);
|
||||
char* getIntArg (S32 arg);
|
||||
char* getStringArg( const char* arg );
|
||||
char* getStringArg( const String& arg );
|
||||
/// @}
|
||||
|
||||
void resetStackFrame();
|
||||
|
||||
/// @name Namespaces
|
||||
/// @{
|
||||
|
||||
|
|
@ -872,21 +847,47 @@ namespace Con
|
|||
/// @name Dynamic Type System
|
||||
/// @{
|
||||
|
||||
///
|
||||
/* void registerType( const char *typeName, S32 type, S32 size, GetDataFunction gdf, SetDataFunction sdf, bool isDatablockType = false );
|
||||
void registerType( const char* typeName, S32 type, S32 size, bool isDatablockType = false );
|
||||
void registerTypeGet( S32 type, GetDataFunction gdf );
|
||||
void registerTypeSet( S32 type, SetDataFunction sdf );
|
||||
|
||||
const char *getTypeName(S32 type);
|
||||
bool isDatablockType( S32 type ); */
|
||||
|
||||
void setData(S32 type, void *dptr, S32 index, S32 argc, const char **argv, const EnumTable *tbl = NULL, BitSet32 flag = 0);
|
||||
const char *getData(S32 type, void *dptr, S32 index, const EnumTable *tbl = NULL, BitSet32 flag = 0);
|
||||
const char *getFormattedData(S32 type, const char *data, const EnumTable *tbl = NULL, BitSet32 flag = 0);
|
||||
|
||||
/// @}
|
||||
};
|
||||
|
||||
struct _EngineConsoleCallbackHelper;
|
||||
template<typename P1> struct _EngineConsoleExecCallbackHelper;
|
||||
|
||||
namespace Con
|
||||
{
|
||||
/// @name Console Execution - executef
|
||||
/// {
|
||||
///
|
||||
/// Implements a script function thunk which automatically converts parameters to relevant console types.
|
||||
/// Can be used as follows:
|
||||
/// - Con::executef("functionName", ...);
|
||||
/// - Con::executef(mySimObject, "functionName", ...);
|
||||
///
|
||||
/// NOTE: if you get a rather cryptic template error coming through here, most likely you are trying to
|
||||
/// convert a parameter which EngineMarshallType does not have a specialization for.
|
||||
/// Another problem can occur if you do not include "console/simBase.h" and "console/engineAPI.h"
|
||||
/// since _EngineConsoleExecCallbackHelper and SimConsoleThreadExecCallback are required.
|
||||
///
|
||||
/// @see _EngineConsoleExecCallbackHelper
|
||||
///
|
||||
template<typename A> ConsoleValueRef executef(A a) { _EngineConsoleExecCallbackHelper<A> callback( a ); return callback.call<ConsoleValueRef>(); }
|
||||
template<typename A, typename B> ConsoleValueRef executef(A a, B b) { _EngineConsoleExecCallbackHelper<A> callback( a ); return callback.call<ConsoleValueRef>(b); }
|
||||
template<typename A, typename B, typename C> ConsoleValueRef executef(A a, B b, C c) { _EngineConsoleExecCallbackHelper<A> callback( a ); return callback.call<ConsoleValueRef>(b, c); }
|
||||
template<typename A, typename B, typename C, typename D> ConsoleValueRef executef(A a, B b, C c, D d) { _EngineConsoleExecCallbackHelper<A> callback( a ); return callback.call<ConsoleValueRef>(b, c, d); }
|
||||
template<typename A, typename B, typename C, typename D, typename E> ConsoleValueRef executef(A a, B b, C c, D d, E e) { _EngineConsoleExecCallbackHelper<A> callback( a ); return callback.call<ConsoleValueRef>(b, c, d, e); }
|
||||
template<typename A, typename B, typename C, typename D, typename E, typename F> ConsoleValueRef executef(A a, B b, C c, D d, E e, F f) { _EngineConsoleExecCallbackHelper<A> callback( a ); return callback.call<ConsoleValueRef>(b, c, d, e, f); }
|
||||
template<typename A, typename B, typename C, typename D, typename E, typename F, typename G> ConsoleValueRef executef(A a, B b, C c, D d, E e, F f, G g) { _EngineConsoleExecCallbackHelper<A> callback( a ); return callback.call<ConsoleValueRef>(b, c, d, e, f, g); }
|
||||
template<typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H> ConsoleValueRef executef(A a, B b, C c, D d, E e, F f, G g, H h) { _EngineConsoleExecCallbackHelper<A> callback( a ); return callback.call<ConsoleValueRef>(b, c, d, e, f, g, h); }
|
||||
template<typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I> ConsoleValueRef executef(A a, B b, C c, D d, E e, F f, G g, H h, I i) { _EngineConsoleExecCallbackHelper<A> callback( a ); return callback.call<ConsoleValueRef>(b, c, d, e, f, g, h, i); }
|
||||
template<typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J> ConsoleValueRef executef(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j) { _EngineConsoleExecCallbackHelper<A> callback( a ); return callback.call<ConsoleValueRef>(b, c, d, e, f, g, h, i, j); }
|
||||
template<typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J, typename K> ConsoleValueRef executef(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k) { _EngineConsoleExecCallbackHelper<A> callback( a ); return callback.call<ConsoleValueRef>(b, c, d, e, f, g, h, i, j, k); }
|
||||
/// }
|
||||
};
|
||||
|
||||
extern void expandEscape(char *dest, const char *src);
|
||||
extern bool collapseEscape(char *buf);
|
||||
extern U32 HashPointer(StringTableEntry ptr);
|
||||
|
|
@ -1103,6 +1104,28 @@ struct ConsoleDocFragment
|
|||
};
|
||||
|
||||
|
||||
/// Utility class to save and restore the current console stack frame
|
||||
///
|
||||
class ConsoleStackFrameSaver
|
||||
{
|
||||
public:
|
||||
|
||||
bool mSaved;
|
||||
|
||||
ConsoleStackFrameSaver() : mSaved(false)
|
||||
{
|
||||
}
|
||||
|
||||
~ConsoleStackFrameSaver()
|
||||
{
|
||||
restore();
|
||||
}
|
||||
|
||||
void save();
|
||||
void restore();
|
||||
};
|
||||
|
||||
|
||||
/// @name Global Console Definition Macros
|
||||
///
|
||||
/// @note If TORQUE_DEBUG is defined, then we gather documentation information, and
|
||||
|
|
|
|||
|
|
@ -1338,14 +1338,20 @@ void Namespace::markGroup(const char* name, const char* usage)
|
|||
|
||||
extern S32 executeBlock(StmtNode *block, ExprEvalState *state);
|
||||
|
||||
const char *Namespace::Entry::execute(S32 argc, ConsoleValueRef *argv, ExprEvalState *state)
|
||||
ConsoleValueRef Namespace::Entry::execute(S32 argc, ConsoleValueRef *argv, ExprEvalState *state)
|
||||
{
|
||||
STR.clearFunctionOffset();
|
||||
|
||||
if(mType == ConsoleFunctionType)
|
||||
{
|
||||
if(mFunctionOffset)
|
||||
{
|
||||
return mCode->exec(mFunctionOffset, argv[0], mNamespace, argc, argv, false, mPackage);
|
||||
}
|
||||
else
|
||||
return "";
|
||||
{
|
||||
return ConsoleValueRef();
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef TORQUE_DEBUG
|
||||
|
|
@ -1354,7 +1360,7 @@ const char *Namespace::Entry::execute(S32 argc, ConsoleValueRef *argv, ExprEvalS
|
|||
if(mToolOnly && ! Con::isCurrentScriptToolScript())
|
||||
{
|
||||
Con::errorf(ConsoleLogEntry::Script, "%s::%s - attempting to call tools only function from outside of tools", mNamespace->mName, mFunctionName);
|
||||
return "";
|
||||
return ConsoleValueRef();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -1362,32 +1368,26 @@ const char *Namespace::Entry::execute(S32 argc, ConsoleValueRef *argv, ExprEvalS
|
|||
{
|
||||
Con::warnf(ConsoleLogEntry::Script, "%s::%s - wrong number of arguments.", mNamespace->mName, mFunctionName);
|
||||
Con::warnf(ConsoleLogEntry::Script, "usage: %s", mUsage);
|
||||
return "";
|
||||
return ConsoleValueRef();
|
||||
}
|
||||
|
||||
static char returnBuffer[32];
|
||||
switch(mType)
|
||||
{
|
||||
case StringCallbackType:
|
||||
return cb.mStringCallbackFunc(state->thisObject, argc, argv);
|
||||
return ConsoleValueRef::fromValue(CSTK.pushStackString(cb.mStringCallbackFunc(state->thisObject, argc, argv)));
|
||||
case IntCallbackType:
|
||||
dSprintf(returnBuffer, sizeof(returnBuffer), "%d",
|
||||
cb.mIntCallbackFunc(state->thisObject, argc, argv));
|
||||
return returnBuffer;
|
||||
return ConsoleValueRef::fromValue(CSTK.pushUINT((U32)cb.mBoolCallbackFunc(state->thisObject, argc, argv)));
|
||||
case FloatCallbackType:
|
||||
dSprintf(returnBuffer, sizeof(returnBuffer), "%g",
|
||||
cb.mFloatCallbackFunc(state->thisObject, argc, argv));
|
||||
return returnBuffer;
|
||||
return ConsoleValueRef::fromValue(CSTK.pushFLT((U32)cb.mBoolCallbackFunc(state->thisObject, argc, argv)));
|
||||
case VoidCallbackType:
|
||||
cb.mVoidCallbackFunc(state->thisObject, argc, argv);
|
||||
return "";
|
||||
return ConsoleValueRef();
|
||||
case BoolCallbackType:
|
||||
dSprintf(returnBuffer, sizeof(returnBuffer), "%d",
|
||||
(U32)cb.mBoolCallbackFunc(state->thisObject, argc, argv));
|
||||
return returnBuffer;
|
||||
return ConsoleValueRef::fromValue(CSTK.pushUINT((U32)cb.mBoolCallbackFunc(state->thisObject, argc, argv)));
|
||||
}
|
||||
|
||||
return "";
|
||||
|
||||
return ConsoleValueRef();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -151,7 +151,7 @@ class Namespace
|
|||
void clear();
|
||||
|
||||
///
|
||||
const char *execute( S32 argc, ConsoleValueRef* argv, ExprEvalState* state );
|
||||
ConsoleValueRef execute( S32 argc, ConsoleValueRef* argv, ExprEvalState* state );
|
||||
|
||||
/// Return a one-line documentation text string for the function.
|
||||
String getBriefDescription( String* outRemainingDocText = NULL ) const;
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -157,13 +157,13 @@ namespace Sim
|
|||
SimTime getTargetTime();
|
||||
|
||||
/// a target time of 0 on an event means current event
|
||||
U32 postEvent(SimObject*, SimEvent*, U32 targetTime);
|
||||
U32 postEvent(SimObject*, SimEvent*, SimTime targetTime);
|
||||
|
||||
inline U32 postEvent(SimObjectId iD,SimEvent*evt, U32 targetTime)
|
||||
inline U32 postEvent(SimObjectId iD,SimEvent*evt, SimTime targetTime)
|
||||
{
|
||||
return postEvent(findObject(iD), evt, targetTime);
|
||||
}
|
||||
inline U32 postEvent(const char *objectName,SimEvent*evt, U32 targetTime)
|
||||
inline U32 postEvent(const char *objectName,SimEvent*evt, SimTime targetTime)
|
||||
{
|
||||
return postEvent(findObject(objectName), evt, targetTime);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,7 +39,10 @@ SimConsoleEvent::SimConsoleEvent(S32 argc, ConsoleValueRef *argv, bool onObject)
|
|||
mArgv[i].value = new ConsoleValue();
|
||||
mArgv[i].value->type = ConsoleValue::TypeInternalString;
|
||||
mArgv[i].value->init();
|
||||
mArgv[i].value->setStringValue((const char*)argv[i]);
|
||||
if (argv)
|
||||
{
|
||||
mArgv[i].value->setStringValue((const char*)argv[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -92,10 +95,19 @@ void SimConsoleEvent::process(SimObject* object)
|
|||
}
|
||||
}
|
||||
|
||||
void SimConsoleEvent::populateArgs(ConsoleValueRef *argv)
|
||||
{
|
||||
for (U32 i=0; i<mArgc; i++)
|
||||
{
|
||||
argv[i].value = mArgv[i].value;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
SimConsoleThreadExecCallback::SimConsoleThreadExecCallback() : retVal(NULL)
|
||||
SimConsoleThreadExecCallback::SimConsoleThreadExecCallback()
|
||||
{
|
||||
retVal.value = NULL;
|
||||
sem = new Semaphore(0);
|
||||
}
|
||||
|
||||
|
|
@ -104,13 +116,13 @@ SimConsoleThreadExecCallback::~SimConsoleThreadExecCallback()
|
|||
delete sem;
|
||||
}
|
||||
|
||||
void SimConsoleThreadExecCallback::handleCallback(const char *ret)
|
||||
void SimConsoleThreadExecCallback::handleCallback(ConsoleValueRef ret)
|
||||
{
|
||||
retVal = ret;
|
||||
sem->release();
|
||||
}
|
||||
|
||||
const char *SimConsoleThreadExecCallback::waitForResult()
|
||||
ConsoleValueRef SimConsoleThreadExecCallback::waitForResult()
|
||||
{
|
||||
if(sem->acquire(true))
|
||||
{
|
||||
|
|
@ -129,7 +141,7 @@ SimConsoleThreadExecEvent::SimConsoleThreadExecEvent(S32 argc, ConsoleValueRef *
|
|||
|
||||
void SimConsoleThreadExecEvent::process(SimObject* object)
|
||||
{
|
||||
const char *retVal;
|
||||
ConsoleValueRef retVal;
|
||||
if(mOnObject)
|
||||
retVal = Con::execute(object, mArgc, mArgv);
|
||||
else
|
||||
|
|
|
|||
|
|
@ -114,19 +114,22 @@ public:
|
|||
|
||||
~SimConsoleEvent();
|
||||
virtual void process(SimObject *object);
|
||||
|
||||
/// Creates a reference to our internal args list in argv
|
||||
void populateArgs(ConsoleValueRef *argv);
|
||||
};
|
||||
|
||||
/// Used by Con::threadSafeExecute()
|
||||
struct SimConsoleThreadExecCallback
|
||||
{
|
||||
Semaphore *sem;
|
||||
const char *retVal;
|
||||
ConsoleValueRef retVal;
|
||||
|
||||
SimConsoleThreadExecCallback();
|
||||
~SimConsoleThreadExecCallback();
|
||||
|
||||
void handleCallback(const char *ret);
|
||||
const char *waitForResult();
|
||||
void handleCallback(ConsoleValueRef ret);
|
||||
ConsoleValueRef waitForResult();
|
||||
};
|
||||
|
||||
class SimConsoleThreadExecEvent : public SimConsoleEvent
|
||||
|
|
@ -136,6 +139,7 @@ class SimConsoleThreadExecEvent : public SimConsoleEvent
|
|||
public:
|
||||
SimConsoleThreadExecEvent(S32 argc, ConsoleValueRef *argv, bool onObject, SimConsoleThreadExecCallback *callback);
|
||||
|
||||
SimConsoleThreadExecCallback& getCB() { return *cb; }
|
||||
virtual void process(SimObject *object);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,8 @@
|
|||
#include "platform/platform.h"
|
||||
#include "console/simObjectList.h"
|
||||
|
||||
#include "console/console.h"
|
||||
#include "console/simBase.h"
|
||||
#include "console/engineAPI.h"
|
||||
#include "console/sim.h"
|
||||
#include "console/simObject.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -31,12 +31,11 @@ void ConsoleValueStack::getArgcArgv(StringTableEntry name, U32 *argc, ConsoleVal
|
|||
U32 argCount = getMin(mStackPos - startStack, (U32)MaxArgs - 1);
|
||||
|
||||
*in_argv = mArgv;
|
||||
mArgv[0] = name;
|
||||
mArgv[0].value = CSTK.pushStackString(name);
|
||||
|
||||
for(U32 i = 0; i < argCount; i++) {
|
||||
ConsoleValueRef *ref = &mArgv[i+1];
|
||||
ref->value = &mStack[startStack + i];
|
||||
ref->stringStackValue = NULL;
|
||||
}
|
||||
argCount++;
|
||||
|
||||
|
|
@ -96,6 +95,36 @@ void ConsoleValueStack::pushValue(ConsoleValue &variable)
|
|||
}
|
||||
}
|
||||
|
||||
ConsoleValue* ConsoleValueStack::reserveValues(U32 count)
|
||||
{
|
||||
U32 startPos = mStackPos;
|
||||
if (startPos+count >= ConsoleValueStack::MaxStackDepth) {
|
||||
AssertFatal(false, "Console Value Stack is empty");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//Con::printf("[%i]CSTK reserveValues %i", mStackPos, count);
|
||||
mStackPos += count;
|
||||
return &mStack[startPos];
|
||||
}
|
||||
|
||||
bool ConsoleValueStack::reserveValues(U32 count, ConsoleValueRef *outValues)
|
||||
{
|
||||
U32 startPos = mStackPos;
|
||||
if (startPos+count >= ConsoleValueStack::MaxStackDepth) {
|
||||
AssertFatal(false, "Console Value Stack is empty");
|
||||
return false;
|
||||
}
|
||||
|
||||
//Con::printf("[%i]CSTK reserveValues %i", mStackPos, count);
|
||||
for (U32 i=0; i<count; i++)
|
||||
{
|
||||
outValues[i].value = &mStack[mStackPos+i];
|
||||
}
|
||||
mStackPos += count;
|
||||
return true;
|
||||
}
|
||||
|
||||
ConsoleValue *ConsoleValueStack::pushString(const char *value)
|
||||
{
|
||||
if (mStackPos == ConsoleValueStack::MaxStackDepth) {
|
||||
|
|
|
|||
|
|
@ -127,6 +127,7 @@ struct StringStack
|
|||
/// Return a temporary buffer we can use to return data.
|
||||
char* getReturnBuffer(U32 size)
|
||||
{
|
||||
AssertFatal(Con::isMainThread(), "Manipulating return buffer from a secondary thread!");
|
||||
validateArgBufferSize(size);
|
||||
return mArgBuffer;
|
||||
}
|
||||
|
|
@ -136,6 +137,7 @@ struct StringStack
|
|||
/// This updates the function offset.
|
||||
char *getArgBuffer(U32 size)
|
||||
{
|
||||
AssertFatal(Con::isMainThread(), "Manipulating console arg buffer from a secondary thread!");
|
||||
validateBufferSize(mStart + mFunctionOffset + size);
|
||||
char *ret = mBuffer + mStart + mFunctionOffset;
|
||||
mFunctionOffset += size;
|
||||
|
|
@ -314,6 +316,8 @@ public:
|
|||
|
||||
void pushVar(ConsoleValue *variable);
|
||||
void pushValue(ConsoleValue &value);
|
||||
ConsoleValue* reserveValues(U32 numValues);
|
||||
bool reserveValues(U32 numValues, ConsoleValueRef *values);
|
||||
ConsoleValue* pop();
|
||||
|
||||
ConsoleValue *pushString(const char *value);
|
||||
|
|
@ -338,4 +342,7 @@ public:
|
|||
ConsoleValueRef mArgv[MaxArgs];
|
||||
};
|
||||
|
||||
extern StringStack STR;
|
||||
extern ConsoleValueStack CSTK;
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue