Easy way of calling methods on SimObject
by Fyodor -bank- Osokin · 05/06/2009 (1:06 pm) · 9 comments
After:
Previously you may have used something like:
ConsoleMethod(SimObject, isMethod, bool, 3, 3, "obj.isMethod(string method name)")
{
return object->isMethod( argv[2] );
}Add:ConsoleMethod(SimObject, call, const char *, 3, 0, "obj.call(funcName [,args ...])")
{
argc -= 2; argv += 2;
if(!object->isMethod(argv[0]))
{
Con::warnf(ConsoleLogEntry::Script, "%s: Unknown command.", argv[0]);
Con::warnf(ConsoleLogEntry::General, "Object: %s(%d) [%s]",
object->getName() ? object->getName() : "",
object->getId(), object->getClassName() );
return "";
}
const char *largv[128];
for(S32 i = 0; i < argc; i++) largv[i+1] = argv[i];
largv[0] = largv[1];
argc++;
return Con::execute(object, argc, argv);
}From now you can call dynamic methods on objects without using "eval" to get a result:Previously you may have used something like:
...
if(%obj.isMethod(%myFuncName))
{
%ev = "%res = " @ %obj @ "." @ %myFuncName @"("@ %param1 @",\""@ %param2 @"\");";
eval(%ev);
echo(%res);
}And now:...
if(%obj.isMethod(%myFuncName))
{
%res = %obj.call(%myFuncName, %param1, %param2);
echo(%res);
}I'm using this a lot, as I have lots of scripts where I need to call functions described as variables.About the author
Game developer.
#2
Actually, I would prefer adding something like this:
05/06/2009 (1:57 pm)
Easy workaround :)if(!object->isMethod(argv[0]))
{
#ifndef TORQUE_SHIPPING
Con::warnf(ConsoleLogEntry::Script, "%s: Unknown command.", argv[0]);
Con::warnf(ConsoleLogEntry::General, "Object: %s(%d) [%s]",
object->getName() ? object->getName() : "",
object->getId(), object->getClassName() );
#endif
return "";
}So, the shipping build will not spam the console. Actually there are many ways to achieve that.Actually, I would prefer adding something like this:
if(!object->isMethod(argv[0]))
{
if(mPrintWarnings)
{
Con::warnf(ConsoleLogEntry::Script, "%s: Unknown command.", argv[0]);
Con::warnf(ConsoleLogEntry::General, "Object: %s(%d) [%s]",
object->getName() ? object->getName() : "",
object->getId(), object->getClassName() );
}
return "";
}Where mPrintWarnings can be linked as bool to SimObject persist.field, or even to global variable via Con::setIntVariable()
#3
since in that case your torquescript is failing silently, i think.
if it's valid for the method to not exist, then you don't want to print warnings in that case (even in a development build). if it's not valid for it not to exist, then why check in torquescript ?
05/06/2009 (2:02 pm)
i guess i assumed it was sometimes valid for the method not to exist,since in that case your torquescript is failing silently, i think.
if it's valid for the method to not exist, then you don't want to print warnings in that case (even in a development build). if it's not valid for it not to exist, then why check in torquescript ?
#4
And in my codebase I have it with getNamespaceList (if I'm not mistaken it was from your resource) together with getScopeName and some other additions.
Edit to reply to your post:
I never check it in scripts like in my example (isMethod), its just example :)
I call with that way only functions I know are existing.
05/06/2009 (2:03 pm)
Orion, before "releasing" scripts to "live" (in my project), I always check if I have something "weird" in the console :)And in my codebase I have it with getNamespaceList (if I'm not mistaken it was from your resource) together with getScopeName and some other additions.
Edit to reply to your post:
I never check it in scripts like in my example (isMethod), its just example :)
I call with that way only functions I know are existing.
#5
05/06/2009 (2:04 pm)
yay getNamespaceList !
#6
05/06/2009 (2:06 pm)
grrrr.. reminder to myself: always check for comments before posting your own reply lol :)
#7
05/06/2009 (4:32 pm)
But I liked the sometimes tricksome and cumbersome syntax of calling eval ;) Cool resource!
#8
Which Torque version you're using? Call() has been there for a while, and applying the resource causes a compilation error because the method already exists. I believe it was added alongside isMethod() and others, which didn't existed in the past.
05/07/2009 (7:05 am)
Huh? TGEA 1.7.1, SimObject.cpp, line 1116:ConsoleMethod( SimObject, call, const char*, 2, 0, "( %args ) - Dynamically call a method on an object." )
{
argv[1] = argv[2];
return Con::execute( object, argc - 1, argv + 1 );
}Which Torque version you're using? Call() has been there for a while, and applying the resource causes a compilation error because the method already exists. I believe it was added alongside isMethod() and others, which didn't existed in the past.
#9
05/07/2009 (7:55 am)
TGE152, hehe! :) And yeah its more simple than my. 
Associate Orion Elenzil
Real Life Plus
if you're using it a lot, what do you think of writing a variant like "callNoWarn" which fails silently if the method doesn't exist ? that way you don't have to check for existence in torquescript.