diff --git a/include/openspace/scene/profile.h b/include/openspace/scene/profile.h index e53612d004..e42705d56f 100644 --- a/include/openspace/scene/profile.h +++ b/include/openspace/scene/profile.h @@ -157,19 +157,6 @@ public: */ void saveCurrentSettingsToProfile(); - /** - * Saves all current settings, starting from the profile that was loaded at startup, - * and all of the property & asset changes that were made since startup. - * \param filename The filename of the new profile to be saved - */ - void saveCurrentSettingsToProfile(const std::string& filename); - - /** - * Saves all current settings, similar to saveCurrentSettingsToProfile() except the - * output is a string without writing to a file. - */ - //std::string saveCurrentSettingsToProfile_string(); - /** * Returns the Lua library that contains all Lua functions available to provide * profile functionality. @@ -196,8 +183,6 @@ private: void modifyPropertiesToReflectChanges(ProfileData& ps); virtual std::vector changedProperties(); - std::string getFullPropertyPath(openspace::properties::Property* prop); - virtual std::string currentTimeUTC() const; virtual interaction::NavigationHandler::NavigationState currentCameraState() const; }; diff --git a/src/scene/profile.cpp b/src/scene/profile.cpp index 9e35028223..4faa969b58 100644 --- a/src/scene/profile.cpp +++ b/src/scene/profile.cpp @@ -446,7 +446,7 @@ void Profile::saveCurrentSettingsToProfile() { // add current time to profile file ProfileData::Time time; - time.time = currentTimeUTC(); + time.time = global::timeManager.time().ISO8601(); time.type = ProfileData::Time::Type::Absolute; profile.time = std::move(time); @@ -472,58 +472,6 @@ void Profile::saveCurrentSettingsToProfile() { profile.camera = std::move(camera); } -void Profile::saveCurrentSettingsToProfile(const std::string& filename) { - //std::string initProfile = initialProfile(); - //std::string inputProfilePath = absPath(_profileBaseDirectory) + "/" + initProfile - // + ".profile"; - //ProfileData ps = readFromFile(inputProfilePath); - - saveCurrentSettingsToProfile(); - - - if (filename.find('/') != std::string::npos) { - LERROR("Profile filename must not contain path (/) elements"); - return; - } - else if (filename.find(':') != std::string::npos) { - LERROR("Profile filename must not contain path (:) elements"); - return; - } - else if (filename.find('.') != std::string::npos) { - LERROR("Only provide the filename to save without file extension"); - return; - } - const std::string absFilename = absPath("${ASSETS}/" + filename + ".profile"); - - if (FileSys.fileExists(absFilename)) { - LERROR(fmt::format( - "Unable to save profile '{}'. File of same name already exists.", - absFilename.c_str() - )); - return; - } - - std::ofstream outFile; - // @TODO (abock, 2020-06-15) Replace with non-throwing stream - try { - outFile.open(absFilename, std::ofstream::out); - } - catch (const std::ofstream::failure& e) { - LERROR(fmt::format( - "Exception opening profile file for write: {} ({})", absFilename, e.what() - )); - } - - try { - outFile << serialize(profile); - } - catch (const std::ofstream::failure& e) { - LERROR(fmt::format("Data write error to file: {} ({})", absFilename, e.what())); - } - - outFile.close(); -} - std::string Profile::initialProfile() const { return global::configuration.profile; } @@ -579,16 +527,12 @@ void Profile::modifyPropertiesToReflectChanges(ProfileData& ps) { for (properties::Property* prop : changedProps) { ProfileData::Property p; p.setType = ProfileData::Property::SetType::SetPropertyValueSingle; - p.name = getFullPropertyPath(prop); + p.name = recurseForFullName(prop->owner()) + prop->identifier(); p.value = prop->getStringValue(); ps.properties.push_back(std::move(p)); } } -std::string Profile::getFullPropertyPath(properties::Property* prop) { - return recurseForFullName(prop->owner()) + prop->identifier(); -} - std::vector Profile::changedProperties() { ZoneScoped @@ -602,10 +546,6 @@ std::vector Profile::changedProperties() { return changedProps; } -std::string Profile::currentTimeUTC() const { - return global::timeManager.time().ISO8601(); -} - interaction::NavigationHandler::NavigationState Profile::currentCameraState() const { return global::navigationHandler.navigationState(); } @@ -642,17 +582,19 @@ scripting::LuaLibrary Profile::luaLibrary() { "", { { - "saveCurrentSettingsToProfile", - &luascriptfunctions::saveCurrentSettingsToProfile, + "saveSettingsToProfile", + &luascriptfunctions::saveSettingsToProfile, {}, - "string", + "[string, bool]", "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." + "and the new saved file will contain all of this information. If the " + "arugment is provided, the settings will be saved into new profile with " + "that name. If the argument is blank, the current profile will be saved " + "to a backup file and the original profile will be overwritten. The " + "second argument determines if a file that already exists should be " + "overwritten, which is 'false' by default" } } }; diff --git a/src/scene/profile_lua.inl b/src/scene/profile_lua.inl index 8fc8759695..e66986380d 100644 --- a/src/scene/profile_lua.inl +++ b/src/scene/profile_lua.inl @@ -24,10 +24,11 @@ #include #include +#include namespace openspace::luascriptfunctions { -int saveCurrentSettingsToProfile(lua_State* L) { +int saveSettingsToProfile(lua_State* L) { if (!global::configuration.usingProfile) { return luaL_error( L, @@ -38,11 +39,11 @@ int saveCurrentSettingsToProfile(lua_State* L) { const int n = ghoul::lua::checkArgumentsAndThrow( L, - { 0, 1 }, - "lua::saveCurrentSettingsToProfile" + { 0, 2 }, + "lua::saveSettingsToProfile" ); - using ghoul::lua::luaTypeToString; + LINFOC("1", ghoul::lua::stackInformation(L)); std::string saveFilePath; if (n == 0) { @@ -61,22 +62,78 @@ int saveCurrentSettingsToProfile(lua_State* L) { utcTime->tm_min, utcTime->tm_sec ); - saveFilePath = fmt::format("{}_{}.{}", f.fullBaseName(), time, f.fileExtension()); + std::string newFile = fmt::format( + "{}_{}.{}", + f.fullBaseName(), time, f.fileExtension() + ); + std::filesystem::copy(global::configuration.profile, newFile); + saveFilePath = global::configuration.profile; } else { - saveFilePath = ghoul::lua::value( - L, - 1, - ghoul::lua::PopValue::Yes - ); + saveFilePath = ghoul::lua::value(L, 1); + LINFOC("2", ghoul::lua::stackInformation(L)); if (saveFilePath.empty()) { return luaL_error(L, "save filepath string is empty"); } } - global::profile.saveCurrentSettingsToProfile(saveFilePath); + global::profile.saveCurrentSettingsToProfile(); + global::configuration.profile = saveFilePath; - ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack"); + if (saveFilePath.find('/') != std::string::npos) { + return luaL_error(L, "Profile filename must not contain path (/) elements"); + } + else if (saveFilePath.find(':') != std::string::npos) { + return luaL_error(L, "Profile filename must not contain path (:) elements"); + } + else if (saveFilePath.find('.') != std::string::npos) { + return luaL_error(L, "Only provide the filename to save without file extension"); + } + const std::string absFilename = absPath("${ASSETS}/" + saveFilePath + ".profile"); + + const bool overwrite = (n == 2) ? ghoul::lua::value< bool>(L, 2) : false; + LINFOC("3", ghoul::lua::stackInformation(L)); + + if (FileSys.fileExists(absFilename) && !overwrite) { + return luaL_error( + L, + fmt::format( + "Unable to save profile '{}'. File of same name already exists.", + absFilename.c_str() + ).c_str() + ); + } + + std::ofstream outFile; + // @TODO (abock, 2020-06-15) Replace with non-throwing stream + try { + outFile.open(absFilename, std::ofstream::out); + } + catch (const std::ofstream::failure& e) { + return luaL_error( + L, + fmt::format( + "Exception opening profile file for write: {} ({})", absFilename, e.what() + ).c_str() + ); + } + + try { + outFile << serialize(global::profile.profile); + } + catch (const std::ofstream::failure& e) { + return luaL_error( + L, + fmt::format( + "Data write error to file: {} ({})", + absFilename, e.what() + ).c_str() + ); + } + + outFile.close(); + + lua_settop(L, 0); return 0; }