Permalink
Browse files

Added support for Lua 5.2 and osg::Object creation from within Lua sc…

…ripts.
  • Loading branch information...
1 parent 3a176fe commit aa97ebc126ebdd39590964a8ef1b388a35a81f16 @osg-training-guest osg-training-guest committed Oct 4, 2013
@@ -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 <lua/lua.h>
+# 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)
+
@@ -474,6 +474,28 @@ int main(int argc, char** argv)
}
+ osg::ref_ptr<osg::Object> obj = pi.createObject("osgVolume::VolumeTile");
+ if (obj.valid()) { OSG_NOTICE<<"obj created "<<obj->getCompoundClassName()<<std::endl; }
+ else { OSG_NOTICE<<"obj creation failed "<<std::endl; }
+ osgDB::PropertyInterface::PropertyMap properties;
+
+ if (pi.getSupportedProperties(obj.get(), properties, true))
+ {
+ OSG_NOTICE<<"Have supported properites found."<<std::endl;
+ for(osgDB::PropertyInterface::PropertyMap::iterator itr = properties.begin();
+ itr != properties.end();
+ ++itr)
+ {
+ OSG_NOTICE<<" Property "<<itr->first<<", "<<pi.getTypeName(itr->second)<<std::endl;
+ }
+ }
+ else
+ {
+ OSG_NOTICE<<"No supported properites found."<<std::endl;
+ }
+
+ //return 0;
+
return viewer.run();
@@ -76,6 +76,50 @@ static int setProperty(lua_State* _lua)
return 0;
}
+static int garabageCollectObject(lua_State* _lua)
+{
+ const LuaScriptEngine* lse = reinterpret_cast<const LuaScriptEngine*>(lua_topointer(_lua, lua_upvalueindex(1)));
+
+ int n = lua_gettop(_lua); /* number of arguments */
+
+ OSG_NOTICE<<"garabageCollectObject() n = "<<n<<std::endl;
+
+ if (n==1)
+ {
+ if (lua_type(_lua, 1)==LUA_TTABLE)
+ {
+ osg::Object* object = 0;
+ lua_pushstring(_lua, "object_ptr");
+ lua_rawget(_lua, 1);
+ if (lua_type(_lua, -1)==LUA_TLIGHTUSERDATA)
+ {
+ object = const_cast<osg::Object*>(reinterpret_cast<const osg::Object*>(lua_topointer(_lua,-1)));
+ OSG_NOTICE<<"Need to garbage collect object "<<object<<" "<<object->getCompoundClassName()<<std::endl;
+ }
+ lua_pop(_lua,1);
+ }
+ }
+
+ return 0;
+}
+
+static int newObject(lua_State * _lua)
+{
+ const LuaScriptEngine* lse = reinterpret_cast<const LuaScriptEngine*>(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"<<std::endl;
+
lua_close(_lua);
}
void LuaScriptEngine::initialize()
{
- _lua = lua_open();
+ _lua = luaL_newstate();
luaL_openlibs(_lua);
+
+ lua_pushlightuserdata(_lua, this);
+ lua_pushcclosure(_lua, newObject, 1);
+ lua_setglobal(_lua, "new");
+
luaL_newmetatable(_lua, "LuaScriptEngine.Object");
lua_pushstring(_lua, "__index");
@@ -113,6 +164,11 @@ void LuaScriptEngine::initialize()
lua_pushlightuserdata(_lua, this);
lua_pushcclosure(_lua, setProperty, 1);
lua_settable(_lua, -3);
+
+ lua_pushstring(_lua, "__gc");
+ lua_pushlightuserdata(_lua, this);
+ lua_pushcclosure(_lua, garabageCollectObject, 1);
+ lua_settable(_lua, -3);
}
bool LuaScriptEngine::loadScript(osg::Script* script)
@@ -162,7 +218,10 @@ bool LuaScriptEngine::run(osg::Script* script, const std::string& entryPoint, Pa
{
- lua_getfield(_lua, LUA_GLOBALSINDEX, entryPoint.c_str()); /* function to be called */
+ //lua_pushglobaltable(pLuaState);
+ //lua_getfield(_lua, LUA_GLOBALSINDEX, entryPoint.c_str()); /* function to be called */
+ //lua_getfield(_lua, -1, entryPoint.c_str()); /* function to be called */
+ lua_getglobal(_lua, entryPoint.c_str()); /* function to be called */
for(osg::ScriptEngine::Parameters::const_iterator itr = inputParameters.begin();
itr != inputParameters.end();
@@ -221,6 +280,8 @@ class PushStackValueVisitor : public osg::ValueObject::GetValueVisitor
virtual void apply(const osg::Matrixd& value) { _lsg->pushValue(value); }
};
+#define lua_rawlen lua_strlen
+
class GetStackValueVisitor : public osg::ValueObject::SetValueVisitor
{
public:
@@ -242,7 +303,7 @@ class GetStackValueVisitor : public osg::ValueObject::SetValueVisitor
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<osg::Object> object = _pi.createObject(compoundName);
+ if (!object) OSG_NOTICE<<"Failed to create object "<<compoundName<<std::endl;
+
+ pushObject(object.get());
+
+ object.release();
+}
+
+void LuaScriptEngine::pushObject(osg::Object* object) const
+{
+ if (object)
+ {
+ OSG_NOTICE<<"Creating lua object representation for "<<object<<" "<<object->getCompoundClassName()<<std::endl;
+
+ lua_newtable(_lua);
+ lua_pushstring(_lua, "object_ptr"); lua_pushlightuserdata(_lua, object); lua_settable(_lua, -3);
+ 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);
+ luaL_getmetatable(_lua, "LuaScriptEngine.Object");
+ lua_setmetatable(_lua, -2);
+ }
+ else
+ {
+ lua_pushnil(_lua);
+ }
+}
+
@@ -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();

0 comments on commit aa97ebc

Please sign in to comment.