29 Jun 2009 - Update on current Ogre.rb work

Work on Ogre.rb has progressed very nicely, and I even have the sky_plane demo working again, albeit without the debug Overlay, but that will come. I unfortunately have to put Ogre.rb work on halt for now and figure out how I’m going to take care of two main issues I’ve run into: memory management and method overloads.

  • Memory Management

Keeping proper object ownership across C++ and Ruby is not an easy problem, and compounding that is making sure that objects are constructed and destructed by the appropriate parties. Get this handling wrong, and the applications will Segfault all over the place. This can actually be seen right now, Ogre.rb applications will Segfault on close 100% of the time (Rice is cleaning up SceneManager instances, so when Root tries to do the same, boom). This will probably just be work in rb++ to open up comprehensive tools for telling Rice who owns what.

  • Method Overloading / Default Arguments

This is a biggie, and is the current blocker for me. Rice doesn’t currently support default arguments, and Ogre makes heavy use of this feature (just see SceneManager::setSkyPlan) and it’s becoming cumbersome having to specify every single argument to a given method. I don’t think this will be a difficult feature to implement, but it’s implementation also helps me with the other problem of method overloading.

Method overloading isn’t supported in Ruby at all, so I will have to fake it by counting arguments and figuring out calls according to argument types that come in (this is exactly what SWIG does). This will require a decent rebuild of Rice’s method wrapping system and is going to take a while to get done and get right.

Hopefully once this hurdle is taken care of Ogre.rb work will progress much smoother and faster.

19 May 2009 - Ogre.rb is back!

It has been a long time since my last annoucement of Ogre.rb, but it was for good reason. I’ve spent the last six months or so building a new toolchain for wrapping C++ libraries into Ruby, effectively creating a Ruby-specific replacement for SWIG. This toolchain is finally mature enough to begin re-writing the Ogre.rb wrapper, along with other libraries like libnoise and OIS. This new Ogre.rb will be closer to Ogre’s API, easier to read, write, and maintain, and many times easier to get started on wrapping other libraries. In short, I hope, the wait is worth it.

So, why did I give up on SWIG and build this tool chain? The short answer is that I wanted what the python-ogre" team has. For them, the tools py++ and pygccxml were well under development, facilitating their switch over from SWIG. I, unfortunately, had to build these libraries for Ruby from scratch, though with plenty of inspiration and help from the Python libraries.

But I digress. SWIG, while a great tool, has some fundamental issues that prevented me from continuing my work with Ogre.rb. The biggest killer was the lack of handling of nested classes. Ogre is full of nested classes, structs, and other constructs that SWIG was just unable to handle. I spent many hours pouring over SWIG’s code, looking to see if I could implement this handling, but I found that the single-pass construct was very much hard coded into the parsing step, and I would have needed to refactor much of the code base, which I wasn’t willing to do, as SWIG is a very complicated beast. So from this, I decided I was going to build a whole new tool chain.

My first problem was the Ruby version of Boost.Python, the powerhouse that does the dirty type management and exposing the C++ API into Python. I like C++ and I don’t mind developing in it, but this type of library requires massive use of templates, something I am very unfamiliar with outside of the very basics. Thankfully, after plenty of research and a few newsgroup posts, I was pointed at Rice, which while not exactly a Boost.Python replacement, did most everything I needed, and I was spared having to write that layer of the toolchain (and honestly, without which I probably would have dropped this project long ago). From here, I started building the two pieces I needed: rb++ and rbgccxml.

Rbgccxml takes XML output from GCC-XML (uses g++’s front-end parser and builds an XML representation of the parsed C/C++ code) and exposes a simple yet very powerful query API. With this library, one can easily and quickly find almost any piece of information from a header file, or from an entire library’s API. Queries like finding all the classes in a namespace, finding a specific instance method, or finding out what arguments a method takes are simple one liners, and chainable:

  # Find all methods in Ogre::SceneManager that have 2 arguments
  source.namespaces("Ogre").classes("SceneManager").methods.find(:arguments => [nil, nil])

With this library in place, I could continue with the toolchain and begin building the Rice code generation library.

Rb++ takes the output of rbgccxml for a given set of header files, applies rules to the code as defined by the user in a control file, generates and compiles Rice code, creating a Ruby extension exposing the C++ library to Ruby. Rb++ goes to great strides to make this process as effortless as possible, handling edge cases, functionality that Rice may not support, and various gotchas that are common occurances when wrapping C++ into Ruby. To see how little one has to do with Rb++, here’s the control file for the libnoise wrapper. The various details are explained in rb++’s documentation, but it’s easy to see at a glance what rules rb++ follows for this wrapper.

So, with those two libraries in great shape I have begun the work of a new Ogre.rb wrapper and hope to be back where I was with the SWIG wrapper very soon (I’m very close to having the SkyPlane demo working with input handling via OIS). Important project updates will go here on the News page and I’ll start getting some documentation up on the system; how to start a new wrapper, how to build and use existing wrappers, etc. The Ogre and OIS wrappers are currently my top priorities, following those I’ll probably look into a physics engine wrapper, though please feel free to suggest, or even start working on yourself, new wrappers or demos. You can find contact information on the About page.

Fork me on GitHub