From 0149162fbe5ffb450376431e104bdec6b777ce25 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sat, 23 Dec 2017 17:32:28 +0100 Subject: [PATCH] Move deinitialization of Assets from OpenSpaceEngine::destroy into OpenSpaceEngine::deinitialize as some of its components might be needed in the asset's deinitialization (like MissionManager) Add function to unload Mission file --- .../missions/newhorizons/newhorizons.asset | 5 +- .../missions/osirisrex/osirisrex.asset | 6 +- include/openspace/mission/missionmanager.h | 12 +++- src/engine/openspaceengine.cpp | 6 +- src/mission/missionmanager.cpp | 29 +++++++++- src/mission/missionmanager_lua.inl | 55 ++++++++++++++++--- 6 files changed, 95 insertions(+), 18 deletions(-) diff --git a/data/assets/scene/solarsystem/missions/newhorizons/newhorizons.asset b/data/assets/scene/solarsystem/missions/newhorizons/newhorizons.asset index a2e4bb03af..7b75da93e1 100644 --- a/data/assets/scene/solarsystem/missions/newhorizons/newhorizons.asset +++ b/data/assets/scene/solarsystem/missions/newhorizons/newhorizons.asset @@ -11,11 +11,12 @@ asset.request('./styx') local mission = asset.localResource("newhorizons.mission") +local missionName asset.onInitialize(function() - openspace.loadMission(mission) + missionName = openspace.loadMission(mission) end) asset.onDeinitialize(function() - -- openspace.unloadMission() + openspace.unloadMission(missionName) end) diff --git a/data/assets/scene/solarsystem/missions/osirisrex/osirisrex.asset b/data/assets/scene/solarsystem/missions/osirisrex/osirisrex.asset index 9083e27e50..6d5bff9427 100644 --- a/data/assets/scene/solarsystem/missions/osirisrex/osirisrex.asset +++ b/data/assets/scene/solarsystem/missions/osirisrex/osirisrex.asset @@ -5,14 +5,16 @@ asset.request('./trail') local mission = asset.localResource('osirisrex.mission') +local missionName + local scriptSchedule = asset.localResource("scheduled_scripts.lua") asset.onInitialize(function() - openspace.loadMission(mission) + missionName = openspace.loadMission(mission) openspace.scriptScheduler.loadFile(scriptSchedule) end) asset.onDeinitialize(function() - -- openspace.unloadMission() + openspace.unloadMission(missionName) -- openspace.scriptScheduler.unloadFile end) diff --git a/include/openspace/mission/missionmanager.h b/include/openspace/mission/missionmanager.h index 06dae81df3..e2c935daae 100644 --- a/include/openspace/mission/missionmanager.h +++ b/include/openspace/mission/missionmanager.h @@ -52,11 +52,21 @@ public: * Reads a mission from file and maps the mission name to the Mission object. If * this is the first mission to be loaded, the mission will also be set as the * current active mission. + * \param filename The file that contains the mission that is to be loaded + * \return The name of the mission that was loaded * \pre \p filename must not be empty * \pre \p filename must not contain tokens * \pre \p filename must exist */ - void loadMission(const std::string& filename); + std::string loadMission(const std::string& filename); + + /** + * Unloads a previously loaded mission identified by the provided \p missionName. + * \param missionName The name of the mission that should be unloded + * \pre \p filename must not be empty + * \pre \p missionName must be a valid mission that has previously been loaded + */ + void unloadMission(const std::string& missionName); /** * Returns whether the provided \p missionName has previously been added to the diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index 2beb9f3d3b..e265df8b3f 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -450,9 +450,6 @@ void OpenSpaceEngine::destroy() { _engine->parallelConnection().signalDisconnect(); } - _engine->assetManager().deinitialize(); - _engine->_scene = nullptr; - _engine->_syncEngine->removeSyncables(_engine->timeManager().getSyncables()); _engine->_syncEngine->removeSyncables(_engine->_renderEngine->getSyncables()); @@ -773,6 +770,9 @@ void OpenSpaceEngine::deinitialize() { for (const auto& func : _engine->_moduleCallbacks.deinitialize) { func(); } + + _engine->assetManager().deinitialize(); + _engine->_scene = nullptr; _navigationHandler->deinitialize(); _renderEngine->deinitialize(); diff --git a/src/mission/missionmanager.cpp b/src/mission/missionmanager.cpp index 17051aa68a..31acf85b9c 100644 --- a/src/mission/missionmanager.cpp +++ b/src/mission/missionmanager.cpp @@ -57,7 +57,7 @@ bool MissionManager::hasCurrentMission() const { return _currentMission != _missionMap.end(); } -void MissionManager::loadMission(const std::string& filename) { +std::string MissionManager::loadMission(const std::string& filename) { ghoul_assert(!filename.empty(), "filename must not be empty"); ghoul_assert(!FileSys.containsToken(filename), "filename must not contain tokens"); ghoul_assert(FileSys.fileExists(filename), "filename " + filename + " must exist"); @@ -75,6 +75,19 @@ void MissionManager::loadMission(const std::string& filename) { if (!currentMission.empty()) { setCurrentMission(currentMission); } + + return missionName; +} + +void MissionManager::unloadMission(const std::string& missionName) { + ghoul_assert(!missionName.empty(), "missionName must not be empty"); + auto it = _missionMap.find(missionName); + ghoul_assert( + it != _missionMap.end(), + "missionName must name a previously loaded mission" + ); + + _missionMap.erase(it); } bool MissionManager::hasMission(const std::string& missionName) { @@ -99,6 +112,20 @@ scripting::LuaLibrary MissionManager::luaLibrary() { "string", "Load mission phases from file" }, + { + "unloadMission", + &luascriptfunctions::unloadMission, + {}, + "string", + "Unloads a previously loaded mission" + }, + { + "hasMission", + &luascriptfunctions::hasMission, + {}, + "string", + "Returns whether a mission with the provided name has been loaded" + }, { "setCurrentMission", &luascriptfunctions::setCurrentMission, diff --git a/src/mission/missionmanager_lua.inl b/src/mission/missionmanager_lua.inl index f48edf31df..3cf0e64d1f 100644 --- a/src/mission/missionmanager_lua.inl +++ b/src/mission/missionmanager_lua.inl @@ -25,28 +25,65 @@ namespace openspace::luascriptfunctions { int loadMission(lua_State* L) { - using ghoul::lua::luaTypeToString; int nArguments = lua_gettop(L); - if (nArguments != 1) + if (nArguments != 1) { return luaL_error(L, "Expected %i arguments, got %i", 1, nArguments); + } std::string missionFileName = luaL_checkstring(L, -1); if (missionFileName.empty()) { - return luaL_error(L, "filepath string is empty"); + return luaL_error(L, "Filepath is empty"); } - MissionManager::ref().loadMission(absPath(missionFileName)); - return 0; + std::string name = MissionManager::ref().loadMission(absPath(missionFileName)); + lua_pushstring(L, name.c_str()); + return 1; } -int setCurrentMission(lua_State* L) { - using ghoul::lua::luaTypeToString; +int unloadMission(lua_State* L) { int nArguments = lua_gettop(L); - if (nArguments != 1) + if (nArguments != 1) { return luaL_error(L, "Expected %i arguments, got %i", 1, nArguments); + } std::string missionName = luaL_checkstring(L, -1); if (missionName.empty()) { - return luaL_error(L, "mission name string is empty"); + return luaL_error(L, "Missing name is empty"); + } + + if (!MissionManager::ref().hasMission(missionName)) { + return luaL_error(L, "Mission was not previously loaded"); + } + + MissionManager::ref().unloadMission(missionName); + return 0; +} + +int hasMission(lua_State* L) { + int nArguments = lua_gettop(L); + if (nArguments != 1) { + return luaL_error(L, "Expected %i arguments, got %i", 1, nArguments); + } + + std::string missionName = luaL_checkstring(L, -1); + if (missionName.empty()) { + return luaL_error(L, "Missing name is empty"); + } + + bool hasMission = MissionManager::ref().hasMission(missionName); + + lua_pushboolean(L, hasMission); + return 1; +} + +int setCurrentMission(lua_State* L) { + int nArguments = lua_gettop(L); + if (nArguments != 1) { + return luaL_error(L, "Expected %i arguments, got %i", 1, nArguments); + } + + std::string missionName = luaL_checkstring(L, -1); + if (missionName.empty()) { + return luaL_error(L, "Mission name is empty"); } MissionManager::ref().setCurrentMission(missionName); return 0;