Game Development Community

Schedule command - Calling Object vs. Calling Function

by Ray Taylor · in Torque 3D Professional · 08/26/2014 (2:41 pm) · 20 replies

I want to enter a trigger and have an object turn hidden.

TestObject1.setHidden(True); //works perfectly

Now I want to have second object turn hidden in 4 seconds.

schedule(4000,0,TestObject2.setHidden(True)); // but it turns hidden instantly, WHY?
schedule(4000,0,nameToID(TestObject2).setHidden(True)); // same problem as above.
I have tried countless other ways but nothing works.

What am I missing here?

I have the schedule command working many times in my game but every other time I have created a
function.

function OpenDoor(){
nameToID(Door).playTread(0,"open");
}

schedule(4000,0,OpenDoor); // command inside the trigger calls the above function, works perfectly.

What it the difference in calling an object directly vs. calling a function?
Can you call an object directly?





#1
08/26/2014 (2:55 pm)
Here you go!

function objectSchedule(%obj, %arg1, %arg2) {
   %obj.schedule(40000, 'myFunction', %arg1, %arg2);
}

function genericSchedule(%obj, %arg1, %arg2) {
   schedule(40000, 0, 'myFunction2', %obj, %arg1, %arg2);
}
#2
08/26/2014 (3:33 pm)
Thanks Robert, I think I understand the use of functions and the schedule command but can I have the game object's name in the trigger using the schedule command without going to a "function"? I think both your examples call a "function". I want to know if it can be done by calling an game object's name directly.

schedule(4000,0,TestObject2.setHidden(True)); // with "TestObject2" being the object's name in the game. I am not a programmer so I hope I'm making sense.

Can you give me the exact command if the "name of an object" is called instead of a function? The name of the object in the game is "TestObject2". I want to make "TestObject2" hidden entering a trigger without having to go to a function. I have had this question for 5 years but never wanted to bother anyone by asking but now I just have to know.
#3
08/26/2014 (6:37 pm)
schedule(%time, %obj, %method, %parm1, %parm2, %parm_etc);
%obj.schedule(%time, %method, %parm1, %parm2, %parm_etc);

So from your example:
// generic schedule
schedule(4000, TestObject2, 'setHidden', true); // should work
schedule(4000, nameToID(TestObject2), 'setHidden', true); // also should work

// SimObject's method schedule
TestObject2.schedule(4000, 'setHidden', true); // also should work

%obj = TestObject2;
%obj.schedule(4000, 'setHidden', true); // again, also should work

Note - should use '' instead of "" because it is more likely to function correctly in multiplayer scenarios.
#4
08/26/2014 (7:21 pm)
Richard's spot on with the example.

%obj is a very generalized term that basically means well, the object in question. This is simply a variable. Now, TestObject2 is your %obj in this case. so simply do:

TestObject2.schedule(TimeInMS, 'function', %arg1, %arg2, ..., %argn);

However, to be a little more specific to what richard is saying about enclosing it in 'x' versus "x" is that the engine expects the transmitted function to be a tag, versus a string. 'x' is generally viewed as a tag.

