SOLVED Confusion with methods and classes
by Jonathan R Hopkins · in Torque Game Builder · 09/15/2009 (3:31 pm) · 4 replies
Solution
Well I solved the problem after doing some more hunting around...
Apparently SimObject (the base class) ignores or can't use namespaces for some reason. I found that out here:
www.garagegames.com/community/forums/viewthread/66547/1#comment-486564
Quote:You are correct, if the "class" (again, we need to make sure that you understand that there are no true object oriented classes in TorqueScript--it's not a fully object oriented language like Java) you want to implement does not directly relate to something like a SceneObject, or AnimatedSprite, or other "core" objects in a scene, then ScriptObject is fine.Stephen Zepp
So, to recap for anyone who may find this topic helpful later:
Classes and Methods in Torque
Torque does not actually allow for the creation of 'true' Object Oriented Programming (OOP) for classes when only using TorqueScript. Real OOP Classes can be created if you have the license to the source code and edit the source in C++.
However one can artificially mimic classes and methods through the use of namespaces, which do not require special definition before use. Put another way, you can just use the namespace without declaring it first:
function namespaceName::method(%this,args...)
{...}It is important that %this is always the first argument passed, because Torque always passes the argument to the method from the calling object when calling the method. %this refers to the object's handle, which allows specific manipulations upon the calling object.
Once the 'class' is created, you can use it by "linking" objects to the class in the initialization of the object:
%obj = new t2dSceneObject()
{
class = "namespaceName";
};NOTE: Classes must be declared at object initialization, and cannot be declared after.
The SimObject base class, as well as SimSet and SimChunk, for some reason, cannot accept/use namespaces (I'm not sure why). But it seems that any other object down the hierarchy can use it.
Simple steps to creating a class, a method, and using them
- Create the method using the namespace. Remember to always include the %this argument as the first argument.
- Create the object and link it to the "class" (i.e. namespace)
- Call the method on an object of the class. Remember that when CALLING the method, %this is always and automatically passed as the first argument:
function namespaceName::method(%this,args...)
{...}%obj = new t2dSceneObject()
{
class = "namespaceName";
};%obj.method(args);
If I'm wrong on any of this, please feel free to correct me. :)
Original Problem
Okay, so far I've managed to program thousands of lines of code by using functions unbound to namespaces (i.e. without methods and classes.) But its starting to feel a little messy, AND I've run into a wall where I'm pretty sure the only reasonable solution is to use methods.
I've tried searching, but every seems to tiptoe around the answer and I can't seem to find it.
Now here's my confusion. How do I establish my method for my custom class? Is this even possible? I've experimented a bit and created the following to try it out:
$testObject1 = new ScriptObject()
{
class = "testClass";
info = "The test was successful!";
};
$testObject2 = new ScriptObject()
{
class = "testClass";
info = "The SECOND test was successful!";
};
function testClass::getInfo(%this)
{
echo(%this.info);
}
function test()
{
$testObject1.getInfo();
$testObject2.getInfo();
}When I run this code, I get the error (unknown function or call...)
My goal is to have some method, like "getInfo" in this case, be bound to the class. I want any object that is a member of that class to be able to use that call thereafter. I've read somewhere that unless the class is an actual class, Torque will simply interpret the whole thing as a function, rather than a method of a namespace, ie the function is "testClass::getInfo". When I substituted the function deceleration with the following:
function ScriptObject::getInfo(...);
I get the desired effect, and both objects inherit the method "getInfo()" but using simObject or other built in classes only seems kind of counterproductive to what I'm trying to do, because it essentially gives every object the same functionality.
I'd like to be able to code:
function className::classMethod(...) ... objectOfClass.classMethod()
Corrections made 9/17/09: Classes cannot be declared after object initialization. Changed SimObject references to ScriptObject references for easier understanding.
#2
good summury: it's always useful to recap one of the most important part of TGB programming. I add some comments to your post.
1) Assigning a class AFTER object creation is not admitted: TGB does not report errors but it will not work because namespace binding is made at creation time and it can't be changed anymore.
So, this code:
will NOT work has expected.
2) I think it could be useful for readers having the solution to your original problem, simply replacing "SimObject" with "ScriptObject".
work has expected.
Byez.
09/17/2009 (12:47 pm)
Hi Jonathan,good summury: it's always useful to recap one of the most important part of TGB programming. I add some comments to your post.
1) Assigning a class AFTER object creation is not admitted: TGB does not report errors but it will not work because namespace binding is made at creation time and it can't be changed anymore.
So, this code:
%obj.class = "namespaceName";
will NOT work has expected.
2) I think it could be useful for readers having the solution to your original problem, simply replacing "SimObject" with "ScriptObject".
$testObject1 = new ScriptObject()
{
class = "testClass";
info = "The test was successful!";
};
$testObject2 = new ScriptObject()
{
class = "testClass";
info = "The SECOND test was successful!";
};
function testClass::getInfo(%this)
{
echo(%this.info);
}
function test()
{
$testObject1.getInfo();
$testObject2.getInfo();
}work has expected.
Byez.
#3
09/17/2009 (1:39 pm)
Hey thanks for pointing that out! I've made the suggested changes :D
#4
changing SimObject references to ScriptObject references is not "for easier understanding" of the original problem, it is the solution of the original problem.
If a guy reads the first post now he could think that code don't work, but it does well indeed. :-)
Byez,
09/18/2009 (6:32 pm)
Hi Jonathan,changing SimObject references to ScriptObject references is not "for easier understanding" of the original problem, it is the solution of the original problem.
If a guy reads the first post now he could think that code don't work, but it does well indeed. :-)
Byez,
Torque Owner Jonathan R Hopkins