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
parent
5f76722ecb
commit
8390d85e46
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
};
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -259,10 +259,8 @@ void CText::FlushCache()
|
|||
}
|
||||
}
|
||||
|
||||
m_lastCachedFont = nullptr;
|
||||
m_lastFontType = FONT_COMMON;
|
||||
m_lastFontSize = 0;
|
||||
|
||||
//TODO: fix this
|
||||
Destroy();
|
||||
Create();
|
||||
}
|
||||
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue