2008-07-16 01:21:25 +08:00
|
|
|
// -*-c++-*- osgWidget - Code by: Jeremy Moles (cubicool) 2007-2008
|
|
|
|
// $Id: Lua.cpp 2 2008-01-24 16:11:26Z cubicool $
|
|
|
|
|
|
|
|
#include <osgDB/FileUtils>
|
|
|
|
#include <osgWidget/Lua>
|
|
|
|
#include <osgWidget/Box>
|
|
|
|
#include <osgWidget/WindowManager>
|
|
|
|
|
|
|
|
// If you want to build with LUA, include it--otherwise, typedef some of the data types
|
|
|
|
// so that we don't pollute our code too much with conditional includes.
|
|
|
|
#ifdef OSGWIDGET_USELUA
|
|
|
|
extern "C" {
|
|
|
|
#include <lua.h>
|
|
|
|
#include <lualib.h>
|
|
|
|
#include <lauxlib.h>
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
namespace osgWidget {
|
|
|
|
|
|
|
|
// This namespace will include all of our Lua library functions. Otherwise, it'll be
|
|
|
|
// an empty namespace. This is 100% for code clarity, as this namespace is internal and
|
|
|
|
// not visible to the outside C/C++ world.
|
|
|
|
namespace lua {
|
|
|
|
#ifdef OSGWIDGET_USELUA
|
|
|
|
|
|
|
|
// Strings representing our global REGISTRY values.
|
|
|
|
const char* G_WM = "osgWidget_G_WindowManager";
|
|
|
|
|
|
|
|
WindowManager* getWindowManager(lua_State* L) {
|
2008-08-18 19:17:44 +08:00
|
|
|
lua_pushstring(L, G_WM);
|
|
|
|
lua_gettable(L, LUA_REGISTRYINDEX);
|
2008-07-16 01:21:25 +08:00
|
|
|
|
2008-08-18 19:17:44 +08:00
|
|
|
return reinterpret_cast<WindowManager*>(lua_touserdata(L, -1));
|
2008-07-16 01:21:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
int newWindow(lua_State* L) {
|
2008-08-18 19:17:44 +08:00
|
|
|
osg::ref_ptr<Window> w = new Box("testLUA", Box::HORIZONTAL);
|
2008-07-16 01:21:25 +08:00
|
|
|
|
2008-08-18 19:17:44 +08:00
|
|
|
lua_pushstring(L, w->getName().c_str());
|
2008-07-16 01:21:25 +08:00
|
|
|
|
2008-08-18 19:17:44 +08:00
|
|
|
return 1;
|
2008-07-16 01:21:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
int newWidget(lua_State* L) {
|
2008-08-18 19:17:44 +08:00
|
|
|
osg::ref_ptr<Widget> w = new Widget("testLUA", 0.0f, 0.0f);
|
|
|
|
|
|
|
|
lua_pushstring(L, w->getName().c_str());
|
2008-07-16 01:21:25 +08:00
|
|
|
|
2008-08-18 19:17:44 +08:00
|
|
|
return 1;
|
2008-07-16 01:21:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
int getWindow(lua_State* L) {
|
2008-08-18 19:17:44 +08:00
|
|
|
WindowManager* wm = getWindowManager(L);
|
2008-07-16 01:21:25 +08:00
|
|
|
|
2008-08-18 19:17:44 +08:00
|
|
|
lua_pushlightuserdata(L, wm);
|
2008-07-16 01:21:25 +08:00
|
|
|
|
2008-08-18 19:17:44 +08:00
|
|
|
return 1;
|
2008-07-16 01:21:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
// A helper function for all those cases where we need to inform the user that there isn't
|
|
|
|
// a LUA engine available.
|
|
|
|
bool noLuaFail(const std::string& err) {
|
2008-08-18 19:17:44 +08:00
|
|
|
warn() << err << "; Lua not compiled in library." << std::endl;
|
2008-07-16 01:21:25 +08:00
|
|
|
|
2008-08-18 19:17:44 +08:00
|
|
|
return false;
|
2008-07-16 01:21:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Our "private", internal data.
|
|
|
|
struct LuaEngineData {
|
|
|
|
#ifdef OSGWIDGET_USELUA
|
2008-08-18 19:17:44 +08:00
|
|
|
LuaEngineData():
|
|
|
|
lua(0) {
|
|
|
|
}
|
2008-07-16 01:21:25 +08:00
|
|
|
|
2008-08-18 19:17:44 +08:00
|
|
|
lua_State* lua;
|
2008-07-16 01:21:25 +08:00
|
|
|
#endif
|
|
|
|
};
|
|
|
|
|
|
|
|
LuaEngine::LuaEngine(WindowManager* wm):
|
|
|
|
_wm(wm) {
|
|
|
|
#ifdef OSGWIDGET_USELUA
|
2008-08-18 19:17:44 +08:00
|
|
|
_data = new LuaEngineData();
|
2008-07-16 01:21:25 +08:00
|
|
|
|
|
|
|
#else
|
2008-08-18 19:17:44 +08:00
|
|
|
_data = 0;
|
2008-07-16 01:21:25 +08:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
bool LuaEngine::initialize() {
|
|
|
|
#ifdef OSGWIDGET_USELUA
|
2008-08-18 19:17:44 +08:00
|
|
|
_data->lua = lua_open();
|
2008-07-16 01:21:25 +08:00
|
|
|
|
2008-08-18 19:17:44 +08:00
|
|
|
luaL_openlibs(_data->lua);
|
|
|
|
|
|
|
|
static const struct luaL_reg library[] = {
|
|
|
|
{"newWindow", lua::newWindow},
|
|
|
|
{"newWidget", lua::newWidget},
|
|
|
|
{"getWindow", lua::getWindow},
|
|
|
|
{0, 0}
|
|
|
|
};
|
2008-07-16 01:21:25 +08:00
|
|
|
|
2008-08-18 19:17:44 +08:00
|
|
|
luaL_openlib(_data->lua, "osgwidget", library, 0);
|
2008-07-16 01:21:25 +08:00
|
|
|
|
2008-08-18 19:17:44 +08:00
|
|
|
// An alternative to using the Registry here would be to pass the WindowManager
|
|
|
|
// as a userdata "closure" (pvalue). Please see the following doc on more info:
|
|
|
|
// http://www.lua.org/pil/27.3.3.html
|
|
|
|
lua_pushstring(_data->lua, lua::G_WM);
|
|
|
|
lua_pushlightuserdata(_data->lua, _wm);
|
|
|
|
lua_settable(_data->lua, LUA_REGISTRYINDEX);
|
2008-07-16 01:21:25 +08:00
|
|
|
|
2008-08-18 19:17:44 +08:00
|
|
|
return true;
|
2008-07-16 01:21:25 +08:00
|
|
|
|
|
|
|
#else
|
2008-08-18 19:17:44 +08:00
|
|
|
return noLuaFail("Can't initialize the LuaEngine");
|
2008-07-16 01:21:25 +08:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
bool LuaEngine::close() {
|
|
|
|
#ifdef OSGWIDGET_USELUA
|
2008-08-18 19:17:44 +08:00
|
|
|
lua_close(_data->lua);
|
2008-07-16 01:21:25 +08:00
|
|
|
|
2008-08-18 19:17:44 +08:00
|
|
|
delete _data;
|
2008-07-16 01:21:25 +08:00
|
|
|
|
2008-08-18 19:17:44 +08:00
|
|
|
return true;
|
2008-07-16 01:21:25 +08:00
|
|
|
|
|
|
|
#else
|
2008-08-18 19:17:44 +08:00
|
|
|
return noLuaFail("Can't close the LuaEngine");
|
2008-07-16 01:21:25 +08:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
bool LuaEngine::eval(const std::string& code) {
|
|
|
|
#ifdef OSGWIDGET_USELUA
|
2008-08-18 19:17:44 +08:00
|
|
|
if(luaL_dostring(_data->lua, code.c_str())) {
|
|
|
|
warn() << "LuaEngine::eval - " << lua_tostring(_data->lua, -1) << std::endl;
|
2008-07-16 01:21:25 +08:00
|
|
|
|
2008-08-18 19:17:44 +08:00
|
|
|
return false;
|
|
|
|
}
|
2008-07-16 01:21:25 +08:00
|
|
|
|
2008-08-18 19:17:44 +08:00
|
|
|
return true;
|
2008-07-16 01:21:25 +08:00
|
|
|
|
|
|
|
#else
|
2008-08-18 19:17:44 +08:00
|
|
|
return noLuaFail("Can't evaluate code in LuaEngine");
|
2008-07-16 01:21:25 +08:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
bool LuaEngine::runFile(const std::string& filePath) {
|
|
|
|
#ifdef OSGWIDGET_USELUA
|
2008-08-18 19:17:44 +08:00
|
|
|
if(!osgDB::fileExists(filePath)) {
|
|
|
|
warn() << "Couldn't find file \"" << filePath << "\" for LuaEngine." << std::endl;
|
2008-07-16 01:21:25 +08:00
|
|
|
|
2008-08-18 19:17:44 +08:00
|
|
|
return false;
|
|
|
|
}
|
2008-07-16 01:21:25 +08:00
|
|
|
|
2008-08-18 19:17:44 +08:00
|
|
|
if(luaL_dofile(_data->lua, filePath.c_str())) {
|
|
|
|
warn() << "LuaEngine::runFile - " << lua_tostring(_data->lua, -1) << std::endl;
|
2008-07-16 01:21:25 +08:00
|
|
|
|
2008-08-18 19:17:44 +08:00
|
|
|
return false;
|
|
|
|
}
|
2008-07-16 01:21:25 +08:00
|
|
|
|
2008-08-18 19:17:44 +08:00
|
|
|
return true;
|
2008-07-16 01:21:25 +08:00
|
|
|
|
|
|
|
#else
|
2008-08-18 19:17:44 +08:00
|
|
|
return noLuaFail("Can't run file in LuaEngine");
|
2008-07-16 01:21:25 +08:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|