Merge branch 'master' of ssh://gitlab.axiodl.com:6431/AxioDL/hecl

This commit is contained in:
Jack Andersen 2018-01-11 15:32:41 -10:00
commit f92caf3810
8 changed files with 356 additions and 4 deletions

View File

@ -31,7 +31,8 @@ enum EFlags
Hidden = (1 << 5), Hidden = (1 << 5),
ReadOnly = (1 << 6), ReadOnly = (1 << 6),
Archive = (1 << 7), Archive = (1 << 7),
Modified = (1 << 8) Modified = (1 << 8),
ModifyRestart = (1 << 9) /*!< If this bit is set, any modification will inform the user that a restart is required */
}; };
ENABLE_BITWISE_ENUM(EFlags) ENABLE_BITWISE_ENUM(EFlags)
@ -98,6 +99,7 @@ public:
bool isLiteral() const { return m_type == EType::Literal; } bool isLiteral() const { return m_type == EType::Literal; }
bool isVec4f() const { return m_type == EType::Vec4f; } bool isVec4f() const { return m_type == EType::Vec4f; }
bool isModified() const; bool isModified() const;
bool modificationRequiresRestart() const;
bool isReadOnly() const; bool isReadOnly() const;
bool isCheat() const; bool isCheat() const;
bool isHidden() const; bool isHidden() const;

View File

@ -30,13 +30,13 @@ public:
{ {
m_graphicsApi = m_mgr.findOrMakeCVar("graphicsApi"sv, m_graphicsApi = m_mgr.findOrMakeCVar("graphicsApi"sv,
"API to use for rendering graphics"sv, "API to use for rendering graphics"sv,
DEFAULT_GRAPHICS_API, hecl::CVar::EFlags::System | hecl::CVar::EFlags::Archive); DEFAULT_GRAPHICS_API, hecl::CVar::EFlags::System | hecl::CVar::EFlags::Archive | hecl::CVar::EFlags::ModifyRestart);
m_drawSamples = m_mgr.findOrMakeCVar("drawSamples"sv, m_drawSamples = m_mgr.findOrMakeCVar("drawSamples"sv,
"Number of MSAA samples to use for render targets"sv, "Number of MSAA samples to use for render targets"sv,
1, hecl::CVar::EFlags::System | hecl::CVar::EFlags::Archive); 1, hecl::CVar::EFlags::System | hecl::CVar::EFlags::Archive | hecl::CVar::EFlags::ModifyRestart);
m_texAnisotropy = m_mgr.findOrMakeCVar("texAnisotropy"sv, m_texAnisotropy = m_mgr.findOrMakeCVar("texAnisotropy"sv,
"Number of anisotropic samples to use for sampling textures"sv, "Number of anisotropic samples to use for sampling textures"sv,
1, hecl::CVar::EFlags::System | hecl::CVar::EFlags::Archive); 1, hecl::CVar::EFlags::System | hecl::CVar::EFlags::Archive | hecl::CVar::EFlags::ModifyRestart);
} }
std::string getGraphicsApi() const std::string getGraphicsApi() const

View File

@ -71,6 +71,12 @@ public:
static CVarManager* instance(); static CVarManager* instance();
void list(class Console* con, const std::vector<std::string>& args);
void setCVar(class Console* con, const std::vector<std::string>& args);
void getCVar(class Console* con, const std::vector<std::string>& args);
bool restartRequired() const;
private: private:
bool suppressDeveloper(); bool suppressDeveloper();
void restoreDeveloper(bool oldDeveloper); void restoreDeveloper(bool oldDeveloper);

View File

