From cd50c3e4cf75879841a833077078d57e47ef8200 Mon Sep 17 00:00:00 2001 From: GPayne Date: Tue, 7 Sep 2021 21:55:44 -0600 Subject: [PATCH] Working non-assetized initializations for profile sections besides modules and interesting nodes --- include/openspace/interaction/actionmanager.h | 8 +- .../openspace/interaction/keybindingmanager.h | 8 ++ .../openspace/navigation/navigationhandler.h | 9 +++ include/openspace/scene/profile.h | 9 +++ include/openspace/scene/scene.h | 31 +++++++ include/openspace/util/time.h | 14 ++++ include/openspace/util/timemanager.h | 19 +++++ src/engine/openspaceengine.cpp | 48 +++++------ src/interaction/actionmanager.cpp | 37 +++++++++ src/interaction/keybindingmanager.cpp | 21 +++++ src/navigation/navigationhandler.cpp | 48 +++++++++++ src/scene/profile.cpp | 55 +++++++------ src/scene/scene.cpp | 80 +++++++++++++++++++ src/scene/scene_lua.inl | 40 ++++++++++ src/util/time.cpp | 17 ++++ src/util/timemanager.cpp | 15 ++++ 16 files changed, 410 insertions(+), 49 deletions(-) diff --git a/include/openspace/interaction/actionmanager.h b/include/openspace/interaction/actionmanager.h index b140fe1bd4..d5e86565fd 100644 --- a/include/openspace/interaction/actionmanager.h +++ b/include/openspace/interaction/actionmanager.h @@ -26,6 +26,7 @@ #define __OPENSPACE_CORE___ACTIONMANAGER___H__ #include +#include #include namespace ghoul { class Dictionary; } @@ -43,7 +44,12 @@ public: void triggerAction(const std::string& identifier, const ghoul::Dictionary& arguments) const; - + /** + * Registers actions from the contents of a profile. + * + * \param p The Profile to be read. + */ + void setFromProfile_actions(const Profile& p); static scripting::LuaLibrary luaLibrary(); private: diff --git a/include/openspace/interaction/keybindingmanager.h b/include/openspace/interaction/keybindingmanager.h index 196848a939..e843b16020 100644 --- a/include/openspace/interaction/keybindingmanager.h +++ b/include/openspace/interaction/keybindingmanager.h @@ -27,6 +27,7 @@ #include +#include #include namespace openspace { @@ -51,6 +52,13 @@ public: std::vector> keyBinding( const KeyWithModifier& key) const; + /** + * Registers keybindings from the contents of a profile. + * + * \param p The Profile to be read. + */ + void setFromProfile_keybindings(const Profile& p); + static scripting::LuaLibrary luaLibrary(); void keyboardCallback(Key key, KeyModifier modifier, KeyAction action); diff --git a/include/openspace/navigation/navigationhandler.h b/include/openspace/navigation/navigationhandler.h index 36d4c51cf4..d2b525e3fa 100644 --- a/include/openspace/navigation/navigationhandler.h +++ b/include/openspace/navigation/navigationhandler.h @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -131,6 +132,14 @@ public: void setNavigationStateNextFrame(NavigationState state); + /** + * Sets the camera position using the time contents of a profile. The function will + * set an absolute position or a go-to-geolocation command using the globebrowsing + * module. + * \param p The Profile to be read. + */ + void setFromProfile_camera(const Profile& p); + /** * \return The Lua library that contains all Lua functions available to affect the * interaction diff --git a/include/openspace/scene/profile.h b/include/openspace/scene/profile.h index f1a9773cfb..63c2e3de90 100644 --- a/include/openspace/scene/profile.h +++ b/include/openspace/scene/profile.h @@ -314,6 +314,15 @@ std::string convertToAsset_camera(const Profile& p); */ std::string convertToAsset_addedScripts(const Profile& p); +/** + * Function to retrieve the individual additional script lines included in the profile + * + * \param p The profile that should be processed + * + * \return vector of strings containing the individual script lines + */ +std::vector& additionalScripts(Profile& p); + } // namespace openspace #endif // __OPENSPACE_CORE___PROFILE___H__ diff --git a/include/openspace/scene/scene.h b/include/openspace/scene/scene.h index f1a03be8e5..2bf112f4d1 100644 --- a/include/openspace/scene/scene.h +++ b/include/openspace/scene/scene.h @@ -27,7 +27,9 @@ #include +#include #include +#include #include #include #include @@ -233,6 +235,35 @@ public: */ static scripting::LuaLibrary luaLibrary(); + /** + * Creates an initial asset file to load, which contains: + * 1. Meta information + * 2. Assets to include + * + * \param p The Profile to be read. + */ + void createInitialAssetToLoad(const Profile& p, const std::string& assetFilename); + + /** + * Sets a property using the 'properties' contents of a profile. The function will + * loop through each setProperty command. A property may be set to a bool, float, + * or string value (which must be converted because a Profile stores all values + * as strings) + * + * \param p The Profile to be read. + */ + void setFromProfile_properties(const Profile& p); + + /** + * Accepts string version of a property value from a profile, converts it to the + * appropriate type, and then pushes the value onto the lua state. + * + * \param L the lua state to push value to + * \param value string representation of the value with which to set property + */ + void property_pushValueFromProfileToLuaState(ghoul::lua::LuaState& L, + const std::string& value); + private: /** * Update dependencies. diff --git a/include/openspace/util/time.h b/include/openspace/util/time.h index b09bae84e6..82adf87f02 100644 --- a/include/openspace/util/time.h +++ b/include/openspace/util/time.h @@ -141,6 +141,20 @@ public: */ double advanceTime(double tickTime); + /** + * Sets a relative time from profile. + * \param setTime a string containing time adjustment as described in documentation + * for luascriptfunctions::time_advancedTime + */ + void setFromProfile_timeRelative(const std::string& setTime); + + /** + * Sets an absolute time from profile. + * \param setTime a string containing time to set, which must be a valid + * ISO 8601-like date string of the format YYYY-MM-DDTHH:MN:SS + */ + void setFromProfile_timeAbsolute(const std::string& setTime); + /** * Returns the Lua library that contains all Lua functions available to change the * current time, retrieve the current time etc. diff --git a/include/openspace/util/timemanager.h b/include/openspace/util/timemanager.h index 5914841073..9de240dd84 100644 --- a/include/openspace/util/timemanager.h +++ b/include/openspace/util/timemanager.h @@ -25,8 +25,11 @@ #ifndef __OPENSPACE_CORE___TIMEMANAGER___H__ #define __OPENSPACE_CORE___TIMEMANAGER___H__ +#include +#include #include #include +#include "openspace/scene/profile.h" #include #include #include @@ -75,6 +78,22 @@ public: * Returns the current delta time, as affected by pause */ double deltaTime() const; + + /** + * Sets the simulation time using the time contents of a profile. The function will + * set either a relative or absolute time. + * + * \param p The Profile to be read. + */ + void setFromProfile_time(const Profile& p); + + /** + * Sets the delta times using the delta time array from a profile. + * + * \param p The Profile to be read. + */ + void setFromProfile_deltaTimes(const Profile& p); + bool isPaused() const; std::vector deltaTimeSteps() const; diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index c1d37797f2..c07331db27 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -333,7 +334,7 @@ void OpenSpaceEngine::initialize() { // Then save the profile to a scene so that we can load it with the // existing infrastructure - convertToSeparatedAssets(outputProfilePrefix, *global::profile); + //convertToSeparatedAssets(outputProfilePrefix, *global::profile); global::configuration->profileOutPrefixName = outputProfilePrefix; global::configuration->usingProfile = true; @@ -751,7 +752,9 @@ void OpenSpaceEngine::loadAsset_init(const std::string assetName) { } _assetManager->removeAll(); - _assetManager->add(assetName); + for (auto a : global::profile->assets) { + _assetManager->add(a); + } _loadingScreen->setPhase(LoadingScreen::Phase::Construction); _loadingScreen->postMessage("Loading assets"); @@ -1114,27 +1117,17 @@ void OpenSpaceEngine::preSynchronization() { _scheduledAssetPathToLoad.clear(); } else if (!_hasInitializedProfile) { - std::string combinedAssetInitStr; - loadInitAssetSection(combinedAssetInitStr, "_meta"); - loadInitAssetSection(combinedAssetInitStr, "_addedAssets"); - combinedAssetInitStr += "asset.onInitialize(function()\n"; - loadInitAssetSection(combinedAssetInitStr, "_modules"); - loadInitAssetSection(combinedAssetInitStr, "_actions"); - loadInitAssetSection(combinedAssetInitStr, "_keybinds"); - loadInitAssetSection(combinedAssetInitStr, "_time"); - loadInitAssetSection(combinedAssetInitStr, "_deltaTimes"); - loadInitAssetSection(combinedAssetInitStr, "_markNodes"); - loadInitAssetSection(combinedAssetInitStr, "_properties"); - loadInitAssetSection(combinedAssetInitStr, "_camera"); - combinedAssetInitStr += "end)\n"; - - std::string outputScenePath = absPath("${TEMPORARY}").string() + - "/combinedInit.asset"; - std::ofstream combinedInitAsset(outputScenePath); - combinedInitAsset << combinedAssetInitStr; - + std::string outputScenePath = absPath("${TEMPORARY}/initAsset.asset").string(); global::profile->ignoreUpdates = true; + global::renderEngine->scene()->createInitialAssetToLoad(*global::profile, + outputScenePath); loadAsset_init(outputScenePath); + global::renderEngine->scene()->setFromProfile_properties(*global::profile); + global::timeManager->setFromProfile_time(*global::profile); + global::timeManager->setFromProfile_deltaTimes(*global::profile); + global::navigationHandler->setFromProfile_camera(*global::profile); + global::actionManager->setFromProfile_actions(*global::profile); + global::keybindingManager->setFromProfile_keybindings(*global::profile); global::profile->ignoreUpdates = false; resetPropertyChangeFlagsOfSubowners(global::rootPropertyOwner); @@ -1187,8 +1180,16 @@ void OpenSpaceEngine::preSynchronization() { } if (!_hasInitializedProfile) { - std::string outputScenePath = absPath("${TEMPORARY}").string() + - "/combinedPostInit.asset"; + std::string output; + for (const std::string& a : global::profile->additionalScripts) { + global::scriptEngine->queueScript( + a, + scripting::ScriptEngine::RemoteScripting::Yes + ); + } + +/* std::string outputScenePath + = absPath("${TEMPORARY}/combinePostInit.asset").string(); std::ofstream combinedPostInitAsset(outputScenePath); std::string profilePostInitAsset = "asset.onInitialize(function()\n"; profilePostInitAsset += fmt::format( @@ -1201,6 +1202,7 @@ void OpenSpaceEngine::preSynchronization() { combinedPostInitAsset << profilePostInitAsset; loadAsset_postInit(outputScenePath); +*/ _hasInitializedProfile = true; } diff --git a/src/interaction/actionmanager.cpp b/src/interaction/actionmanager.cpp index e49c39eeb4..2b0ef58f09 100644 --- a/src/interaction/actionmanager.cpp +++ b/src/interaction/actionmanager.cpp @@ -24,14 +24,20 @@ #include +#include #include #include +#include #include #include #include #include "actionmanager_lua.inl" +namespace { + constexpr const char* _loggerCat = "ActionManager"; +} // namespace + namespace openspace::interaction { bool ActionManager::hasAction(const std::string& identifier) const { @@ -98,6 +104,37 @@ void ActionManager::triggerAction(const std::string& identifier, } } +void ActionManager::setFromProfile_actions(const Profile& p) +{ + for (Profile::Action a : p.actions) { + if (a.identifier.empty()) { + LERROR("Identifier must to provided to register action"); + } + if (hasAction(a.identifier)) { + LERROR(fmt::format("Action for identifier '{}' already existed & registered", + a.identifier)); + } + if (a.script.empty()) { + LERROR(fmt::format("Identifier '{}' doesn't provide a Lua command to execute", + a.identifier)); + } + interaction::Action action; + action.identifier = a.identifier; + action.command = a.script; + if (!a.name.empty()) { + action.name = a.name; + } + if (!a.documentation.empty()) { + action.documentation = a.documentation; + } + if (!a.guiPath.empty()) { + action.guiPath = a.guiPath; + } + action.synchronization = interaction::Action::IsSynchronized(a.isLocal); + registerAction(std::move(action)); + } +} + scripting::LuaLibrary ActionManager::luaLibrary() { return { "action", diff --git a/src/interaction/keybindingmanager.cpp b/src/interaction/keybindingmanager.cpp index 9532f41725..4299b1180b 100644 --- a/src/interaction/keybindingmanager.cpp +++ b/src/interaction/keybindingmanager.cpp @@ -35,6 +35,10 @@ #include "keybindingmanager_lua.inl" +namespace { + constexpr const char* _loggerCat = "KeyBindingManager"; +} // namespace + namespace openspace::interaction { KeybindingManager::KeybindingManager() @@ -138,6 +142,23 @@ std::string KeybindingManager::generateJson() const { return json.str(); } +void KeybindingManager::setFromProfile_keybindings(const Profile& p) +{ + for (Profile::Keybinding k : p.keybindings) { + if (k.action.empty()) { + LERROR("Action must not be empty"); + } + if (!global::actionManager->hasAction(k.action)) { + LERROR(fmt::format("Action '{}' does not exist", k.action)); + } + if (k.key.key == openspace::Key::Unknown) { + LERROR(fmt::format("Could not find key '{}'", + std::to_string(static_cast(k.key.key)))); + } + bindKey(k.key.key, k.key.modifier, k.action); + } +} + scripting::LuaLibrary KeybindingManager::luaLibrary() { return { "", diff --git a/src/navigation/navigationhandler.cpp b/src/navigation/navigationhandler.cpp index fcae0c1e47..2105021d9e 100644 --- a/src/navigation/navigationhandler.cpp +++ b/src/navigation/navigationhandler.cpp @@ -29,9 +29,11 @@ #include #include #include +#include #include #include #include +#include #include #include #include @@ -43,6 +45,10 @@ #include namespace { + // Helper structs for the visitor pattern of the std::variant + template struct overloaded : Ts... { using Ts::operator()...; }; + template overloaded(Ts...)->overloaded; + constexpr const char* _loggerCat = "NavigationHandler"; const double Epsilon = 1E-7; @@ -434,6 +440,48 @@ std::vector NavigationHandler::joystickButtonCommand(int button) co return _orbitalNavigator.joystickStates().buttonCommand(button); } +void NavigationHandler::setFromProfile_camera(const Profile& p) { + std::visit( + overloaded { + [this](const Profile::CameraNavState& navStateProfile) { + NavigationState nav; + nav.anchor = navStateProfile.anchor; + if (navStateProfile.aim.has_value()) { + nav.aim = navStateProfile.aim.value(); + } + if (nav.referenceFrame.empty()) { + nav.referenceFrame = "Root"; + } + nav.position = navStateProfile.position; + if (navStateProfile.up.has_value()) { + nav.up = navStateProfile.up; + } + if (navStateProfile.yaw.has_value()) { + nav.yaw = navStateProfile.yaw.value(); + } + if (navStateProfile.pitch.has_value()) { + nav.pitch = navStateProfile.pitch.value(); + } + _pendingNavigationState.reset(); + _pendingNavigationState = std::move(nav); + }, + [this](const Profile::CameraGoToGeo& geo) { + std::string geoScript = fmt::format("openspace.globebrowsing.goToGeo" + "([[{}]], {}, {}", geo.anchor, geo.latitude, geo.longitude); + if (geo.altitude.has_value()) { + geoScript += fmt::format(", {}", geo.altitude.value()); + } + geoScript += ")"; + global::scriptEngine->queueScript( + geoScript, + scripting::ScriptEngine::RemoteScripting::Yes + ); + } + }, + p.camera.value() + ); +} + scripting::LuaLibrary NavigationHandler::luaLibrary() { return { "navigation", diff --git a/src/scene/profile.cpp b/src/scene/profile.cpp index c28cbce3f0..ea2c94cc11 100644 --- a/src/scene/profile.cpp +++ b/src/scene/profile.cpp @@ -23,6 +23,7 @@ ****************************************************************************************/ #include +#include #include #include @@ -742,17 +743,17 @@ scripting::LuaLibrary Profile::luaLibrary() { } void convertToSeparatedAssets(const std::string filePre, const Profile& p) { - convertSectionToAssetFile(filePre, p, "_meta", convertToAsset_meta); - convertSectionToAssetFile(filePre, p, "_addedAssets", convertToAsset_addedAssets); - convertSectionToAssetFile(filePre, p, "_modules", convertToAsset_modules); - convertSectionToAssetFile(filePre, p, "_actions", convertToAsset_actions); - convertSectionToAssetFile(filePre, p, "_keybinds", convertToAsset_keybinds); - convertSectionToAssetFile(filePre, p, "_time", convertToAsset_time); - convertSectionToAssetFile(filePre, p, "_deltaTimes", convertToAsset_deltaTimes); - convertSectionToAssetFile(filePre, p, "_markNodes", convertToAsset_markNodes); - convertSectionToAssetFile(filePre, p, "_properties", convertToAsset_properties); - convertSectionToAssetFile(filePre, p, "_camera", convertToAsset_camera); - convertSectionToAssetFile(filePre, p, "_addedScripts", convertToAsset_addedScripts); + convertSectionToAssetFile(filePre, p, "meta", convertToAsset_meta); + convertSectionToAssetFile(filePre, p, "addedAssets", convertToAsset_addedAssets); + convertSectionToAssetFile(filePre, p, "modules", convertToAsset_modules); + convertSectionToAssetFile(filePre, p, "actions", convertToAsset_actions); + convertSectionToAssetFile(filePre, p, "keybinds", convertToAsset_keybinds); + convertSectionToAssetFile(filePre, p, "time", convertToAsset_time); + convertSectionToAssetFile(filePre, p, "deltaTimes", convertToAsset_deltaTimes); + convertSectionToAssetFile(filePre, p, "markNodes", convertToAsset_markNodes); + convertSectionToAssetFile(filePre, p, "properties", convertToAsset_properties); + convertSectionToAssetFile(filePre, p, "camera", convertToAsset_camera); + convertSectionToAssetFile(filePre, p, "addedScripts", convertToAsset_addedScripts); } void convertSectionToAssetFile(const std::string profilePrefix, const Profile& p, @@ -831,7 +832,7 @@ std::string convertToAsset_actions(const Profile& p) { for (const Profile::Action& action : p.actions) { const std::string name = action.name.empty() ? action.identifier : action.name; output += fmt::format( - " openspace.action.registerAction({{" + "openspace.action.registerAction({{" "Identifier=[[{}]], Command=[[{}]], Name=[[{}]], Documentation=[[{}]], " "GuiPath=[[{}]], IsLocal={}" "}})\n", @@ -850,7 +851,7 @@ std::string convertToAsset_keybinds(const Profile& p) { for (size_t i = 0; i < p.keybindings.size(); ++i) { const Profile::Keybinding& k = p.keybindings[i]; const std::string key = keyToString(k.key); - output += fmt::format(" openspace.bindKey([[{}]], [[{}]])\n", key, k.action); + output += fmt::format("openspace.bindKey([[{}]], [[{}]])\n", key, k.action); } return output; @@ -862,14 +863,14 @@ std::string convertToAsset_time(const Profile& p) { std::string output; switch (p.time->type) { case Profile::Time::Type::Absolute: - output += fmt::format(" openspace.time.setTime(\"{}\")\n", p.time->value); + output += fmt::format("openspace.time.setTime(\"{}\")\n", p.time->value); break; case Profile::Time::Type::Relative: - output += " local now = openspace.time.currentWallTime();\n"; + output += "local now = openspace.time.currentWallTime();\n"; output += fmt::format( - " local prev = openspace.time.advancedTime(now, \"{}\");\n", p.time->value + "local prev = openspace.time.advancedTime(now, \"{}\");\n", p.time->value ); - output += " openspace.time.setTime(prev);\n"; + output += "openspace.time.setTime(prev);\n"; break; default: throw ghoul::MissingCaseException(); @@ -887,7 +888,7 @@ std::string convertToAsset_deltaTimes(const Profile& p) { for (double d : p.deltaTimes) { times += fmt::format("{}, ", d); } - output += fmt::format(" openspace.time.setDeltaTimeSteps({{ {} }});\n", times); + output += fmt::format("openspace.time.setDeltaTimeSteps({{ {} }});\n", times); } return output; @@ -902,7 +903,7 @@ std::string convertToAsset_markNodes(const Profile& p) { for (const std::string& n : p.markNodes) { nodes += fmt::format("[[{}]],", n); } - output += fmt::format(" openspace.markInterestingNodes({{ {} }});\n", nodes); + output += fmt::format("openspace.markInterestingNodes({{ {} }});\n", nodes); } return output; @@ -916,12 +917,12 @@ std::string convertToAsset_properties(const Profile& p) { switch (prop.setType) { case Profile::Property::SetType::SetPropertyValue: output += fmt::format( - " openspace.setPropertyValue(\"{}\", {});\n", prop.name, prop.value + "openspace.setPropertyValue(\"{}\", {});\n", prop.name, prop.value ); break; case Profile::Property::SetType::SetPropertyValueSingle: output += fmt::format( - " openspace.setPropertyValueSingle(\"{}\", {});\n", + "openspace.setPropertyValueSingle(\"{}\", {});\n", prop.name, prop.value ); break; @@ -942,7 +943,7 @@ std::string convertToAsset_camera(const Profile& p) { overloaded { [](const Profile::CameraNavState& c) { std::string result; - result += " openspace.navigation.setNavigationState({"; + result += "openspace.navigation.setNavigationState({"; result += fmt::format("Anchor = [[{}]], ", c.anchor); if (c.aim.has_value()) { result += fmt::format("Aim = [[{}]], ", *c.aim); @@ -973,13 +974,13 @@ std::string convertToAsset_camera(const Profile& p) { [](const Profile::CameraGoToGeo& c) { if (c.altitude.has_value()) { return fmt::format( - " openspace.globebrowsing.goToGeo([[{}]], {}, {}, {});\n", + "openspace.globebrowsing.goToGeo([[{}]], {}, {}, {});\n", c.anchor, c.latitude, c.longitude, *c.altitude ); } else { return fmt::format( - " openspace.globebrowsing.goToGeo([[{}]], {}, {});\n", + "openspace.globebrowsing.goToGeo([[{}]], {}, {});\n", c.anchor, c.latitude, c.longitude ); } @@ -997,10 +998,14 @@ std::string convertToAsset_addedScripts(const Profile& p) { std::string output; for (const std::string& a : p.additionalScripts) { - output += fmt::format(" {}\n", a); + output += fmt::format("{}\n", a); } return output; } +std::vector& additionalScripts(Profile& p) { + return p.additionalScripts; +} + } // namespace openspace diff --git a/src/scene/scene.cpp b/src/scene/scene.cpp index 74fdc1def5..a21e3d688e 100644 --- a/src/scene/scene.cpp +++ b/src/scene/scene.cpp @@ -602,6 +602,86 @@ const std::vector& Scene::interestingTimes() const { return _interestingTimes; } +void Scene::createInitialAssetToLoad(const Profile& p, const std::string& assetFilename) +{ + std::ofstream converted(assetFilename); + std::string output; + //Meta + if (p.meta.has_value()) { + output += "asset.meta = {\n"; + + if (p.meta->name.has_value()) { + output += fmt::format(" Name = [[{}]],\n", *p.meta->name); + } + if (p.meta->version.has_value()) { + output += fmt::format(" Version = [[{}]],\n", *p.meta->version); + } + if (p.meta->description.has_value()) { + output += fmt::format(" Description = [[{}]],\n", *p.meta->description); + } + if (p.meta->author.has_value()) { + output += fmt::format(" Author = [[{}]],\n", *p.meta->author); + } + if (p.meta->url.has_value()) { + output += fmt::format(" URL = [[{}]],\n", *p.meta->url); + } + if (p.meta->license.has_value()) { + output += fmt::format(" License = [[{}]]\n", *p.meta->license); + } + + output += "}\n\n"; + } + + // Assets + for (const std::string& asset : p.assets) { + output += fmt::format("asset.require(\"{}\");\n", asset); + } + + converted << output; +} + +void Scene::setFromProfile_properties(const Profile& p) { + ghoul::lua::LuaState L(ghoul::lua::LuaState::IncludeStandardLibrary::Yes); + + for (const Profile::Property& prop : p.properties) { + std::string uriOrRegex = prop.name; + std::string groupName; + if (doesUriContainGroupTag(uriOrRegex, groupName)) { + // Remove group name from start of regex and replace with '*' + uriOrRegex = removeGroupNameFromUri(uriOrRegex); + } + ghoul::lua::push(L, uriOrRegex); + ghoul::lua::push(L, 0.0); + // Later functions expect the value to be at the last position on the stack + property_pushValueFromProfileToLuaState(L, prop.value); + + applyRegularExpression( + L, + uriOrRegex, + allProperties(), + 0.0, + groupName, + ghoul::EasingFunction::Linear + ); + //Clear lua state stack + lua_settop(L, 0); + } +} + +void Scene::property_pushValueFromProfileToLuaState(ghoul::lua::LuaState& L, + const std::string& value) +{ + if (!luascriptfunctions::convertStringToLuaAndPush_bool(L, value)) { + if (!luascriptfunctions::convertStringToLuaAndPush_float(L, value)) { + std::string stringRepresentation = value; + if (value.compare("nil") != 0) { + stringRepresentation = "[[" + stringRepresentation + "]]"; + } + ghoul::lua::push(L, stringRepresentation); + } + } +} + scripting::LuaLibrary Scene::luaLibrary() { return { "", diff --git a/src/scene/scene_lua.inl b/src/scene/scene_lua.inl index e685a23370..e85489cb09 100644 --- a/src/scene/scene_lua.inl +++ b/src/scene/scene_lua.inl @@ -26,8 +26,11 @@ #include #include #include +#include +#include #include #include +#include namespace openspace { @@ -972,4 +975,41 @@ int worldRotation(lua_State* L) { return 1; } +/** + * \ingroup LuaScripts + * convertStringToLuaAndPush_bool(lua_State*, string): + * Used to convert a string value from a text file (e.g. profile) to a lua bool type. + * If string value is a bool, the value gets pushed to the lua_State, and returns true. + * If string value is not a bool, the lua_State is unchanged and returns false. + */ +bool convertStringToLuaAndPush_bool(lua_State* L, std::string s) { + if (s.compare("true") == 0) { + ghoul::lua::push(L, true); + return true; + } + else if (s.compare("false") == 0) { + ghoul::lua::push(L, false); + return true; + } + return false; +} + +/** + * \ingroup LuaScripts + * convertStringToLuaAndPush_float(lua_State*, string): + * Used to convert a string value from a text file (e.g. profile) to a lua float type. + * If string value is a float, the value gets pushed to the lua_State, and returns true. + * If string value is not a float, the lua_State is unchanged and returns false. + */ +bool convertStringToLuaAndPush_float(lua_State* L, std::string s) { + try { + float converted = std::stof(s); + ghoul::lua::push(L, converted); + return true; + } + catch (...) { + return false; + } +} + } // namespace openspace::luascriptfunctions diff --git a/src/util/time.cpp b/src/util/time.cpp index 84bbe09594..cbdb353bf5 100644 --- a/src/util/time.cpp +++ b/src/util/time.cpp @@ -25,6 +25,7 @@ #include #include +#include #include #include #include @@ -121,6 +122,22 @@ void Time::ISO8601(char* buffer) const { SpiceManager::ref().dateFromEphemerisTime(_time, buffer, S, Format); } +void Time::setFromProfile_timeRelative(const std::string& setTime) { + ghoul::lua::LuaState L(ghoul::lua::LuaState::IncludeStandardLibrary::Yes); + + luascriptfunctions::time_currentWallTime(L); + ghoul::lua::push(L, setTime); + luascriptfunctions::time_advancedTime(L); + luascriptfunctions::time_setTime(L); +} + +void Time::setFromProfile_timeAbsolute(const std::string& setTime) { + ghoul::lua::LuaState L(ghoul::lua::LuaState::IncludeStandardLibrary::Yes); + + ghoul::lua::push(L, setTime); + luascriptfunctions::time_setTime(L); +} + scripting::LuaLibrary Time::luaLibrary() { return { "time", diff --git a/src/util/timemanager.cpp b/src/util/timemanager.cpp index a6781be9e2..bee80c4db2 100644 --- a/src/util/timemanager.cpp +++ b/src/util/timemanager.cpp @@ -868,4 +868,19 @@ double TimeManager::previousApplicationTimeForInterpolation() const { return _previousApplicationTime; } +void TimeManager::setFromProfile_time(const Profile& p) { + Time t; + + if (p.time->type == Profile::Time::Type::Relative) { + t.setFromProfile_timeRelative(p.time->value); + } + else if (p.time->type == Profile::Time::Type::Absolute) { + t.setFromProfile_timeAbsolute(p.time->value); + } +} + +void TimeManager::setFromProfile_deltaTimes(const Profile& p) { + global::timeManager->setDeltaTimeSteps(p.deltaTimes); +} + } // namespace openspace