Datablock / Script Object question
by Nicki Vankoughnett · in Torque Game Engine · 07/28/2006 (1:19 pm) · 6 replies
I am sure that this probably answered in one of the .docs somewhere, but if the answer is already written somewhere, I am unable to find it.
Consider this function example:
function SomeScriptObjectType::DoStuff(%this, %obj)
{
//blah blah blah
}
Now, in some other function, I will see something like this:
function SomeScriptObjectType::SomeRandomFunction(%this, %obj)
{
%this.DoStuff();
}
Now, it is my understanding that functions written in that form are written that way so that the '%this' variable is the datablock and the '%obj' variable is the script object. Why then is DoStuff() being called from the Datablock instead of the script object instance?
END COMMUNICATION
Consider this function example:
function SomeScriptObjectType::DoStuff(%this, %obj)
{
//blah blah blah
}
Now, in some other function, I will see something like this:
function SomeScriptObjectType::SomeRandomFunction(%this, %obj)
{
%this.DoStuff();
}
Now, it is my understanding that functions written in that form are written that way so that the '%this' variable is the datablock and the '%obj' variable is the script object. Why then is DoStuff() being called from the Datablock instead of the script object instance?
END COMMUNICATION
#2
The AI stuff I am working on has the core AI code not being a part of the player class, and rely's on the player object being accessed through it. I can access the player object in the script easily enough, but I dont have the players datablock. And this is creating problems when I need to call certain functions that should apparantly be called via the datablock.
Knowing why this is will help me understand. I dont suppose you can tell me which part of the website has the documentation that would best explain this?
END COMMUNICATION
07/29/2006 (7:28 am)
Oh, I have no doubts about calling via the Datablock as being the right thing. I am just wondering why its the right thing.The AI stuff I am working on has the core AI code not being a part of the player class, and rely's on the player object being accessed through it. I can access the player object in the script easily enough, but I dont have the players datablock. And this is creating problems when I need to call certain functions that should apparantly be called via the datablock.
Knowing why this is will help me understand. I dont suppose you can tell me which part of the website has the documentation that would best explain this?
END COMMUNICATION
#3
The AI stuff I am working on has the core AI code not being a part of the player class, and rely's on the player object being accessed through it. I can access the player object in the script easily enough, but I dont have the players datablock. And this is creating problems when I need to call certain functions that should apparantly be called via the datablock.
Knowing why this is will help me understand. I dont suppose you can tell me which part of the website has the documentation that would best explain this?
END COMMUNICATION
07/29/2006 (12:10 pm)
Oh, I have no doubts about calling via the Datablock as being the right thing. I am just wondering why its the right thing.The AI stuff I am working on has the core AI code not being a part of the player class, and rely's on the player object being accessed through it. I can access the player object in the script easily enough, but I dont have the players datablock. And this is creating problems when I need to call certain functions that should apparantly be called via the datablock.
Knowing why this is will help me understand. I dont suppose you can tell me which part of the website has the documentation that would best explain this?
END COMMUNICATION
#4
07/29/2006 (12:12 pm)
If you need the player's datablock, you just use %player.getDatablock().
#5
TorqueScript supports function namespaces. All objects which derive from the ConsoleObject class (this includes both the player and the playerData) can have at least one namespace (I'll talk about multiple namespaces later).
When you call a method on an object instance, Torque will lookup the object's namespace, then call the function on that namespace, passing the object itself as the first parameter:
In the example above, %this is equal to $foo. It's no different for datablocks, but I'll get on that later. First, let's see a basic multiple-namespace example:
Same situation as previous example, but the $foo object now has two namespaces (SimObject and Bar). The object name is a valid namespace too. Now, a simple datablock example:
This datablock contains 3 namespaces, stacked in the following order: ShapeBaseData->bar->foo.
Datablocks contain the "class" field which allows you to define an extra namespace for them. In the starter.fps example, the player datablock is of "Armor" class. That's why there's a bunch of Armor:: methods in it's script: those are methods for PlayerData datablocks of the Armor class.
What about the %obj in those functions? And why it contains the object? You see, the datablocks exist with one reason: to provide a template for object instances. So if you have 3 different kinds of players, you create 3 datablocks.
When you call a method directly on the player, it'll be called on the player namespace, and %this will be the player itself. To call a method on a player's datablock, you need to:
In this case, %this will be the player's datablock, not the player itself. But the datablock is shared, and is the same for all players which use it, so what if you want doStuff() to do stuff (!) with the player instance? You pass it as a parameter, of course:
In the source code, many events generate callbacks which are invoked on the player's/trigger's/staticShape's datablock instead of the object instance itself, and the object is passed as another parameter, allowing you to customize the callbacks per datablock class. If the callback where called on the object itself, you'd need an
07/29/2006 (3:19 pm)
I don't know exactly where you can find a doc on the namespace/datablock dance, but I'll try to explain...TorqueScript supports function namespaces. All objects which derive from the ConsoleObject class (this includes both the player and the playerData) can have at least one namespace (I'll talk about multiple namespaces later).
When you call a method on an object instance, Torque will lookup the object's namespace, then call the function on that namespace, passing the object itself as the first parameter:
function SimObject::doStuff(%this)
{
//Stuff here
}
$foo = new SimObject();
$foo.doStuff();In the example above, %this is equal to $foo. It's no different for datablocks, but I'll get on that later. First, let's see a basic multiple-namespace example:
function Bar::doStuff(%this)
{
//Stuff here
}
$foo = new SimObject(Bar);
$foo.doStuff();Same situation as previous example, but the $foo object now has two namespaces (SimObject and Bar). The object name is a valid namespace too. Now, a simple datablock example:
datablock ShapeBaseData(foo)
{
class = bar;
};This datablock contains 3 namespaces, stacked in the following order: ShapeBaseData->bar->foo.
Datablocks contain the "class" field which allows you to define an extra namespace for them. In the starter.fps example, the player datablock is of "Armor" class. That's why there's a bunch of Armor:: methods in it's script: those are methods for PlayerData datablocks of the Armor class.
What about the %obj in those functions? And why it contains the object? You see, the datablocks exist with one reason: to provide a template for object instances. So if you have 3 different kinds of players, you create 3 datablocks.
When you call a method directly on the player, it'll be called on the player namespace, and %this will be the player itself. To call a method on a player's datablock, you need to:
player.getDatablock().doStuff()
In this case, %this will be the player's datablock, not the player itself. But the datablock is shared, and is the same for all players which use it, so what if you want doStuff() to do stuff (!) with the player instance? You pass it as a parameter, of course:
player.getDatablock().doStuff(player)
function PlayerData::doStuff(%this, %obj)
{
/// stuff
}Now, %this is the datablock, and %obj is the player, because you did it so. In the source code, many events generate callbacks which are invoked on the player's/trigger's/staticShape's datablock instead of the object instance itself, and the object is passed as another parameter, allowing you to customize the callbacks per datablock class. If the callback where called on the object itself, you'd need an
Torque Owner Alberto Ganesh Barbati
Default Studio Name