@ -0,0 +1,81 @@
#ifndef __URDE_CONSOLE_HPP__
#define __URDE_CONSOLE_HPP__
#include <string>
#include <unordered_map>
#include <vector>
#include <functional>
#include "logvisor/logvisor.hpp"
namespace hecl
{
struct SConsoleCommand
{
std::string m_displayName;
std::string m_helpString;
std::string m_usage;
std::function<void(class Console*, const std::vector<std::string>&)> m_func;
};
class Console
{
friend class LogVisorAdapter;
struct LogVisorAdapter : logvisor::ILogger
{
Console* m_con;
LogVisorAdapter(Console* con)
: m_con(con) {}
~LogVisorAdapter() {}
void report(const char* modName, logvisor::Level severity,
const char* format, va_list ap);
void report(const char* modName, logvisor::Level severity,
const wchar_t* format, va_list ap);
void reportSource(const char* modName, logvisor::Level severity,
const char* file, unsigned linenum,
const char* format, va_list ap);
void reportSource(const char* modName, logvisor::Level severity,
const char* file, unsigned linenum,
const wchar_t* format, va_list ap);
};
public:
static Console* m_instance;
enum class Level
{
Info, /**< Non-error informative message */
Warning, /**< Non-error warning message */
Error, /**< Recoverable error message */
Fatal /**< Non-recoverable error message (Kept for compatibility with logvisor) */
};
private:
std::unordered_map<std::string, SConsoleCommand> m_commands;
std::vector<std::pair<std::string, Level>> m_log;
void visorReport(Level level, const char* mod, const char* fmt, va_list list);
void visorReport(Level level, const char* mod, const char* fmt, ...);
void visorReportSource(Level, const char* mod, const char* file, unsigned line, const char* fmt, va_list);
void visorReportSource(Level, const char* mod, const char* file, unsigned line, const char* fmt, ...);
void visorReport(Level level, const char* mod, const wchar_t* fmt, va_list list);
void visorReport(Level level, const char* mod, const wchar_t* fmt, ...);
void visorReportSource(Level, const char* mod, const char* file, unsigned line, const wchar_t* fmt, va_list);
void visorReportSource(Level, const char* mod, const char* file, unsigned line, const wchar_t* fmt, ...);
public:
Console(class CVarManager*);
void registerCommand(std::string_view name, std::string_view helpText, std::string_view usage, const std::function<void(Console*, const std::vector<std::string>&)>&& func);
void executeString(const std::string& strToExec);
void help(Console* con, const std::vector<std::string>& args);
void listCommands(Console* con, const std::vector<std::string>& args);
bool commandExists(std::string_view cmd);
void report(Level level, const char *fmt, va_list list);
void report(Level, const char* fmt, ...);
void dumpLog();
static Console* instance();
static void RegisterLogger(Console* con);
};
}
#endif // __URDE_CONSOLE_HPP__

View File

