diff --git a/.gitmodules b/.gitmodules index 89936f20..6a3260ac 100644 --- a/.gitmodules +++ b/.gitmodules @@ -7,3 +7,6 @@ [submodule "doc/generation/LDoc"] path = doc/generation/LDoc url = https://github.com/stevedonovan/LDoc.git +[submodule "third-party/luarocks"] + path = third-party/luarocks + url = https://github.com/vancegroup/luarocks.git diff --git a/CMakeLists.txt b/CMakeLists.txt index 5fa4e2c6..d03197d7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,6 +40,9 @@ endif() if(NOT SHARE_OUTPUT_DIRECTORY) set(SHARE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/share) endif() +if(NOT ROOT_OUTPUT_DIRECTORY) + set(ROOT_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) +endif() # Define Simple Options option(BUILD_DOCS "Add a target to build documentation" on) diff --git a/third-party/CMakeLists.txt b/third-party/CMakeLists.txt index 0d31eb54..ebd66438 100644 --- a/third-party/CMakeLists.txt +++ b/third-party/CMakeLists.txt @@ -6,15 +6,18 @@ endif() if(BUILD_EMBEDDED_LUA) # Lua 5.1.5 - if(BUILD_SHARED_LUA) + if(BUILD_SHARED_LUA AND WIN32) set(LUA_DEFINITIONS "-DLUA_BUILD_AS_DLL") set(LUA_DEFINITIONS ${LUA_DEFINITIONS} PARENT_SCOPE) endif() add_subdirectory(lua-5.1.5/src) - set(LUA_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/lua-5.1.5/src") + set(LUA_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/lua-5.1.5/src") + set(LUA_INCLUDE_DIRS "${LUA_INCLUDE_DIR}") set(LUA_INCLUDE_DIRS ${LUA_INCLUDE_DIRS} PARENT_SCOPE) + set(LUA_LIBRARY lua) set(LUA_LIBRARIES lua) set(LUA_LIBRARIES ${LUA_LIBRARIES} PARENT_SCOPE) + set(LUA_INTERPRETER "lua-interp") set(LUA51_FOUND YES) add_definitions(${LUA_DEFINITIONS}) @@ -37,3 +40,19 @@ endif() add_subdirectory(stdlib/modules) add_subdirectory(lua_modules) + +if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/luarocks/CMakeLists.txt") + message(STATUS "NOTE: Skipping LuaRocks because the submodule is missing. Try 'git submodule update --init --recursive'") + +elseif(BUILD_LUA_AS_CPP) + message(STATUS "NOTE: Skipping LuaRocks because BUILD_LUA_AS_CPP is set which would confuse most compiled modules.") + +else() + set(LUAROCKS_LUA_SUFFIX "") + add_subdirectory(luarocks) + include(luarocks/UseLuarocks.cmake) + + luarocks_install(luarocks-luafilesystem luafilesystem "${ROOT_OUTPUT_DIRECTORY}") + + luarocks_install(luarocks-luasocket "${CMAKE_CURRENT_SOURCE_DIR}/luasocket-2.0.2-5.rockspec" "${ROOT_OUTPUT_DIRECTORY}") +endif() diff --git a/third-party/lua-5.1.5/src/CMakeLists.txt b/third-party/lua-5.1.5/src/CMakeLists.txt index 31d6e4cc..4f6b35a6 100644 --- a/third-party/lua-5.1.5/src/CMakeLists.txt +++ b/third-party/lua-5.1.5/src/CMakeLists.txt @@ -89,7 +89,9 @@ set(LUA_EXTRA_LIBS ${LUA_EXTRA_LIBS} CACHE INTERNAL "" FORCE) if(BUILD_SHARED_LUA) set(LIBTYPE SHARED) - set(LUALIB_EXTRA_DEFINES LUA_BUILD_AS_DLL) + if(WIN32) + set(LUALIB_EXTRA_DEFINES LUA_BUILD_AS_DLL) + endif() else() set(LIBTYPE STATIC) set(LUALIB_EXTRA_DEFINES) diff --git a/third-party/lua-5.1.5/src/luaconf.h b/third-party/lua-5.1.5/src/luaconf.h index d678de50..0423724b 100644 --- a/third-party/lua-5.1.5/src/luaconf.h +++ b/third-party/lua-5.1.5/src/luaconf.h @@ -757,7 +757,8 @@ union luai_Cast { double l_d; long l_l; }; ** without modifying the main part of the file. */ - +/* Required for osgLua to work properly. */ +#define LUA_DL_USE_RTLD_GLOBAL #endif diff --git a/third-party/luarocks b/third-party/luarocks new file mode 160000 index 00000000..d5798de5 --- /dev/null +++ b/third-party/luarocks @@ -0,0 +1 @@ +Subproject commit d5798de50c799b855be758cc0af3e5bc2f3d5ab0 diff --git a/third-party/luasocket-2.0.2-5.rockspec b/third-party/luasocket-2.0.2-5.rockspec new file mode 100644 index 00000000..164d4319 --- /dev/null +++ b/third-party/luasocket-2.0.2-5.rockspec @@ -0,0 +1,65 @@ +-- This is an unofficial modified version of the 2.0.2-5 rockspec that replaces +-- the Windows build system so that it actually works. + +package = "LuaSocket" +version = "2.0.2-5" +source = { + url = "http://luaforge.net/frs/download.php/2664/luasocket-2.0.2.tar.gz", + md5 = "41445b138deb7bcfe97bff957503da8e" +} +description = { + summary = "Network support for the Lua language", + detailed = [[ + LuaSocket is a Lua extension library that is composed by two parts: a C core + that provides support for the TCP and UDP transport layers, and a set of Lua + modules that add support for functionality commonly needed by applications + that deal with the Internet. + ]], + homepage = "http://luaforge.net/projects/luasocket/", + license = "MIT" +} +dependencies = { + "lua >= 5.1, < 5.2" +} +build = { + type = "make", + build_variables = { + CFLAGS = "$(CFLAGS) -DLUASOCKET_DEBUG -I$(LUA_INCDIR)", + LDFLAGS = "$(LIBFLAG) -O -fpic", + LD = "$(CC)" + }, + install_variables = { + INSTALL_TOP_SHARE = "$(LUADIR)", + INSTALL_TOP_LIB = "$(LIBDIR)" + }, + platforms = { + macosx = { + build_variables = { + CFLAGS = "$(CFLAGS) -DLUASOCKET_DEBUG -DUNIX_HAS_SUN_LEN -fno-common -I$(LUA_INCDIR)" + } + }, + windows={ + type="builtin", + modules = { + ["ltn12"] = "src/ltn12.lua", + mime = "src/mime.lua", + socket = "src/socket.lua", + ["socket.ftp"] = "src/ftp.lua", + ["socket.http"] = "src/http.lua", + ["socket.smtp"] = "src/smtp.lua", + ["socket.tp"] = "src/tp.lua", + ["socket.url"] = "src/url.lua", + ["mime.core"] = { + sources = {"src/mime.c"}, + defines = {"MIME_EXPORTS", "MIME_API=__declspec(dllexport)"} + }, + ["socket.core"] = { + sources = {"src/auxiliar.c", "src/buffer.c", "src/except.c", "src/inet.c", "src/io.c", "src/luasocket.c", "src/options.c", "src/select.c", "src/tcp.c", "src/timeout.c", "src/udp.c", "src/wsocket.c"}, + defines = {"LUASOCKET_EXPORTS", "LUASOCKET_API=__declspec(dllexport)"}, + libraries = {"ws2_32"} + } + } + } + }, + copy_directories = { "doc", "samples", "etc", "test" } +} diff --git a/vrjugglua/AddToLuaPaths.cpp b/vrjugglua/AddToLuaPaths.cpp new file mode 100644 index 00000000..c40aa5c8 --- /dev/null +++ b/vrjugglua/AddToLuaPaths.cpp @@ -0,0 +1,135 @@ +/** + @file + @brief Implementation + + @date 2013 + + @author + Ryan Pavlik + and + http://academic.cleardefinition.com/ + Iowa State University Virtual Reality Applications Center + Human-Computer Interaction Graduate Program +*/ + +// Copyright Iowa State University 2013. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// Internal Includes +#include "AddToLuaPaths.h" + +// Library/third-party includes +#include + +// Standard includes +// - none + +namespace vrjLua { +#define LUA_VER "5.1" + + namespace { + template + class PushBackFunctor { + public: + PushBackFunctor(T & container) : _container(container) {} + void operator()(typename T::value_type a) { + _container.push_back(a); + } + private: + T & _container; + }; + } // end of namespace + + namespace detail { + template + struct GetDirsFromRoot { + static const char * dirs[]; + }; + + template<> + const char * GetDirsFromRoot::dirs[] = { + "share/vrjugglua/lua/", + "share/lua/" LUA_VER "/", + "lib/lua/" LUA_VER "/" + }; + + template<> + const char * GetDirsFromRoot::dirs[] = { + "lib/lua/" LUA_VER "/", + "lib/" +#ifdef _WIN32 + , + "bin/" +#endif + }; + + template + struct CallWithPatterns; + + template<> + struct CallWithPatterns { + template + static void apply(std::string const& dir, F func) { + static const char * luaPatterns[] = { + "?.lua", + "?/init.lua" + }; + BOOST_FOREACH(const char * patt, luaPatterns) { + func(dir + patt); + } + } + }; + + template<> + struct CallWithPatterns { + template + static void apply(std::string const& dir, F func) { +#ifdef _WIN32 + static const char luaCPattern[] = "?.dll"; +#else + static const char luaCPattern[] = "?.so"; +#endif + func(dir + luaCPattern); + } + }; + + + template + struct CallWithDirectory; + + template + struct CallWithDirectory { + template + static void apply(std::string const& rootdir, F func) { + BOOST_FOREACH(const char * patt, GetDirsFromRoot::dirs) { + CallWithPatterns::apply(rootdir + patt, func); + } + } + }; + + template + struct CallWithDirectory { + template + static void apply(std::string const& rootdir, F func) { + CallWithPatterns::apply(rootdir, func); + } + }; + + template + void extendLuaSearchPath(DirectoryBase const& d, SearchPathContainerBase & s) { + typedef std::vector StringList; + StringList newpaths; + CallWithDirectory::apply(d.get(), PushBackFunctor(newpaths)); + s.insert(newpaths); + } + + // Explicit instantiation of function template above, so we can hide this all in the CPP file. + template void extendLuaSearchPath(DirectoryBase const&, SearchPathContainerBase &); + template void extendLuaSearchPath(DirectoryBase const&, SearchPathContainerBase &); + template void extendLuaSearchPath(DirectoryBase const&, SearchPathContainerBase &); + template void extendLuaSearchPath(DirectoryBase const&, SearchPathContainerBase &); + } // end of namespace detail + +} // end of namespace vrjLua diff --git a/vrjugglua/AddToLuaPaths.h b/vrjugglua/AddToLuaPaths.h new file mode 100644 index 00000000..87b311cb --- /dev/null +++ b/vrjugglua/AddToLuaPaths.h @@ -0,0 +1,136 @@ +/** @file + @brief Header + + @date 2013 + + @author + Ryan Pavlik + and + http://academic.cleardefinition.com/ + Iowa State University Virtual Reality Applications Center + Human-Computer Interaction Graduate Program +*/ + +// Copyright Iowa State University 2013. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#pragma once +#ifndef INCLUDED_AddToLuaPaths_h_GUID_7c879366_eb17_457c_be5c_cd606e6943a2 +#define INCLUDED_AddToLuaPaths_h_GUID_7c879366_eb17_457c_be5c_cd606e6943a2 + +// Internal Includes +#include "SearchPath.h" + +// Library/third-party includes +#include +#include +#include + +// Standard includes +// - none + + +namespace vrjLua { + + namespace LuaPathTags { + struct RootDirectory; + struct SearchDirectory; + struct LuaSearch; + struct LuaCSearch; + } // end of namespace LuaPathTags + + namespace detail { + inline std::string ensureTrailingSlash(std::string dir) { + if (dir.size() > 0) { + const char back = *(dir.end() - 1); + if (back != '/' && back != '\\') { + dir += '/'; + } + } + return dir; + } + + template + class DirectoryBase { + public: + DirectoryBase(std::string const& dir) + : _dir(detail::ensureTrailingSlash(dir)) + {} + std::string const& get() const { + return _dir; + } + private: + std::string const _dir; + + }; + + template + class SearchPathContainerBase; + + template + extern void extendLuaSearchPath(DirectoryBase const& d, SearchPathContainerBase & s); + + template + class SearchPathContainerBase { + public: + SearchPathContainerBase(SearchPath const& p) + : _path(p) {} + + void insert(std::vector const& patterns) { + _path.insertAt(patterns, 1); + } + + template + void extend(DirectoryBase const& d) { + detail::extendLuaSearchPath(d, *this); + } + + std::string toString() { + return _path.toString(); + } + private: + SearchPath _path; + }; + } // end of namespace detail + + + + + class RootDirectory : public detail::DirectoryBase { + public: + RootDirectory(std::string const& dir) + : detail::DirectoryBase(dir) {} + }; + + class SearchDirectory : public detail::DirectoryBase { + public: + SearchDirectory(std::string const& dir) + : detail::DirectoryBase(dir) {} + }; + + + + class LuaSearchPath : public detail::SearchPathContainerBase { + public: + LuaSearchPath(std::string const& s) : detail::SearchPathContainerBase(s) {} + + static const char * getTableKey() { + return "path"; + } + }; + + class LuaCSearchPath : public detail::SearchPathContainerBase { + public: + LuaCSearchPath(std::string const& s) : detail::SearchPathContainerBase(s) {} + static const char * getTableKey() { + return "cpath"; + } + }; + + + +} // end of namespace vrjLua + +#endif // INCLUDED_AddToLuaPaths_h_GUID_7c879366_eb17_457c_be5c_cd606e6943a2 diff --git a/vrjugglua/CMakeLists.txt b/vrjugglua/CMakeLists.txt index 149ae27f..93edd39e 100644 --- a/vrjugglua/CMakeLists.txt +++ b/vrjugglua/CMakeLists.txt @@ -27,6 +27,7 @@ add_subdirectory(lua) add_subdirectory(constants) set(SOURCES + AddToLuaPaths.cpp FindVPRDLL.cpp FindVPRDLL.h Internal_AnalogInterface.cpp @@ -37,13 +38,16 @@ set(SOURCES LuaRunBuffer.cpp LuaScript.cpp LuaPath.cpp + LuaPathLuabind.cpp OsgAppProxy.cpp Reconfiguration.cpp + SearchPath.cpp SynchronizedRunBuffer.cpp VRJLua_C_Interface.cpp VRJLuaConfig.h.in) set(API + AddToLuaPaths.h osgLuaBind.h Internal_AnalogInterface.h Internal_DigitalInterface.h @@ -54,10 +58,12 @@ set(API LuaIncludeFull.h LuaInclude.h LuaPath.h + LuaPathUpdater.h LuaRunBuffer.h LuaScript.h OsgAppProxy.h Reconfiguration.h + SearchPath.h SynchronizedRunBuffer.h VRJLua_C_Interface.h VRJLuaOutput.h) diff --git a/vrjugglua/LuaPath.cpp b/vrjugglua/LuaPath.cpp index ecd61a6a..48c467bd 100644 --- a/vrjugglua/LuaPath.cpp +++ b/vrjugglua/LuaPath.cpp @@ -30,7 +30,6 @@ #include #include -#include // for VPR_OS_Linux #include // for __VJ_version define // Standard includes @@ -39,24 +38,6 @@ namespace fs = boost::filesystem; -#ifdef VPR_OS_Linux - -#include - -extern "C" { - int sharedObjectCallback(struct dl_phdr_info *info, - size_t, void *data); -} - -int sharedObjectCallback(struct dl_phdr_info *info, size_t, void *data) { - std::string fn(info->dlpi_name); - if (fn.find("vpr") != std::string::npos) { - (*static_cast(data)) = fn; - } - return 0; -} - -#endif // VPR_OS_Linux namespace vrjLua { @@ -247,26 +228,8 @@ namespace vrjLua { std::string const& LuaPath::getInitialPath() const { return _initialPath; } - - std::string LuaPath::getPathToLuaScript(const std::string & scriptfn) const { - return (fs::path(_luaDir) / scriptfn).string(); - } - - void LuaPath::chdir(std::string const& path) { - fs::current_path(path); - } - - void LuaPath::addLuaRequirePath(LuaStatePtr state, std::string const& dirEndingInSlash) { - _searchPaths.push_front(dirEndingInSlash + "?.lua"); - _searchPaths.push_front(dirEndingInSlash + "?"); - updateLuaRequirePath(state); - } - - void LuaPath::updateLuaRequirePath(LuaStatePtr state) { - if (_searchPaths.empty()) { - _populateSearchPathsVector(state); - } - _setLuaSearchPaths(state); + std::string const& LuaPath::getLuaDir() const { + return _luaDir; } bool LuaPath::_setJugglerEnvironment() const { diff --git a/vrjugglua/LuaPath.h b/vrjugglua/LuaPath.h index d1318e67..462a10e5 100644 --- a/vrjugglua/LuaPath.h +++ b/vrjugglua/LuaPath.h @@ -46,13 +46,10 @@ namespace vrjLua { std::string const& getShareDir() const; std::string const& getExeDir() const; std::string const& getInitialPath() const; - std::string getPathToLuaScript(const std::string & scriptfn) const; - - void chdir(std::string const& path); + std::string const& getLuaDir() const; + /// DEPRECATED void addLuaRequirePath(LuaStatePtr state, std::string const& dirEndingInSlash); - void updateLuaRequirePath(LuaStatePtr state); - protected: LuaPath(); @@ -61,8 +58,6 @@ namespace vrjLua { static std::string _findFilePath(std::vector const& startingPlaces, std::string const& qualified); static std::string _findFilePath(std::string const& startingAt, std::string const& fn); - void _populateSearchPathsVector(LuaStatePtr state); - void _setLuaSearchPaths(LuaStatePtr state); std::string _findJuggler(); bool _setJugglerEnvironment() const; @@ -77,8 +72,6 @@ namespace vrjLua { std::string _jugglerRoot; bool _valid; - - std::deque _searchPaths; }; // -- inline implementations -- / diff --git a/vrjugglua/LuaPathLuabind.cpp b/vrjugglua/LuaPathLuabind.cpp new file mode 100644 index 00000000..b0301eee --- /dev/null +++ b/vrjugglua/LuaPathLuabind.cpp @@ -0,0 +1,36 @@ +/** + @file + @brief Implementation + + @date 2013 + + @author + Ryan Pavlik + and + http://academic.cleardefinition.com/ + Iowa State University Virtual Reality Applications Center + Human-Computer Interaction Graduate Program +*/ + +// Copyright Iowa State University 2013. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// Internal Includes +#include "LuaPath.h" +#include "LuaPathUpdater.h" + +// Library/third-party includes +// - none + +// Standard includes +// - none + +namespace vrjLua { + void LuaPath::addLuaRequirePath(LuaStatePtr state, std::string const& dirEndingInSlash) { + LuaSearchPathUpdater searchpath(state.get()); + + searchpath.extend(SearchDirectory(dirEndingInSlash)); + } +} // end of namespace vrjLua diff --git a/vrjugglua/LuaPathUpdater.h b/vrjugglua/LuaPathUpdater.h new file mode 100644 index 00000000..776fdb18 --- /dev/null +++ b/vrjugglua/LuaPathUpdater.h @@ -0,0 +1,58 @@ +/** @file + @brief Header + + @date 2013 + + @author + Ryan Pavlik + and + http://academic.cleardefinition.com/ + Iowa State University Virtual Reality Applications Center + Human-Computer Interaction Graduate Program +*/ + +// Copyright Iowa State University 2013. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#pragma once +#ifndef INCLUDED_LuaPathUpdater_h_GUID_ebe0b3e8_34e2_442c_afa8_2ffbdf2f4864 +#define INCLUDED_LuaPathUpdater_h_GUID_ebe0b3e8_34e2_442c_afa8_2ffbdf2f4864 + +// Internal Includes +#include + +// Library/third-party includes +#include + +// Standard includes +// - none + +namespace vrjLua { + + template + class SearchPathUpdater { + public: + SearchPathUpdater(lua_State * L) + : package(luabind::globals(L)["package"]) + , _p(luabind::object_cast(package[Contained::getTableKey()])) + {} + ~SearchPathUpdater() { + package[Contained::getTableKey()] = _p.toString(); + } + template + void extend(detail::DirectoryBase const& d) { + _p.extend(d); + } + private: + luabind::object package; + Contained _p; + }; + + typedef SearchPathUpdater LuaSearchPathUpdater; + typedef SearchPathUpdater LuaCSearchPathUpdater; + +} // end of namespace vrjLua + +#endif // INCLUDED_LuaPathUpdater_h_GUID_ebe0b3e8_34e2_442c_afa8_2ffbdf2f4864 diff --git a/vrjugglua/LuaScript.cpp b/vrjugglua/LuaScript.cpp index f43d1079..24c4d2b2 100644 --- a/vrjugglua/LuaScript.cpp +++ b/vrjugglua/LuaScript.cpp @@ -24,6 +24,7 @@ #include "OsgAppProxy.h" #include "LuaPath.h" +#include "LuaPathUpdater.h" #include "LuaGCBlock.h" #include "VRJLuaOutput.h" @@ -215,7 +216,17 @@ namespace vrjLua { // Extend the lua script search path for "require" LuaPath& lp = LuaPath::instance(); - lp.updateLuaRequirePath(_state); + { + LuaSearchPathUpdater searchpath(_state.get()); + searchpath.extend(SearchDirectory(lp.getLuaDir())); + searchpath.extend(RootDirectory(lp.getRootDir())); + } + + { + /// @todo c search path + //LuaCSearchPathUpdater csearchpath(_state.get()); + } + // osgLua bindOsgToLua(_state); @@ -308,39 +319,4 @@ namespace vrjLua { << VRJLUA_MSG_END(dbgVRJLUA_APP, MSG_STATUS); } } - - - void LuaPath::_populateSearchPathsVector(LuaStatePtr state) { - luabind::object package = luabind::globals(state.get())["package"]; - std::string input = luabind::object_cast(package["path"]); - boost::algorithm::split(_searchPaths, input, boost::is_any_of(";")); - - // Remove the items we'll add ourselves. - std::deque::iterator it = std::find(_searchPaths.begin(), _searchPaths.end(), "?"); - while (it != _searchPaths.end()) { - _searchPaths.erase(it); - it = std::find(_searchPaths.begin(), _searchPaths.end(), "?"); - } - - it = std::find(_searchPaths.begin(), _searchPaths.end(), "?.lua"); - while (it != _searchPaths.end()) { - _searchPaths.erase(it); - it = std::find(_searchPaths.begin(), _searchPaths.end(), "?.lua"); - } - - _searchPaths.push_front(_luaDir + "?.lua"); - _searchPaths.push_front(_luaDir + "?"); - } - - void LuaPath::_setLuaSearchPaths(LuaStatePtr state) { - std::ostringstream scr; - scr << "?;"; - scr << "?.lua;"; - for (unsigned int i = 0; i < _searchPaths.size(); ++i) { - scr << _searchPaths[i] << ";"; - } - luabind::object package = luabind::globals(state.get())["package"]; - package["path"] = scr.str(); - } - } // end of vrjLua namespace diff --git a/vrjugglua/SearchPath.cpp b/vrjugglua/SearchPath.cpp new file mode 100644 index 00000000..2ee3915f --- /dev/null +++ b/vrjugglua/SearchPath.cpp @@ -0,0 +1,54 @@ +/** + @file + @brief Implementation + + @date 2013 + + @author + Ryan Pavlik + and + http://academic.cleardefinition.com/ + Iowa State University Virtual Reality Applications Center + Human-Computer Interaction Graduate Program +*/ + +// Copyright Iowa State University 2013. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// Internal Includes +#include "SearchPath.h" + +// Library/third-party includes +#include +#include +#include + +#include + +// Standard includes +// - none + +namespace vrjLua { + SearchPath::SearchPath(std::string const& input, const char * delim) { + boost::algorithm::split(_data, input, boost::algorithm::is_any_of(delim)); + _reapplyUniqueness(); + } + + void SearchPath::insertAt(StringList const& elts, size_t position) { + BOOST_ASSERT(position <= _data.size() && "Position is bound by the size of the existing list!"); + _data.insert(_data.begin() + position, elts.begin(), elts.end()); + _reapplyUniqueness(); + } + + std::string SearchPath::toString(const char * delim) const { + return boost::algorithm::join(_data, delim); + } + + void SearchPath::_reapplyUniqueness() { + StringList::iterator it = std::unique(_data.begin(), _data.end()); + _data.resize(std::distance(_data.begin(), it)); + } + +} diff --git a/vrjugglua/SearchPath.h b/vrjugglua/SearchPath.h new file mode 100644 index 00000000..3f797211 --- /dev/null +++ b/vrjugglua/SearchPath.h @@ -0,0 +1,56 @@ +/** @file + @brief Header + + @date 2013 + + @author + Ryan Pavlik + and + http://academic.cleardefinition.com/ + Iowa State University Virtual Reality Applications Center + Human-Computer Interaction Graduate Program +*/ + +// Copyright Iowa State University 2013. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#pragma once +#ifndef INCLUDED_SearchPath_h_GUID_1091ef29_04ea_4776_a191_3d2bf5a56ecd +#define INCLUDED_SearchPath_h_GUID_1091ef29_04ea_4776_a191_3d2bf5a56ecd + +// Internal Includes +// - none + +// Library/third-party includes +// - none + +// Standard includes +#include +#include + +namespace vrjLua { + class SearchPath { + public: + static const char * defaultDelimiter() { + return ";"; + } + + typedef std::vector StringList; + + SearchPath(std::string const& input, const char * delim = defaultDelimiter()); + + void insertAt(StringList const& elts, size_t position = 0); + + std::string toString(const char * delim = defaultDelimiter()) const; + private: + StringList _data; + + void _reapplyUniqueness(); + }; + + +} + +#endif // INCLUDED_SearchPath_h_GUID_1091ef29_04ea_4776_a191_3d2bf5a56ecd diff --git a/vrjugglua/binding_detail/BindvrjLuaToLua.inl b/vrjugglua/binding_detail/BindvrjLuaToLua.inl index 65e67bdd..b82cd3b3 100644 --- a/vrjugglua/binding_detail/BindvrjLuaToLua.inl +++ b/vrjugglua/binding_detail/BindvrjLuaToLua.inl @@ -22,6 +22,7 @@ #include "BindvrjLuaToLua.h" #include #include +#include #include // Library/third-party includes @@ -39,29 +40,37 @@ namespace vrjLua { using namespace luabind; - static void appendToModelSearchPath(std::string const& path) { - std::string p = path; - if (osgDB::fileExists(path)) { - p = osgDB::convertFileNameToUnixStyle(osgDB::getRealPath(path)); + static inline std::string getDirectoryPart(std::string p) { + if (p.empty()) { + return p; + } + if (osgDB::fileExists(p)) { + p = osgDB::convertFileNameToUnixStyle(osgDB::getRealPath(p)); if (osgDB::fileType(p) == osgDB::REGULAR_FILE) { p = osgDB::getFilePath(p); } } + if (p[p.size() - 1] != '/') { + p.push_back('/'); + } + return p; + } + static void appendToModelSearchPath(std::string const& path) { + std::string p = getDirectoryPart(path); + if (p.empty()) { + throw std::runtime_error("Can't append an empty string to the model search path!"); + } osgDB::Registry::instance()->getDataFilePathList().push_back(p); } static void appendToLuaRequirePath(LuaStateRawPtr s, std::string const& path) { - std::string p = path; - if (osgDB::fileExists(path)) { - p = osgDB::convertFileNameToUnixStyle(osgDB::getRealPath(path)); - if (osgDB::fileType(p) == osgDB::REGULAR_FILE) { - p = osgDB::getFilePath(p); - } + std::string p = getDirectoryPart(path); + if (p.empty()) { + throw std::runtime_error("Can't append an empty string to the require path!"); } - if (p[p.size() - 1] != '/') { - p.push_back('/'); - } - LuaPath::instance().addLuaRequirePath(borrowStatePtr(s), path); + LuaSearchPathUpdater searchpath(s); + + searchpath.extend(SearchDirectory(p)); } static luabind::object getModelSearchPath(lua_State *L) {