Game Development Community

Classes

by Danny Mejia · in Torque Game Builder · 09/07/2006 (6:30 am) · 14 replies

I have 10 object in a game that will almost be the same so I was think of use a super class. But how do I set up a super class in torque script or do I use a simobject? Here want a outline of what I need

Super Class (MasterObject)
{
dyanmicFlied1
dyanmicFlied2
dyanmicFlied3
dyanmicFlied4
....
.....
.....
}

%testObject = new t2dStaticSprite() {
class = "myclass";
super class = "MasterObject";
};

Thanks for your help

#1
09/07/2006 (7:55 am)
If I understand your question you are asking how to declare and or define a super class? I believe the answer is that you do not have to declare it. I made the same mistake for a long time using both classes and superclasses. See this thread for more info...

www.garagegames.com/mg/forums/result.thread.php?qt=48687

EDIT: Here is another link on the subject also

www.garagegames.com/mg/forums/result.thread.php?qt=50178
#2
09/07/2006 (9:43 am)
@Danny

Your situation seems more tailored to datablocks than superclasses. If you want objects to have the same properties, then use config datablocks. If you want many objects to have the same methods in their callchain, you use classes. If you want objects to have more than one class' namespace in its callchain, then you use superclasses (and object names).
#3
09/08/2006 (2:36 pm)
Thanks.. I will need all object to use the same method to.
#4
09/08/2006 (3:12 pm)
Just put the superclass declaration in the datblock. Then all objects using that config datablock will use that superclass namespace assuming they don't explicitly override it.
#5
09/09/2006 (2:04 am)
To answer the question in a simple manner here's a little example...

Given the following code:
// a function on namespace A
function A::hello( %this )
{
   echo( "hi  (from A)" );
}

// functions on namespace B
function B::hello( %this )
{
   echo( "heya  (from B)" );
}

function B::goodbye( %this )
{
   echo( "bye  (from B)" );
}

// a new object
new ScriptObject( something )
{
   class = A;
   superclass = B;
};

// some calls on the new object
something.hello();
something.goodbye();

The output would be:

hi (from A)
bye (from B)

What this was meant to show is that you set up class and superclass functions the same - on a namespace. The only difference is that functions on your class namespace (A) take precedence over functions on your superclass namespace (B).

It's important to understand that this applies on a per-object basis so, for example, you could have another object with B as its class and A as its superclass. If that were the case with our above object, the output would be the following:

heya (from B)
bye (from B)

Hope this was helpful.
#6
09/09/2006 (2:21 am)
Still a bit new to classes and precedence, so this may sound silly, but how would you go about accessing "hello" from the superclass, in your example?
#7
09/09/2006 (3:22 am)
@Teck: Good question. I did a little digging and came up with my own set of test classes...

function supr::func ( %this )
{
   echo("supr::func");
}

function supr::foo ( %this )
{
   echo("supr::foo");
}

function chld::func ( %this )
{
   parent::func();
   echo("child::func");
}

new ScriptObject ( c )
{
   class = chld;
   superclass = supr;
};

So, the call to "c.foo();" will return "supr:foo" and the call to "c.func();" will return:

supr::func
chld::func

I know, it seems odd to make a call to "parent::func" when you really want its superclass. I tested it and it does work.

EDIT: Made some typos. Too early in the morning.
#8
09/09/2006 (4:07 am)
Scott, parent::func seems to make sense, and is good to know, thanks. However, what I actually meant (and I probably should have made this clearer) was, how would you go about accessing the superclass from outside the class function declaration? For example, you have:
function chld::func ( %this )
{
   parent::func();
   echo("child::func");
}
I'm wondering if there's some sort of way to do something like:
parent.c.func();
(And no, the above line doesn't work, and neither does c.parent.func(). :p)

edit:
The one way that comes to mind, would be to pass a variable to the class function, that then runs the superclass function instead of the containing code, though I don't know if this is desirable, nor the best way to go about it:
function chld::func(%this, %super) {  // %super would be a boolean, I reckon
  if(!%super) {
    echo("chld::func");
  }
  else {
    parent::func();
  }
}
So "c.func();" would give you "chld::func", and "c.func(1);" would give you "supr::func".
Or something like that.

(come to think of it, is there a way to give a passed variable in the function declaration a default value?)
#9
09/09/2006 (4:39 am)
The basic idea of inheritance stems from the need to have basic common functionality shared among several different types of objects. In my example the superclass goodbye function is called because there is no goodbye function defined on the class namespace. Normally if you want to have two different things happen in two different scenarios, you would write two seperate functions to handle those cases, rather than have the superclass and class be defined differently.

That said, if for some reason you need to call a function on the superclass namespace without calling that function on the class namespace, you can do so directly on the namespace like this:

// call supr::func on the object 'c'
supr::func( c );

// or if the specific superclass is unknown or variable...  
// the following evaluates to "supr::func( c );" in this case
eval( c.superclass @ "::func(" @ c @ ");" );

Note that when you use this syntax to call a function you have to explicitly pass "%this" as a parameter.

Edit: Typo.
#10
09/09/2006 (4:45 am)
Thanks Thomas, that makes sense. As for why one would do this, I honestly don't have a clue. It was just one of those idle questions that my mind seems to like coming up with. :)
#11
09/09/2006 (9:54 am)
@Scott's example:

...

function chld::func ( %this )
{
   parent::func(%this);
   echo("child::func");
}

...

Be sure to pass %this explicitly as a parameter to the parent or it will receive an empty in that parameter.
#12
09/09/2006 (11:34 pm)
Secondary Edit: I removed this comment since the technique is no longer viable due to namespace linking changes--and it was honestly a hack anyway! This was effective way back when we were using ScriptObjects for class/superclass, but it is not a good technique anymore, so I dont want to confuse the forums.
#13
09/10/2006 (1:15 am)
Won't you still need to explicitly pass your %this into the function since your invocation of the function in that case is tied to the namespace of the superclass and not a specific instance of an object having that superclass? Or are you saying that %myObject.superclass is actually not just a string naming the superclass namespace but actually a 'sliced' object having superclass as its namespace? I'm thinking of the concept of slicing in the c++ sense.
#14
09/10/2006 (8:01 am)
I'm going to have to trackdown some old code and see exactly how I used this, because you bring up a good point :) I'm pretty sure you are correct however, you'll need to pass along the proper object ID manually to make sure your function has the correct information to use.

EDIT: Tracked down the code, and it is now out of date, so I've removed the suggestion from above. Good catch guys, hope I didn't confuse anyone for to long!