diff --git a/include/openspace/scenegraph/scenegraph.h b/include/openspace/scenegraph/scenegraph.h index b41cd79532..59e6e2b08e 100644 --- a/include/openspace/scenegraph/scenegraph.h +++ b/include/openspace/scenegraph/scenegraph.h @@ -31,12 +31,15 @@ #include +#include + // ghoul includes #include #include namespace openspace { + class SceneGraphNode; class SceneGraph { @@ -94,9 +97,17 @@ public: */ SceneGraphNode* sceneGraphNode(const std::string& name) const; + /** + * Returns the Lua library that contains all Lua functions available to change the + * scene graph. The functions contained are + * - openspace::luascriptfunctions::property_setValue + * - openspace::luascriptfunctions::property_getValue + * \return The Lua library that contains all Lua functions available to change the + * scene graph + */ + static scripting::ScriptEngine::LuaLibrary luaLibrary(); + private: - bool registerScriptFunctions(); - std::string _focus, _position; // actual scenegraph diff --git a/include/openspace/scripting/scriptfunctions.h b/include/openspace/scripting/scriptfunctions.h deleted file mode 100644 index a590cca1d0..0000000000 --- a/include/openspace/scripting/scriptfunctions.h +++ /dev/null @@ -1,48 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014 * - * * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this * - * software and associated documentation files (the "Software"), to deal in the Software * - * without restriction, including without limitation the rights to use, copy, modify, * - * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * - * permit persons to whom the Software is furnished to do so, subject to the following * - * conditions: * - * * - * The above copyright notice and this permission notice shall be included in all copies * - * or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - ****************************************************************************************/ - -#ifndef __SCRIPTFUNCTIONS_H__ -#define __SCRIPTFUNCTIONS_H__ - -struct lua_State; - -namespace openspace { -namespace scripting { - -// Helper functions -int printDebug(lua_State* L); -int printInfo(lua_State* L); -int printWarning(lua_State* L); -int printError(lua_State* L); -int printFatal(lua_State* L); - -// Properties - -int property_setValue(lua_State* L); -int property_getValue(lua_State* L); - -} // namespace scripting -} // namespace openspace - -#endif // __SCRIPTFUNCTIONS_H__ diff --git a/scripts/default_startup.lua b/scripts/default_startup.lua index e064f06acd..f3d66d3ddc 100644 --- a/scripts/default_startup.lua +++ b/scripts/default_startup.lua @@ -1,3 +1,5 @@ --openspace.setPropertyValue('Earth.renderable.colorTexture', '${OPENSPACE_DATA}/modules/mars/textures/mars.png') -openspace.time.setTime(1000000) -openspace.time.setDeltaTime(100) \ No newline at end of file +openspace.time.setTime("2000-01-01T00:00:00") +openspace.time.setDeltaTime(0.0) + +print(openspace.time.currentTimeUTC()) diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index f30dd8d8c1..7bf0f04ceb 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -340,6 +340,8 @@ bool OpenSpaceEngine::initialize() scriptEngine().initialize(); // Register Lua script functions + LDEBUG("Registering Lua libraries"); + scriptEngine().addLibrary(SceneGraph::luaLibrary()); scriptEngine().addLibrary(Time::luaLibrary()); // Load scenegraph diff --git a/src/scenegraph/scenegraph.cpp b/src/scenegraph/scenegraph.cpp index b2ac485212..a6ac8cf10e 100644 --- a/src/scenegraph/scenegraph.cpp +++ b/src/scenegraph/scenegraph.cpp @@ -28,10 +28,10 @@ #include #include #include -#include #include #include #include +#include // ghoul includes #include "ghoul/opengl/programobject.h" @@ -55,17 +55,127 @@ namespace { const std::string _loggerCat = "SceneGraph"; const std::string _moduleExtension = ".mod"; -//{ -// LDEBUGC("Tree", pre << node->name()); -// const std::vector& children = node->children(); -// for (openspace::SceneGraphNode* child : children) -// printTree(child, pre + " "); -//} -// } namespace openspace { +namespace luascriptfunctions { + +/** + * \ingroup LuaScripts + * setPropertyValue(string, *): + * Sets the property identified by the URI in the first argument to the value passed to + * the second argument. The type of the second argument is arbitrary, but it must agree + * with the type the denoted Property expects + */ +int property_setValue(lua_State* L) { + using ghoul::lua::luaTypeToString; + const std::string _loggerCat = "property_setValue"; + + // TODO Check for argument number (ab) + std::string uri = luaL_checkstring(L, -2); + const int type = lua_type(L, -1); + // boost::any propertyValue; + // switch (type) { + // case LUA_TNONE: + // case LUA_TLIGHTUSERDATA: + // case LUA_TFUNCTION: + // case LUA_TUSERDATA: + // case LUA_TTHREAD: + // LERROR("Function parameter was of type '" << luaTypeToString(type) << "'"); + // return 0; + // case LUA_TNIL: + // propertyValue = 0; + // break; + // case LUA_TBOOLEAN: + // propertyValue = lua_toboolean(L, -1); + // break; + // case LUA_TNUMBER: + // propertyValue = lua_tonumber(L, -1); + // break; + // case LUA_TSTRING: + // propertyValue = std::string(lua_tostring(L, -1)); + // break; + //case LUA_TTABLE: { + // ghoul::Dictionary d; + // ghoul::lua::populateDictionary(L, d); + // propertyValue = d; + // break; + //} + // } + + openspace::properties::Property* prop = property(uri); + if (!prop) { + LERROR("Property with uri '" << uri << "' could not be found"); + return 0; + } + + //if (propertyValue.type() != prop->type()) { + if (type != prop->typeLua()) + LERROR("Property '" << uri << "' does not accept input of type '" + << luaTypeToString(type) << "'. Requested type: '" + << luaTypeToString(prop->typeLua()) << "'"); + else + prop->setLua(L); + //prop->set(propertyValue); + + return 0; +} + +/** + * \ingroup LuaScripts + * getPropertyValue(string): + * Returns the value of the property identified by the passed URI as a Lua object that can + * be passed to the setPropertyValue method. + */ +int property_getValue(lua_State* L) { + const std::string _loggerCat = "property_getValue"; + + // TODO Check for argument number (ab) + std::string uri = luaL_checkstring(L, -1); + + openspace::properties::Property* prop = property(uri); + if (!prop) { + LERROR("Property with uri '" << uri << "' could not be found"); + lua_pushnil(L); + } + else { + prop->getLua(L); + + //switch (type) { + // case LUA_TNONE: + // case LUA_TLIGHTUSERDATA: + // case LUA_TFUNCTION: + // case LUA_TUSERDATA: + // case LUA_TTHREAD: + // LERROR("Function parameter was of type '" << luaTypeToString(type) + // << "'"); + // return 0; + // case LUA_TNIL: + // propertyValue = 0; + // break; + // case LUA_TBOOLEAN: + // propertyValue = lua_toboolean(L, -1); + // break; + // case LUA_TNUMBER: + // propertyValue = lua_tonumber(L, -1); + // break; + // case LUA_TSTRING: + // propertyValue = std::string(lua_tostring(L, -1)); + // break; + // case LUA_TTABLE: { + // ghoul::Dictionary d; + // ghoul::lua::populateDictionary(L, d); + // propertyValue = d; + // break; + // } + //} + } + return 1; +} + +} // namespace luascriptfunctions + SceneGraph::SceneGraph() : _focus(SceneGraphNode::RootNodeName) , _position(SceneGraphNode::RootNodeName) @@ -82,10 +192,6 @@ bool SceneGraph::initialize() { LDEBUG("Initializing SceneGraph"); - const bool scriptSuccess = registerScriptFunctions(); - if (!scriptSuccess) - return false; - LDEBUG("Creating ProgramObjects"); using ghoul::opengl::ShaderObject; using ghoul::opengl::ProgramObject; @@ -387,24 +493,6 @@ SceneGraphNode* SceneGraph::root() const return _root; } -bool SceneGraph::registerScriptFunctions() -{ - LDEBUG("Registering Script Functions"); - - using namespace scripting; - - ScriptEngine::LuaLibrary sceneGraphLibrary = { - "", - { - { "setPropertyValue", &property_setValue}, - { "getPropertyValue", &property_getValue} - } - }; - - OsEng.scriptEngine().addLibrary(sceneGraphLibrary); - return true; -} - SceneGraphNode* SceneGraph::sceneGraphNode(const std::string& name) const { auto it = _allNodes.find(name); if (it == _allNodes.end()) @@ -413,4 +501,27 @@ SceneGraphNode* SceneGraph::sceneGraphNode(const std::string& name) const { return it->second; } +scripting::ScriptEngine::LuaLibrary SceneGraph::luaLibrary() { + scripting::ScriptEngine::LuaLibrary sceneGraphLibrary = { + "", + { + { + "setPropertyValue", + &luascriptfunctions::property_setValue, + "setPropertyValue(string, *): Sets a property identified by the URI in " + "the first argument. The second argument can be any type, but it has to " + " agree with the type that the property expects" + }, + { + "getPropertyValue", + &luascriptfunctions::property_getValue, + "getPropertyValue(string): Returns the value the property, identified by " + "the provided URI, has" + } + } + }; + + return std::move(sceneGraphLibrary); +} + } // namespace openspace diff --git a/src/scripting/scriptengine.cpp b/src/scripting/scriptengine.cpp index 1810def1a4..b42fd198a2 100644 --- a/src/scripting/scriptengine.cpp +++ b/src/scripting/scriptengine.cpp @@ -24,8 +24,6 @@ #include -#include - #include #include @@ -33,6 +31,99 @@ #include namespace openspace { + +namespace luascriptfunctions { + + void printInternal(ghoul::logging::LogManager::LogLevel level, lua_State* L) { + using ghoul::lua::luaTypeToString; + const std::string _loggerCat = "print"; + + const int type = lua_type(L, -1); + switch (type) { + case LUA_TNONE: + case LUA_TLIGHTUSERDATA: + case LUA_TTABLE: + case LUA_TFUNCTION: + case LUA_TUSERDATA: + case LUA_TTHREAD: + LOG(level, "Function parameter was of type '" << + luaTypeToString(type) << "'"); + case LUA_TNIL: + break; + case LUA_TBOOLEAN: + LOG(level, lua_toboolean(L, -1)); + break; + case LUA_TNUMBER: + LOG(level, lua_tonumber(L, -1)); + break; + case LUA_TSTRING: + LOG(level, lua_tostring(L, -1)); + break; + } + } + + /** + * \ingroup LuaScripts + * printDebug(*): + * Logs the passed value to the installed LogManager with a LogLevel of 'Debug'. + * For Boolean, numbers, and strings, the internal values are printed, for all other + * types, the type is printed instead + */ + int printDebug(lua_State* L) { + printInternal(ghoul::logging::LogManager::LogLevel::Debug, L); + return 0; + } + + /** + * \ingroup LuaScripts + * printInfo(*): + * Logs the passed value to the installed LogManager with a LogLevel of 'Info'. + * For Boolean, numbers, and strings, the internal values are printed, for all other + * types, the type is printed instead + */ + int printInfo(lua_State* L) { + printInternal(ghoul::logging::LogManager::LogLevel::Info, L); + return 0; + } + + /** + * \ingroup LuaScripts + * printWarning(*): + * Logs the passed value to the installed LogManager with a LogLevel of 'Warning'. + * For Boolean, numbers, and strings, the internal values are printed, for all other + * types, the type is printed instead + */ + int printWarning(lua_State* L) { + printInternal(ghoul::logging::LogManager::LogLevel::Warning, L); + return 0; + } + + /** + * \ingroup LuaScripts + * printError(*): + * Logs the passed value to the installed LogManager with a LogLevel of 'Error'. + * For Boolean, numbers, and strings, the internal values are printed, for all other + * types, the type is printed instead + */ + int printError(lua_State* L) { + printInternal(ghoul::logging::LogManager::LogLevel::Error, L); + return 0; + } + + /** + * \ingroup LuaScripts + * printFatal(*): + * Logs the passed value to the installed LogManager with a LogLevel of 'Fatal'. + * For Boolean, numbers, and strings, the internal values are printed, for all other + * types, the type is printed instead + */ + int printFatal(lua_State* L) { + printInternal(ghoul::logging::LogManager::LogLevel::Fatal, L); + return 0; + } + +} // namespace luascriptfunctions + namespace scripting { namespace { @@ -41,7 +132,7 @@ namespace { const std::string _openspaceLibraryName = "openspace"; const std::string _luaGlobalNamespace = "_G"; const std::string _printFunctionName = "print"; - const lua_CFunction _printFunctionReplacement = printInfo; + const lua_CFunction _printFunctionReplacement = luascriptfunctions::printInfo; const int _setTableOffset = -3; // -1 (top) -1 (first argument) -1 (second argument) @@ -251,16 +342,36 @@ void ScriptEngine::addBaseLibrary() { LuaLibrary lib = { "", { - { "printDebug", &printDebug, "printDebug(*): Logs the passed value to the " - "installed LogManager with a LogLevel of 'Debug'" }, - { "printInfo", &printInfo, "printInfo(*): Logs the passed value to the " - "installed LogManager with a LogLevel of 'Info'" }, - { "printWarning", &printWarning, "printWarning(*): Logs the passed value to " - "the installed LogManager with a LogLevel of 'Warning'" }, - { "printError", &printError, "printError(*): Logs the passed value to the " - "installed LogManager with a LogLevel of 'Error'" }, - { "printFatal", &printFatal, "printFatal(*): Logs the passed value to the " - "installed LogManager with a LogLevel of 'Fatal'" } + { + "printDebug", + &luascriptfunctions::printDebug, + "printDebug(*): Logs the passed value to the installed LogManager with a " + "LogLevel of 'Debug'" + }, + { + "printInfo", + &luascriptfunctions::printInfo, + "printInfo(*): Logs the passed value to the installed LogManager with a " + " LogLevel of 'Info'" + }, + { + "printWarning", + &luascriptfunctions::printWarning, + "printWarning(*): Logs the passed value to the installed LogManager with " + "a LogLevel of 'Warning'" + }, + { + "printError", + &luascriptfunctions::printError, + "printError(*): Logs the passed value to the installed LogManager with a " + "LogLevel of 'Error'" + }, + { + "printFatal", + &luascriptfunctions::printFatal, + "printFatal(*): Logs the passed value to the installed LogManager with a " + "LogLevel of 'Fatal'" + } } }; addLibrary(lib); diff --git a/src/scripting/scriptfunctions.cpp b/src/scripting/scriptfunctions.cpp deleted file mode 100644 index cf7279f20d..0000000000 --- a/src/scripting/scriptfunctions.cpp +++ /dev/null @@ -1,195 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014 * - * * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this * - * software and associated documentation files (the "Software"), to deal in the Software * - * without restriction, including without limitation the rights to use, copy, modify, * - * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * - * permit persons to whom the Software is furnished to do so, subject to the following * - * conditions: * - * * - * The above copyright notice and this permission notice shall be included in all copies * - * or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - ****************************************************************************************/ - -#include - -#include -#include - -#include -#include -#include - -namespace openspace { -namespace scripting { - -using namespace openspace::properties; - -void printInternal(ghoul::logging::LogManager::LogLevel level, lua_State* L) { - using ghoul::lua::luaTypeToString; - const std::string _loggerCat = "print"; - - const int type = lua_type(L, -1); - switch (type) { - case LUA_TNONE: - case LUA_TLIGHTUSERDATA: - case LUA_TTABLE: - case LUA_TFUNCTION: - case LUA_TUSERDATA: - case LUA_TTHREAD: - LOG(level, "Function parameter was of type '" << - luaTypeToString(type) << "'"); - case LUA_TNIL: - break; - case LUA_TBOOLEAN: - LOG(level, lua_toboolean(L, -1)); - break; - case LUA_TNUMBER: - LOG(level, lua_tonumber(L, -1)); - break; - case LUA_TSTRING: - LOG(level, lua_tostring(L, -1)); - break; - } -} - -int printDebug(lua_State* L) { - printInternal(ghoul::logging::LogManager::LogLevel::Debug, L); - return 0; -} - -int printInfo(lua_State* L) { - printInternal(ghoul::logging::LogManager::LogLevel::Info, L); - return 0; -} - -int printWarning(lua_State* L) { - printInternal(ghoul::logging::LogManager::LogLevel::Warning, L); - return 0; -} - -int printError(lua_State* L) { - printInternal(ghoul::logging::LogManager::LogLevel::Error, L); - return 0; -} - -int printFatal(lua_State* L) { - printInternal(ghoul::logging::LogManager::LogLevel::Fatal, L); - return 0; -} - - -int property_setValue(lua_State* L) -{ - using ghoul::lua::luaTypeToString; - const std::string _loggerCat = "property_setValue"; - - // TODO Check for argument number (ab) - std::string uri = luaL_checkstring(L, -2); - const int type = lua_type(L, -1); - // boost::any propertyValue; - // switch (type) { - // case LUA_TNONE: - // case LUA_TLIGHTUSERDATA: - // case LUA_TFUNCTION: - // case LUA_TUSERDATA: - // case LUA_TTHREAD: - // LERROR("Function parameter was of type '" << luaTypeToString(type) << "'"); - // return 0; - // case LUA_TNIL: - // propertyValue = 0; - // break; - // case LUA_TBOOLEAN: - // propertyValue = lua_toboolean(L, -1); - // break; - // case LUA_TNUMBER: - // propertyValue = lua_tonumber(L, -1); - // break; - // case LUA_TSTRING: - // propertyValue = std::string(lua_tostring(L, -1)); - // break; - //case LUA_TTABLE: { - // ghoul::Dictionary d; - // ghoul::lua::populateDictionary(L, d); - // propertyValue = d; - // break; - //} - // } - - Property* prop = property(uri); - if (!prop) { - LERROR("Property with uri '" << uri << "' could not be found"); - return 0; - } - - //if (propertyValue.type() != prop->type()) { - if (type != prop->typeLua()) - LERROR("Property '" << uri << "' does not accept input of type '" - << luaTypeToString(type) << "'. Requested type: '" - << luaTypeToString(prop->typeLua()) << "'"); - else - prop->setLua(L); - //prop->set(propertyValue); - - return 0; -} - -int property_getValue(lua_State* L) { - const std::string _loggerCat = "property_getValue"; - - // TODO Check for argument number (ab) - std::string uri = luaL_checkstring(L, -1); - - Property* prop = property(uri); - if (!prop) { - LERROR("Property with uri '" << uri << "' could not be found"); - lua_pushnil(L); - } - else { - prop->getLua(L); - - //switch (type) { - // case LUA_TNONE: - // case LUA_TLIGHTUSERDATA: - // case LUA_TFUNCTION: - // case LUA_TUSERDATA: - // case LUA_TTHREAD: - // LERROR("Function parameter was of type '" << luaTypeToString(type) - // << "'"); - // return 0; - // case LUA_TNIL: - // propertyValue = 0; - // break; - // case LUA_TBOOLEAN: - // propertyValue = lua_toboolean(L, -1); - // break; - // case LUA_TNUMBER: - // propertyValue = lua_tonumber(L, -1); - // break; - // case LUA_TSTRING: - // propertyValue = std::string(lua_tostring(L, -1)); - // break; - // case LUA_TTABLE: { - // ghoul::Dictionary d; - // ghoul::lua::populateDictionary(L, d); - // propertyValue = d; - // break; - // } - //} -} - return 1; -} - -} // namespace scripting -} // namespace openspace