Configurable Callbacks
by Michael Woerister · in Torque Game Builder · 01/23/2006 (7:42 am) · 24 replies
Hi,
it seems to me it's the case very often that the various types of sceneobjects need to do something different in there callback. E.g. you have a player, an enemy, and another enemy, all of which are t2dAnimatedSprite, but all of which want to do something different in the onTimer-callback. Right now you have to do something like this:
This can be very annoying, I think, as you have to modify this function every time you add another type of object that needs its own callback, and it gets slower every time as the function has more an more cases to evaluate.
My solution to this in script looks like this:
where %this.onTimerCallback was some function name you specified yourself.
However, as callbacks tend to get called very often it would be good, to do this in C++, with no overhead. If any t2dSceneObject had a member mOnTimerCallback that defaults to "onTimer" and just gets called instead of the "onTimer" literal string, this would mean absolutly no overhead performance-wise. (Though you had to store on additional string table pointer for every callback you want to make configurable).
This way would be perfectly backwards compatible and fairly easy to implement.
Have a nice day!
- Michael
it seems to me it's the case very often that the various types of sceneobjects need to do something different in there callback. E.g. you have a player, an enemy, and another enemy, all of which are t2dAnimatedSprite, but all of which want to do something different in the onTimer-callback. Right now you have to do something like this:
function t2dAnimatedSprite::onTimer(%this)
{
switch(%this.spriteType)
{
case $TYPE_PLAYER: ... break;
case $TYPE_ENEMY1: ... break;
case $TYPE_ENEMY2: ... break;
};
}This can be very annoying, I think, as you have to modify this function every time you add another type of object that needs its own callback, and it gets slower every time as the function has more an more cases to evaluate.
My solution to this in script looks like this:
function t2dAnimatedSprite::onTimer(%this)
{
if( %this.onTimerCallback )
call( %this.onTimerCallback, %this);
}where %this.onTimerCallback was some function name you specified yourself.
However, as callbacks tend to get called very often it would be good, to do this in C++, with no overhead. If any t2dSceneObject had a member mOnTimerCallback that defaults to "onTimer" and just gets called instead of the "onTimer" literal string, this would mean absolutly no overhead performance-wise. (Though you had to store on additional string table pointer for every callback you want to make configurable).
This way would be perfectly backwards compatible and fairly easy to implement.
Have a nice day!
- Michael
#22
/em wonders if Adam caught that as well when he made this change to TGB HEAD...
03/13/2006 (10:44 pm)
Good catch Robert!/em wonders if Adam caught that as well when he made this change to TGB HEAD...
#23
I was looking at ScriptObject as a reference. Shouldn't ScriptObject::onRemove() do this as well?
Anyway, here is what needs to be copied from t2dSceneGraph::onRemove() where this functionality already was implemented:
I placed this piece of code between mMountNodes.clear() and Parent::onRemove() in t2dSceneObject::onRemove().
May you want to replace
03/14/2006 (1:53 am)
Thanks Robert.I was looking at ScriptObject as a reference. Shouldn't ScriptObject::onRemove() do this as well?
Anyway, here is what needs to be copied from t2dSceneGraph::onRemove() where this functionality already was implemented:
// Restore NameSpace's
StringTableEntry child = getName();
if( child && child[0] )
{
if(mClassName && mClassName[0])
{
if(Con::unlinkNamespaces(mClassName, child))
child = mClassName;
}
if(mSuperClassName && mSuperClassName[0])
{
if(Con::unlinkNamespaces(mSuperClassName, child))
child = mSuperClassName;
}
Con::unlinkNamespaces(getClassName(), child);
}
else
{
child = mClassName;
if(child && child[0])
{
if(mSuperClassName && mSuperClassName[0])
{
if(Con::unlinkNamespaces(mSuperClassName, child))
child = mSuperClassName;
}
Con::unlinkNamespaces(getClassName(), child);
}
else
{
if(mSuperClassName && mSuperClassName[0])
Con::unlinkNamespaces(getClassName(), mSuperClassName);
}
}I placed this piece of code between mMountNodes.clear() and Parent::onRemove() in t2dSceneObject::onRemove().
May you want to replace
StringTableEntry parent = getClassRep()->getNameSpace()->mName;with
StringTableEntry parent = getClassName(); //<- editthen for consistancy. But it should not make a difference.
#24
's code for this over to T2D forgot a few things. ScriptObject and I think also ScriptGroup should do what you pasted above as well.
03/14/2006 (4:55 am)
Hmm it sounds like whoever merged in from
Torque 3D Owner Robert Blanchet Jr.
You'll want to diff more than that. While there is nothing wrong with just using what you posted, you should also diff in the onRemove as well as that will then unlink the namespaces. Otherwise if more than just one type of object uses the same namespace it will get cluttered and confused, and probably die a painful death.