From 79e2d1309fd24af5cc48c3a35bb34147b4d0ef6b Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 4 Oct 2013 16:30:25 +0000 Subject: [PATCH] Added support for Lua 5.2 and osg::Object creation from within Lua scripts. --- CMakeModules/FindLua52.cmake | 83 ++++++++++++++ examples/osgpresentation/osgpresentation.cpp | 22 ++++ src/osgPlugins/lua/LuaScriptEngine.cpp | 109 ++++++++++++++++--- src/osgPlugins/lua/LuaScriptEngine.h | 4 + 4 files changed, 204 insertions(+), 14 deletions(-) create mode 100644 CMakeModules/FindLua52.cmake diff --git a/CMakeModules/FindLua52.cmake b/CMakeModules/FindLua52.cmake new file mode 100644 index 000000000..e6eff7e9d --- /dev/null +++ b/CMakeModules/FindLua52.cmake @@ -0,0 +1,83 @@ +# Locate Lua library +# This module defines +# LUA51_FOUND, if false, do not try to link to Lua +# LUA_LIBRARIES +# LUA_INCLUDE_DIR, where to find lua.h +# LUA_VERSION_STRING, the version of Lua found (since CMake 2.8.8) +# +# Note that the expected include convention is +# #include "lua.h" +# and not +# #include +# This is because, the lua location is not standardized and may exist +# in locations other than lua/ + +#============================================================================= +# Copyright 2007-2009 Kitware, Inc. +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + +find_path(LUA_INCLUDE_DIR lua.h + HINTS + ENV LUA_DIR + PATH_SUFFIXES include/lua52 include/lua5.2 include/lua include + PATHS + ~/Library/Frameworks + /Library/Frameworks + /sw # Fink + /opt/local # DarwinPorts + /opt/csw # Blastwave + /opt +) + +find_library(LUA_LIBRARY + NAMES lua52 lua5.2 lua-5.2 lua + HINTS + ENV LUA_DIR + PATH_SUFFIXES lib + PATHS + ~/Library/Frameworks + /Library/Frameworks + /sw + /opt/local + /opt/csw + /opt +) + +if(LUA_LIBRARY) + # include the math library for Unix + if(UNIX AND NOT APPLE) + find_library(LUA_MATH_LIBRARY m) + set( LUA_LIBRARIES "${LUA_LIBRARY};${LUA_MATH_LIBRARY}" CACHE STRING "Lua Libraries") + # For Windows and Mac, don't need to explicitly include the math library + else() + set( LUA_LIBRARIES "${LUA_LIBRARY}" CACHE STRING "Lua Libraries") + endif() +endif() + +if(LUA_INCLUDE_DIR AND EXISTS "${LUA_INCLUDE_DIR}/lua.h") + file(STRINGS "${LUA_INCLUDE_DIR}/lua.h" lua_version_str REGEX "^#define[ \t]+LUA_RELEASE[ \t]+\"Lua .+\"") + + string(REGEX REPLACE "^#define[ \t]+LUA_RELEASE[ \t]+\"Lua ([^\"]+)\".*" "\\1" LUA_VERSION_STRING "${lua_version_str}") + unset(lua_version_str) +endif() + + +include(${CMAKE_MODULE_PATH}/FindPackageHandleStandardArgs.cmake) + +# handle the QUIETLY and REQUIRED arguments and set LUA_FOUND to TRUE if +# all listed variables are TRUE +FIND_PACKAGE_HANDLE_STANDARD_ARGS(Lua52 + REQUIRED_VARS LUA_LIBRARIES LUA_INCLUDE_DIR + VERSION_VAR LUA_VERSION_STRING) + +mark_as_advanced(LUA_INCLUDE_DIR LUA_LIBRARIES LUA_LIBRARY LUA_MATH_LIBRARY) + diff --git a/examples/osgpresentation/osgpresentation.cpp b/examples/osgpresentation/osgpresentation.cpp index fd3883a68..de13312f3 100644 --- a/examples/osgpresentation/osgpresentation.cpp +++ b/examples/osgpresentation/osgpresentation.cpp @@ -474,6 +474,28 @@ int main(int argc, char** argv) } + osg::ref_ptr obj = pi.createObject("osgVolume::VolumeTile"); + if (obj.valid()) { OSG_NOTICE<<"obj created "<getCompoundClassName()<first<<", "<second)<(lua_topointer(_lua, lua_upvalueindex(1))); + + int n = lua_gettop(_lua); /* number of arguments */ + + OSG_NOTICE<<"garabageCollectObject() n = "<(reinterpret_cast(lua_topointer(_lua,-1))); + OSG_NOTICE<<"Need to garbage collect object "<getCompoundClassName()<(lua_topointer(_lua, lua_upvalueindex(1))); + + int n = lua_gettop(_lua); /* number of arguments */ + if (n==1) + { + if (lua_type(_lua, 1)==LUA_TSTRING) + { + std::string compoundName = lua_tostring(_lua, 1); + + lse->createAndPushObject(compoundName); + return 1; + } + } + return 0; +} LuaScriptEngine::LuaScriptEngine(): osg::ScriptEngine("lua"), @@ -93,15 +137,22 @@ LuaScriptEngine::LuaScriptEngine(const LuaScriptEngine& rhs, const osg::CopyOp&) LuaScriptEngine::~LuaScriptEngine() { + OSG_NOTICE<<"Closing lua"<pushValue(value); } }; +#define lua_rawlen lua_strlen + class GetStackValueVisitor : public osg::ValueObject::SetValueVisitor { public: @@ -242,7 +303,7 @@ public: virtual void apply(unsigned int& value) { if (lua_isnumber(_lua, _index)) { value = lua_tonumber(_lua, _index)!=0; _numberToPop = 1; } } virtual void apply(float& value) { if (lua_isnumber(_lua, _index)) { value = lua_tonumber(_lua, _index)!=0; _numberToPop = 1; } } virtual void apply(double& value) { if (lua_isnumber(_lua, _index)) { value = lua_tonumber(_lua, _index)!=0; _numberToPop = 1; } } - virtual void apply(std::string& value) { if (lua_isstring(_lua, _index)) { value = std::string(lua_tostring(_lua, _index), lua_strlen(_lua, _index)); _numberToPop = 1; } } + virtual void apply(std::string& value) { if (lua_isstring(_lua, _index)) { value = std::string(lua_tostring(_lua, _index), lua_rawlen(_lua, _index)); _numberToPop = 1; } } virtual void apply(osg::Vec2f& value) { _lsg->getValue(value); _numberToPop = 2;} virtual void apply(osg::Vec3f& value) { _lsg->getValue(value); _numberToPop = 2; } virtual void apply(osg::Vec4f& value) { _lsg->getValue(value); _numberToPop = 4; } @@ -941,16 +1002,7 @@ bool LuaScriptEngine::pushParameter(osg::Object* object) } else { - osgDB::PropertyInterface::PropertyMap properties; - lua_newtable(_lua); - lua_pushstring(_lua, "object_ptr"); lua_pushlightuserdata(_lua, object); lua_settable(_lua, -3); -#if 1 - lua_pushstring(_lua, "libraryName"); lua_pushstring(_lua, object->libraryName()); lua_settable(_lua, -3); - lua_pushstring(_lua, "className"); lua_pushstring(_lua, object->className()); lua_settable(_lua, -3); -#endif - luaL_getmetatable(_lua, "LuaScriptEngine.Object"); - lua_setmetatable(_lua, -2); - + pushObject( object); } return false; @@ -970,6 +1022,35 @@ bool LuaScriptEngine::popParameter(osg::Object* object) lua_pop(_lua, 1); } - return false; } + +void LuaScriptEngine::createAndPushObject(const std::string& compoundName) const +{ + osg::ref_ptr object = _pi.createObject(compoundName); + if (!object) OSG_NOTICE<<"Failed to create object "<getCompoundClassName()<libraryName()); lua_settable(_lua, -3); + lua_pushstring(_lua, "className"); lua_pushstring(_lua, object->className()); lua_settable(_lua, -3); + luaL_getmetatable(_lua, "LuaScriptEngine.Object"); + lua_setmetatable(_lua, -2); + } + else + { + lua_pushnil(_lua); + } +} + diff --git a/src/osgPlugins/lua/LuaScriptEngine.h b/src/osgPlugins/lua/LuaScriptEngine.h index 4269f534a..87d1aaa24 100644 --- a/src/osgPlugins/lua/LuaScriptEngine.h +++ b/src/osgPlugins/lua/LuaScriptEngine.h @@ -86,6 +86,10 @@ class LuaScriptEngine : public osg::ScriptEngine bool pushParameter(osg::Object* object); bool popParameter(osg::Object* object); + + void createAndPushObject(const std::string& compoundName) const; + void pushObject(osg::Object* object) const; + protected: void initialize();