diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2fa18acc..f70489ab 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -145,6 +145,8 @@ set(BASE_SOURCES app/controller.h app/input.cpp app/input.h + app/modman.cpp + app/modman.h app/pathman.cpp app/pathman.h app/pausemanager.cpp diff --git a/src/app/app.cpp b/src/app/app.cpp index d0cb9692..2bb6a805 100644 --- a/src/app/app.cpp +++ b/src/app/app.cpp @@ -21,6 +21,7 @@ #include "app/controller.h" #include "app/input.h" +#include "app/modman.h" #include "app/pathman.h" #include "common/config_file.h" @@ -113,7 +114,8 @@ CApplication::CApplication(CSystemUtils* systemUtils) m_private(MakeUnique()), m_configFile(MakeUnique()), m_input(MakeUnique()), - m_pathManager(MakeUnique(systemUtils)) + m_pathManager(MakeUnique(systemUtils)), + m_modManager(MakeUnique(this, m_pathManager.get())) { m_exitCode = 0; m_active = false; @@ -220,6 +222,11 @@ CSoundInterface* CApplication::GetSound() return m_sound.get(); } +CModManager* CApplication::GetModManager() +{ + return m_modManager.get(); +} + void CApplication::LoadEnvironmentVariables() { auto dataDir = m_systemUtils->GetEnvVar("COLOBOT_DATA_DIR"); @@ -513,6 +520,8 @@ bool CApplication::Create() GetLogger()->Warn("Config could not be loaded. Default values will be used!\n"); } + m_modManager->ReinitMods(); + // Create the sound instance. #ifdef OPENAL_SOUND if (!m_headless) @@ -698,21 +707,7 @@ bool CApplication::Create() // Create the robot application. m_controller = MakeUnique(); - CThread musicLoadThread([this]() - { - GetLogger()->Debug("Cache sounds...\n"); - SystemTimeStamp* musicLoadStart = m_systemUtils->CreateTimeStamp(); - m_systemUtils->GetCurrentTimeStamp(musicLoadStart); - - m_sound->CacheAll(); - - SystemTimeStamp* musicLoadEnd = m_systemUtils->CreateTimeStamp(); - m_systemUtils->GetCurrentTimeStamp(musicLoadEnd); - float musicLoadTime = m_systemUtils->TimeStampDiff(musicLoadStart, musicLoadEnd, STU_MSEC); - GetLogger()->Debug("Sound loading took %.2f ms\n", musicLoadTime); - }, - "Sound loading thread"); - musicLoadThread.Start(); + StartLoadingMusic(); if (m_runSceneCategory == LevelCategory::Max) m_controller->StartApp(); @@ -726,22 +721,11 @@ bool CApplication::Create() return true; } -void CApplication::Reload() +void CApplication::ReloadResources() { - m_sound->Create(); + GetLogger()->Info("Reloading resources\n"); m_engine->ReloadAllTextures(); - CThread musicLoadThread([this]() - { - SystemTimeStamp* musicLoadStart = m_systemUtils->CreateTimeStamp(); - m_systemUtils->GetCurrentTimeStamp(musicLoadStart); - m_sound->CacheAll(); - SystemTimeStamp* musicLoadEnd = m_systemUtils->CreateTimeStamp(); - m_systemUtils->GetCurrentTimeStamp(musicLoadEnd); - float musicLoadTime = m_systemUtils->TimeStampDiff(musicLoadStart, musicLoadEnd, STU_MSEC); - GetLogger()->Debug("Sound loading took %.2f ms\n", musicLoadTime); - }, - "Sound loading thread"); - musicLoadThread.Start(); + StartLoadingMusic(); m_controller->GetRobotMain()->UpdateCustomLevelList(); } @@ -1559,6 +1543,24 @@ void CApplication::InternalResumeSimulation() m_absTimeBase = m_exactAbsTime; } +void CApplication::StartLoadingMusic() +{ + CThread musicLoadThread([this]() + { + GetLogger()->Debug("Cache sounds...\n"); + SystemTimeStamp* musicLoadStart = m_systemUtils->CreateTimeStamp(); + m_systemUtils->GetCurrentTimeStamp(musicLoadStart); + + m_sound->CacheAll(); + + SystemTimeStamp* musicLoadEnd = m_systemUtils->CreateTimeStamp(); + m_systemUtils->GetCurrentTimeStamp(musicLoadEnd); + float musicLoadTime = m_systemUtils->TimeStampDiff(musicLoadStart, musicLoadEnd, STU_MSEC); + GetLogger()->Debug("Sound loading took %.2f ms\n", musicLoadTime); + }, "Sound loading thread"); + musicLoadThread.Start(); +} + bool CApplication::GetSimulationSuspended() const { return m_simulationSuspended; diff --git a/src/app/app.h b/src/app/app.h index c45e6320..af385cf2 100644 --- a/src/app/app.h +++ b/src/app/app.h @@ -42,6 +42,7 @@ class CEventQueue; class CController; class CSoundInterface; class CInput; +class CModManager; class CPathManager; class CConfigFile; class CSystemUtils; @@ -162,6 +163,8 @@ public: CEventQueue* GetEventQueue(); //! Returns the sound subsystem CSoundInterface* GetSound(); + //! Returns the mod manager + CModManager* GetModManager(); public: //! Loads some data from environment variables @@ -170,8 +173,8 @@ public: ParseArgsStatus ParseArguments(int argc, char *argv[]); //! Initializes the application bool Create(); - //! Reloads the application - void Reload(); + //! Reloads the application resources, e.g. mods + void ReloadResources(); //! Main event loop int Run(); //! Returns the code to be returned at main() exit @@ -303,6 +306,9 @@ protected: //! Internal procedure to reset time counters void InternalResumeSimulation(); + //! Loads music in a new thread + void StartLoadingMusic(); + protected: //! System utils instance CSystemUtils* m_systemUtils; @@ -324,6 +330,8 @@ protected: std::unique_ptr m_input; //! Path manager std::unique_ptr m_pathManager; + //! Mod manager + std::unique_ptr m_modManager; //! Code to return at exit int m_exitCode; diff --git a/src/app/modman.cpp b/src/app/modman.cpp new file mode 100644 index 00000000..e86edb5f --- /dev/null +++ b/src/app/modman.cpp @@ -0,0 +1,117 @@ +/* + * This file is part of the Colobot: Gold Edition source code + * Copyright (C) 2001-2020, Daniel Roux, EPSITEC SA & TerranovaTeam + * http://epsitec.ch; http://colobot.info; http://github.com/colobot + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://gnu.org/licenses + */ + +#include "modman.h" + +//TODO: clean up includes +#include "common/config.h" + +#include "app/app.h" +#include "app/pathman.h" + +#include "common/restext.h" +#include "common/logger.h" +#include "common/settings.h" +#include "common/stringutils.h" + +#include "common/resources/resourcemanager.h" + +#include "common/system/system.h" + +#include +#include +#include + +using namespace boost::filesystem; + +CModManager::CModManager(CApplication* app, CPathManager* pathManager) + : m_app{app}, + m_pathManager{pathManager} +{ +} + +void CModManager::ReinitMods() +{ + m_mods.clear(); + const auto foundMods = m_pathManager->FindMods(); + for (const auto& modPath : foundMods) + { + Mod mod; + mod.name = boost::filesystem::path(modPath).stem().string(); + mod.path = modPath; + mod.enabled = m_pathManager->ModLoaded(mod.path); //TODO: load from some config file + m_mods.push_back(mod); + } +} + +void CModManager::EnableMod(const std::string& modName) +{ + Mod* mod = FindMod(modName); + if (!mod) + { + GetLogger()->Error("Could not enable mod: %s not found\n", modName.c_str()); + return; + } + mod->enabled = true; +} + +void CModManager::DisableMod(const std::string& modName) +{ + Mod* mod = FindMod(modName); + if (!mod) + { + GetLogger()->Error("Could not disable mod: %s not found\n", modName.c_str()); + return; + } + mod->enabled = false; +} + +void CModManager::ReloadMods() +{ + for (const auto& mod : m_mods) + { + bool loaded = m_pathManager->ModLoaded(mod.path); + if (mod.enabled && !loaded) + { + m_pathManager->AddMod(mod.path); + } + else if (!mod.enabled && loaded) + { + m_pathManager->RemoveMod(mod.path); + } + } + m_app->ReloadResources(); +} + +boost::optional CModManager::GetMod(const std::string& modName) +{ + Mod* mod = FindMod(modName); + return mod != nullptr ? *mod : boost::optional(); +} + +const std::vector& CModManager::GetMods() const +{ + return m_mods; +} + +Mod* CModManager::FindMod(const std::string& modName) +{ + auto it = std::find_if(m_mods.begin(), m_mods.end(), [&](Mod& mod) { return mod.name == modName; }); + return it != m_mods.end() ? &(*it) : nullptr; +} diff --git a/src/app/modman.h b/src/app/modman.h new file mode 100644 index 00000000..e1a47467 --- /dev/null +++ b/src/app/modman.h @@ -0,0 +1,75 @@ +/* + * This file is part of the Colobot: Gold Edition source code + * Copyright (C) 2001-2020, Daniel Roux, EPSITEC SA & TerranovaTeam + * http://epsitec.ch; http://colobot.info; http://github.com/colobot + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://gnu.org/licenses + */ + +#pragma once + +#include "ui/maindialog.h" + +#include "ui/screen/screen_setup.h" + +#include +#include + +class CPathManager; + +struct Mod +{ + std::string name; + std::string path; + bool enabled = false; + //TODO: add metadata for UI +}; + +/** + * \class CApplication + * \brief Main application + * + * This class handles the list of currently loaded mods. + * + */ +class CModManager +{ +public: + CModManager(CApplication* app, CPathManager* pathManager); + + //! Finds all the mods along with their metadata + void ReinitMods(); + + //! Removes a mod from the list of loaded mods + void EnableMod(const std::string& modName); + + //! Adds a mod to the list of loaded mods + void DisableMod(const std::string& modName); + + //! Reloads application resources so the enabled mods are applied + void ReloadMods(); + + boost::optional GetMod(const std::string& modName); + const std::vector& GetMods() const; + +private: + Mod* FindMod(const std::string& modName); + +private: + CApplication* m_app; + CPathManager* m_pathManager; + + //TODO: better data structure? + std::vector m_mods; +}; diff --git a/src/app/pathman.cpp b/src/app/pathman.cpp index d007b0fd..4c4a1a71 100644 --- a/src/app/pathman.cpp +++ b/src/app/pathman.cpp @@ -41,8 +41,7 @@ CPathManager::CPathManager(CSystemUtils* systemUtils) : m_dataPath(systemUtils->GetDataPath()) , m_langPath(systemUtils->GetLangPath()) , m_savePath(systemUtils->GetSaveDir()) - , m_modAutoloadDir{} - , m_mods{} + , m_modSearchDirs{} { } @@ -65,35 +64,41 @@ void CPathManager::SetSavePath(const std::string &savePath) m_savePath = savePath; } -void CPathManager::AddModAutoloadDir(const std::string &modAutoloadDirPath) +void CPathManager::AddModSearchDir(const std::string &modSearchDirPath) { - m_modAutoloadDir.push_back(modAutoloadDirPath); + m_modSearchDirs.push_back(modSearchDirPath); } void CPathManager::AddMod(const std::string &modPath) { - std::string::size_type enabled; - enabled = modPath.find('~'); - if (enabled == std::string::npos) - { - GetLogger()->Info("Loading mod: '%s'\n", modPath.c_str()); - CResourceManager::AddLocation(modPath, true); - } - else - { - GetLogger()->Info("Found excluded mod: '%s'\n", modPath.c_str()); - } + GetLogger()->Info("Loading mod: '%s'\n", modPath.c_str()); + CResourceManager::AddLocation(modPath, true); } void CPathManager::RemoveMod(const std::string &modPath) { - std::string::size_type enabled; - enabled = modPath.find('~'); - if (enabled == std::string::npos) + GetLogger()->Info("Unloading mod: '%s'\n", modPath.c_str()); + CResourceManager::RemoveLocation(modPath); +} + +bool CPathManager::ModLoaded(const std::string& modPath) +{ + return CResourceManager::LocationExists(modPath); +} + +std::vector CPathManager::FindMods() const +{ + std::vector mods; + GetLogger()->Info("Found mods:\n"); + for (const auto &searchPath : m_modSearchDirs) { - GetLogger()->Info("Unloading mod: '%s'\n", modPath.c_str()); - CResourceManager::RemoveLocation(modPath); + for (const auto &modPath : FindModsInDir(searchPath)) + { + GetLogger()->Info(" * %s\n", modPath.c_str()); + mods.push_back(modPath); + } } + return mods; } const std::string& CPathManager::GetDataPath() @@ -152,58 +157,18 @@ void CPathManager::InitPaths() GetLogger()->Info("Data path: %s\n", m_dataPath.c_str()); GetLogger()->Info("Save path: %s\n", m_savePath.c_str()); - m_modAutoloadDir.push_back(m_dataPath + "/mods"); - m_modAutoloadDir.push_back(m_savePath + "/mods"); + m_modSearchDirs.push_back(m_dataPath + "/mods"); + m_modSearchDirs.push_back(m_savePath + "/mods"); - if (!m_modAutoloadDir.empty()) + if (!m_modSearchDirs.empty()) { - GetLogger()->Info("Mod autoload dirs:\n"); - for(const std::string& modAutoloadDir : m_modAutoloadDir) - GetLogger()->Info(" * %s\n", modAutoloadDir.c_str()); - } - if (!m_mods.empty()) - { - GetLogger()->Info("Mods:\n"); - for(const std::string& modPath : m_mods) - GetLogger()->Info(" * %s\n", modPath.c_str()); + GetLogger()->Info("Mod search dirs:\n"); + for(const std::string& modSearchDir : m_modSearchDirs) + GetLogger()->Info(" * %s\n", modSearchDir.c_str()); } CResourceManager::AddLocation(m_dataPath); - for (const std::string& modAutoloadDir : m_modAutoloadDir) - { - GetLogger()->Trace("Searching for mods in '%s'...\n", modAutoloadDir.c_str()); - for (const std::string& modPath : FindModsInDir(modAutoloadDir)) - { - std::string::size_type enabled; - enabled = modPath.find('~'); - if (enabled == std::string::npos) - { - GetLogger()->Info("Autoloading mod: '%s'\n", modPath.c_str()); - CResourceManager::AddLocation(modPath); - } - else - { - GetLogger()->Info("Found excluded mod: '%s'\n", modPath.c_str()); - } - } - } - - for (const std::string& modPath : m_mods) - { - std::string::size_type enabled; - enabled = modPath.find('~'); - if (enabled == std::string::npos) - { - GetLogger()->Info("Loading mod: '%s'\n", modPath.c_str()); - CResourceManager::AddLocation(modPath); - } - else - { - GetLogger()->Info("Found excluded mod: '%s'\n", modPath.c_str()); - } - } - CResourceManager::SetSaveLocation(m_savePath); CResourceManager::AddLocation(m_savePath); @@ -213,7 +178,7 @@ void CPathManager::InitPaths() GetLogger()->Debug(" * %s\n", path.c_str()); } -std::vector CPathManager::FindModsInDir(const std::string &dir) +std::vector CPathManager::FindModsInDir(const std::string &dir) const { std::vector ret; try diff --git a/src/app/pathman.h b/src/app/pathman.h index 9cd9ffe1..3712d307 100644 --- a/src/app/pathman.h +++ b/src/app/pathman.h @@ -37,9 +37,11 @@ public: void SetDataPath(const std::string &dataPath); void SetLangPath(const std::string &langPath); void SetSavePath(const std::string &savePath); - void AddModAutoloadDir(const std::string &modAutoloadDirPath); + void AddModSearchDir(const std::string &modAutoloadDirPath); void AddMod(const std::string &modPath); void RemoveMod(const std::string &modPath); + bool ModLoaded(const std::string& modPath); + std::vector FindMods() const; const std::string& GetDataPath(); const std::string& GetLangPath(); @@ -52,7 +54,7 @@ public: private: //! Loads all mods from given directory - std::vector FindModsInDir(const std::string &dir); + std::vector FindModsInDir(const std::string &dir) const; private: //! Data path @@ -61,8 +63,6 @@ private: std::string m_langPath; //! Save path std::string m_savePath; - //! Mod autoload paths - std::vector m_modAutoloadDir; - //! Mod paths - std::vector m_mods; + //! Mod search paths + std::vector m_modSearchDirs; }; diff --git a/src/common/resources/resourcemanager.cpp b/src/common/resources/resourcemanager.cpp index b51325b8..bddb5236 100644 --- a/src/common/resources/resourcemanager.cpp +++ b/src/common/resources/resourcemanager.cpp @@ -95,6 +95,12 @@ std::vector CResourceManager::GetLocations() return ret; } +bool CResourceManager::LocationExists(const std::string& location) +{ + auto locations = GetLocations(); + auto it = std::find(locations.cbegin(), locations.cend(), location); + return it != locations.cend(); +} bool CResourceManager::SetSaveLocation(const std::string &location) { diff --git a/src/common/resources/resourcemanager.h b/src/common/resources/resourcemanager.h index 8c09b91a..0a1bca16 100644 --- a/src/common/resources/resourcemanager.h +++ b/src/common/resources/resourcemanager.h @@ -41,6 +41,8 @@ public: static bool RemoveLocation(const std::string &location); //! List all locations in the search path static std::vector GetLocations(); + //! Check if given location is in the search path + static bool LocationExists(const std::string &location); static bool SetSaveLocation(const std::string &location); static std::string GetSaveLocation(); diff --git a/src/graphics/engine/text.cpp b/src/graphics/engine/text.cpp index 4306dae8..a85bd5fd 100644 --- a/src/graphics/engine/text.cpp +++ b/src/graphics/engine/text.cpp @@ -259,10 +259,8 @@ void CText::FlushCache() } } - m_lastCachedFont = nullptr; - m_lastFontType = FONT_COMMON; - m_lastFontSize = 0; - + //TODO: fix this + Destroy(); Create(); } diff --git a/src/ui/mainui.cpp b/src/ui/mainui.cpp index 14fc454d..57436f89 100644 --- a/src/ui/mainui.cpp +++ b/src/ui/mainui.cpp @@ -85,7 +85,7 @@ CMainUserInterface::CMainUserInterface() m_screenSetupDisplay = MakeUnique(); m_screenSetupGame = MakeUnique(); m_screenSetupGraphics = MakeUnique(); - m_screenSetupMods = MakeUnique(m_dialog.get()); + m_screenSetupMods = MakeUnique(m_dialog.get(), m_app->GetModManager()); m_screenSetupSound = MakeUnique(); m_screenMainMenu = MakeUnique(); m_screenPlayerSelect = MakeUnique(m_dialog.get()); diff --git a/src/ui/screen/screen_setup_mods.cpp b/src/ui/screen/screen_setup_mods.cpp index 9415ad24..60e8a47f 100644 --- a/src/ui/screen/screen_setup_mods.cpp +++ b/src/ui/screen/screen_setup_mods.cpp @@ -1,6 +1,6 @@ /* * This file is part of the Colobot: Gold Edition source code - * Copyright (C) 2001-2019, Daniel Roux, EPSITEC SA & TerranovaTeam + * Copyright (C) 2001-2020, Daniel Roux, EPSITEC SA & TerranovaTeam * http://epsitec.ch; http://colobot.info; http://github.com/colobot * * This program is free software: you can redistribute it and/or modify @@ -19,18 +19,20 @@ #include "ui/screen/screen_setup_mods.h" -#include "app/app.h" -#include "app/pathman.h" +#include "common/config.h" -#include "common/system/system.h" +#include "app/app.h" +#include "app/modman.h" #include "common/restext.h" -#include "common/config.h" #include "common/logger.h" #include "common/settings.h" #include "common/stringutils.h" #include "common/resources/resourcemanager.h" + +#include "common/system/system.h" + #include "level/parser/parser.h" #include "ui/controls/button.h" @@ -49,8 +51,9 @@ using namespace boost::filesystem; namespace Ui { -CScreenSetupMods::CScreenSetupMods(CMainDialog* mainDialog) - : m_dialog(mainDialog) +CScreenSetupMods::CScreenSetupMods(CMainDialog* dialog, CModManager* modManager) + : m_dialog(dialog), + m_modManager(modManager) { } @@ -128,6 +131,7 @@ void CScreenSetupMods::CreateInterface() pb->SetState(STATE_SHADOW); pb->ClearState(STATE_ENABLE); } + bool CScreenSetupMods::EventProcess(const Event &event) { CWindow* pw; @@ -135,7 +139,7 @@ bool CScreenSetupMods::EventProcess(const Event &event) CList* pl; std::string modName; const std::string website = "https://www.moddb.com/games/colobot-gold-edition"; - const std::string modDir = CResourceManager::GetSaveLocation() + "/" + "mods"; + const std::string modDir = CResourceManager::GetSaveLocation() + "/mods"; auto systemUtils = CSystemUtils::Create(); // platform-specific utils if (!CScreenSetup::EventProcess(event)) return false; @@ -149,9 +153,10 @@ bool CScreenSetupMods::EventProcess(const Event &event) pl = static_cast(pw->SearchControl(EVENT_INTERFACE_MODS_UNLOADED)); if (pl == nullptr) return false; modName = pl->GetItemName(pl->GetSelect()); - LoadMod(modName); - m_app->Reload(); + m_modManager->EnableMod(modName); + m_modManager->ReloadMods(); + m_main->ChangePhase(PHASE_SETUPm); break; @@ -159,9 +164,10 @@ bool CScreenSetupMods::EventProcess(const Event &event) pl = static_cast(pw->SearchControl(EVENT_INTERFACE_MODS_LOADED)); if (pl == nullptr) return false; modName = pl->GetItemName(pl->GetSelect()); - UnloadMod(modName); - m_app->Reload(); + m_modManager->DisableMod(modName); + m_modManager->ReloadMods(); + m_main->ChangePhase(PHASE_SETUPm); break; @@ -200,7 +206,7 @@ bool CScreenSetupMods::EventProcess(const Event &event) GetResource(RES_TEXT, RT_DIALOG_OPEN_PATH_FAILED_TITLE, title); GetResource(RES_TEXT, RT_DIALOG_OPEN_PATH_FAILED_TEXT, text); - // Workaround for how labels treat the \\ character on Windows + // Workaround for Windows: the label skips everything after the first \\ character std::string modDirWithoutBackSlashes = modDir; std::replace(modDirWithoutBackSlashes.begin(), modDirWithoutBackSlashes.end(), '\\', '/'); @@ -224,34 +230,11 @@ bool CScreenSetupMods::EventProcess(const Event &event) return false; } -void CScreenSetupMods::UnloadMod(std::string modName) -{ - std::string modPath, modPathRaw, disabled = "~"; - - modPathRaw = CResourceManager::GetSaveLocation() + "/" + "mods" + "/"; - modPath = modPathRaw.c_str(); - - m_pathManager->RemoveMod(modPath+modName); - boost::filesystem::rename(modPath+modName, modPath+disabled+modName); -} - -void CScreenSetupMods::LoadMod(std::string modName) -{ - std::string modPath, modPathRaw, disabled = "~"; - - modPathRaw = CResourceManager::GetSaveLocation() + "/" + "mods" + "/"; - modPath = modPathRaw.c_str(); - - boost::filesystem::rename(modPath+disabled+modName, modPath+modName); - m_pathManager->AddMod(modPath+modName); -} - void CScreenSetupMods::UpdateUnloadedModList() { CWindow* pw; CList* pl; int i = 0; - std::string modPath, modPathRaw; directory_iterator end_itr; pw = static_cast(m_interface->SearchControl(EVENT_WINDOW5)); @@ -261,30 +244,22 @@ void CScreenSetupMods::UpdateUnloadedModList() if ( pl == nullptr ) return; pl->Flush(); - modPathRaw = CResourceManager::GetSaveLocation() + "/" + "mods" + "/"; - modPath = modPathRaw.c_str(); - - for (directory_iterator itr(modPath); itr != end_itr; ++itr) + for (const auto& mod : m_modManager->GetMods()) { - std::string modName = itr->path().string(); - boost::erase_all(modName, modPath); - std::string::size_type enabled; - enabled = modName.find('~'); - if (enabled != std::string::npos) + if (!mod.enabled) { - modName.erase(0,1); - pl->SetItemName(i++, modName); + pl->SetItemName(i++, mod.name); } } pl->ShowSelect(false); // shows the selected columns } + void CScreenSetupMods::UpdateLoadedModList() { CWindow* pw; CList* pl; int i = 0; - std::string modPath, modPathRaw; directory_iterator end_itr; pw = static_cast(m_interface->SearchControl(EVENT_WINDOW5)); @@ -294,19 +269,15 @@ void CScreenSetupMods::UpdateLoadedModList() if ( pl == nullptr ) return; pl->Flush(); - modPathRaw = CResourceManager::GetSaveLocation() + "/" + "mods" + "/"; - modPath = modPathRaw.c_str(); - - for (directory_iterator itr(modPath); itr != end_itr; ++itr) + for (const auto& mod : m_modManager->GetMods()) { - std::string modName = itr->path().string(); - boost::erase_all(modName, modPath); - std::string::size_type enabled; - enabled = modName.find('~'); - if (enabled == std::string::npos) - pl->SetItemName(i++, modName); + if (mod.enabled) + { + pl->SetItemName(i++, mod.name); + } } pl->ShowSelect(false); // shows the selected columns } + } // namespace Ui diff --git a/src/ui/screen/screen_setup_mods.h b/src/ui/screen/screen_setup_mods.h index 75b8c5a1..fbe2c6eb 100644 --- a/src/ui/screen/screen_setup_mods.h +++ b/src/ui/screen/screen_setup_mods.h @@ -1,6 +1,6 @@ /* * This file is part of the Colobot: Gold Edition source code - * Copyright (C) 2001-2019, Daniel Roux, EPSITEC SA & TerranovaTeam + * Copyright (C) 2001-2020, Daniel Roux, EPSITEC SA & TerranovaTeam * http://epsitec.ch; http://colobot.info; http://github.com/colobot * * This program is free software: you can redistribute it and/or modify @@ -20,11 +20,12 @@ #pragma once #include "ui/maindialog.h" + #include "ui/screen/screen_setup.h" #include -class CPathManager; +class CModManager; namespace Ui { @@ -32,24 +33,20 @@ namespace Ui class CScreenSetupMods : public CScreenSetup { public: - CScreenSetupMods(CMainDialog* mainDialog); + CScreenSetupMods(CMainDialog* dialog, CModManager* modManager); void SetActive() override; void CreateInterface() override; bool EventProcess(const Event &event) override; protected: - void UnloadMod(std::string ModName); - void LoadMod(std::string ModName); void UpdateUnloadedModList(); void UpdateLoadedModList(); protected: - CMainDialog* m_dialog; + CModManager* m_modManager; - CPathManager* m_pathManager; - std::vector m_unloadedModList; - std::vector m_loadedModList; + CMainDialog* m_dialog; }; } // namespace Ui