mirror of https://github.com/AxioDL/metaforce.git
Add support for string literals in Console::executeString, add implicit get/set for CVars
This commit is contained in:
parent
eff677ca20
commit
801214d9a8
|
@ -22,6 +22,7 @@ enum class EType : atUint8
|
|||
|
||||
enum EFlags
|
||||
{
|
||||
None = -1,
|
||||
System = (1 << 0),
|
||||
Game = (1 << 1),
|
||||
Editor = (1 << 2),
|
||||
|
@ -113,7 +114,7 @@ public:
|
|||
void setModified();
|
||||
|
||||
EType type() const { return m_type; }
|
||||
EFlags flags() const { return m_flags; }
|
||||
EFlags flags() const { return (m_unlocked ? m_oldFlags : m_flags); }
|
||||
|
||||
/*!
|
||||
* \brief Unlocks the CVar for writing if it is ReadOnly.
|
||||
|
|
|
@ -63,7 +63,7 @@ public:
|
|||
}
|
||||
|
||||
std::vector<CVar*> archivedCVars() const;
|
||||
std::vector<CVar*> cvars() const;
|
||||
std::vector<CVar*> cvars(CVar::EFlags filter = CVar::EFlags::None) const;
|
||||
|
||||
void deserialize(CVar* cvar);
|
||||
void serialize();
|
||||
|
|
|
@ -14,7 +14,7 @@ CVar* com_developer = nullptr;
|
|||
CVar* com_configfile = nullptr;
|
||||
CVar* com_enableCheats = nullptr;
|
||||
|
||||
static const std::regex cmdLineRegex("\\+(\\w+)=([\\w\\.\\-]+)");
|
||||
static const std::regex cmdLineRegex("\\+([\\w\\.]+)=([\\w\\.\\-]+)");
|
||||
CVarManager* CVarManager::m_instance = nullptr;
|
||||
|
||||
static logvisor::Module CVarLog("CVarManager");
|
||||
|
@ -65,11 +65,12 @@ std::vector<CVar*> CVarManager::archivedCVars() const
|
|||
return ret;
|
||||
}
|
||||
|
||||
std::vector<CVar*> CVarManager::cvars() const
|
||||
std::vector<CVar*> CVarManager::cvars(CVar::EFlags filter) const
|
||||
{
|
||||
std::vector<CVar*> ret;
|
||||
for (const auto& pair : m_cvars)
|
||||
ret.push_back(pair.second.get());
|
||||
if (filter == CVar::EFlags::None || (pair.second->flags() & filter) != 0)
|
||||
ret.push_back(pair.second.get());
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -201,7 +202,7 @@ void CVarManager::list(Console* con, const std::vector<std::string>& /*args*/)
|
|||
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());
|
||||
con->report(Console::Level::Info, "%s: %s", cvar.second->name().data(), cvar.second->help().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -222,13 +223,20 @@ void CVarManager::setCVar(Console* con, const std::vector<std::string> &args)
|
|||
}
|
||||
|
||||
const auto& cv = m_cvars[cvName];
|
||||
std::string oldVal = cv->value();
|
||||
std::string value = args[1];
|
||||
auto it = args.begin() + 2;
|
||||
for (; it != args.end(); ++it)
|
||||
value += " " + *it;
|
||||
|
||||
/* Check to make sure we're not redundantly assigning the value */
|
||||
if (cv->value() == value)
|
||||
return;
|
||||
|
||||
if (!cv->fromLiteralToType(value))
|
||||
con->report(Console::Level::Warning, "Unable to set cvar '%s' to value '%s'", args[0].c_str(), value.c_str());
|
||||
con->report(Console::Level::Warning, "Unable to set cvar '%s' to value '%s'", cv->name().data(), value.c_str());
|
||||
else
|
||||
con->report(Console::Level::Info, "Set '%s' from '%s' to '%s'", cv->name().data(), oldVal.c_str(), value.c_str());
|
||||
}
|
||||
|
||||
void CVarManager::getCVar(Console* con, const std::vector<std::string> &args)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "hecl/Console.hpp"
|
||||
#include "hecl/CVarManager.hpp"
|
||||
#include "hecl/CVar.hpp"
|
||||
#include "hecl/hecl.hpp"
|
||||
#include "athena/Utility.hpp"
|
||||
|
||||
namespace hecl
|
||||
|
@ -54,10 +55,50 @@ void Console::executeString(const std::string& str)
|
|||
for (std::string command : commands)
|
||||
{
|
||||
command = athena::utility::trim(command);
|
||||
std::vector<std::string> args = athena::utility::split(command, ' ');
|
||||
|
||||
if (args.empty())
|
||||
std::vector<std::string> tmpArgs = athena::utility::split(command, ' ');
|
||||
if (tmpArgs.empty())
|
||||
continue;
|
||||
std::vector<std::string> args;
|
||||
args.reserve(tmpArgs.size());
|
||||
/* detect string literals */
|
||||
bool isInLiteral = false;
|
||||
std::string curLiteral;
|
||||
int depth = 0;
|
||||
for (std::string arg : tmpArgs)
|
||||
{
|
||||
if ((arg.front() == '\'' || arg.front() == '"'))
|
||||
{
|
||||
++depth;
|
||||
isInLiteral = true;
|
||||
curLiteral += arg;
|
||||
}
|
||||
else if ((arg.back() == '\'' || arg.back() == '"') && isInLiteral)
|
||||
{
|
||||
--depth;
|
||||
curLiteral += arg;
|
||||
args.push_back(curLiteral);
|
||||
if (depth <= 0)
|
||||
{
|
||||
depth = 0;
|
||||
isInLiteral = false;
|
||||
curLiteral.clear();
|
||||
}
|
||||
}
|
||||
else if (isInLiteral)
|
||||
curLiteral += arg;
|
||||
else
|
||||
args.push_back(arg);
|
||||
}
|
||||
|
||||
if (isInLiteral)
|
||||
{
|
||||
if ((curLiteral.back() != '\'' && curLiteral.back() != '"') || depth > 1)
|
||||
{
|
||||
report(Level::Warning, "Unterminated string literal");
|
||||
return;
|
||||
}
|
||||
args.push_back(curLiteral);
|
||||
}
|
||||
|
||||
std::string commandName = args[0];
|
||||
args.erase(args.begin());
|
||||
|
@ -80,6 +121,14 @@ void Console::executeString(const std::string& str)
|
|||
}
|
||||
m_commands[lowComName].m_func(this, args);
|
||||
}
|
||||
else if (const CVar* cv = m_cvarMgr->findCVar(commandName))
|
||||
{
|
||||
args.insert(args.begin(), commandName);
|
||||
if (args.size() > 1)
|
||||
m_cvarMgr->setCVar(this, args);
|
||||
else
|
||||
m_cvarMgr->getCVar(this, args);
|
||||
}
|
||||
else
|
||||
report(Level::Error, "Command '%s' is not valid!", commandName.c_str());
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue