Game Development Community

Creating instantiable objects in script

by Maxime Jouin · in Torque Game Engine · 01/18/2008 (12:42 am) · 7 replies

Hello all,

I'd like to create a group of GUI elements, with it's own methods, that I can instantiate at will, and I want to do it in script only. Kind of like creating a class in C++. Is there a way to achieve such a thing?

Thanks

#1
01/18/2008 (2:34 am)
I fail to see the problem arising from your question so I will be blunt:

Yes.
#2
01/18/2008 (2:47 am)
Sorry, I see I wasn't clear enough :) What I want to do is create a group of GUI elements (a button next to a textbox, for example). Say I name it myGuiGroup, I want to be able to create different instances of this group and place them all over my main GUI, something like:

new myGuiGroup( group1 )
{
   position = "0 0";
   extent  = "150 30";
};

new myGuiGroup( group2 )
{
   position = "0 50";
   extent  = "150 30";
};

I would like this group to have specific console methods, that would be called with the %this parameter by each instance. So basically, I want to create a new GUI component that I can manipulate and instantiate at will, and I would like to do it all in script.

The reason I want to do this is because I find myself duplicating a lot of code in my .gui files, because I am using the same combination of elements over and over again.

Now what would be the syntax to declare the object? And how do I instantiate it and use it?

Furthermore, how can I name the objects contained niside my group so that I can access them individually within each instance? Kind of like protected members in a C++ class.

Thanks.
#3
01/19/2008 (3:29 am)
First off, to be clear this is probably not going to turn out as pretty as you are expecting. Second, there are many ways to do this and I probably don't know the best.

So anyways here we go....

I've taken the example control (which can be extended into multiple controls) from the MainMenuGUI
function CreateMyGuiGroup(%pos, %extent)
{
   [b]// Create the base (container control)[/b]
   %newControl = new GuiChunkedBitmapCtrl(MainMenuGui) {
   canSaveDynamicFields = "0";
   Profile = "GuiContentProfile";
   HorizSizing = "width";
   VertSizing = "height";
   position = [b]%pos[/b];
   Extent = [b]%extent[/b];
   MinExtent = "8 8";
   canSave = "1";
   Visible = "1";
   Variable = "";
   hovertime = "1000";
   bitmap = "./images/sbf01";
   useVariable = "0";
   tile = "0";
  };
   
   [b]// Create child controls assigning them to names within the base control[/b]
   %newControl.myButton = new GuiButtonCtrl() {
      profile = "GuiButtonProfile";
      horizSizing = "right";
      vertSizing = "top";
      position = "36 237";
      extent = "110 20";
      minExtent = "8 8";
      visible = "1";
      command = "Canvas.setContent(startMissionGui);";
      text = "Start Mission...";
      groupNum = "-1";
      buttonType = "PushButton";
         helpTag = "0";
   };

    [b]// return the control(s) we create[/b]
    return %newControl;
}


[b]// Now:
%myControl1 = CreateMyGUIGroup(%pos, %extent);
%myControl2 = CreateMyGUIGroup(%pos, %extent);

%myControl1.myButton.text = "Button1";
%myControl2.myButton.text = "Button2";
[/b]


NOW: To be fair, I haven't tried this and it may need tweaking but the main idea here is just define a function that creates your controls. Make sure you assign sub controls to variables. Call this function and use the stuff returned.

Perhaps it is possible to create a more structured system but this is quick and easy.
#4
01/21/2008 (12:28 am)
Thanks Brian,

That is how I ended up doing it (although I didn't think about assigning subcontrols to variables, thanks for that). I even pass the control's name and the callback function as parameters to the function, and it works just fine.

I was kinda hoping for a more object oriented approach, but if that's the only way to go, it's better than nothing.
#5
01/21/2008 (4:16 am)
There are some resources for making TorqueScript more object oriented. I don't know how well they work but you should look them up. Besides that, without writing your own C++ classes I think your stuck with the more procedural version.
#6
01/21/2008 (10:19 am)
You can inherit datablocks if thats what your asking? The function is actually a good way to do it also.

new myGuiGroup( group2 : group1 )
{
};

That would inherit the parmeters of group1 which are not defined. So position and extent would be the same.

I think it works the same with gui stuff...as it does with other datablocks. :/

edit: you can also add parms to your function to inherit a certain datablock... something like:

function CreateMyGuiGroup(%inheritDB, %newDB)
{
new myGuiGroup( %newDB: %inheritDB)
{
};

}


Datablocks, Objects, and Namespaces Revisited
#7
01/22/2008 (12:58 am)
@mb: The problem with inheritance is that you need to inherit form a type, not an instance (if i'm not mistaken). So I don't think this would work for my problem (also, I'm not sure inheritance works for Gui controls).

@Brian: Thereis one major modification to make to the code you proposed in order for it to work. The secondary Gui has to be added explicitely to the main one:
%newControl.addGuiControl(%newControl.myButton);

Also, the position and extent of myButton need to be expressed using the position and extent passed as parameters to the function.

I got things working as I want them, not entirely happy with the procedural way all this happened, but it seems I have no other choice.

Thanks for the help guys.