Game Development Community

What is the "superclass" used for?

by Vince Gee · in Torque 3D Professional · 05/02/2013 (10:54 am) · 7 replies

I know,

ClassName = C++ Class Name
ClassNameSpace = The TorqueScript Class Name

But..

What is the SuperClass used for?

#1
05/02/2013 (11:08 am)
I do believe it's used to define a "parent" class. I'm not 100% sure but some experiments with Tribes 2 stuff has come up with this:

So, let's say I define a new ScriptObject class, let's call it "myClass", so I'll have this:

new ScriptObject(test) {
   class = "myClass";
};

Now, it's pretty obvious the parent class here is ScriptObject (it's the name of the created object). But let's say I want to expand the functioning to include "all" of the SimObject tools. I could then do this:

new ScriptObject(test) {
   class = "myClass";
   superClass = "SimObject";
};

Someone correct me here if I'm wrong, but this is what I recall superClass being used for.
#2
05/02/2013 (12:42 pm)
nice to know.
#3
05/02/2013 (3:30 pm)
Quote:ClassName = C++ Class Name
ClassNameSpace = The TorqueScript Class Name
Not sure if I've seen ClassNameSpace used anywhere, but I'll explain what I understand of the system.

When you create an object, it has a class hierarchy that determines what methods you can call on it. An object's name is the first level in this hierarchy, then its actual class, then any classes that class was inherited from. So, for example, creating a SceneObject named Bill makes a class hierarchy that looks like:

Bill -> SceneObject -> SimObject -> ConObject -> NetObject or whatever the inheritance chain is

So if you call a method on Bill, the engine first checks if there is a function Bill::whatever, and then it checks for SceneObject::whatever and so on.

The 'class' and 'superclass' fields just let you insert arbitrary steps in this chain after the object's name. So giving Bill the 'Armor' class makes the chain look like:

Bill -> Armor -> SceneObject -> ...

And giving him the 'Something' superclass makes it look like:

Bill -> Something -> SceneObject -> ...

And giving him both results in:

Bill -> Armor -> Something -> SceneObject -> ...

Someone please correct me if it's not, but I'm pretty sure that's how it works.

OKAY I TESTED IT.

Here's my script:
function ScriptObject::testStuff(%this) { echo("ScriptObject"); }
function ClassA::testStuff(%this) { echo("class A"); Parent::testStuff(%this); }
function ClassB::testStuff(%this) { echo("class B"); Parent::testStuff(%this); }
function Bill::testStuff(%this) { echo("Bill"); Parent::testStuff(%this); }
function Ben::testStuff(%this) { echo("Ben"); Parent::testStuff(%this); }
function Daisy::testStuff(%this) { echo("Daisy"); Parent::testStuff(%this); }

new ScriptObject(Bill) { class = "ClassA"; };
new ScriptObject(Ben) { superClass = "ClassB"; };
new ScriptObject(Daisy) { superClass = "ClassB"; class = "ClassA"; };

echo("===");
Bill.testStuff();
Bill.doSomething();
echo("===");
Ben.testStuff();
Ben.doSomething();
echo("===");
Daisy.testStuff();
Daisy.doSomething();
echo("===");

Apparently Daisy, who has a class and superclass, is only a member of class B. Her echo looks like this:

===
Daisy
class B
ScriptObject
main.cs (301): Unknown command doSomething.
  Object Daisy(3957) Daisy -> ClassB -> ScriptObject -> SimObject
===

So it looks like superClass is stomping on class, which makes zero sense. Maybe I'm doing something nonstandard in my build... shouldn't be though. Hrm.
#4
05/02/2013 (3:40 pm)
Aha! Found a hidden funny thing which kind of makes sense. In a debug build, my code above throws this: 'Error: cannot change namespace parent linkage of ClassA from ScriptObject to ClassB.' Basically, when I create Bill, I'm saying that ClassA inheritc from SceneObject. But when I create Daisy, I'm saying that ClassA inherits from ClassB. So, I changed it to this:

function ScriptObject::testStuff(%this) { echo("ScriptObject"); }
function ClassA::testStuff(%this) { echo("class A"); Parent::testStuff(%this); }
function ClassB::testStuff(%this) { echo("class B"); Parent::testStuff(%this); }
function ClassC::testStuff(%this) { echo("class C"); Parent::testStuff(%this); }
function Bill::testStuff(%this) { echo("Bill"); Parent::testStuff(%this); }
function Ben::testStuff(%this) { echo("Ben"); Parent::testStuff(%this); }
function Daisy::testStuff(%this) { echo("Daisy"); Parent::testStuff(%this); }

new ScriptObject(Bill) { class = "ClassA"; };
new ScriptObject(Ben) { superClass = "ClassB"; };
new ScriptObject(Daisy) { superClass = "ClassB"; class = "ClassC"; };

echo("===");
Bill.testStuff();
Bill.doSomething();
echo("===");
Ben.testStuff();
Ben.doSomething();
echo("===");
Daisy.testStuff();
Daisy.doSomething();
echo("===");

And everything works as expected:

===
Bill
class A
ScriptObject
main.cs (296): Unknown command doSomething.
  Object Bill(3955) Bill -> ClassA -> ScriptObject -> SimObject
===
Ben
class B
ScriptObject
main.cs (299): Unknown command doSomething.
  Object Ben(3956) Ben -> ClassB -> ScriptObject -> SimObject
===
Daisy
class C
class B
ScriptObject
main.cs (302): Unknown command doSomething.
  Object Daisy(3957) Daisy -> ClassC -> ClassB -> ScriptObject -> SimObject
===
#5
05/02/2013 (4:56 pm)
why? Why make something that convoluted?

Why not just make

class b derive from ScriptObject
class c derive from b
class daisy derive from c?

Why the reach around?
#6
05/02/2013 (5:28 pm)
Because TorqueScript has no class declarations in which to do that. It's all implicit based on how you use the class and superClass fields. I guess you could make some dummy ScriptObjects to hold your 'class declarations', and then you'd get warnings if you used it incorrectly in other scripts.
#7
05/02/2013 (7:22 pm)
"Superclass" is something for regular classes to look up to....