Previous Blog Next Blog
Prev/Next Blog
by date

Ruby Binding for TGEA

Ruby Binding for TGEA
Name:Matthias Georgi 
Date Posted:Jan 24, 2008
Rating:4.7 out of 5
Public:YES
Comments:YES
RSS Feed:GarageGames Blog feedor Subscribe with .
Profile Page:View profile page for Matthias Georgi

Blog post
After finishing a working implementation of my binding for the Ruby language, I'm gonna try now a tighter support using gccxml. After reading the post of Prairie Games and their work on the Python binding I was inspired to use the same route for generating wrappers for C++ classes.

My current implementation asks the Torque Scripting Environment for all defined classes, methods and fields and generates wrappers as script files, which call my binding code to interface with the Torque Engine. This has the drawback, that arguments and return values are converted to strings and my binding has to figure out, how to convert back and forth using the intermediate string representation.

This works quite well and has some kind of type safety in contrast to the Torque Scripting Language. I was able to convert all torque scripts to ruby scripts and the syntax is very nice to work with. Especially the scripts for the world editor got a lot clearer by using Ruby. A simple example will show you the advantages of using a full fledged scripting language. This is my implementation of the FileDialog GUI:


class FileDialogClass < GuiControl

child_accessor :window, :okButton, :cancelButton, :dirTree, :textEdit, :fileList

def_on(:add) do

window.on(:close) do
close
end

okButton.on(:action) do |sender|
@callback.call selectedFile
close
end

cancelButton.on(:action) do |sender|
close
end

dirTree.on(:selectPath) do |sender, path|
fileList.setPath(path, @filespec)
end

fileList.on(:select) do |sender, id, filename|
textEdit.setText(filename)
end

textEdit.on(:return) do |sender|
@callback.call(selectedFile)
close
end
end

def open(title = "Open File", button_text = "Open", filespec = "*.*", &proc)
window.text = title
okButton.text = button_text
@filespec = filespec
@callback = proc
Canvas.pushDialog(self, 99)
fileList.setPath(dirTree.getSelectedPath, @filespec)
end

def selectedPath=(file)
dirTree.setSelectedPath file
end

def selectedPath
dirTree.getSelectedPath
end

def selectedFile
"#{selectedPath}/#{textEdit.getValue}"
end

def close
Canvas.popDialog(self)
end

end


Essential was the implementation of the Event/Observer pattern, which simplifies the use of callbacks like onAdd. In Torque Script you are limited to one callback method for an event like onAdd. In my implementation you can attach more than one event listener to one instance or to the class itself. So you don't have to use namespaces, instead you attach the event listener to a particular instance, which should be done in the onAdd event handler, which gets called right after the creation of an object.

You may have noticed the child_accessor method. This one generates a accessor method for getting the child or descendant of a SimObject. This is cool, as you can avoid messing up the global namespace. You just use the internalName property of a child object and reach it via the accessor method.

So back to the GCCXML stuff. This is really exciting, as the xml format exposes the internal structure of a c++ program. I'm currently working on a small library, which parses the xml and makes the program structure accessible to the ruby world.

A simple Rakefile (like Make in Ruby) will transform the C++ classes to their xml representation and automatically generate wrapper code, which can be compiled by good old Visual Studio. This route allows a tight ruby binding avoiding the intermediate string representation. Furthermore all desired elements of the engine may be exposed to scripting and the burden of writing repetitive wrapper code is avoided.

If anyone is interested in ruby development, just let me know. I have invested a lot of time into this stuff (about 2 years) and like to share my experiences.

Submit ResourceSubmit your own resources!

Novack   (Jan 24, 2008 at 02:59 GMT)
Awesome job Matthias, What a 1st blog!

Montgomery Tidwell   (Jan 24, 2008 at 06:14 GMT)
truly amazing.

any chance this will work with TGE (and on non Win systems)? :)

Matthias Georgi   (Jan 24, 2008 at 11:42 GMT)
Thanks.

@Montgomery:
TGE should work fine, but It would require some merging of C++ code and removing some shader, material scripts.

I patched the engine on several places. First there were some little bugs in the engine code like wrong argument count for callbacks. A change was made in the GameConnection to avoid the ugly serverCmd* functions. Now the GameConnection itself dispatches the commmands and delegates to the server module, which in turn delegates to the corresponding module. Another change was made to the ActionMap class to issue the mouse/key callbacks to the ActionMap object itself to avoid global functions.

For non-win systems to work, ruby needs to be compiled, so you can distribute your own ruby executable. The engine must be compiled as dll extension, so a little change to the makefile is needed.

Porting and maintaining should be easier, once the componentized engine is available, as the code base is the same for TGEA and TGE.

Brian Richardson   (Jan 24, 2008 at 17:33 GMT)   Resource Rating: 5
Cool stuff!

Saiko   (Jan 24, 2008 at 19:52 GMT)   Resource Rating: 5
That is just cool! Any chance of a ruby binding for TGB? ;)

Matthias Georgi   (Jan 24, 2008 at 23:44 GMT)
@Saiko:
I don't own the TGB engine, but as far as I know, TGB is based on the same scripting engine. So it would be possible, but would require rewriting of some scripts.

Brandon Pollet   (May 13, 2008 at 19:12 GMT)
This is really exciting stuff Matthias! I've been away from game dev for awhile and working mostly with Ruby so it's great to see that as I jump back into the Torque experience I can leverage what I've learned. I would love to talk Ruby and Torque with you if you're interested.

Matthias Georgi   (Jun 02, 2008 at 20:24 GMT)
Hi Brandon, just write me an email. Your email seems to be outdated.

You must be a member and be logged in to either append comments or rate this resource.