A Torque Script class is really not a class in terms of C++ classes. It is more or less a namespace grouping "class" member functions together.
function MyClass::MyFunction1(%param1)
{
echo(%param1);
}
function MyClass::MyFunction2(%param1,%param2)
{
echo(%param1 + %param2);
}
These two functions are in the same namespace aka Class, MyClass
. We can call the functions as static members.
MyClass::Function1("Hello World"); // echo Hello World
MyClass::Function2(10,5); // echo 15
Like in JavaScript, fields aka variables can be added to a collection of fields. But you can't add them to a static class. You must add them to an instance of the class.
There are two ways to get access to a "class" instance.
%MyObj = new ScriptObject();
%MyObj
is a numeric integer value representing the instance handle. This handle can be used to access any members of the class. The second way is to create an object instead of an instance handle.
new ScriptObject(MyObj);
But why did we create a scriptObject
instead of our MyClass
?
You can't create classes that isn't defined and exposed in the Torque core (C++ source). All Torque classes are derived from the SimObject
class and so are ScriptObject
and it also defines some special fields.
%MyObj = new ScriptObject(MyObject)
{
class = "MyClass";
};
Now we can call our functions from the handle because we told it to be class MyClass
.
%MyObj.Function1("Hello World");
or from the object.
MyObject.Function1("Hello World");
Since MyObject
isn't a variable, it shall not be accessed with the %
Well, not entierly true. Because we call it through its handle, the first parameter will always be the handle itself and is usually defined like this.
function MyClass::MyFunction1(%this,%param1)
{
echo("Handle:" SPC %this SPC "Param:" SPC %param1);
}
The "instance" is passed in as the first parameter. It doesn't need to be called %this
, but it has been the common practice to name it %this
.
We can add fields as we please to this particular instance by just assigning values to it.
function MyClass::MyFunction1(%this,%param1)
{
%this.Message = %param1;
}
function MyClass::MyFunction2(%this)
{
echo("Handle:" SPC %this SPC "Param:" SPC %this.Message);
}
Okay so what are DataBlocks?
Let's say we have different configurations of MyClass
. We can create a DataBlock for each configuration and then tell the instance to use it. All members of the DataBlock will be accessible fields in the instance.
datablock AudioProfile(audioName)
{
filename = "~/data/sound/Audio.wav";
description = "myaudioDescription";
preload = false;
};
As for classes a datablock
must be based on a predefined datablock
. However, you can add new fields as you like to them.
datablock AudioProfile(MyAudioDatablock)
{
filename = "~/data/sound/Audio.wav";
description = "myaudioDescription";
preload = false;
Message = "My field";
};
Here we created a new datablock
based on the AudioProfile datablock
and added one extra field; Message.
We can now create our class and add all the fields from the datablock
at once.
%MyObj = new ScriptObject()
{
datablock = MyAudioDatablock;
class = "MyClass";
};
%myObj.Function2(); // echo My field
If we have the same class but many different configurations, we can create one datablock
for each configuration and assign them when we create the class instance.