I could pull the relevant source code to this, but I'm lazy ATM. :)
#5
08/26/2014 (7:23 pm)
Richard, perfect on the 3rd and 4th options but not the first two (I can't get those to work).
Thank you the many options or I would still be wondering what is wrong. As long as I have one that works, I am good. Five years of questioning myself that there must be a way of doing that is now gone. I don't have to use functions now on the simple ones but I will continue to use them on complicated ones.

Thank you!

I just realized based on Robert that I missed the ' vs. ".

I will try with that now.
#6
08/26/2014 (7:30 pm)
I see why I missed the ' vs ", I was reading my email and not this post. The email version of the Robert's answer has all " in it, no ' at all. That is very strange.
#7
08/26/2014 (7:41 pm)
Here is the only thing that works in mine. I have Pro 1.1
TestObject2.schedule(4000, "setHidden", true);  // need " to work for me

%obj = TestObject2;  
%obj.schedule(4000, "setHidden", true); // again only " worked


Thanks guys! I am happy now.
#8
08/27/2014 (4:42 am)
Quote:Note - should use '' instead of "" because it is more likely to function correctly in multiplayer scenarios.
AFAIK schedule has nothing to do with multiplayer. Scheduled commands operate only on the client/server, wherever they are initiated from. Tagging schedule commands won't really do anything - it's commandToClient/Server that really need to use tagged strings.

Quote:schedule(4000,0,TestObject2.setHidden(True));
What's going on here is that TestObject2.setHidden(True) is a function call. So it gets evaluated and its result is passed as the third argument of schedule(). So the object gets hidden immediately, and you've called schedule(4000, 0, "") (I assume setHidden doesn't return anything, so that call results in an empty string), which obviously doesn't do much!
#9
08/27/2014 (6:20 am)
Daniel, that makes sense to me now.
Seeing now that
-- TestObject2.setHidden(True) -- IS a "function call" makes all the difference.
As a non-programmer, that just seamed like a simple command waiting to be started at a specified time.
Now I understand why it failed to work like I was expecting it to. Thanks.
#10
08/27/2014 (8:39 am)
If this doesn't work:
schedule(4000, TestObject2, 'setHidden', true);
then there is a bug in the engine, because that should work. I'll have to play with this to get it sorted out.

@Daniel - You're right, I was being paranoid and it doesn't hurt.
#11
08/27/2014 (1:56 pm)
It occurred to me that I should have clarified the expected parameters:
// %time - in milliseconds, time to wait before executing.
// %obj - the object to call the function (method) against.
// %method - the function (or object method) to execute.
// %param... - parameters to pass to the function - as many as you need, separated by commas.

// generic schedule
schedule(%time, %obj, %method, %parm1, %parm2, %parm_etc);

// From the source code - sim.cpp, around line 196
ConsoleFunction(schedule, S32, 4, 0, "schedule(time, refobject|0, command, <arg1...argN>)")
// (I know, not very helpful...)

// ------------------

// object method schedule
%obj.schedule(%time, %method, %parm1, %parm2, %parm_etc);

// From the source code - simObject.cpp, around line 2632
ConsoleMethod( SimObject,schedule, S32, 4, 0, "( float time, string method, string args... ) Delay an invocation of a method.n"
   "@param time The number of milliseconds after which to invoke the method.  This is a soft limit.n"
   "@param method The method to call.n"
   "@param args The arguments with which to call the method.n"
   "@return The numeric ID of the created schedule.  Can be used to cancel the call.n" )
#12
08/27/2014 (7:42 pm)
Hey Guys, I can only get the following code to work and it works fine.
TestObject2.schedule(4000, "setHidden", true);

The following one does not work but I am okay with it since the above code works.
schedule(4000, TestObject2, 'setHidden', true);

As long one works, I am good. Maybe it is only a problem in 1.1 or maybe just in my game. I was too far along and I didn't need any of the extra features to upgrade.

If someone wants to explore reason for error for the sake of exploration, that it fine but I am good to go since one of them works.
#13
08/28/2014 (3:31 am)
Okay, if you're interested, try this one:
TestObject2.schedule(4000, 'setHidden', true);
Then try this in the console:
echo("hello");
echo('hello');
I think you'll see why tagged strings aren't getting you what you want. This page gives a few details about tagged strings.
#14
08/28/2014 (10:12 am)
hello

and then

29
#15
08/28/2014 (10:51 am)
@Daniel - you know, I never really thought about this, but it makes sense. It's not going through the client-server hoops, so it doesn't get translated back - you just get the tag. I am of the opinion that tagged strings should be handled the same way across all use cases, though.
#16
09/02/2014 (3:14 pm)
Well, they're handled exactly the way they're designed - instead of being a string value, they're a named integer constant.

So, Ray, given those results, can you see why doing this:
TestObject2.schedule(4000, 'setHidden', true);
doesn't work? Once the engine has translated the tagged string into its tag, your code becomes this:
TestObject2.schedule(4000, 47, true);
though the actual tag value may be anything, not just 47 (that was just a random example). And since the "47" isn't a valid method to call on the object, well, schedule can't do anything!
#17
09/02/2014 (4:20 pm)
@Daniel - sure, they're a mapped integer constant. My point is that at precompile the system should map them in context so this doesn't arise....
#18
09/03/2014 (7:23 pm)
I suspect that isn't really doable. The TS parser would have to know the difference between a function that expects a tagged string, and one that expects a literal string. The only real way to do that is to just use literal strings everywhere and call tag/untag manually before doing any client/server commands.
#19
09/04/2014 (9:34 am)
I wouldn't classify it as "not doable" - more like "really not worth the effort." It would be nice, though. I think it would work if a separate dictionary was added and all 'tagged' strings were just looked up via the shared dictionary object. Like you say, a pain in the ass and not worth the effort.
#20
09/04/2014 (12:07 pm)
Not worth the effort is what I say :P