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:
James Urquhart 2015-02-07 22:41:54 +00:00
parent b1ad72692c
commit f44a3f27d6
43 changed files with 1781 additions and 358 deletions

View file

@ -459,6 +459,14 @@ bool GameConnection::readConnectRequest(BitStream *stream, const char **errorStr
return false;
}
ConsoleValueRef connectArgv[MaxConnectArgs + 3];
ConsoleValue connectArgvValue[MaxConnectArgs + 3];
for(U32 i = 0; i < mConnectArgc+3; i++)
{
connectArgv[i].value = &connectArgvValue[i];
connectArgvValue[i].init();
}
for(U32 i = 0; i < mConnectArgc; i++)
{
char argString[256];
@ -466,11 +474,11 @@ bool GameConnection::readConnectRequest(BitStream *stream, const char **errorStr
mConnectArgv[i] = dStrdup(argString);
connectArgv[i + 3] = mConnectArgv[i];
}
connectArgv[0] = "onConnectRequest";
connectArgv[1] = 0;
connectArgvValue[0].setStackStringValue("onConnectRequest");
connectArgvValue[1].setIntValue(0);
char buffer[256];
Net::addressToString(getNetAddress(), buffer);
connectArgv[2] = buffer;
connectArgvValue[2].setStackStringValue(buffer);
// NOTE: Cannot convert over to IMPLEMENT_CALLBACK as it has variable args.
const char *ret = Con::execute(this, mConnectArgc + 3, connectArgv);

View file

@ -32,6 +32,7 @@
#include "app/game.h"
#include "T3D/gameBase/gameConnection.h"
#include "T3D/gameBase/gameConnectionEvents.h"
#include "console/engineAPI.h"
#define DebugChecksum 0xF00DBAAD
@ -234,7 +235,7 @@ void SimDataBlockEvent::process(NetConnection *cptr)
if(mProcess)
{
//call the console function to set the number of blocks to be sent
Con::executef("onDataBlockObjectReceived", Con::getIntArg(mIndex), Con::getIntArg(mTotal));
Con::executef("onDataBlockObjectReceived", mIndex, mTotal);
String &errorBuffer = NetConnection::getErrorBuffer();

View file

@ -292,7 +292,7 @@ IMPLEMENT_CALLBACK( Item, onStickyCollision, void, ( const char* objID ),( objID
"@see Item, ItemData\n"
);
IMPLEMENT_CALLBACK( Item, onEnterLiquid, void, ( const char* objID, const char* waterCoverage, const char* liquidType ),( objID, waterCoverage, liquidType ),
IMPLEMENT_CALLBACK( Item, onEnterLiquid, void, ( const char* objID, F32 waterCoverage, const char* liquidType ),( objID, waterCoverage, liquidType ),
"Informs an Item object that it has entered liquid, along with information about the liquid type.\n"
"@param objID Object ID for this Item object.\n"
"@param waterCoverage How much coverage of water this Item object has.\n"
@ -1005,7 +1005,7 @@ void Item::updatePos(const U32 /*mask*/, const F32 dt)
{
if(!mInLiquid && mWaterCoverage != 0.0f)
{
onEnterLiquid_callback( getIdString(), Con::getFloatArg(mWaterCoverage), mLiquidType.c_str() );
onEnterLiquid_callback( getIdString(), mWaterCoverage, mLiquidType.c_str() );
mInLiquid = true;
}
else if(mInLiquid && mWaterCoverage == 0.0f)

View file

@ -114,7 +114,7 @@ class Item: public ShapeBase
protected:
DECLARE_CALLBACK( void, onStickyCollision, ( const char* objID ));
DECLARE_CALLBACK( void, onEnterLiquid, ( const char* objID, const char* waterCoverage, const char* liquidType ));
DECLARE_CALLBACK( void, onEnterLiquid, ( const char* objID, F32 waterCoverage, const char* liquidType ));
DECLARE_CALLBACK( void, onLeaveLiquid, ( const char* objID, const char* liquidType ));
public:

View file

@ -104,7 +104,7 @@ ConsoleDocClass( PathCamera,
"@ingroup PathCameras\n"
);
IMPLEMENT_CALLBACK( PathCamera, onNode, void, (const char* node), (node),
IMPLEMENT_CALLBACK( PathCamera, onNode, void, (S32 node), (node),
"A script callback that indicates the path camera has arrived at a specific node in its path. Server side only.\n"
"@param Node Unique ID assigned to this node.\n");
@ -408,7 +408,7 @@ void PathCamera::popFront()
void PathCamera::onNode(S32 node)
{
if (!isGhost())
onNode_callback(Con::getIntArg(node));
onNode_callback(node);
}

View file

@ -93,7 +93,7 @@ private:
public:
DECLARE_CONOBJECT(PathCamera);
DECLARE_CALLBACK( void, onNode, (const char* node));
DECLARE_CALLBACK( void, onNode, (S32 node));
PathCamera();
~PathCamera();

View file

@ -153,7 +153,7 @@ ConsoleDocClass( RigidShape,
);
IMPLEMENT_CALLBACK( RigidShape, onEnterLiquid, void, ( const char* objId, const char* waterCoverage, const char* liquidType ),
IMPLEMENT_CALLBACK( RigidShape, onEnterLiquid, void, ( const char* objId, F32 waterCoverage, const char* liquidType ),
( objId, waterCoverage, liquidType ),
"@brief Called whenever this RigidShape object enters liquid.\n\n"
"@param objId The ID of the rigidShape object.\n"
@ -1088,7 +1088,7 @@ void RigidShape::updatePos(F32 dt)
// Water script callbacks
if (!inLiquid && mWaterCoverage != 0.0f)
{
onEnterLiquid_callback(getIdString(), Con::getFloatArg(mWaterCoverage), mLiquidType.c_str() );
onEnterLiquid_callback(getIdString(), mWaterCoverage, mLiquidType.c_str() );
inLiquid = true;
}
else if (inLiquid && mWaterCoverage == 0.0f)

View file

@ -296,7 +296,7 @@ public:
void unpackUpdate(NetConnection *conn, BitStream *stream);
DECLARE_CONOBJECT(RigidShape);
DECLARE_CALLBACK( void, onEnterLiquid, ( const char* objId, const char* waterCoverage, const char* liquidType ));
DECLARE_CALLBACK( void, onEnterLiquid, ( const char* objId, F32 waterCoverage, const char* liquidType ));
DECLARE_CALLBACK( void, onLeaveLiquid, ( const char* objId, const char* liquidType ));
};

View file

@ -1342,7 +1342,7 @@ static void processPingsAndQueries( U32 session, bool schedule )
else
dSprintf( msg, sizeof( msg ), "%d servers found.", foundCount );
Con::executef( "onServerQueryStatus", "done", msg, "1");
Con::executef( "onServerQueryStatus", "done", (const char*)msg, "1");
}
}

View file

@ -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 );
}

View file

@ -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();

View file

@ -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

View file

@ -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;

View file

@ -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();
}
}
}

View file

@ -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

View file

@ -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();
}
//-----------------------------------------------------------------------------

