Refactor the mod manager

Moved list of mods logic to a new CModManager class.

The list of enabled mods is now managed by a flag instead of directory
names of mods.

Mods are now disabled by default.

Also general cleanup, fixing issues from the code review in
https://github.com/colobot/colobot/pull/1191 and fixing linter issues.

Regression: the state of enabled/disabled mods is now not persistent.
The plan is to use some kind of config file for this.
pyro-refactor
MrSimbax 2020-07-18 14:30:50 +02:00
parent 5f76722ecb
commit 8390d85e46
13 changed files with 320 additions and 177 deletions

View File

@ -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

View File

@ -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<ApplicationPrivate>()),
m_configFile(MakeUnique<CConfigFile>()),
m_input(MakeUnique<CInput>()),
m_pathManager(MakeUnique<CPathManager>(systemUtils))
m_pathManager(MakeUnique<CPathManager>(systemUtils)),
m_modManager(MakeUnique<CModManager>(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<CController>();
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;

View File

@ -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<CInput> m_input;
//! Path manager
std::unique_ptr<CPathManager> m_pathManager;
//! Mod manager
std::unique_ptr<CModManager> m_modManager;
//! Code to return at exit
int m_exitCode;

117
src/app/modman.cpp Normal file
View File

@ -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 <algorithm>
#include <boost/filesystem.hpp>
#include <boost/algorithm/string.hpp>
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<Mod> CModManager::GetMod(const std::string& modName)
{
Mod* mod = FindMod(modName);
return mod != nullptr ? *mod : boost::optional<Mod>();
}
const std::vector<Mod>& 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;
}

75
src/app/modman.h Normal file
View File

@ -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 <unordered_map>
#include <boost/optional.hpp>
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<Mod> GetMod(const std::string& modName);
const std::vector<Mod>& GetMods() const;
private:
Mod* FindMod(const std::string& modName);
private:
CApplication* m_app;
CPathManager* m_pathManager;
//TODO: better data structure?
std::vector<Mod> m_mods;
};

View File

@ -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<std::string> CPathManager::FindMods() const
{
std::vector<std::string> 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<std::string> CPathManager::FindModsInDir(const std::string &dir)
std::vector<std::string> CPathManager::FindModsInDir(const std::string &dir) const
{
std::vector<std::string> ret;
try

View File

@ -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<std::string> FindMods() const;
const std::string& GetDataPath();
const std::string& GetLangPath();
@ -52,7 +54,7 @@ public:
private:
//! Loads all mods from given directory
std::vector<std::string> FindModsInDir(const std::string &dir);
std::vector<std::string> 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<std::string> m_modAutoloadDir;
//! Mod paths
std::vector<std::string> m_mods;
//! Mod search paths
std::vector<std::string> m_modSearchDirs;
};

View File

@ -95,6 +95,12 @@ std::vector<std::string> 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)
{

View File

@ -41,6 +41,8 @@ public:
static bool RemoveLocation(const std::string &location);
//! List all locations in the search path
static std::vector<std::string> 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();

View File

@ -259,10 +259,8 @@ void CText::FlushCache()
}
}
m_lastCachedFont = nullptr;
m_lastFontType = FONT_COMMON;
m_lastFontSize = 0;
//TODO: fix this
Destroy();
Create();
}

View File

@ -85,7 +85,7 @@ CMainUserInterface::CMainUserInterface()
m_screenSetupDisplay = MakeUnique<CScreenSetupDisplay>();
m_screenSetupGame = MakeUnique<CScreenSetupGame>();
m_screenSetupGraphics = MakeUnique<CScreenSetupGraphics>();
m_screenSetupMods = MakeUnique<CScreenSetupMods>(m_dialog.get());
m_screenSetupMods = MakeUnique<CScreenSetupMods>(m_dialog.get(), m_app->GetModManager());
m_screenSetupSound = MakeUnique<CScreenSetupSound>();
m_screenMainMenu = MakeUnique<CScreenMainMenu>();
m_screenPlayerSelect = MakeUnique<CScreenPlayerSelect>(m_dialog.get());

View File

@ -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<CList*>(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<CList*>(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<CWindow*>(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<CWindow*>(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

View File

@ -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 <vector>
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<std::string> m_unloadedModList;
std::vector<std::string> m_loadedModList;
CMainDialog* m_dialog;
};
} // namespace Ui