From 207c7d565744860a78e07cdca65afc1e247d0c1b Mon Sep 17 00:00:00 2001 From: GPayne Date: Fri, 27 Mar 2020 15:10:46 -0600 Subject: [PATCH] Profile file handler in progress --- include/openspace/engine/configuration.h | 1 + include/openspace/engine/globals.h | 3 + include/openspace/scene/assetloader.h | 5 +- include/openspace/scene/profile.h | 66 +++++ include/openspace/scene/profileFile.h | 128 ++++++++++ src/engine/globals.cpp | 7 +- src/engine/openspaceengine.cpp | 1 + src/scene/assetloader.cpp | 6 +- src/scene/profile.cpp | 99 ++++++++ src/scene/profileFile.cpp | 308 +++++++++++++++++++++++ src/scene/profile_lua.inl | 50 ++++ src/scene/scene.cpp | 10 +- 12 files changed, 674 insertions(+), 10 deletions(-) create mode 100644 include/openspace/scene/profile.h create mode 100644 include/openspace/scene/profileFile.h create mode 100644 src/scene/profile.cpp create mode 100644 src/scene/profileFile.cpp create mode 100644 src/scene/profile_lua.inl diff --git a/include/openspace/engine/configuration.h b/include/openspace/engine/configuration.h index 907ccd0e3f..41643b3041 100644 --- a/include/openspace/engine/configuration.h +++ b/include/openspace/engine/configuration.h @@ -91,6 +91,7 @@ struct Configuration { glm::dvec3 screenSpaceRotation = glm::dvec3(0.0); glm::dvec3 masterRotation = glm::dvec3(0.0); bool isConsoleDisabled = false; + bool usingProfile = false; std::map moduleConfigurations; diff --git a/include/openspace/engine/globals.h b/include/openspace/engine/globals.h index c7133339bf..60b0a8479a 100644 --- a/include/openspace/engine/globals.h +++ b/include/openspace/engine/globals.h @@ -65,6 +65,7 @@ namespace scripting { class ScriptEngine; class ScriptScheduler; } // namespace scripting +class Profile; namespace global { @@ -100,6 +101,7 @@ properties::PropertyOwner& gRootPropertyOwner(); properties::PropertyOwner& gScreenSpaceRootPropertyOwner(); scripting::ScriptEngine& gScriptEngine(); scripting::ScriptScheduler& gScriptScheduler(); +Profile& gProfile(); } // namespace detail @@ -138,6 +140,7 @@ static properties::PropertyOwner& screenSpaceRootPropertyOwner = detail::gScreenSpaceRootPropertyOwner(); static scripting::ScriptEngine& scriptEngine = detail::gScriptEngine(); static scripting::ScriptScheduler& scriptScheduler = detail::gScriptScheduler(); +static Profile& profile = detail::gProfile(); void initialize(); void initializeGL(); diff --git a/include/openspace/scene/assetloader.h b/include/openspace/scene/assetloader.h index 6b3dac5369..374448644f 100644 --- a/include/openspace/scene/assetloader.h +++ b/include/openspace/scene/assetloader.h @@ -227,8 +227,9 @@ private: _onDependencyDeinitializationFunctionRefs; int _assetsTableRef; - std::vector profileAssetsAdded; - std::vector profileAssetsRemoved; + std::vector _profileAssetsRequired; + std::vector _profileAssetsRequested; + std::vector _profileAssetsRemoved; }; } // namespace openspace diff --git a/include/openspace/scene/profile.h b/include/openspace/scene/profile.h new file mode 100644 index 0000000000..c90b28556d --- /dev/null +++ b/include/openspace/scene/profile.h @@ -0,0 +1,66 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2020 * + * * + * 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 __OPENSPACE_CORE___PROFILE___H__ +#define __OPENSPACE_CORE___PROFILE___H__ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace ghoul { class Dictionary; } +namespace ghoul::opengl { class ProgramObject; } + +namespace openspace { + +namespace documentation { struct Documentation; } +namespace scripting { struct LuaLibrary; } + + +class Profile { +public: + Profile(); + + void saveCurrentSettingsToProfile(std::string filename); + + /** + * Returns the Lua library that contains all Lua functions available to provide + * profile functionality. + * \return The Lua library that contains all Lua functions available for profiles + */ + static scripting::LuaLibrary luaLibrary(); + +private: +}; + +} // namespace openspace + +#endif // __OPENSPACE_CORE___PROFILE___H__ diff --git a/include/openspace/scene/profileFile.h b/include/openspace/scene/profileFile.h new file mode 100644 index 0000000000..132dd0ee96 --- /dev/null +++ b/include/openspace/scene/profileFile.h @@ -0,0 +1,128 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2020 * + * * + * 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 __OPENSPACE_CORE___PROFILEFILE___H__ +#define __OPENSPACE_CORE___PROFILEFILE___H__ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace ghoul { class Dictionary; } +namespace ghoul::opengl { class ProgramObject; } + +namespace openspace { + +namespace documentation { struct Documentation; } +namespace scripting { struct LuaLibrary; } + + +class ProfileFile { +public: + ProfileFile(std::string filename); + ~ProfileFile(); + + //Need a copy constructor here to do a deep copy + + void read(); + void write(); + + void setFilename(std::string filename); + + //Methods for updating contents + void updateTime(); + void updateCamera(); + void addModuleLine(std::string line); + void addAssetLine(std::string line); + void addPropertyLine(std::string line); + void addKeybindingLine(std::string line); + void addMarkNodesLine(std::string line); + + //Methods for getting contents of each section + std::string time(); + std::string camera(); + std::vector modules(); + std::vector assets(); + std::vector properties(); + std::vector keybindings(); + std::vector markNodes(); + +private: + void logError(std::string message); + void clearAllFields(); + bool isBlank(std::string line); + int splitByTab(std::string line, std::vector& result); + bool determineSection(std::string line); + void parseCurrentSection(std::string line); + void parseVersion(std::string line); + void parseModule(std::string line); + void parseAsset(std::string line); + void parseProperty(std::string line); + void parseKeybinding(std::string line); + void parseTime(std::string line); + void parseCamera(std::string line); + void parseMarkNodes(std::string line); + void verifyRequiredFields(std::string sectionName, std::vector fields, + std::vector standard, unsigned int nFields); + + const int versionLinesExpected = 1; + const int timeLinesExpected = 1; + const int cameraLinesExpected = 1; + + const int versionFieldsExpected = 1; + const int moduleFieldsExpected = 3; + const int assetFieldsExpected = 2; + const int propertyFieldsExpected = 3; + const int keybindingFieldsExpected = 6; + const int timeFieldsExpected = 2; + const int cameraNavigationFieldsExpected = 8; + const int cameraGeoFieldsExpected = 5; + const int markNodesFieldsExpected = 1; + + std::string _filename; + unsigned int _lineNum = 1; + unsigned int _numLinesVersion = 0; + unsigned int _numLinesTime = 0; + unsigned int _numLinesCamera = 0; + + std::string _version; + std::string _time; + std::string _camera; + std::vector _modules; + std::vector _assets; + std::vector _properties; + std::vector _keybindings; + std::vector _markNodes; +}; + +} // namespace openspace + +#endif // __OPENSPACE_CORE___PROFILEFILE___H__ diff --git a/src/engine/globals.cpp b/src/engine/globals.cpp index a2e3c6b5a2..34effc2cc5 100644 --- a/src/engine/globals.cpp +++ b/src/engine/globals.cpp @@ -48,6 +48,7 @@ #include #include #include +#include #include #include #include @@ -182,7 +183,6 @@ interaction::SessionRecording& gSessionRecording() { return g; } - interaction::ShortcutManager& gShortcutManager() { static interaction::ShortcutManager g; return g; @@ -213,6 +213,11 @@ scripting::ScriptScheduler& gScriptScheduler() { return g; } +Profile& gProfile() { + static Profile g; + return g; +} + } // namespace detail void initialize() { diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index 0d0a8f4ad0..033ab87322 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -338,6 +338,7 @@ void OpenSpaceEngine::initialize() { // an asset name if both are provided. global::configuration.asset = absPath("${TEMPORARY}/") + global::configuration.profile; + global::configuration.usingProfile = true; } // Set up asset loader diff --git a/src/scene/assetloader.cpp b/src/scene/assetloader.cpp index 888ee4fc3f..9439ea805a 100644 --- a/src/scene/assetloader.cpp +++ b/src/scene/assetloader.cpp @@ -444,6 +444,7 @@ std::shared_ptr AssetLoader::require(const std::string& identifier) { std::shared_ptr asset = getAsset(identifier); std::shared_ptr dependant = _currentAsset; dependant->require(asset); + _profileAssetsRequired.push_back(asset->assetFilePath()); return asset; } @@ -452,6 +453,7 @@ std::shared_ptr AssetLoader::request(const std::string& identifier) { std::shared_ptr parent = _currentAsset; parent->request(asset); assetRequested(parent, asset); + _profileAssetsRequested.push_back(asset->assetFilePath()); return asset; } @@ -473,7 +475,7 @@ ghoul::filesystem::Directory AssetLoader::currentDirectory() const { std::shared_ptr AssetLoader::add(const std::string& identifier) { setCurrentAsset(_rootAsset); - profileAssetsAdded.push_back(identifier); + return request(identifier); } @@ -481,7 +483,7 @@ std::shared_ptr AssetLoader::add(const std::string& identifier) { void AssetLoader::remove(const std::string& identifier) { setCurrentAsset(_rootAsset); unrequest(identifier); - profileAssetsRemoved.push_back(identifier); + _profileAssetsRemoved.push_back(identifier); } std::shared_ptr AssetLoader::has(const std::string& identifier) const { diff --git a/src/scene/profile.cpp b/src/scene/profile.cpp new file mode 100644 index 0000000000..b4b0560d5b --- /dev/null +++ b/src/scene/profile.cpp @@ -0,0 +1,99 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2020 * + * * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "profile_lua.inl" + +namespace { + constexpr const char* _loggerCat = "Profile"; + constexpr const char* KeyIdentifier = "Identifier"; + constexpr const char* KeyParent = "Parent"; + +} // namespace + +namespace openspace { + +Profile::Profile() + : properties::PropertyOwner({"Scene", "Scene"}) + , _initializer(std::move(initializer)) +{ + _rootDummy.setIdentifier(SceneGraphNode::RootNodeIdentifier); + _rootDummy.setScene(this); +} + +Profile::~Profile() { + clear(); + _rootDummy.setScene(nullptr); +} + +void Profile::saveCurrentSettingsToProfile(std::string filename) { + if (! global::configuration.usingProfile) { + std::string errorMessage = "Program was not started using a profile, " + "so cannot use this save-current-settings feature."; + LERROR(errorMessage); + } + std::string initProfile = global::configuration.profile; +} + +scripting::LuaLibrary Profile::luaLibrary() { + return { + "", + { + { + "saveCurrentSettingsToProfile", + &luascriptfunctions::saveCurrentSettingsToProfile, + {}, + "string", + "Collects all changes that have been made since startup, including all " + "property changes and assets required, requested, or removed. All " + "changes will be added to the profile that OpenSpace was started with, " + "and the new saved file will contain all of this information. The " + "file will be named according to the argument provided. If this argument " + "is blank, then the new file will have the base name of the profile that " + " was started, with a _YYYYMMDD suffix." + } + } + }; +} + +} // namespace openspace diff --git a/src/scene/profileFile.cpp b/src/scene/profileFile.cpp new file mode 100644 index 0000000000..d029f5ac1b --- /dev/null +++ b/src/scene/profileFile.cpp @@ -0,0 +1,308 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2020 * + * * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace { + constexpr const char* _loggerCat = "ProfileFile"; + constexpr const char* KeyIdentifier = "Identifier"; + constexpr const char* KeyParent = "Parent"; + +} // namespace + +namespace openspace { + +ProfileFile::ProfileFile(std::string filename) + : _filename(filename) +{ +} + +ProfileFile::~ProfileFile() { +} + +void ProfileFile::read() { + clearAllFields(); + std::ifstream inFile; + inFile.open(_filename, std::ifstream::in); + std::string line; + _lineNum = 1; + bool insideSection = false; + + while (getline(inFile, line)) { + if (insideSection) { + if (isBlank(line)) { + insideSection = false; + } + else { + parseCurrentSection(line); + } + } + else if (line.substr(0, 1) == "#") { + if (determineSection(line)) { + insideSection = true; + } + } + _lineNum++; + } + inFile.close(); +} + +void ProfileFile::clearAllFields() { + _numLinesVersion = 0; + _numLinesTime = 0; + _numLinesCamera = 0; + + _version.clear(); + _time.clear(); + _camera.clear(); + _modules.clear(); + _assets.clear(); + _properties.clear(); + _keybindings.clear(); + _markNodes.clear(); +} + +bool ProfileFile::isBlank(std::string line) { + char* c = line.c_str(); + int nonBlanks = 0; + while (*c) { + if (!isspace(*c)) { + nonBlanks++; + } + c++; + } + return (nonBlanks == 0); +} + +bool ProfileFile::determineSection(std::string line) { + +} + +void ProfileFile::parseCurrentSection(std::string line) { + +} + +void ProfileFile::logError(std::string message) { + std::string e = "Error @ line " + std::to_string(_lineNum) + ": "; + LERROR(e + message); +} + +void ProfileFile::parseVersion(std::string line) { + std::vector fields; + + if (++_numLinesVersion > versionLinesExpected) { + logError("Too many lines in Version section"); + } + if (splitByTab(line, fields) > versionFieldsExpected) { + logError("No tabs allowed in Version entry"); + } + else { + _version = line; + } +} + +void ProfileFile::parseModule(std::string line) { + std::vector fields; + + if (splitByTab(line, fields) != moduleFieldsExpected) { + logError(std::to_string(moduleFieldsExpected) + + " fields required in a Module entry"); + } + std::vector standard = { + "module name", + "", + "" + }; + verifyRequiredFields(fields, standard, moduleFieldsExpected); + _modules.push_back(line); +} + +void ProfileFile::parseAsset(std::string line) { + std::vector fields; + + if (splitByTab(line, fields) != assetFieldsExpected) { + logError(std::to_string(assetFieldsExpected) + + " fields required in an Asset entry"); + } + std::vector standard = { + "asset name", + "" + }; + verifyRequiredFields(fields, standard, assetFieldsExpected); + _assets.push_back(line); +} + +void ProfileFile::parseProperty(std::string line) { + std::vector fields; + + if (splitByTab(line, fields) != propertyFieldsExpected) { + logError(std::to_string(propertyFieldsExpected) + + " fields required in Property entry"); + } + std::vector standard = { + "set command", + "name", + "value" + }; + verifyRequiredFields("Property", fields, standard, propertyFieldsExpected); + _properties.push_back(line); +} + +void ProfileFile::parseKeybinding(std::string line) { + std::vector fields; + + if (splitByTab(line, fields) != keybindingFieldsExpected) { + logError(std::to_string(keybindingFieldsExpected) + + " fields required in Keybinding entry"); + } + std::vector standard = { + "key", + "documentation", + "name", + "GuiPath", + "local(T/F)", + "script to execute" + }; + verifyRequiredFields("Keybinding", fields, standard, propertyFieldsExpected); + _properties.push_back(line); +} + +void ProfileFile::parseTime(std::string line) { + std::vector fields; + + if (++_numLinesTime > timeLinesExpected) { + logError("Too many lines in time section"); + } + if (splitByTab(line, fields) != timeFieldsExpected) { + logError(std::to_string(timeFieldsExpected) + + " fields required in Time entry"); + } + std::vector standard = { + "time set type", + "time value to set" + }; + verifyRequiredFields("Time", fields, standard, propertyFieldsExpected); + _time = line; +} + +void ProfileFile::parseCamera(std::string line) { + std::vector fields; + + if (++_numLinesCamera > cameraLinesExpected) { + logError("Too many lines in camera section"); + } + int nFields = splitByTab(line, fields); + if (nFields == cameraNavigationFieldsExpected) { + std::vector standard = { + "Type of camera set (setNavigationState)", + "setNavigationState Anchor", + "", + "", + "setNavigationState position vector", + "", + "", + "" + }; + verifyRequiredFields("Camera", fields, standard, cameraNavigationFieldsExpected); + } + else if (nFields == cameraGeoFieldsExpected) { + std::vector standard = { + "Type of camera set (goToGeo)", + "", + "Camera goToGeo Latitude", + "Camera goToGeo Longitude", + "" + }; + verifyRequiredFields("Camera goToGeo", fields, standard, + cameraNavigationFieldsExpected); + } + else { + logError(std::to_string(cameraNavigationFieldsExpected) + " or " + + std::to_string(cameraGeoFieldsExpected) + " fields required in Camera entry"); + } + _camera = line; +} + +void ProfileFile::parseMarkNodes(std::string line) { + std::vector fields; + + if (splitByTab(line, fields) != markNodesFieldsExpected) { + logError(std::to_string(markNodesFieldsExpected) + + " field required in an Mark Nodes entry"); + } + std::vector standard = { + "Mark Interesting Node name" + }; + verifyRequiredFields("Mark Interesting Nodes", fields, standard, + markNodesFieldsExpected); + _assets.push_back(line); +} + +void ProfileFile::verifyRequiredFields(std::string sectionName, + std::vector fields, + std::vector standard, + unsigned int nFields) +{ + for (unsigned int i = 0; i < fields.size(); i++) { + if (!standard[i].empty() && fields[i].empty()) { + std::string errMsg = sectionName + " " + standard[i]; + errMsg += "(arg " + std::to_string(i) + "/" + nFields + ") is required"; + logError(errMsg); + } + } +} + +int ProfileFile::splitByTab(std::string line, std::vector& result) { + std::istringstream iss(line); + std::string tmp; + result.clear(); + while(std::getline(iss, tmp, '\t')) { + result.push_back(tmp); + } + return result.size(); +} + +} // namespace openspace diff --git a/src/scene/profile_lua.inl b/src/scene/profile_lua.inl new file mode 100644 index 0000000000..e647961a32 --- /dev/null +++ b/src/scene/profile_lua.inl @@ -0,0 +1,50 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2020 * + * * + * 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. * + ****************************************************************************************/ + +namespace openspace::luascriptfunctions { + + +int saveCurrentSettingsToProfile(lua_State* L) { + ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::saveCurrentSettingsToProfile"); + + using ghoul::lua::luaTypeToString; + + const std::string saveFilePath = ghoul::lua::value( + L, + 1, + ghoul::lua::PopValue::Yes + ); + + if (saveFilePath.empty()) { + return luaL_error(L, "save filepath string is empty"); + } + global::profile.saveCurrentSettingsToProfile( + saveFilePath + ); + + ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack"); + return 0; +} + +} // namespace openspace::luascriptfunctions diff --git a/src/scene/scene.cpp b/src/scene/scene.cpp index 1f5574816f..82a0672084 100644 --- a/src/scene/scene.cpp +++ b/src/scene/scene.cpp @@ -616,19 +616,19 @@ scripting::LuaLibrary Scene::luaLibrary() { "to match the type that the property (or properties) expect. If the " "third is not present or is '0', the value changes instantly, otherwise " "the change will take that many seconds and the value is interpolated at " - "each steap in between. The fourth parameter is an optional easing " + "each step in between. The fourth parameter is an optional easing " "function if a 'duration' has been specified. If 'duration' is 0, this " "parameter value is ignored. Otherwise, it can be one of many supported " "easing functions. See easing.h for available functions. The fifth " - "argument must be either empty, 'regex', or 'single'. If the last " + "argument must be either empty, 'regex', or 'single'. If the fifth" "argument is empty (the default), the URI is interpreted using a " "wildcard in which '*' is expanded to '(.*)' and bracketed components " "'{ }' are interpreted as group tag names. Then, the passed value will " "be set on all properties that fit the regex + group name combination. " - "If the third argument is 'regex' neither the '*' expansion, nor the " + "If the fifth argument is 'regex' neither the '*' expansion, nor the " "group tag expansion is performed and the first argument is used as an " "ECMAScript style regular expression that matches against the fully " - "qualified IDs of properties. If the third arugment is 'single' no " + "qualified IDs of properties. If the fifth argument is 'single' no " "substitutions are performed and exactly 0 or 1 properties are changed." }, { @@ -640,7 +640,7 @@ scripting::LuaLibrary Scene::luaLibrary() { "second argument can be any type, but it has to match the type that the " "property expects. If the third is not present or is '0', the value " "changes instantly, otherwise the change will take that many seconds and " - "the value is interpolated at each steap in between. The fourth " + "the value is interpolated at each step in between. The fourth " "parameter is an optional easing function if a 'duration' has been " "specified. If 'duration' is 0, this parameter value is ignored. " "Otherwise, it has to be 'linear', 'easein', 'easeout', or 'easeinout'. "