Recently I've been getting back into live coding, and as part of that I have been experimenting with a simple livecoding framework in C++.

One of my experiments involves using C++ as a scripting language, by compiling code on the fly (using g++, but any compiler should work) into a shared object, and then dlopen-ing the resultant file and hooking up the necessary functions.

By doing this I can have full access to the engine/framework and speed is never a concern. It also means I can modify it later to load any arbitrary shared object (ie. generated via C or any other language, perhaps Chicken?).

The workflow I desired to achieve was to have an OpenGL context open, blank at first. From there I could open the editor of my choice, hack on some high level C++/OpenGL, and when I saved the file, the engine would recompile the file and load it, causing its rendering function to be overridden with the new one.

I'm happy to say I've achieved what I was after!

I will be posting the relevant source to do this in the next post, but for now I will say that it involves a very simple class called FileTools that wraps inotify on the Linux operating system (so it will need to be ported for other OS's, or a generic polling solution could be used very easily, by simply resorting to stat)), which allows one to watch a file with some simple code that looks like this:

int fd = FileTools::addWatch("test.cpp");

while (mainloop) {
      if (FileTools::hasChanged(fd)) { // Uses select internally
         // Cool!


For my engine to extend this to include recompilation, I have another class called CodeTools, which wraps system and dlopen. This is also very easy to use, it looks like this:

if (FileTools::hasChanged(fd)) {
   CodeTools::compileFile("test.cpp", [](void* handle) {
      Renderer::renderp render = (Renderer::renderp)dlsym(handle, "render");
      if (render) // Hook 'er up
         ::engine.renderer->userRender = render;

Here we are passing a path to a file to compile, and a function (I'm using C++0x lambdas here) that takes a valid handle from dlopen.

Using this class it is also possible to using compileString to compile a string via temp files.

Oh and a screenshot for those wanting to see it in action!


(Maybe) Related posts: