Game Development Community

Bugg or intended design?

by Max Kielland · in Torque Game Builder · 11/02/2009 (9:10 pm) · 4 replies

Hello fellows,

I ran into a problem which I don't know if it is a bug or not. Logically it might not be a bug after all.
Consider this simple script (Made out from my head to not have to copy my whole project). Supose all globals have correct values.

function MyBase::onMouseDown(%this, %modifier, %worldPosition, %clicks) {

  %this.Clicked();
}

function MyClass::Clicked(%this) {

  echo("MyClass");
}

function Create() {

  %Object = new t2dStaticSprite() {
    scenegraph = $SceneGraph;
    class = "MyClass";
    superclass = "MyBase";
    imageMap = "MyImageMap";
    useMouseEvents = true;
  };
}

This scenario works well. When the sprite is clicked The onMouseDown in MyBase will be called and then call Clicked in MyClass. No problems here.

But if I do like this instead:

function MyBase::onMouseDown(%this, %modifier, %worldPosition, %clicks) {

  %this.Clicked();
}

function MyClass::Clicked(%this) {

  echo("MyClass");
}

function Create() {

  %Object = new t2dStaticSprite() {
    scenegraph = $SceneGraph;
    superclass = "MyBase";
    imageMap = "MyImageMap";
    useMouseEvents = true;
  };

  %Object.class = "MyClass";
}

This time I assign the class after the object was created. When I click the sprite this time, onMouseDown is called as usual, but! The class has not been set correctly and I get an error that Clicked() doesn't exist and it has started to search from the superclass not the class.

Is this the intended design?

(Okay, I wrote this example right out of my mind so son't complain about script errors, you get the point of what I mean with the class being assigned in the new statement and after the new statement).

#1
11/02/2009 (9:36 pm)
Researching something else earlier today, I happened to stumble upon this exact issue. I tucked it away in my brain for future use, but I guess I'm not the only one who needs this!

The problem is that even after the name is set, the namespaces must be linked up. The following link just shows Vern Jensen exposing the correct function to the scrips.

www.garagegames.com/community/forums/viewthread/75679/3#comment-537019

Fortunately, you have the Pro version and can make these changes.

Personally, I'd just modify the setClassNamespace and setSuperClassNamespace functions (which are already exposed to scripts) to call this automatically.
#2
11/02/2009 (11:17 pm)
Tanks William, good to know I'm not the only one.

However, I did a work around since I need the class to be set at creation (for the moment).

function Create(%fType) {

  switch(%fType) {
    
    case 0:
      %Class = "MyClassA";

    case 1:
      %Class = "MyClassB";

  }

  %Object = new t2dStaticSprite() {  
    scenegraph = $SceneGraph;
    class = %Class;  
    superclass = "MyBase";  
    imageMap = "MyImageMap";  
    useMouseEvents = true;  
  };  

}

I usually try to stay away from modifying third party products. It usually get messy at upgrades. But if I need to reuse the sprites, your modification will be handy. Thank you.

Still, is this a Bug or the intended behavior?

GG someone?

#3
01/25/2010 (12:02 pm)
just want to add that it unlikely that there will be any updates for TGB, so modifying the source shouldnt be a big problem, especially with source control there to help you determine how things have been changed over time..
#4
01/26/2010 (9:23 pm)
Hi, I'm new to Torquescript, but I wanted to add:

While your workaround (making a "create" function which takes a class type as a function parameter and returns a new object of that type) may seem weird, it's actually a well-known programming pattern in normal object oriented programming, so I would say in the future you should always do something like what you did, and consider it "clean" rather than "a workaround".

In normal object oriented programming (like c++) you must define the class of an object when you create it, so you need to do something like what you did (it's called a Factory method).

If you think about it in torquescript, it's less "important" since it's all just a bunch of namespaced functions (as far as I understand it anyways; I could be wrong), but I would guess as a general rule you'd want to define the class when you create an instance. For example, which class's "onAddToScene" callback gets called if you create the new instance before you define the class?

See also:
http://en.wikipedia.org/wiki/Factory_method_pattern
(scroll down to the ActionScript example to see exactly what you described doing above)