I’ve been working in this a few weeks in my spare time after work. I took the idea of using C++ as a scripting language from http://molecularmusings.wordpress.com/2013/08/27/using-runtime-compiled-c-code-as-a-scripting-language/ and http://runtimecompiledcplusplus.blogspot.com. This is technically called “Runtime-compiled C++”, which I’ll call RCCpp from now on.
Obviously, C++ is not a real scripting language, nor it tends to be. The main goal is to shrink iterations’ time while having a quick preview of what you’re trying to accomplish while using a well-known language such as C++. You have the power of C++ with trusted IDEs, autocompletion, debugger and everything you’d need to work already, so you don’t need either to learn other language nor look for new tools to work with Lua or AngelScript. Of course, you can still shoot yourself in the foot, and have to be very careful about memory leaks, as the idea is to have Urho3DPlayer always running while it loads dynamically a recent compiled version of what you’re trying to do. Ok, enough chit-chat. This is what it looks like:
Enable HD to be able to read the code
To put it simple those are the steps that Urho3D’s RCCpp follows:
-
If a .cpp is passed as an argument (instead of a .lua or .as), a Makefile is generated on the fly (only GCC/MinGW is supported for now) with all the .cpp’s within that same folder and compiles everything into a shared library. So let’s say we run “Urho3DPlayer RCCpp/Game.cpp”. This will try to compile Game.cpp and all the cpp’s within RCCpp into a shared library called Game.dll (or Game.so if we’re on a Unix system). If instead we pass an already compiled library (.dll or .so), step 2 applies inmediately.
-
If the compilation succeeds, it will load at runtime the shared library and will execute its “Start” method, the same way it’s done with Lua or AngelScript.
-
Every time there’s a change in any .cpp being watched (within RCCpp folder, in this case), it will compile again and if it was successful, it will call the “Stop” method of Game, destroy the old Game object, unload the old library, load the new one and call its “Start” method. This has been done this way to avoid freezing the update loop so that the game plays as smoothly as possible. Please note that a total different object is created, so if you would like to have exactly the same state as before, you’ll have to serialize and unserialize it by yourself.
So, right now everything is compiled into a single library. This has pros and cons, but I ended up doing it like that because if I wanted to have a different library for each class (which is desirable in terms of extensibility and speed, so that I don’t have to unload and load all the classes at the same time, just the ones that need to be replaced) I’d have to use a fixed interface (usually Update and Render methods) and have somehow a list of dependencies among classes so that if I change one class, all of its dependant classes are also compiled or at least reloaded. This was quite painful at the end, so having everything in a single library eases things up and avoids some other problems.
I’ve tried to follow the rules that I’ve read in the documentation so that RCCpp is only used if a define is passed via CMake (URHO3D_RCCPP) and so on. I use the FileWatcher to know when a file has changed and needs to be recompiled. I also send useful events when a library/class is going to be unloaded or loaded, when the compilation has started or finished and so. It’s been tested it on Mac and Windows (with MinGW, no Visual Studio support yet) and it should work on Linux too. The only thing you need to make it work is adding your toolchain binary folder in your path so that “make” and “g++” can be called and define an environment variable called URHO3D_HOME pointing to your Urho3D’s main folder so that the include and library paths can be found in order to compile. You could also create a “PreMakefile” that will be included at the very beginning of the Makefile to pass to the compiler/linker your own flags. Take a look into the content of the Makefile generated to find the name of the variables to set.
Lastly, I’d like to hear your thoughts about this. Do you think is useful, do you think is a waste of time, what would you improve, do you have any suggestions? I’ve easily ported all the examples so that the same file and the same code works for the C++ samples as well as for RCCpp using a couple macros. The code is not the cleanest nor the most commented thing right now, but if people are interested, we could clean things up together and polish the bugs that may arise: github.com/pamarcos/Urho3D/tree/RCCpp