From 79174d5b6cc43d45880a11ec99112a8fc6ba2c30 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Fri, 29 Aug 2014 13:04:20 +0200 Subject: [PATCH] Cleaned up scripts directory Made scripts runnable at startup Added printing functions and remapped default Lua printing --- ext/ghoul | 2 +- include/openspace/engine/openspaceengine.h | 4 +- include/openspace/scripting/scriptengine.h | 12 ++- include/openspace/scripting/scriptfunctions.h | 12 +++ include/openspace/util/constants.h | 1 + openspace.cfg | 5 +- scripts/DefaultConfig.lua | 16 ---- scripts/ExtraConfigScript.lua | 15 ---- scripts/config.lua | 5 -- scripts/config2.lua | 6 -- scripts/defaultSettings.cfg | 4 - scripts/default_startup.lua | 1 + src/engine/openspaceengine.cpp | 32 ++++++- src/query/query.cpp | 13 +++ src/scenegraph/scenegraph.cpp | 5 +- src/scripting/scriptengine.cpp | 83 ++++++++++++++++++- src/scripting/scriptfunctions.cpp | 64 +++++++++++++- 17 files changed, 221 insertions(+), 59 deletions(-) delete mode 100644 scripts/DefaultConfig.lua delete mode 100644 scripts/ExtraConfigScript.lua delete mode 100644 scripts/config.lua delete mode 100644 scripts/config2.lua delete mode 100644 scripts/defaultSettings.cfg create mode 100644 scripts/default_startup.lua diff --git a/ext/ghoul b/ext/ghoul index 17608b8800..54dfc9b508 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit 17608b8800d412f99b6eef8e9dcc4741c5a1f38c +Subproject commit 54dfc9b50825c392662cab0c7c42724a38734ef2 diff --git a/include/openspace/engine/openspaceengine.h b/include/openspace/engine/openspaceengine.h index 3026d19d79..ef98decc83 100644 --- a/include/openspace/engine/openspaceengine.h +++ b/include/openspace/engine/openspaceengine.h @@ -65,7 +65,7 @@ public: ghoul::opencl::CLContext& clContext(); InteractionHandler& interactionHandler(); RenderEngine& renderEngine(); - ScriptEngine& scriptEngine(); + scripting::ScriptEngine& scriptEngine(); // SGCT callbacks bool initializeGL(); @@ -92,7 +92,7 @@ private: ghoul::Dictionary* _configurationManager; InteractionHandler* _interactionHandler; RenderEngine* _renderEngine; - ScriptEngine* _scriptEngine; + scripting::ScriptEngine* _scriptEngine; ghoul::cmdparser::CommandlineParser* _commandlineParser; #ifdef FLARE_ONLY Flare* _flare; diff --git a/include/openspace/scripting/scriptengine.h b/include/openspace/scripting/scriptengine.h index 81b9f77c05..83c3795b18 100644 --- a/include/openspace/scripting/scriptengine.h +++ b/include/openspace/scripting/scriptengine.h @@ -28,6 +28,9 @@ #include #include +namespace openspace { +namespace scripting { + class ScriptEngine { public: struct LuaLibrary { @@ -43,14 +46,21 @@ public: bool addLibrary(const LuaLibrary& library); bool hasLibrary(const std::string& name); - bool runScript(std::string script); + bool runScript(const std::string& script); + bool runScriptFile(const std::string& filename); private: bool isLibraryNameAllowed(const std::string& name); void addLibraryFunctions(const LuaLibrary& library, bool replace); + void addBaseLibrary(); + void remapPrintFunction(); + lua_State* _state; std::set _registeredLibraries; }; + +} // namespace scripting +} // namespace openspace #endif // __SCRIPTENGINE_H__ diff --git a/include/openspace/scripting/scriptfunctions.h b/include/openspace/scripting/scriptfunctions.h index 59c58c84f2..9fbad7229e 100644 --- a/include/openspace/scripting/scriptfunctions.h +++ b/include/openspace/scripting/scriptfunctions.h @@ -27,10 +27,22 @@ 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); //static int property_getValue(lua_State* L); +} // namespace scripting +} // namespace openspace #endif // __SCRIPTFUNCTIONS_H__ diff --git a/include/openspace/util/constants.h b/include/openspace/util/constants.h index 6c004dbda2..2fde16e5f5 100644 --- a/include/openspace/util/constants.h +++ b/include/openspace/util/constants.h @@ -34,6 +34,7 @@ namespace openspaceengine { const std::string keyPathScene = "Paths.SCENEPATH"; const std::string keyConfigSgct = "SGCTConfig"; const std::string keyConfigScene = "Scene"; + const std::string keyStartupScript = "StartupScripts"; } // namespace openspaceengine namespace scenegraph { diff --git a/openspace.cfg b/openspace.cfg index 4becaf05a8..9b45f4704d 100644 --- a/openspace.cfg +++ b/openspace.cfg @@ -12,5 +12,8 @@ return { SGCTConfig = "${SGCT}/single.xml", --SGCTConfig = "${SGCT}/two_nodes.xml", --SGCTConfig = "${SGCT}/single_sbs_stereo.xml", - Scene = "${SCENEPATH}/default.scene" + Scene = "${SCENEPATH}/default.scene", + StartupScripts = { + "${SCRIPTS}/default_startup.lua" + } } \ No newline at end of file diff --git a/scripts/DefaultConfig.lua b/scripts/DefaultConfig.lua deleted file mode 100644 index 3e0738115a..0000000000 --- a/scripts/DefaultConfig.lua +++ /dev/null @@ -1,16 +0,0 @@ -{ - level1_string = "music1", - level1_integer = 2332, - level1_dictionary = - { - level2_string = "stuff", - level2_integer = 32, - level2_dictionary = { - level3_string = "levels", - level3_integer = 323232 - } - }, - level2_double = 3.4, - level2_boolean = true - -} \ No newline at end of file diff --git a/scripts/ExtraConfigScript.lua b/scripts/ExtraConfigScript.lua deleted file mode 100644 index a2b9ca86c5..0000000000 --- a/scripts/ExtraConfigScript.lua +++ /dev/null @@ -1,15 +0,0 @@ -musicname = "music2" -lyrics = "This is not, the greatest lyrics in the world. This is just a tribute" - -config = -{ - level1_string = musicname, - level1_lyrics = lyrics, - level1_secrets = - { - secret_stuff1 = "Password", - secret_stuff2 = "123456", - }, - level2_double = 4.3 - -} \ No newline at end of file diff --git a/scripts/config.lua b/scripts/config.lua deleted file mode 100644 index 1cd7d986d2..0000000000 --- a/scripts/config.lua +++ /dev/null @@ -1,5 +0,0 @@ -{ - setting1 = 1, - setting2 = 2, - t = {s = 1, t = 2, u = 3} -} \ No newline at end of file diff --git a/scripts/config2.lua b/scripts/config2.lua deleted file mode 100644 index db728fe51c..0000000000 --- a/scripts/config2.lua +++ /dev/null @@ -1,6 +0,0 @@ -{ - setting2 = 4, - setting3 = 1, - t = { s = 2, v = 0}, - tt = { t = { a = "a", b = "b", ff="2" }, u = { a = "a", b = "b" } } -} \ No newline at end of file diff --git a/scripts/defaultSettings.cfg b/scripts/defaultSettings.cfg deleted file mode 100644 index d93b7d07f8..0000000000 --- a/scripts/defaultSettings.cfg +++ /dev/null @@ -1,4 +0,0 @@ -{ - BasePathOffset = "../../.." - -} \ No newline at end of file diff --git a/scripts/default_startup.lua b/scripts/default_startup.lua new file mode 100644 index 0000000000..a39eef89ee --- /dev/null +++ b/scripts/default_startup.lua @@ -0,0 +1 @@ +print "foo" \ No newline at end of file diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index 209917c5ea..9ef104ac1a 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -48,6 +48,8 @@ using namespace ghoul::filesystem; using namespace ghoul::logging; +using namespace openspace::scripting; + namespace { const std::string _loggerCat = "OpenSpaceEngine"; const std::string _configurationFile = "openspace.cfg"; @@ -316,9 +318,9 @@ bool OpenSpaceEngine::initialize() FactoryManager::initialize(); scriptEngine().initialize(); - scriptEngine().addLibrary(ScriptEngine::LuaLibrary()); +// scriptEngine().addLibrary(ScriptEngine::LuaLibrary()); - _engine->scriptEngine().runScript("return mylib.mysin(4)"); +// _engine->scriptEngine().runScript("return mylib.mysin(4)"); // Load scenegraph @@ -362,6 +364,32 @@ bool OpenSpaceEngine::initialize() DeviceIdentifier::ref().scanDevices(); _engine->_interactionHandler->connectDevices(); + // Run start up scripts + using ghoul::Dictionary; + using constants::openspaceengine::keyStartupScript; + const bool hasScript = _engine->configurationManager().hasKeyAndValue(keyStartupScript); + if (hasScript) { + Dictionary scripts; + _engine->configurationManager().getValue(keyStartupScript, scripts); + + for (size_t i = 0; i < scripts.size(); ++i) { + std::stringstream stream; + // Dictionary-size is 0-based; script numbers are 1-based + stream << (i + 1); + const std::string& key = stream.str(); + const bool hasKey = scripts.hasKeyAndValue(key); + if (!hasKey) { + LERROR("The startup scripts have to be declared in a simple array format"); + break; + } + + std::string scriptPath; + scripts.getValue(key, scriptPath); + const std::string absoluteScriptPath = absPath(scriptPath); + _engine->scriptEngine().runScriptFile(absoluteScriptPath); + } + } + return true; } diff --git a/src/query/query.cpp b/src/query/query.cpp index aabd8f3eb4..ffe1143f93 100644 --- a/src/query/query.cpp +++ b/src/query/query.cpp @@ -53,8 +53,21 @@ properties::Property* property(const std::string& uri) properties::Property* property(const std::string& nodeName, const std::string& propertyName) { SceneGraphNode* node = sceneGraphNode(nodeName); + if (!node) { + LERROR("Node '" << nodeName << "' did not exist"); + return nullptr; + } Renderable* propertyOwner = node->renderable(); + if (!propertyOwner) { + LERROR("Node '" << nodeName << "' is not a PropertyOwner"); + return nullptr; + } properties::Property* property = propertyOwner->property(propertyName);; + if (!property) { + LERROR("Node '" << nodeName << "' did not have property '" << + propertyName << "'"); + return nullptr; + } return property; } diff --git a/src/scenegraph/scenegraph.cpp b/src/scenegraph/scenegraph.cpp index 57409ebcd2..f9001edd32 100644 --- a/src/scenegraph/scenegraph.cpp +++ b/src/scenegraph/scenegraph.cpp @@ -347,14 +347,17 @@ bool SceneGraph::registerScriptFunctions() { LDEBUG("Registering Script Functions"); + using namespace scripting; - ScriptEngine::LuaLibrary l = { + ScriptEngine::LuaLibrary sceneGraphLibrary = { "", { { "setPropertyValue", &property_setValue} // { "getPropertyValue", &property_getValue}, } }; + + OsEng.scriptEngine().addLibrary(sceneGraphLibrary); return true; } diff --git a/src/scripting/scriptengine.cpp b/src/scripting/scriptengine.cpp index cdeb177aaf..6ec891e83b 100644 --- a/src/scripting/scriptengine.cpp +++ b/src/scripting/scriptengine.cpp @@ -24,13 +24,26 @@ #include +#include + #include +#include #include +#include + +namespace openspace { +namespace scripting { + namespace { const std::string _loggerCat = "ScriptEngine"; const std::string _openspaceLibraryName = "openspace"; + const std::string _luaGlobalNamespace = "_G"; + const std::string _printFunctionName = "print"; + const lua_CFunction _printFunctionReplacement = printInfo; + + const int _setTableOffset = -3; // -1 (top) -1 (first argument) -1 (second argument) } ScriptEngine::ScriptEngine() @@ -50,9 +63,16 @@ bool ScriptEngine::initialize() { LDEBUG("Add OpenSpace modules"); + LDEBUG("Create openspace base library"); lua_newtable(_state); lua_setglobal(_state, _openspaceLibraryName.c_str()); + LDEBUG("Adding base functions"); + addBaseLibrary(); + + LDEBUG("Remap print function"); + remapPrintFunction(); + return true; } @@ -80,14 +100,16 @@ bool ScriptEngine::addLibrary(const ScriptEngine::LuaLibrary& library) { lua_pushstring(_state, library.name.c_str()); lua_newtable(_state); addLibraryFunctions(library, false); - lua_settable(_state, -3); + lua_settable(_state, _setTableOffset); _registeredLibraries.insert(ghoul::hashCRC32(library.name)); } return true; } -bool ScriptEngine::runScript(std::string script) { +bool ScriptEngine::runScript(const std::string& script) { + if (script.empty()) + return false; int status = luaL_loadstring(_state, script.c_str()); if (status != LUA_OK) { LERROR("Error loading script: '" << lua_tostring(_state, -1) << "'"); @@ -103,6 +125,29 @@ bool ScriptEngine::runScript(std::string script) { return true; } +bool ScriptEngine::runScriptFile(const std::string& filename) { + if (filename.empty()) { + LWARNING("Filename was empty"); + return false; + } + if (!FileSys.fileExists(filename)) { + LERROR("Script with name '" << filename << "' did not exist"); + return false; + } + std::ifstream file(filename.c_str()); + if (file.bad()) { + LERROR("Error opening file '" << filename << "'"); + return false; + } + + // Read the contents of the script + std::string script((std::istreambuf_iterator(file)), + std::istreambuf_iterator()); + + const bool runSuccess = runScript(script); + return runSuccess; +} + bool ScriptEngine::hasLibrary(const std::string& name) { const unsigned int hash = ghoul::hashCRC32(name); @@ -172,6 +217,38 @@ void ScriptEngine::addLibraryFunctions(const LuaLibrary& library, bool replace) } lua_pushstring(_state, p.first.c_str()); lua_pushcfunction(_state, p.second); - lua_settable(_state, -3); + lua_settable(_state, _setTableOffset); } } + +void ScriptEngine::addBaseLibrary() { + ScriptEngine::LuaLibrary sceneGraphLibrary = { + "", + { + { "setPropertyValue", &property_setValue} + // { "getPropertyValue", &property_getValue}, + } + }; + + LuaLibrary lib = { + "", + { + { "printDebug", &printDebug }, + { "printInfo", &printInfo }, + { "printWarning", &printWarning }, + { "printError", &printError }, + { "printFatal", &printFatal } + } + }; + addLibrary(lib); +} + +void ScriptEngine::remapPrintFunction() { + lua_getglobal(_state, _luaGlobalNamespace.c_str()); + lua_pushstring(_state, _printFunctionName.c_str()); + lua_pushcfunction(_state, _printFunctionReplacement); + lua_settable(_state, _setTableOffset); +} + +} // namespace scripting +} // namespace openspace diff --git a/src/scripting/scriptfunctions.cpp b/src/scripting/scriptfunctions.cpp index 9f0a6577c3..c5ffae260f 100644 --- a/src/scripting/scriptfunctions.cpp +++ b/src/scripting/scriptfunctions.cpp @@ -27,15 +27,72 @@ #include #include +#include #include -using namespace openspace; +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) { - const std::string _loggerCat = "property_setValue"; using ghoul::lua::luaTypeToString; + const std::string _loggerCat = "property_setValue"; // TODO Check for argument number (ab) std::string nodeName = luaL_checkstring(L, -3); @@ -81,3 +138,6 @@ int property_setValue(lua_State* L) //{ // //} + +} // namespace scripting +} // namespace openspace