Game Development Community

Event driven?

by Joao Caxaria · in Technical Issues · 10/06/2008 (3:06 pm) · 9 replies

Hi all,

I'm from a .Net/Java background and although the all experience of working in Torsion has been great, there is something that I have been finding hard to live without... How can I have a custom event on a class that I create? (something like EventHandler in c#). If the concept does not exist in Torque, is it possible to pass a function pointer to another function?

I would expect something like this:

function Level::MethodStart(%this)
{
echo("starting");
%this.start(%this.MethodEnd);
}

function Level::start(%this, %callback)
{
%callback();
}

function Level::MethodEnd(%this)
{
echo("finished");
}

to print both "starting" and "finished", when MethodStart gets called.

I seem to be too stuck with the 'old ways' and I'm finding it hard to think out of the box on these details... any help would be greatly appreciated!

Thanks,
Jo

#1
10/06/2008 (3:53 pm)
Joao,

That's actually exactly what you do. TorqueScript is simple in that you don't have to declare any of the event handlers in the 'classic' ways - you just code them and they work.

So if I had an object name "refinery" whose classname property was 'level', I could then use any of your above event handlers, I would just have to add a call to the function at the proper place. In that case, I could use "refinery.MethodStart();" if I had integrated your above code.

Hope that helps!
-Dave Calabrese
Gaslight Studios
#2
10/06/2008 (7:26 pm)
// Try one of these and see which works for you
%callback();
(%callback)();
call( %callback );

At least one of the above should work if its a function, if its a METHOD they probably wont. You might need to do an eval, or pass the callback object as a second parameter.
#3
10/07/2008 (1:44 am)
Hi Dave,

Thanks, I see your point. I would just call the method on the class getting the event. Now just out of curiosity, if the method is not implemented I know we don't get a runtime error but is there any performance hit?

James,

Thanks, the call(%callback) works for functions but on the others I get a compilation error.

As I'm trying with methods I tried call(%callback, %this) but it did not work.

Is there a way of, by storing a method name (as a String) and a class instance variable, to call that method on that instance?

Thanks guys!
#4
10/07/2008 (5:20 am)
You're looking for eval in this case:

%evalString = %this @ "." @ %callback @ "();";

echo("My string evaluates to:" @ %evalString );

eval(%evalString);

Note that this is not necessarily a best practice when used extravagantly--string processing isn't the fastest processing in the world, and this is run time processing, so you don't gain any compilation speed gains.

The most important thing to keep in mind is that TorqueScript is not a true object oriented language--it's not intended or designed to be, and it really isn't necessary for it to be one. TorqueScript provides a quick, easy to learn, easy to modify, and relatively performant way to modify runtime behavior of a project without source code changes, but when designing and implementing an application source code is your primary choice if your project demands strong OOP structure.

Also addressing your first question in the post above, you do get a run time warning (in your console.log) if you attempt to call a TorqueScript function or method that does not exist. The performance hit is there, but not noticeable in normal operations unless you are doing this at a very high frequency--and again, in that case, you should probably be considering placing complex/OOP derived logic within C++ as appropriate.
#5
10/07/2008 (6:23 am)
I see. I know this is a bit of a paradigm shift from what I usually do so I do need to change my thinking process.

Thanks everyone.
#6
10/07/2008 (6:50 am)
For an excellent use example of what Stephen explains, open Stronghold\game\scriptsAndAssets\server\scripts\aiPlayer.cs (or example\starter.fps\server\scripts\aiPlayer.cs in TGE) and look for the TASK related methods.
#7
10/07/2008 (8:03 am)
Novack,

are those distributed only with TGE? I can't seem to be able to find them, but I only have TGB. Just out of curiosity, could you post one of the examples you're referring?

Thanks!
#8
10/07/2008 (5:15 pm)
Joao yes, they are on TGE and TGEA. Sure thing, I believe there is no problem on sharing script code (as it cames with the themo anyway) so here it is:

function AIPlayer::pushTask(%this,%method)
{
   if (%this.taskIndex $= "") {
      %this.taskIndex = 0;
      %this.taskCurrent = -1;
   }
   %this.task[%this.taskIndex] = %method; 
   %this.taskIndex++;
   if (%this.taskCurrent == -1)
      %this.executeTask(%this.taskIndex - 1);
}

function AIPlayer::clearTasks(%this)
{
   %this.taskIndex = 0;
   %this.taskCurrent = -1;
}

function AIPlayer::nextTask(%this)
{
   if (%this.taskCurrent != -1)
      if (%this.taskCurrent < %this.taskIndex - 1)
         %this.executeTask(%this.taskCurrent++);
      else
         %this.taskCurrent = -1;
}

function AIPlayer::executeTask(%this,%index)
{
   %this.taskCurrent = %index;
   eval(%this.getId() @ "." @ %this.task[%index] @ ";");
}
#9
10/08/2008 (1:27 am)
Thanks!