View file

@ -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

View file

@ -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);
}

View file

@ -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

View file

@ -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);
};

View file

@ -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"

View file

@ -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) {

View file

@ -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

View file

@ -517,7 +517,7 @@ bool ForestSelectionTool::updateGuiInfo()
Con::executef( statusbar, "setInfo", text.c_str() );
Con::executef( statusbar, "setSelectionObjectsByCount", Con::getIntArg( mSelection.size() ) );
Con::executef( statusbar, "setSelectionObjectsByCount", mSelection.size() );
return true;
}

View file

@ -113,7 +113,7 @@ void GuiConsoleTextCtrl::onPreRender()
{
if ( mConsoleExpression.isNotEmpty() )
{
mResult = Con::evaluatef( "$guiConsoleTextCtrlTemp = %s;", mConsoleExpression.c_str() );
mResult = (const char*)Con::evaluatef( "$guiConsoleTextCtrlTemp = %s;", mConsoleExpression.c_str() );
// Of the resulting string we will be printing,
// Find the number of lines and length of each.

View file

@ -71,7 +71,7 @@ IMPLEMENT_CALLBACK( GuiListBoxCtrl, onClearSelection, void, (),(),
"@see GuiControl\n\n"
);
IMPLEMENT_CALLBACK( GuiListBoxCtrl, onUnSelect, void, ( const char* index, const char* itemText),( index, itemText ),
IMPLEMENT_CALLBACK( GuiListBoxCtrl, onUnSelect, void, ( S32 index, const char* itemText),( index, itemText ),
"@brief Called whenever a selected item in the list has been unselected.\n\n"
"@param index Index id of the item that was unselected\n"
"@param itemText Text for the list entry at the index id that was unselected\n\n"
@ -85,7 +85,7 @@ IMPLEMENT_CALLBACK( GuiListBoxCtrl, onUnSelect, void, ( const char* index, const
"@see GuiControl\n\n"
);
IMPLEMENT_CALLBACK( GuiListBoxCtrl, onSelect, void, ( const char* index , const char* itemText ),( index, itemText ),
IMPLEMENT_CALLBACK( GuiListBoxCtrl, onSelect, void, ( S32 index , const char* itemText ),( index, itemText ),
"@brief Called whenever an item in the list is selected.\n\n"
"@param index Index id for the item in the list that was selected.\n"
"@param itemText Text for the list item at the index that was selected.\n\n"
@ -111,7 +111,7 @@ IMPLEMENT_CALLBACK( GuiListBoxCtrl, onDoubleClick, void, (),(),
"@see GuiControl\n\n"
);
IMPLEMENT_CALLBACK( GuiListBoxCtrl, onMouseUp, void, (const char* itemHit, const char* mouseClickCount),( itemHit,mouseClickCount),
IMPLEMENT_CALLBACK( GuiListBoxCtrl, onMouseUp, void, ( S32 itemHit, S32 mouseClickCount ),( itemHit,mouseClickCount ),
"@brief Called whenever the mouse has previously been clicked down (onMouseDown) and has now been raised on the control.\n"
"If an item in the list was hit during the click cycle, then the index id of the clicked object along with how many clicks occured are passed\n"
"into the callback.\n\n"
@ -309,7 +309,7 @@ void GuiListBoxCtrl::removeSelection( LBItem *item, S32 index )
{
mSelectedItems.erase( &mSelectedItems[i] );
item->isSelected = false;
onUnSelect_callback(Con::getIntArg(index), item->itemText);
onUnSelect_callback(index, item->itemText);
return;
}
}
@ -355,7 +355,7 @@ void GuiListBoxCtrl::addSelection( LBItem *item, S32 index )
item->isSelected = true;
mSelectedItems.push_front( item );
onSelect_callback(Con::getIntArg( index ), item->itemText);
onSelect_callback(index, item->itemText);
}
S32 GuiListBoxCtrl::getItemIndex( LBItem *item )
@ -1224,7 +1224,7 @@ void GuiListBoxCtrl::onMouseUp( const GuiEvent& event )
{
S32 itemHit = -1;
if( hitTest( event.mousePoint, itemHit ) )
onMouseUp_callback(Con::getIntArg( itemHit ), Con::getIntArg( event.mouseClickCount ) );
onMouseUp_callback( itemHit, event.mouseClickCount );
// Execute console command
execConsoleCallback();

View file

@ -57,10 +57,10 @@ public:
DECLARE_CALLBACK( void, onMouseDragged, ());
DECLARE_CALLBACK( void, onClearSelection, ());
DECLARE_CALLBACK( void, onUnSelect, ( const char* index, const char* itemText));
DECLARE_CALLBACK( void, onSelect, ( const char* index , const char* itemText ));
DECLARE_CALLBACK( void, onUnSelect, ( S32 index, const char* itemText));
DECLARE_CALLBACK( void, onSelect, ( S32 index , const char* itemText ));
DECLARE_CALLBACK( void, onDoubleClick, ());
DECLARE_CALLBACK( void, onMouseUp, (const char* itemHit, const char* mouseClickCount));
DECLARE_CALLBACK( void, onMouseUp, ( S32 itemHit, S32 mouseClickCount ));
DECLARE_CALLBACK( void, onDeleteKey, ());
DECLARE_CALLBACK( bool, isObjectMirrored, ( const char* indexIdString ));

View file

@ -73,7 +73,7 @@ IMPLEMENT_CALLBACK( GuiMLTextCtrl, onURL, void, ( const char* url ),( url ),
"@see GuiControl\n\n"
);
IMPLEMENT_CALLBACK( GuiMLTextCtrl, onResize, void, ( const char* width, const char* maxY ),( width, maxY ),
IMPLEMENT_CALLBACK( GuiMLTextCtrl, onResize, void, ( S32 width, S32 maxY ),( width, maxY ),
"@brief Called whenever the control size changes.\n\n"
"@param width The new width value for the control\n"
"@param maxY The current maximum allowed Y value for the control\n\n"
@ -2133,7 +2133,7 @@ textemit:
processEmitAtoms();
emitNewLine(mScanPos);
setHeight( mMaxY );
onResize_callback(Con::getIntArg( getWidth() ), Con::getIntArg( mMaxY ) );
onResize_callback( getWidth(), mMaxY );
//make sure the cursor is still visible - this handles if we're a child of a scroll ctrl...
ensureCursorOnScreen();

View file

@ -128,7 +128,7 @@ class GuiMLTextCtrl : public GuiControl
~GuiMLTextCtrl();
DECLARE_CALLBACK( void, onURL, (const char* url));
DECLARE_CALLBACK( void, onResize, ( const char* width, const char* maxY ));
DECLARE_CALLBACK( void, onResize, ( S32 width, S32 maxY ));
// Text retrieval functions
U32 getNumChars() const;

View file

@ -52,7 +52,7 @@ ConsoleDocClass( GuiTextListCtrl,
);
IMPLEMENT_CALLBACK( GuiTextListCtrl, onSelect, void, (const char* cellid, const char* text),( cellid , text ),
IMPLEMENT_CALLBACK( GuiTextListCtrl, onSelect, void, (S32 cellid, const char* text),( cellid , text ),
"@brief Called whenever an item in the list is selected.\n\n"
"@param cellid The ID of the cell that was selected\n"
"@param text The text in the selected cel\n\n"
@ -66,7 +66,7 @@ IMPLEMENT_CALLBACK( GuiTextListCtrl, onSelect, void, (const char* cellid, const
"@see GuiControl\n\n"
);
IMPLEMENT_CALLBACK( GuiTextListCtrl, onDeleteKey, void, ( const char* id ),( id ),
IMPLEMENT_CALLBACK( GuiTextListCtrl, onDeleteKey, void, ( S32 id ),( id ),
"@brief Called when the delete key has been pressed.\n\n"
"@param id Id of the selected item in the list\n"
"@tsexample\n"
@ -172,7 +172,7 @@ bool GuiTextListCtrl::cellSelected(Point2I cell)
void GuiTextListCtrl::onCellSelected(Point2I cell)
{
onSelect_callback(Con::getIntArg(mList[cell.y].id), mList[cell.y].text);
onSelect_callback(mList[cell.y].id, mList[cell.y].text);
execConsoleCallback();
}
@ -497,7 +497,7 @@ bool GuiTextListCtrl::onKeyDown( const GuiEvent &event )
break;
case KEY_DELETE:
if ( mSelectedCell.y >= 0 && mSelectedCell.y < mList.size() )
onDeleteKey_callback(Con::getIntArg( mList[mSelectedCell.y].id ) );
onDeleteKey_callback( mList[mSelectedCell.y].id );
break;
default:
return( Parent::onKeyDown( event ) );

View file

@ -67,8 +67,8 @@ class GuiTextListCtrl : public GuiArrayCtrl
DECLARE_CATEGORY( "Gui Lists" );
DECLARE_DESCRIPTION( "A control that displays text in tabular form." );
DECLARE_CALLBACK( void, onSelect, (const char* cellid, const char* text));
DECLARE_CALLBACK( void, onDeleteKey, ( const char* id ));
DECLARE_CALLBACK( void, onSelect, (S32 cellid, const char* text));
DECLARE_CALLBACK( void, onDeleteKey, ( S32 id ));
static void initPersistFields();

View file

@ -111,7 +111,7 @@ IMPLEMENT_CALLBACK( GuiMenuBar, onMouseInMenu, void, (bool isInMenu),( isInMenu
"@see GuiTickCtrl\n\n"
);
IMPLEMENT_CALLBACK( GuiMenuBar, onMenuSelect, void, ( const char* menuId, const char* menuText ),( menuId , menuText ),
IMPLEMENT_CALLBACK( GuiMenuBar, onMenuSelect, void, ( S32 menuId, const char* menuText ),( menuId , menuText ),
"@brief Called whenever a menu is selected.\n\n"
"@param menuId Index id of the clicked menu\n"
"@param menuText Text of the clicked menu\n\n"
@ -125,7 +125,7 @@ IMPLEMENT_CALLBACK( GuiMenuBar, onMenuSelect, void, ( const char* menuId, const
"@see GuiTickCtrl\n\n"
);
IMPLEMENT_CALLBACK( GuiMenuBar, onMenuItemSelect, void, ( const char* menuId, const char* menuText, const char* menuItemId, const char* menuItemText ),
IMPLEMENT_CALLBACK( GuiMenuBar, onMenuItemSelect, void, ( S32 menuId, const char* menuText, S32 menuItemId, const char* menuItemText ),
( menuId, menuText, menuItemId, menuItemText ),
"@brief Called whenever an item in a menu is selected.\n\n"
"@param menuId Index id of the menu which contains the selected menu item\n"
@ -142,7 +142,7 @@ IMPLEMENT_CALLBACK( GuiMenuBar, onMenuItemSelect, void, ( const char* menuId, co
"@see GuiTickCtrl\n\n"
);
IMPLEMENT_CALLBACK( GuiMenuBar, onSubmenuSelect, void, ( const char* submenuId, const char* submenuText ),( submenuId, submenuText ),
IMPLEMENT_CALLBACK( GuiMenuBar, onSubmenuSelect, void, ( S32 submenuId, const char* submenuText ),( submenuId, submenuText ),
"@brief Called whenever a submenu is selected.\n\n"
"@param submenuId Id of the selected submenu\n"
"@param submenuText Text of the selected submenu\n\n"
@ -1393,7 +1393,7 @@ void GuiMenuBar::acceleratorKeyPress(U32 index)
if(item->acceleratorIndex == index)
{
// first, call the script callback for menu selection:
onMenuSelect_callback(Con::getIntArg(menu->id), menu->text);
onMenuSelect_callback(menu->id, menu->text);
if(item->visible)
menuItemSelected(menu, item);
@ -1575,7 +1575,7 @@ bool GuiSubmenuBackgroundCtrl::pointInControl(const Point2I& parentCoordPoint)
void GuiMenuBar::menuItemSelected(GuiMenuBar::Menu *menu, GuiMenuBar::MenuItem *item)
{
if(item->enabled)
onMenuItemSelect_callback(Con::getIntArg(menu->id), menu->text, Con::getIntArg(item->id), item->text);
onMenuItemSelect_callback(menu->id, menu->text, item->id, item->text);
}
void GuiMenuBar::onSleep()
@ -1668,7 +1668,7 @@ void GuiMenuBar::onAction()
return;
// first, call the script callback for menu selection:
onMenuSelect_callback(Con::getIntArg(mouseDownMenu->id), mouseDownMenu->text);
onMenuSelect_callback(mouseDownMenu->id, mouseDownMenu->text);
MenuItem *visWalk = mouseDownMenu->firstMenuItem;
while(visWalk)
@ -1783,7 +1783,7 @@ void GuiMenuBar::onSubmenuAction(S32 selectionIndex, RectI bounds, Point2I cellS
return;
// first, call the script callback for menu selection:
onSubmenuSelect_callback(Con::getIntArg(mouseOverSubmenu->id), mouseOverSubmenu->text);
onSubmenuSelect_callback(mouseOverSubmenu->id, mouseOverSubmenu->text);
MenuItem *visWalk = mouseOverSubmenu->submenu->firstMenuItem;
while(visWalk)

View file

@ -220,10 +220,10 @@ public:
static void initPersistFields();
DECLARE_CONOBJECT(GuiMenuBar);
DECLARE_CALLBACK( void, onMouseInMenu, (bool hasLeftMenu));
DECLARE_CALLBACK( void, onMenuSelect, (const char* menuId, const char* menuText));
DECLARE_CALLBACK( void, onMenuItemSelect, ( const char* menuId, const char* menuText, const char* menuItemId, const char* menuItemText ));
DECLARE_CALLBACK( void, onSubmenuSelect, ( const char* submenuId, const char* submenuText));
DECLARE_CALLBACK( void, onMouseInMenu, ( bool hasLeftMenu ));
DECLARE_CALLBACK( void, onMenuSelect, ( S32 menuId, const char* menuText ));
DECLARE_CALLBACK( void, onMenuItemSelect, ( S32 menuId, const char* menuText, S32 menuItemId, const char* menuItemText ));
DECLARE_CALLBACK( void, onSubmenuSelect, ( S32 submenuId, const char* submenuText ));
};
#endif

View file

@ -20,6 +20,8 @@
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "console/simBase.h"
#include "console/engineAPI.h"
#include "gui/editor/inspector/customField.h"
#include "gui/editor/guiInspector.h"

View file

@ -269,7 +269,7 @@ void GuiInspectorField::setData( const char* data, bool callbacks )
{
char buffer[ 2048 ];
expandEscape( buffer, newValue );
newValue = Con::evaluatef( "%%f = \"%s\"; return ( %s );", oldValue.c_str(), buffer );
newValue = (const char*)Con::evaluatef( "%%f = \"%s\"; return ( %s );", oldValue.c_str(), buffer );
}
else if( type == TypeS32Vector
|| type == TypeF32Vector

View file

@ -24,6 +24,7 @@
#include "lighting/common/sceneLighting.h"
#include "T3D/gameBase/gameConnection.h"
#include "console/engineAPI.h"
#include "console/consoleTypes.h"
#include "scene/sceneManager.h"
#include "lighting/common/shadowVolumeBSP.h"
@ -605,7 +606,7 @@ void SceneLighting::completed(bool success)
}
if(gCompleteCallback && gCompleteCallback[0])
Con::executef(gCompleteCallback);
Con::executef((const char*)gCompleteCallback);
dFree(gCompleteCallback);
gCompleteCallback = NULL;

View file

@ -22,6 +22,7 @@
#include "core/strings/stringFunctions.h"
#include "console/console.h"
#include "console/simBase.h"
#include "console/engineAPI.h"
#include "platform/platformRedBook.h"

View file

@ -24,6 +24,7 @@
#include "platform/menus/popupMenu.h"
#include "platformWin32/platformWin32.h"
#include "console/engineAPI.h"
#include "console/consoleTypes.h"
#include "gui/core/guiCanvas.h"
#include "windowManager/platformWindowMgr.h"

View file

@ -20,6 +20,8 @@
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "console/simBase.h"
#include "console/engineAPI.h"
#include "sfx/sfxModifier.h"
#include "sfx/sfxSource.h"

View file

@ -22,6 +22,7 @@
#include "sfx/sfxParameter.h"
#include "console/consoleTypes.h"
#include "console/simBase.h"
#include "console/engineAPI.h"
#include "console/simSet.h"
#include "math/mMathFn.h"

View file

@ -23,6 +23,7 @@
#include "platform/platform.h"
#include "core/dnet.h"
#include "console/simBase.h"
#include "console/engineAPI.h"
#include "sim/netConnection.h"
#include "core/stream/bitStream.h"
#include "core/stream/fileStream.h"

View file

@ -29,6 +29,12 @@
#ifndef _TVECTOR_H_
#include "core/util/tVector.h"
#endif
#ifndef _SIMBASE_H_
#include "console/simBase.h"
#endif
#ifndef _ENGINEAPI_H_
#include "console/engineAPI.h"
#endif
class UndoManager;