Adding Lua Hooks to Celestia
Posted: 11.09.2006, 22:51
I've been experimenting with a scheme for hooking Lua code into Celestia at strategic points. The goal is a mechanism that would allow experimenters and add-on developers to add new features to Celestia using Lua without having to modify the source code and recompile the application.
Here's a brief explanation of what I've done: (Some familiarity with Celestia internals and Lua is assumed.)
I added a new (optional) entry called LuaHook to the Celestia configuration file. It specifies the path to a file containing a chunk of Lua code that is loaded and run when Celestia starts up. This Lua code calls a new method called celestia:setluahook which I added ito celx. The argument to this method is a Lua object (a table of method functions) which will have its methods called by Celestia at strategic points.
I added a LuaState* variable called luaHook to CelestiaCore which is used to call Lua. (This is separate from the LuaState variable celxScript used for end-user scripting.) The luaHook variable is initially nil. If a LuaHook startup file is specified in the Celestia configuration file, then a LuaState is created and assigned to luaHook, and the specified file is loaded and run there. This is done in a new method added to CelestiaCore called initLuaHook.
After luaHook is initialized, the methods of the Lua object which was set in the LuaHook startup file using celestia:setluahook() can be called from CelestiaCore using a new method added to LuaState called callLuaHook(). Obviously calls to this method are made only if luaHook is not nil.
For example, to experiment with custom info overlays, I added this call to the draw method of CelestiaCore:
Similar calls are easily added at other points in the Celestia code. For example, to allow the Lua object to intercept keyboard input I added this call to the charentered method of CelestiaCore:
Note that the callLuaHook method is overloaded to accomodate passing arguments to the Lua method. Also note that a reference to the CelestiaCore object is included in the call, so that Lua hooks can be associated with Celestia objects other than the CeletiaCore.
That's the basic hookup mechanism. I've also made some additions to celx and enabled loadlib for dynamic libraries. More details will follow.
- Hank
Here's a brief explanation of what I've done: (Some familiarity with Celestia internals and Lua is assumed.)
I added a new (optional) entry called LuaHook to the Celestia configuration file. It specifies the path to a file containing a chunk of Lua code that is loaded and run when Celestia starts up. This Lua code calls a new method called celestia:setluahook which I added ito celx. The argument to this method is a Lua object (a table of method functions) which will have its methods called by Celestia at strategic points.
I added a LuaState* variable called luaHook to CelestiaCore which is used to call Lua. (This is separate from the LuaState variable celxScript used for end-user scripting.) The luaHook variable is initially nil. If a LuaHook startup file is specified in the Celestia configuration file, then a LuaState is created and assigned to luaHook, and the specified file is loaded and run there. This is done in a new method added to CelestiaCore called initLuaHook.
After luaHook is initialized, the methods of the Lua object which was set in the LuaHook startup file using celestia:setluahook() can be called from CelestiaCore using a new method added to LuaState called callLuaHook(). Obviously calls to this method are made only if luaHook is not nil.
For example, to experiment with custom info overlays, I added this call to the draw method of CelestiaCore:
Code: Select all
if (luaHook) then luaHook->callLuaHook(this,"luaoverlay");
Similar calls are easily added at other points in the Celestia code. For example, to allow the Lua object to intercept keyboard input I added this call to the charentered method of CelestiaCore:
Code: Select all
if (luaHook && luaHook->callLuaHook(this,"luacharentered", c))
return;
Note that the callLuaHook method is overloaded to accomodate passing arguments to the Lua method. Also note that a reference to the CelestiaCore object is included in the call, so that Lua hooks can be associated with Celestia objects other than the CeletiaCore.
That's the basic hookup mechanism. I've also made some additions to celx and enabled loadlib for dynamic libraries. More details will follow.
- Hank