Difference between "class" and "superClass" properties
by Kareem Ergawy · in Torque 3D Beginner · 09/15/2014 (12:18 pm) · 9 replies
Hi,
I am currently studying the Torque 3D Cookbook. And it is very interesting :). One interesting fact that I came along is while a specific class namespace can be used with ONLY one type of a particular C++ class the superClass namespace doesn't have that restriction.
Why is that?
I know this may be an engine-design related question but I am very interested in understanding the internals of the engine.
I am currently studying the Torque 3D Cookbook. And it is very interesting :). One interesting fact that I came along is while a specific class namespace can be used with ONLY one type of a particular C++ class the superClass namespace doesn't have that restriction.
Why is that?
I know this may be an engine-design related question but I am very interested in understanding the internals of the engine.
#2
09/15/2014 (1:48 pm)
Basically, superclass just gives you more options when defining class hierarchies in script. For example, I used it to make objects behave like StateMachines:function AI::brain(%this, %obj, %template) {
%obj.brain = new ScriptObject();
%obj.brain.superclass = StateMachine;
%obj.brain.class = %template @ Brain;
}This means I can define functions for all StateMachines, as well as for a template class for each brain type.
#3
Richard said that
However, I didn't find this to be true. Perhaps this was changed with newer versions?
Here I used a superClass that is only defined on script-side and not in C++.
So what I understood from Daniel's reply is that a superClass can be thought of just as an additional block of ready functionality that is added to an object. In which case, to name it superClass is a little bit misleading in my opinion!
09/15/2014 (2:14 pm)
Thank you Richard and Daniel for your replies.Richard said that
Quote:
it appears that an object can only belong to a superClass that exists engine-side and is in the object's parent namespace:
"SimObject::linkNamespaces - cannot link object to superclass %s because c++ class %s is not in the parent namespace chain. Linking object to c++ class."
However, I didn't find this to be true. Perhaps this was changed with newer versions?
Here I used a superClass that is only defined on script-side and not in C++.
function useClassProperty2()
{
new ScriptObject(MyScriptObj)
{
class = MyExtensionClass2;
superClass = MyExtensionClass3;
};
%result = MyScriptObj.getName();
echo("getName() returned: '" @ %result @ "'");
MyScriptObj.delete();
}
function MyExtensionClass2::getName(%this)
{
%result = Parent::getName(%this);
return "Name from class " @ %result;
}
function MyExtensionClass3::getName(%this)
{
%result = Parent::getName(%this);
return "Name from superClass " @ %result;
}So what I understood from Daniel's reply is that a superClass can be thought of just as an additional block of ready functionality that is added to an object. In which case, to name it superClass is a little bit misleading in my opinion!
#4
Object Name -> Script Class -> Script Superclass -> Class -> ...
Where 'Class' is the actual engine class of the object, and ... is whatever hierarchy it has.
09/15/2014 (4:11 pm)
Kareem, it's basically that. Use it the same way you would use class, if you need multiple layers of hierarchy. In usual OO class hierarchies, you can keep inheriting and have an inheritance chain as long as you want. In TorqueScript, AFAIR, you can only haveObject Name -> Script Class -> Script Superclass -> Class -> ...
Where 'Class' is the actual engine class of the object, and ... is whatever hierarchy it has.
#5
I have used this feature in the past but never stepped beyond using it to create common script-side behavior for standard objects.
Which, now that I think about it, is what Daniel was talking about - wow. I had forgotten all about that....
Why do you find the term "superClass" misleading? It is intended to be a level "above" the "current" object, similar to the Java term in many ways. In theory it should work like this:
And really, I should probably test stuff like this before posting but I like to live dangerously....
09/15/2014 (4:28 pm)
Hey, I was only copy/pasting an error message from the engine - lol. It does indeed appear that at some point this restriction was lifted.I have used this feature in the past but never stepped beyond using it to create common script-side behavior for standard objects.
function GameSprite::updateSchedules(%this)
{
// ...
}
%obj = new Sprite()
{
class = Enemy;
superClass = GameSprite;
};
%obj.updateSchedules();Which, now that I think about it, is what Daniel was talking about - wow. I had forgotten all about that....
Why do you find the term "superClass" misleading? It is intended to be a level "above" the "current" object, similar to the Java term in many ways. In theory it should work like this:
function ParentClassDef::getTheName(%this)
{
return %this.Name;
}
function Child1ClassDef::getTheName(%this)
{
return %this.Name @ "_" @ %this.superClass;
}
function Child2ClassDef::getTheName(%this)
{
return %this.superClass @ "_" @ %this.Name;
}
%obj = new ScriptObject(Object1){
class = Child1ClassDef;
superClass = ParentClassDef;
};
%obj2 = new ScriptObject(Object2){
class = Child2ClassDef;
superClass = ParentClassDef;
};
%obj3 = new ScriptObject(Object3){
superClass = ParentClassDef;
};
echo(%obj.getTheName()); // should be Object1_ParentClassDef
echo(%obj2.getTheName()); // should be ParentClassDef_Object2
echo(%obj3.getTheName()); // should be Object3So, in theory the superClass should provide base functionality that "descendant" classes can override. The main disjoint between this and, say, Java's definition is that there is no true inheritance tree here - it's just namespace trickery.And really, I should probably test stuff like this before posting but I like to live dangerously....
#6
Richard, I guess we are to blame the un-updated engine code base here :). No problem. The code base is large and small things may be left out. I also like to live dangerously.
Anyway, I can go with the superClass naming. I know it's a minor issue. However, I'd like to think about it as a plug-in or a component (as in Unity3D for example) that can be added to the namespace hierarchy of an "object" and not a superClass in the OOP sense. I say that because a superClass in Java or C++ doesn't have this special ability to be used in the "middle" of totally different inheritance trees. I mean it is not a tree in that sense and more of a graph or, well, a hierarchy.
09/15/2014 (8:39 pm)
Daniel thanks a lot you made the idea clear.Richard, I guess we are to blame the un-updated engine code base here :). No problem. The code base is large and small things may be left out. I also like to live dangerously.
Anyway, I can go with the superClass naming. I know it's a minor issue. However, I'd like to think about it as a plug-in or a component (as in Unity3D for example) that can be added to the namespace hierarchy of an "object" and not a superClass in the OOP sense. I say that because a superClass in Java or C++ doesn't have this special ability to be used in the "middle" of totally different inheritance trees. I mean it is not a tree in that sense and more of a graph or, well, a hierarchy.
#7
09/16/2014 (6:02 am)
Yeah, TorqueScript's version of OOP is loose to say the least. According to that error message it was intended to be within the same actual class tree, but somewhere along the line it was broken - probably to facilitate sharing superclass code between TSStatic and StaticShape (which I believe are derived from different base classes) or something like that. It does get the job done, but it's weird.
#8
Looking at the code and comments, it appears much of that section deals with namespace issues that arise when multiple packages have been loaded. In the simple case when a superclass is not explicitly linked to a package namespace hierarchy, the routine seems to simply hard-link the object's c++ namespace as the superclass namespace's package root ... and the error checking code will not even execute. At any rate, the code is definitely not checking the c++ class tree but rather walking the script-defined namespace links to make sure the object and superclass "see" each other.
Which brings us to ...
The terms "superclass" and "class" (and "namespace" for that matter) are often characterized as misleading in Torque because of exactly misunderstandings such as the one you have here. Both C++ and Torquescript have relevance to development tasks and both use the same terms to describe significantly different functionality. Then to top it off, in script the C++ class name is always referenced as the "top-level" parent that applies to all objects of that C++ class ... requiring the differentiation "script class" and "class" be used when talking about defining complex script objects (e.g. Daniel Buckmaster's previous comment). It is sometimes damn near impossible to differentiate between the "script" meaning and the "engine" meaning of the same term ... especially when the usages are seemingly mixed in the same error message. It really can get confusing as all hell.
09/17/2014 (9:16 pm)
@richard: The code to generate the error you mentioned will only be processed in a debug build ... and then only under certain conditions. There is no indicator this sanity checking has been removed or broken. I don't think the script examples provided here would ever generate the highlighted error even in debug mode. Looking at the code and comments, it appears much of that section deals with namespace issues that arise when multiple packages have been loaded. In the simple case when a superclass is not explicitly linked to a package namespace hierarchy, the routine seems to simply hard-link the object's c++ namespace as the superclass namespace's package root ... and the error checking code will not even execute. At any rate, the code is definitely not checking the c++ class tree but rather walking the script-defined namespace links to make sure the object and superclass "see" each other.
Which brings us to ...
The terms "superclass" and "class" (and "namespace" for that matter) are often characterized as misleading in Torque because of exactly misunderstandings such as the one you have here. Both C++ and Torquescript have relevance to development tasks and both use the same terms to describe significantly different functionality. Then to top it off, in script the C++ class name is always referenced as the "top-level" parent that applies to all objects of that C++ class ... requiring the differentiation "script class" and "class" be used when talking about defining complex script objects (e.g. Daniel Buckmaster's previous comment). It is sometimes damn near impossible to differentiate between the "script" meaning and the "engine" meaning of the same term ... especially when the usages are seemingly mixed in the same error message. It really can get confusing as all hell.
#9
I'm just saying that the intent was for them to work effectively as named, not that they strictly do work as named. I completely understand how someone from a Java background might be extremely confused at some of the weirdness Torquescript brings. I guess for me it's less surprising because of the order in which I learned my languages: Assembly, C/C++, Torquescript, Lua, then Java.... I guess "parent class" is what C++ would expect it to be called, but for some reason I just accepted the oddness and rolled on.
09/18/2014 (6:21 am)
Ah - right, packages.... It's funny how easy it is to forget about those.I'm just saying that the intent was for them to work effectively as named, not that they strictly do work as named. I completely understand how someone from a Java background might be extremely confused at some of the weirdness Torquescript brings. I guess for me it's less surprising because of the order in which I learned my languages: Assembly, C/C++, Torquescript, Lua, then Java.... I guess "parent class" is what C++ would expect it to be called, but for some reason I just accepted the oddness and rolled on.
Torque Owner Richard Ranft
Roostertail Games
// from source/console/scriptObjects.cpp, line 36 ConsoleDocClass( ScriptObject, "@brief A script-level OOP object which allows binding of a class, superClass and arguments along with declaration of methods.nn" "ScriptObjects are extrodinarily powerful objects that allow defining of any type of data required. They can optionally haven" "a class and a superclass defined for added control of multiple ScriptObjects through a simple class definition.nn" "@tsexamplen" "new ScriptObject(Game)n" "{n" " class = "DeathMatchGame";n" " superClass = GameCore;n" " genre = "Action FPS"; // Note the new, non-Torque variablen" "};n" "@endtsexamplen" "@see SimObjectn" "@ingroup Consolen" "@ingroup Scripting" );To control an object from script, you have three namespaces you can use for defining methods; object name, class, and superClass. From the following error message (found in source/console/simObject.cpp at line 1476) it appears that an object can only belong to a superClass that exists engine-side and is in the object's parent namespace:I think that superClass is used so that, for instance, GameSprite and HUDSprite can derive from Sprite but still share common script-defined methods without duplicating effort (I might be off, I haven't bothered with superClasses in forever).
The script class is so that you can have Sprite objects, for instance, of class Enemy, Bullet, PickUp, etc - they're all Sprites but have a general "class" of behavior that differs from type to type.
The script object name can be used to scope methods that only apply to a specific object.
Ultimately, the best way to get a feel for it is to just jump in and play with it.