@ -27,6 +27,7 @@ endif()
set(HECL_HEADERS set(HECL_HEADERS
../include/hecl/CVar.hpp ../include/hecl/CVar.hpp
../include/hecl/CVarManager.hpp ../include/hecl/CVarManager.hpp
../include/hecl/Console.hpp
../include/hecl/CVarCommons.hpp ../include/hecl/CVarCommons.hpp
../include/hecl/hecl.hpp ../include/hecl/hecl.hpp
../include/hecl/FourCC.hpp ../include/hecl/FourCC.hpp
@ -56,6 +57,7 @@ set(COMMON_SOURCES
HumanizeNumber.cpp HumanizeNumber.cpp
CVar.cpp CVar.cpp
CVarManager.cpp CVarManager.cpp
Console.cpp
ClientProcess.cpp ClientProcess.cpp
SteamFinder.cpp SteamFinder.cpp
WideStringConvert.cpp WideStringConvert.cpp

View File

@ -352,6 +352,7 @@ bool CVar::fromLiteral(std::wstring_view val)
} }
bool CVar::isModified() const { return int(m_flags & EFlags::Modified) != 0;} bool CVar::isModified() const { return int(m_flags & EFlags::Modified) != 0;}
bool CVar::modificationRequiresRestart() const { return int(m_flags & EFlags::ModifyRestart) != 0; }
bool CVar::isReadOnly() const { return int(m_flags & EFlags::ReadOnly) != 0; } bool CVar::isReadOnly() const { return int(m_flags & EFlags::ReadOnly) != 0; }

View File

@ -1,5 +1,6 @@
#include "hecl/CVarManager.hpp" #include "hecl/CVarManager.hpp"
#include "hecl/CVar.hpp" #include "hecl/CVar.hpp"
#include "hecl/Console.hpp"
#include <athena/FileWriter.hpp> #include <athena/FileWriter.hpp>
#include <athena/Utility.hpp> #include <athena/Utility.hpp>
#include <hecl/Runtime.hpp> #include <hecl/Runtime.hpp>
@ -175,6 +176,31 @@ CVarManager* CVarManager::instance()
return m_instance; return m_instance;
} }
void CVarManager::list(Console* con, const std::vector<std::string> &args)
{
}
void CVarManager::setCVar(Console* con, const std::vector<std::string> &args)
{
}
void CVarManager::getCVar(Console* con, const std::vector<std::string> &args)
{
}
bool CVarManager::restartRequired() const
{
for (const auto& cv : m_cvars)
{
if (cv.second->isModified() && cv.second->modificationRequiresRestart())
return true;
}
return false;
}
bool CVarManager::suppressDeveloper() bool CVarManager::suppressDeveloper()
{ {
bool oldDeveloper = com_developer->toBoolean(); bool oldDeveloper = com_developer->toBoolean();

234
hecl/lib/Console.cpp Normal file
View File

@ -0,0 +1,234 @@
#include "hecl/Console.hpp"
#include "hecl/CVarManager.hpp"
#include "hecl/CVar.hpp"
#include "athena/Utility.hpp"
namespace hecl
{
Console* Console::m_instance = nullptr;
Console::Console(CVarManager* cvarMgr)
{
m_instance = this;
registerCommand("help", "Prints information about a given function", "<command>", std::bind(&Console::help, this, std::placeholders::_1, std::placeholders::_2));
registerCommand("listCommands", "Prints a list of all available Commands", "", std::bind(&Console::listCommands, this, std::placeholders::_1, std::placeholders::_2));
registerCommand("listCVars", "Lists all available CVars", "", std::bind(&CVarManager::list, cvarMgr, std::placeholders::_1, std::placeholders::_2));
registerCommand("setCVar", "Sets a given Console Variable to the specified value", "<cvar> <value>", std::bind(&CVarManager::setCVar, cvarMgr, std::placeholders::_1, std::placeholders::_2));
registerCommand("getCVar", "Prints the value stored in the specified Console Variable", "<cvar>", std::bind(&CVarManager::getCVar, cvarMgr, std::placeholders::_1, std::placeholders::_2));
}
void Console::registerCommand(std::string_view name, std::string_view helpText, std::string_view usage, const std::function<void(Console*, const std::vector<std::string> &)>&& func)
{
std::string lowName = name.data();
athena::utility::tolower(lowName);
if (m_commands.find(lowName) == m_commands.end())
m_commands[lowName] = SConsoleCommand{name.data(), helpText.data(), usage.data(), std::move(func)};
}
void Console::executeString(const std::string& str)
{
if (str.empty())
return;
/* First let's split semi-colon delimited commands */
std::vector<std::string> commands = athena::utility::split(str, ';');
if (commands.empty())
return;
for (std::string command : commands)
{
command = athena::utility::trim(command);
std::vector<std::string> args = athena::utility::split(command, ' ');
if (args.empty())
continue;
std::string commandName = args[0];
args.erase(args.begin());
std::string lowComName = commandName;
athena::utility::tolower(lowComName);
if (m_commands.find(lowComName) != m_commands.end())
m_commands[lowComName].m_func(this, args);
else
report(Level::Error, "Command '%s' is not valid!", commandName.c_str());
}
}
void Console::help(Console* /*con*/, const std::vector<std::string>& args)
{
if (args.empty())
{
report(Level::Info, "Expected usage: help <command>");
return;
}
std::string cmd = args.front();
athena::utility::tolower(cmd);
auto it = m_commands.find(cmd);
if (it == m_commands.end())
{
report(Level::Error, "No such command '%s'", args.front().c_str());
return;
}
report(Level::Info, "%s: %s", it->second.m_displayName.c_str(), it->second.m_helpString.c_str());
if (!it->second.m_usage.empty())
report(Level::Info, "Usage: %s %s", it->second.m_displayName.c_str(), it->second.m_usage.c_str());
}
void Console::listCommands(Console* /*con*/, const std::vector<std::string>& /*args*/)
{
for (const auto& comPair : m_commands)
report(Level::Info, "'%s': %s", comPair.second.m_displayName.c_str(), comPair.second.m_helpString.c_str());
}
bool Console::commandExists(std::string_view cmd)
{
std::string cmdName = cmd.data();
athena::utility::tolower(cmdName);
return m_commands.find(cmdName) != m_commands.end();
}
void Console::report(Level level, const char* fmt, va_list list)
{
char tmp[2048];
vsnprintf(tmp, 2048, fmt, list);
m_log.emplace_back(std::string(tmp), level);
}
void Console::report(Level level, const char* fmt, ...)
{
va_list ap;
va_start(ap, fmt);
report(level, fmt, ap);
va_end(ap);
}
void Console::visorReport(Console::Level level, const char* mod, const wchar_t* fmt, va_list list)
{
wchar_t tmp[2048];
vswprintf(tmp, 2048, fmt, list);
std::string v = athena::utility::sprintf("[%s] %s", mod, athena::utility::wideToUtf8(tmp).c_str());
m_log.emplace_back(athena::utility::wideToUtf8(tmp), level);
}
void Console::visorReport(Console::Level level, const char* mod, const wchar_t* fmt, ...)
{
va_list ap;
va_start(ap, fmt);
report(level, mod, fmt, ap);
va_end(ap);
}
void Console::visorReportSource(Console::Level level, const char* mod, const char* file, unsigned line, const char* fmt, ...)
{
va_list ap;
va_start(ap, fmt);
visorReportSource(level, mod, file, line, fmt, ap);
va_end(ap);
}
void Console::visorReportSource(Console::Level level, const char *mod, const char *file, unsigned line, const wchar_t *fmt, va_list ap)
{
wchar_t tmp[2048];
vswprintf(tmp, 2048, fmt, ap);
std::string v = athena::utility::sprintf("[%s] %s %s:%i", mod, athena::utility::wideToUtf8(tmp).c_str(), file, line);
m_log.emplace_back(v, level);
}
void Console::visorReportSource(Console::Level level, const char *mod, const char* file, unsigned line, const wchar_t* fmt, ...)
{
va_list ap;
va_start(ap, fmt);
visorReportSource(level, mod, file, line, fmt, ap);
va_end(ap);
}
void Console::visorReport(Console::Level level, const char* mod, const char* fmt, va_list ap)
{
char tmp[2048];
vsnprintf(tmp, 2048, fmt, ap);
std::string v = athena::utility::sprintf("[%s] %s", mod, tmp);
m_log.emplace_back(v, level);
}
void Console::visorReport(Console::Level level, const char* mod, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
report(level, mod, fmt, ap);
va_end(ap);
}
void Console::visorReportSource(Console::Level level, const char* mod, const char* file, unsigned line, const char* fmt, va_list ap)
{
char tmp[2048];
vsnprintf(tmp, 2048, fmt, ap);
std::string v = athena::utility::sprintf("[%s] %s %s:%i", mod, tmp, file, line);
m_log.emplace_back(v, level);
}
void Console::LogVisorAdapter::report(const char* modName, logvisor::Level severity, const char *format, va_list ap)
{
m_con->visorReport(Console::Level(severity), modName, format, ap);
}
void Console::LogVisorAdapter::report(const char* modName, logvisor::Level severity, const wchar_t* format, va_list ap)
{
m_con->visorReport(Console::Level(severity), modName, format, ap);
}
void Console::LogVisorAdapter::reportSource(const char* modName, logvisor::Level severity, const char* file, unsigned linenum, const char* format, va_list ap)
{
m_con->visorReportSource(Console::Level(severity), modName, file, linenum, format, ap);
}
void Console::LogVisorAdapter::reportSource(const char* modName, logvisor::Level severity, const char* file, unsigned linenum, const wchar_t* format, va_list ap)
{
wchar_t tmp[2048];
vswprintf(tmp, 2048, format, ap);
std::string v = athena::utility::wideToUtf8(tmp);
m_con->visorReportSource(Console::Level(severity), modName, file, linenum, format, ap);
}
void Console::dumpLog()
{
for (const auto& l : m_log)
{
switch(l.second)
{
case Level::Info:
printf("%s\n", l.first.c_str());
break;
case Level::Warning:
printf("[Warning] %s\n", l.first.c_str());
break;
case Level::Error:
printf("[ Error ] %s\n", l.first.c_str());
break;
case Level::Fatal:
printf("[ Fatal ] %s\n", l.first.c_str());
break;
}
}
}
void Console::RegisterLogger(Console* con)
{
/* Determine if console logger already added */
for (auto& logger : logvisor::MainLoggers)
{
if (typeid(logger.get()) == typeid(LogVisorAdapter))
return;
}
/* Otherwise construct new console logger */
logvisor::MainLoggers.emplace_back(new LogVisorAdapter(con));
}
Console* Console::instance()
{
return m_instance;
}
}