Just to Make Sure: No "extends" keyword in script?
by Eric Robinson · in Torque Game Builder · 09/19/2006 (3:12 am) · 30 replies
Or anything similar? Is there any way to extend an object in script and make an entirely new object? Like, make a new class with fields and then be able to do something like "$myObj = new t2dStaticSpriteTwoPointOh()"? Or do I just have to do everything through dynamic fields and functions? Namespaces?
One more question: what does the colon do? For instance, what is someone trying to do in the following:
One more question: what does the colon do? For instance, what is someone trying to do in the following:
datablock ItemData(FlamingCrossbowAmmo : CrossbowAmmo)
{
...
};(The above is from the TDN Namespace page.
#2
Thanks for the explanation of the datablock stuff. Makes perfect sense now!
09/19/2006 (2:53 pm)
Right, so how exactly do I go about extending class A with class B in TorqueScript? What's the syntax for that? I haven't been able to find that in the documentation.Thanks for the explanation of the datablock stuff. Makes perfect sense now!
#3
09/19/2006 (4:45 pm)
For instance:new t2dStaticSprite()
{
class = "ClassA";
superclass = "ClassB";
};
#4
Perhaps this should be added to the TorqueScript Reference tutorial? It seems like awfully useful and awfully pertinent information, given the OO nature of the language.
Maybe in the Objects section? I mean... subclassing is kind of the point of objects, right?
09/21/2006 (6:12 pm)
Ahh, the superclass keyword! That's exactly what I needed to see! Thanks!!!Perhaps this should be added to the TorqueScript Reference tutorial? It seems like awfully useful and awfully pertinent information, given the OO nature of the language.
Maybe in the Objects section? I mean... subclassing is kind of the point of objects, right?
#6
To a point...TorqueScript is not a fully object oriented programming language. We provide some limited functionality that object oriented design has proven to be very useful, but there are fundamental differences that you will quickly run into if you are trying to force strong oop into TorqueScript.
09/21/2006 (10:27 pm)
Quote:
Maybe in the Objects section? I mean... subclassing is kind of the point of objects, right?
To a point...TorqueScript is not a fully object oriented programming language. We provide some limited functionality that object oriented design has proven to be very useful, but there are fundamental differences that you will quickly run into if you are trying to force strong oop into TorqueScript.
#7
In particular, I feel like Creating a Subclass in Script should be a sub-section alongside Handles and Names, Fields and Commands, Dynamic Fields, Namespaces, etc.
If there isn't any particular reason to not add it I could add it myself, I guess. After I play around with it a little bit to be sure of an implementation.
09/21/2006 (10:27 pm)
That resource is cool but it seems geared towards the TGE in particular. Tags... raindrops... etc. Putting mention of classes into this section seems to make the most sense to me. It's the logical place to put it and the resource I keep returning to thinking that I must have somehow missed it during the previous read-throughs.In particular, I feel like Creating a Subclass in Script should be a sub-section alongside Handles and Names, Fields and Commands, Dynamic Fields, Namespaces, etc.
If there isn't any particular reason to not add it I could add it myself, I guess. After I play around with it a little bit to be sure of an implementation.
#8
09/21/2006 (10:33 pm)
@Stephen:Quote:We provide some limited functionality that object oriented design has proven to be very useful, but there are fundamental differences that you will quickly run into if you are trying to force strong oop into TorqueScript.Could you expand upon this a bit possibly? In what areas will problems arise? What are some pitfalls to look out for?
#9
--you only have 2 "parent classes" to use. You cannot subclass indefinitely.
--there are quite a few restrictions on what types of classes can be child classes using the "class" and "superclass" namespace linkages. For example, you cannot have a t2dStaticSprite and a t2dAnimatedSprite both have the same "superclass".
--in true oop, it's common practice that instantiating a subclass calls the constructors of parent classes as part of the instantiation process. This is not true in TorqueScript (there is no real concept of script constructors in the first place).
--many of the slightly more esoteric relationships in oop theory aren't present, such as "friend" classes, "has a" relationships, and the like. You can of course explicitly set them up, but they aren't done for you automatically.
Just a little history to give some rationale for why TorqueScript hasn't evolved into a fully oop based language:
The original purpose of TorqueScript was to provide scripters interface to project specific c++ classes written for a project. It was an inherent design assumption that oop requirements would all be implemented in c++, and therefore TorqueScript didn't need any major oop enforcement--it was innate in the expected design/implementation flow of projects.
Obviously, things have changed with TGB, and specifically the binary only version, and TorqueScript has evolved somewhat to meet new requirements and expected use, but it's still not a fully oop language.
R&D is being performed to resolve these issues, but it's currently just that--research and (prototyping) development. No expected ETA, or even expected functionality at this time.
09/21/2006 (10:47 pm)
Well, just a couple:--you only have 2 "parent classes" to use. You cannot subclass indefinitely.
--there are quite a few restrictions on what types of classes can be child classes using the "class" and "superclass" namespace linkages. For example, you cannot have a t2dStaticSprite and a t2dAnimatedSprite both have the same "superclass".
--in true oop, it's common practice that instantiating a subclass calls the constructors of parent classes as part of the instantiation process. This is not true in TorqueScript (there is no real concept of script constructors in the first place).
--many of the slightly more esoteric relationships in oop theory aren't present, such as "friend" classes, "has a" relationships, and the like. You can of course explicitly set them up, but they aren't done for you automatically.
Just a little history to give some rationale for why TorqueScript hasn't evolved into a fully oop based language:
The original purpose of TorqueScript was to provide scripters interface to project specific c++ classes written for a project. It was an inherent design assumption that oop requirements would all be implemented in c++, and therefore TorqueScript didn't need any major oop enforcement--it was innate in the expected design/implementation flow of projects.
Obviously, things have changed with TGB, and specifically the binary only version, and TorqueScript has evolved somewhat to meet new requirements and expected use, but it's still not a fully oop language.
R&D is being performed to resolve these issues, but it's currently just that--research and (prototyping) development. No expected ETA, or even expected functionality at this time.
#10
Quick question here: I have just included the t2dTextObject into my code and compiled it. I now want to get a t2dTextObject into the editor. Could I do this by using something akin to the following in script:
What I want to do is position t2dTextObjects in the editor and pass them a class name in the Scripting variables. Then use that value as a namespace/class identifier so that I can add my own functions and set up to the object and all applicable callbacks, etc.
Or Plan B:
- Create a Scene Object in the editor.
- Edit the new Scene Objects Scriptable tab with the following settings:
Does that make sense?
09/21/2006 (11:26 pm)
Okay, that explanation makes good sense. Thanks!Quick question here: I have just included the t2dTextObject into my code and compiled it. I now want to get a t2dTextObject into the editor. Could I do this by using something akin to the following in script:
// Though I don't really understand [i]where[/i] to stick this block... does it need "var1=" before it so that var1 gets the new object? I assume there's no overwriting the new operator in script, right?
new t2dStaticSprite()
{
class = "myTextObject";
};and then give the Scene Object I drag into the level a class name of "myTextObject"? Does that make sense? (The code block doesn't seem to make sense to me but...)What I want to do is position t2dTextObjects in the editor and pass them a class name in the Scripting variables. Then use that value as a namespace/class identifier so that I can add my own functions and set up to the object and all applicable callbacks, etc.
Or Plan B:
- Create a Scene Object in the editor.
- Edit the new Scene Objects Scriptable tab with the following settings:
class = myTextObject superclass = t2dTextObject- Script the myTextObject class as usual (like a "Player::" class in any of the demos).
Does that make sense?
#11
Think of the namespace call chain as going
objectName -> class -> superclass -> type -> (into the engine c++ hierarchy)
Keep in mind that the "type" itself is already in the engine hierarchy but I just separated it here because I think it's easiest to think of it that way.
09/21/2006 (11:31 pm)
You never declare your classes in TS like you do in full featured OO languages. For instance, in langs like C++ and Java you have to have a class definition declared in order to instantiate it. Since TS is not actually instantiating anything you don't need to do this. OO in TS is more like syntactic sugar wrapped around a fancy namespace chaining trick. The only thing you need for a class to exist is to give an object the class field. Also, if something *is* a t2dTextObject, you never set the class or superclass to be t2dTextObject because that name is already in the namespace chain.Think of the namespace call chain as going
objectName -> class -> superclass -> type -> (into the engine c++ hierarchy)
Keep in mind that the "type" itself is already in the engine hierarchy but I just separated it here because I think it's easiest to think of it that way.
#12
09/21/2006 (11:37 pm)
Additionally, don't get confused by the way things are named. Even though one of the fields is called "superclass" you never really have an object that is a subclass of another. It's all smoke and mirrors with namespaces. You can think of it on an abstract level as subclassing, but from a technological standpoint it is not an actual subclass. For that matter, it isn't even an actual class. It's just namespacing and adding to the call chain.
#13
The object wouldn't be anything more than an instantiation of the t2dSceneObject class (which is in the class tree for t2dTextObject). If I put in t2dTextObject for the objects 'superclass' through the editor, would I then be telling the engine that I am actually using a t2dTextObject or does that simply not work because the actual object that I put in the editor knows nothing about the t2dTextObject functionality...?
Does that mean that I'd nead to edit the editor's source code to make t2dTextObjects accessible like sprites (static and animated), triggers, etc.?
09/22/2006 (12:24 am)
@Ben:Quote:Also, if something *is* a t2dTextObject, you never set the class or superclass to be t2dTextObject because that name is already in the namespace chain.So just to be clear, my Plan B from above works?
Think of the namespace call chain as going
objectName -> class -> superclass -> type -> (into the engine c++ hierarchy)
The object wouldn't be anything more than an instantiation of the t2dSceneObject class (which is in the class tree for t2dTextObject). If I put in t2dTextObject for the objects 'superclass' through the editor, would I then be telling the engine that I am actually using a t2dTextObject or does that simply not work because the actual object that I put in the editor knows nothing about the t2dTextObject functionality...?
Does that mean that I'd nead to edit the editor's source code to make t2dTextObjects accessible like sprites (static and animated), triggers, etc.?
#14
If you do
The namespace call chain of the object is
myName -> classA -> classB -> t2dTextObject -> t2dSceneObject.
If you had put t2dTextObject as class or super class the engine would likely give an error about not being able to unlink a namespace since you were trying to put it in there twice.
You seriously need to read a few namespace tutorials and even consider picking up Maurina's excellent Game Programmer's Guide To Torque.
09/22/2006 (8:28 am)
T2dTextObject is already a class in C++. I haven't traced the hierarchy of it but for the sake of example let's assume in C++ that t2dTextObject is a direct descendant of t2dSceneObject.If you do
new t2dTextObject(myName)
{
class = "classA";
superclass = "classB";
};The namespace call chain of the object is
myName -> classA -> classB -> t2dTextObject -> t2dSceneObject.
If you had put t2dTextObject as class or super class the engine would likely give an error about not being able to unlink a namespace since you were trying to put it in there twice.
You seriously need to read a few namespace tutorials and even consider picking up Maurina's excellent Game Programmer's Guide To Torque.
#15
If we create our own object, do we have to explicitly code-in editor support for it in order to use it editor side? Or is there a way to add a generic item from the "Create" section of the editor and then tell the engine that what we really want is one of it's subclasses?
If we can't then I seriously recommend a name-change for the language from "class" and "superclass" to "namespace" and "supernamespace" or something. The terms "class" and "superclass" simply imply way too much if I cannot use them as in the scenario I present above. That and as I understand it now (I've read the tutorials on namespace stuff... linked them on the first post), you cannot actually do any "class"-work with the script code. As someone mentioned above: it's all kind of smoke and mirrors... except that users don't want smoke and mirrors. Users want clarity and "class" simply isn't the right word. Provided my interpretation of Namespaces and the whole situation is correct... and I just re-read the Namespace Tutorial. Actually, is it just me or is the last block of examle code actually supposed to have read:
09/24/2006 (6:14 am)
Quote:If you doOkay, I understand that. My point is that what I really want to do is take a t2dSceneObject (which I believe t2dTextObject actually does subclass), place it in the level using the editor and then manipulate that object through the script. The idea is that I tell the editor that it's a t2dTextObject by giving the object "superclass=t2dTextObject". Then I tell it that it should use the namespace "myTextPro" (versus my other option, "myTextCon", which also happens to rely on t2dTextObjects) by giving the object, editor-side, "class=myTextPro". There's no built in support for the t2dTextObject class in the editor so what I'm wondering now is:
new t2dTextObject(myName) { class = "classA"; superclass = "classB"; };The namespace call chain of the object is
myName -> classA -> classB -> t2dTextObject -> t2dSceneObject.
If you had put t2dTextObject as class or super class the engine would likely give an error about not being able to unlink a namespace since you were trying to put it in there twice.
If we create our own object, do we have to explicitly code-in editor support for it in order to use it editor side? Or is there a way to add a generic item from the "Create" section of the editor and then tell the engine that what we really want is one of it's subclasses?
If we can't then I seriously recommend a name-change for the language from "class" and "superclass" to "namespace" and "supernamespace" or something. The terms "class" and "superclass" simply imply way too much if I cannot use them as in the scenario I present above. That and as I understand it now (I've read the tutorials on namespace stuff... linked them on the first post), you cannot actually do any "class"-work with the script code. As someone mentioned above: it's all kind of smoke and mirrors... except that users don't want smoke and mirrors. Users want clarity and "class" simply isn't the right word. Provided my interpretation of Namespaces and the whole situation is correct... and I just re-read the Namespace Tutorial. Actually, is it just me or is the last block of examle code actually supposed to have read:
datablock ItemData(FlamingCrossbowAmmo [b]: CrossbowAmmo[/b])
{
...
};Without the bold part it's not actually copying the "className" variable and adding the "ammo" namespace to its call chain, right?
#16
So... basically the "class" and "superclass" variables exposed to the user are only for modifying the namespace call chain with user defined, scripted namespaces, huh?
Why call them "class" and "superclass"?
09/24/2006 (6:39 am)
Okay, I did some digging around in the code and it seems that "setClass" and "setSuperClass" simply call "setClassNamespace" and "setSuperClassNamespace" respectively. Both of those result in "StringTable->insert(classNamespace)".So... basically the "class" and "superclass" variables exposed to the user are only for modifying the namespace call chain with user defined, scripted namespaces, huh?
Why call them "class" and "superclass"?
#17
I understand the confusion when you try and equate this to a real OO language, but TS isn't a real OO language and will use terms differently. In this case using class and superClass was probably easier and shorter to type ;p
09/24/2006 (10:15 am)
It's just the way it is. Been that way since the beginning, back before 2000, and will continue to stay that way for compatibility reasons.I understand the confusion when you try and equate this to a real OO language, but TS isn't a real OO language and will use terms differently. In this case using class and superClass was probably easier and shorter to type ;p
#18
You don't create a t2dTextObject by setting its class to t2dTextObject. You create a t2dTextObject by creating a t2dTextObject. To create a t2dTextObject you do this (which I've posted several times already in this thread):
The callchain then goes
myName -> classA -> classB -> t2dTextObject -> t2dSceneObject
The call chain already contains both t2dTextObject and t2dSceneObject. Why would you want to place a t2dSceneObject and give it a class of t2dTextObject? That doesn't make sense in any abstract or concrete way. That's not the way namespaces work. Maybe this will make more sense of you think a little (but not too much) about classes in the engine being like classes in java and namespaces in script being like interfaces in java (with the limitation that you can only ever implement three of them). So if t2dTextObject and t2dSceneObject are classes, you could never say "implements t2dTextObject" which is essentially what you're trying to do when you say in TS class = "t2dTextObject" ***doesn't work***. Name, class, and superclass are just namespaces that are added to an object. Putting an engine class in there is not ever going to work. If you want a t2dTextObject you HAVE to make a t2dTextObject. You can't make something that's not a t2dTextObject and try to tell it that it is a t2dTextObject. That doesn't work in any language.
I feel like we're talking two different languages here. Which part of this is not making sense. Why are you trying to make a t2dSceneObject if a t2dTextObject is what you want?
09/24/2006 (5:57 pm)
@EricYou don't create a t2dTextObject by setting its class to t2dTextObject. You create a t2dTextObject by creating a t2dTextObject. To create a t2dTextObject you do this (which I've posted several times already in this thread):
new t2dTextObject(myName)
{
class = "classA";
superclass = "classB";
};The callchain then goes
myName -> classA -> classB -> t2dTextObject -> t2dSceneObject
The call chain already contains both t2dTextObject and t2dSceneObject. Why would you want to place a t2dSceneObject and give it a class of t2dTextObject? That doesn't make sense in any abstract or concrete way. That's not the way namespaces work. Maybe this will make more sense of you think a little (but not too much) about classes in the engine being like classes in java and namespaces in script being like interfaces in java (with the limitation that you can only ever implement three of them). So if t2dTextObject and t2dSceneObject are classes, you could never say "implements t2dTextObject" which is essentially what you're trying to do when you say in TS class = "t2dTextObject" ***doesn't work***. Name, class, and superclass are just namespaces that are added to an object. Putting an engine class in there is not ever going to work. If you want a t2dTextObject you HAVE to make a t2dTextObject. You can't make something that's not a t2dTextObject and try to tell it that it is a t2dTextObject. That doesn't work in any language.
I feel like we're talking two different languages here. Which part of this is not making sense. Why are you trying to make a t2dSceneObject if a t2dTextObject is what you want?
#19
Sorry about harping on this point. It's just that when you see the situation from a new users eyes then you see how ridiculous it seems. Nowhere in the documentation is it ever stated that "the class and superClass keywords do not actually refer to classes, but namespaces. Use these to modify the namespace call chain." Further, they aren't mentioned in the only two places it makes sense to mention them in any of the documentation: the TorqueScript Object section and the TorqueScript Namespace section. It would really help was if the situation were explained in: A) the prior only to mention that the two fields exist for all objects of classes that subclass t2dSceneObject and, B) the latter to specify that the two keywords actually refer to Namespaces. (There should also be a link in the Object section to their explanation/use in the Namespace section.)
Why not deprecate? Backwards compatibility is retained and, as I can tell you coming from a new user's perspective, obtain a new level of clarity.
@Ben: I understand that now. It's not what I was asking. What I wanted to know was if the TGB Level Editor interpreted things in that way (specially) so that you wouldn't have to modify the Editor to include your own objects in it. As it stands, I now understand that the editor does not have that functionality and I have yet to find documentation explaining how to add support for your own objects (t2dSceneObject descendents) or the time in which to figure it out on my own.
To be specific, I want to put a t2dTextObject into my level using the Level Editor, not through script. Up until now this has been done by dragging t2dAnimatedSprites and such from the Create panel to the level and then positioning them. It's fast, easy, and something that [coding-inexperienced] level designers can do. My thinking was that, hey, t2dTextObject subclasses t2dSceneObject. Well, maybe I can add the t2dSceneObject and then tell the Level Editor that it's actual class is t2dTextObject. This would let me add my own objects to levels without having to edit the Level Editor source code. Yesterday I waded through some of the editor source code and found my hopes dashed: the "Class" and "SuperClass" variables, setable in the Level Editor, do not, as explained above, refer to classes, but namespaces. I understand that I can't do it in the Level Editor which is disheartening. Positioning things in the level with the editor is much easier than through script. I would hope that there was a way to add/specify your own objects within the editor for ease-of-use purposes but it seems that you have to actually edit the Level Editor code.
Sorry if that's repetitive. I'm just trying to make sure everything makes sense... does it?
09/24/2006 (11:32 pm)
@Robert: It really is too bad to hear that. I seriously feel like it wouldn't be that hard to improve the language by deprecating those keywords and adding in new, more appropriate, less confusing, etc. keywords to take their place. Deprecation would not ruin compatibility but would improve usability. Drastically, if you ask me. I recalled seeing "class" and "superclass" in my initial perusing through the documention and then went on a wild search for that functionality, culminating in this forum thread. And it's wonderful that Torque isn't a real OOL... it's just that using standardized keywords seemingly without purpose is just... silly. Heck, you admit yourself that it's probably just "easier and shorter to type".Sorry about harping on this point. It's just that when you see the situation from a new users eyes then you see how ridiculous it seems. Nowhere in the documentation is it ever stated that "the class and superClass keywords do not actually refer to classes, but namespaces. Use these to modify the namespace call chain." Further, they aren't mentioned in the only two places it makes sense to mention them in any of the documentation: the TorqueScript Object section and the TorqueScript Namespace section. It would really help was if the situation were explained in: A) the prior only to mention that the two fields exist for all objects of classes that subclass t2dSceneObject and, B) the latter to specify that the two keywords actually refer to Namespaces. (There should also be a link in the Object section to their explanation/use in the Namespace section.)
Why not deprecate? Backwards compatibility is retained and, as I can tell you coming from a new user's perspective, obtain a new level of clarity.
@Ben: I understand that now. It's not what I was asking. What I wanted to know was if the TGB Level Editor interpreted things in that way (specially) so that you wouldn't have to modify the Editor to include your own objects in it. As it stands, I now understand that the editor does not have that functionality and I have yet to find documentation explaining how to add support for your own objects (t2dSceneObject descendents) or the time in which to figure it out on my own.
To be specific, I want to put a t2dTextObject into my level using the Level Editor, not through script. Up until now this has been done by dragging t2dAnimatedSprites and such from the Create panel to the level and then positioning them. It's fast, easy, and something that [coding-inexperienced] level designers can do. My thinking was that, hey, t2dTextObject subclasses t2dSceneObject. Well, maybe I can add the t2dSceneObject and then tell the Level Editor that it's actual class is t2dTextObject. This would let me add my own objects to levels without having to edit the Level Editor source code. Yesterday I waded through some of the editor source code and found my hopes dashed: the "Class" and "SuperClass" variables, setable in the Level Editor, do not, as explained above, refer to classes, but namespaces. I understand that I can't do it in the Level Editor which is disheartening. Positioning things in the level with the editor is much easier than through script. I would hope that there was a way to add/specify your own objects within the editor for ease-of-use purposes but it seems that you have to actually edit the Level Editor code.
Sorry if that's repetitive. I'm just trying to make sure everything makes sense... does it?
#20
--I personally agree with you on the naming issue, but was out voted for backwards compatibility/historical reasons. I'll bring it back up again!
--Currently, you have to write a new editor mode. Fortunately, R&D and documentation both are being worked on to make editor design/implementation mucheasier and effienct to perform.
09/25/2006 (7:38 am)
@Eric:--I personally agree with you on the naming issue, but was out voted for backwards compatibility/historical reasons. I'll bring it back up again!
--Currently, you have to write a new editor mode. Fortunately, R&D and documentation both are being worked on to make editor design/implementation mucheasier and effienct to perform.
Torque Owner Ben R Vesco
Think of the colon in your example like this:
1. Make a new ItemData datablock which is a copy of CrossbowAmmo
2. Name this new datablock FlamingCrossbowAmmo
3. Override the fields of the datablock with whatever values are shown in {...}
The colon essentially allows you to copy another datablock but override values as you see fit.