metaforce/hecl/lib/CVarManager.cpp

222 lines
6.1 KiB
C++
Raw Normal View History

2016-03-04 23:02:44 +00:00
#include "hecl/CVarManager.hpp"
#include "hecl/CVar.hpp"
2018-01-11 09:35:27 +00:00
#include "hecl/Console.hpp"
2016-03-04 23:02:44 +00:00
#include <athena/FileWriter.hpp>
#include <athena/Utility.hpp>
#include <hecl/Runtime.hpp>
2015-12-02 21:11:10 +00:00
#include <memory>
2016-03-04 23:02:44 +00:00
namespace hecl
2015-12-02 21:11:10 +00:00
{
2018-01-15 12:34:02 +00:00
BoolCVar* com_developer = nullptr;
StringCVar* com_configfile = nullptr;
BoolCVar* com_enableCheats = nullptr;
2015-12-02 21:11:10 +00:00
2015-12-04 01:43:29 +00:00
CVarManager* CVarManager::m_instance = nullptr;
2018-01-14 07:37:00 +00:00
static logvisor::Module CVarLog("CVarManager");
2016-03-04 23:02:44 +00:00
CVarManager::CVarManager(hecl::Runtime::FileStoreManager& store, bool useBinary)
2015-12-02 21:11:10 +00:00
: m_store(store),
m_useBinary(useBinary)
{
2015-12-04 01:43:29 +00:00
m_instance = this;
2018-01-15 12:34:02 +00:00
com_configfile = dynamic_cast<StringCVar*>(findOrMakeCVar("config", "File to store configuration", m_configFile, CVar::EFlags::System));
com_developer = dynamic_cast<BoolCVar*>(findOrMakeCVar("developer", "Enables developer mode", m_developerMode, (CVar::EFlags::System | CVar::EFlags::ReadOnly | CVar::EFlags::InternalArchivable)));
com_enableCheats = dynamic_cast<BoolCVar*>(findOrMakeCVar("iamaweiner", "Enable cheats", m_enableCheats, (CVar::EFlags::System | CVar::EFlags::ReadOnly | CVar::EFlags::Hidden)));
2015-12-02 21:11:10 +00:00
}
CVarManager::~CVarManager()
{
}
void CVarManager::update()
{
for (const std::pair<std::string, CVar*>& pair : m_cvars)
if (pair.second->isModified())
{
pair.second->clearModified();
}
}
bool CVarManager::registerCVar(CVar* cvar)
{
2017-11-13 06:13:53 +00:00
std::string tmp(cvar->name());
2016-03-04 23:02:44 +00:00
athena::utility::tolower(tmp);
2015-12-02 21:11:10 +00:00
if (m_cvars.find(tmp) != m_cvars.end())
return false;
m_cvars[tmp] = cvar;
return true;
}
2017-11-13 06:13:53 +00:00
CVar* CVarManager::findCVar(std::string_view name)
2015-12-02 21:11:10 +00:00
{
2017-11-13 06:13:53 +00:00
std::string lower(name);
athena::utility::tolower(lower);
auto search = m_cvars.find(lower);
if (search == m_cvars.end())
2015-12-02 21:11:10 +00:00
return nullptr;
2017-11-13 06:13:53 +00:00
return search->second;
2015-12-02 21:11:10 +00:00
}
std::vector<CVar*> CVarManager::archivedCVars() const
{
std::vector<CVar*> ret;
for (const std::pair<std::string, CVar*>& pair : m_cvars)
if (pair.second->isArchive())
ret.push_back(pair.second);
return ret;
}
std::vector<CVar*> CVarManager::cvars() const
{
std::vector<CVar*> ret;
for (const std::pair<std::string, CVar*>& pair : m_cvars)
ret.push_back(pair.second);
return ret;
}
void CVarManager::deserialize(CVar* cvar)
{
2018-01-14 07:37:00 +00:00
if (!cvar || (!cvar->isArchive() && !cvar->isInternalArchivable()))
2015-12-02 21:11:10 +00:00
return;
#if _WIN32
2018-01-15 12:34:02 +00:00
hecl::SystemString filename = hecl::SystemString(m_store.getStoreRoot()) + _S('/') + hecl::UTF8ToWide(m_configFile);
2015-12-02 21:11:10 +00:00
#else
2018-01-15 12:34:02 +00:00
hecl::SystemString filename = hecl::SystemString(m_store.getStoreRoot()) + _S('/') + m_configFile;
2015-12-02 21:11:10 +00:00
#endif
2016-03-04 23:02:44 +00:00
hecl::Sstat st;
2015-12-02 21:11:10 +00:00
2018-01-15 12:34:02 +00:00
filename += _S(".yaml");
if (hecl::Stat(filename.c_str(), &st) || !S_ISREG(st.st_mode))
return;
athena::io::FileReader reader(filename);
if (reader.isOpen())
2015-12-02 21:11:10 +00:00
{
2018-01-15 12:34:02 +00:00
athena::io::YAMLDocReader doc;
doc.parse(&reader);
if (doc.hasVal(cvar->name().c_str()))
2015-12-02 21:11:10 +00:00
{
2018-01-15 12:34:02 +00:00
cvar->unlock();
cvar->deserialize(doc);
cvar->m_wasDeserialized = true;;
cvar->lock();
2015-12-02 21:11:10 +00:00
}
}
}
void CVarManager::serialize()
{
#if _WIN32
2018-01-15 12:34:02 +00:00
hecl::SystemString filename = hecl::SystemString(m_store.getStoreRoot()) + _S('/') + hecl::UTF8ToWide(m_configFile);
2015-12-02 21:11:10 +00:00
#else
2018-01-15 12:34:02 +00:00
hecl::SystemString filename = hecl::SystemString(m_store.getStoreRoot()) + _S('/') + m_configFile;
2015-12-02 21:11:10 +00:00
#endif
2018-01-15 12:34:02 +00:00
filename += _S(".yaml");
athena::io::FileWriter writer(filename);
if (writer.isOpen())
2015-12-02 21:11:10 +00:00
{
2018-01-15 12:34:02 +00:00
athena::io::YAMLDocWriter doc(nullptr);
for (const std::pair<std::string, CVar*>& pair : m_cvars)
if (pair.second->isArchive() || (pair.second->isInternalArchivable() && pair.second->wasDeserialized() && !pair.second->hasDefaultValue()))
pair.second->serialize(doc);
doc.finish(&writer);
2015-12-02 21:11:10 +00:00
}
}
2018-01-15 12:34:02 +00:00
2015-12-04 01:43:29 +00:00
CVarManager* CVarManager::instance()
{
return m_instance;
}
2018-01-14 07:37:00 +00:00
void CVarManager::list(Console* con, const std::vector<std::string>& /*args*/)
2018-01-11 09:35:27 +00:00
{
for (const auto& cvar : m_cvars)
{
if (!cvar.second->isHidden())
con->report(Console::Level::Info, "%s: %s", cvar.first.c_str(), cvar.second->help().c_str());
}
2018-01-11 09:35:27 +00:00
}
void CVarManager::setCVar(Console* con, const std::vector<std::string> &args)
2018-01-11 09:35:27 +00:00
{
if (args.size() < 2)
{
con->report(Console::Level::Info, "Usage setCvar <cvar> <value>");
return;
}
2018-01-11 09:35:27 +00:00
std::string cvName = args[0];
athena::utility::tolower(cvName);
if (m_cvars.find(cvName) == m_cvars.end())
{
con->report(Console::Level::Error, "CVar '%s' does not exist", args[0].c_str());
return;
}
CVar* cv = m_cvars[cvName];
std::string value = args[1];
auto it = args.begin() + 2;
for (; it != args.end(); ++it)
value += " " + *it;
2018-01-15 12:34:02 +00:00
if (!cv->fromString(value))
con->report(Console::Level::Warning, "Unable to cvar '%s' to value '%s'", args[0].c_str(), value.c_str());
2018-01-15 12:34:02 +00:00
2018-01-11 09:35:27 +00:00
}
void CVarManager::getCVar(Console* con, const std::vector<std::string> &args)
2018-01-11 09:35:27 +00:00
{
if (args.empty())
{
con->report(Console::Level::Info, "Usage getCVar <cvar>");
return;
}
std::string cvName = args[0];
athena::utility::tolower(cvName);
if (m_cvars.find(cvName) == m_cvars.end())
{
con->report(Console::Level::Error, "CVar '%s' does not exist", args[0].c_str());
return;
}
const CVar* cv = m_cvars[cvName];
2018-01-15 12:34:02 +00:00
con->report(Console::Level::Info, "'%s' = '%s'", cv->name().data(), cv->toString().c_str());
2018-01-11 09:35:27 +00:00
}
bool CVarManager::restartRequired() const
{
for (const auto& cv : m_cvars)
{
if (cv.second->isModified() && cv.second->modificationRequiresRestart())
return true;
}
return false;
}
2015-12-02 21:11:10 +00:00
bool CVarManager::suppressDeveloper()
{
2018-01-15 12:34:02 +00:00
bool oldDeveloper = m_developerMode;
m_developerMode = false;
2015-12-02 21:11:10 +00:00
return oldDeveloper;
2018-01-15 12:34:02 +00:00
2015-12-02 21:11:10 +00:00
}
void CVarManager::restoreDeveloper(bool oldDeveloper)
{
2018-01-15 12:34:02 +00:00
m_developerMode = oldDeveloper;
2015-12-02 21:11:10 +00:00
}
}