diff --git a/hecl/extern/boo b/hecl/extern/boo index 1a48dd9c4..0a93d6c10 160000 --- a/hecl/extern/boo +++ b/hecl/extern/boo @@ -1 +1 @@ -Subproject commit 1a48dd9c42cd25030281345831e7cfb2359426bd +Subproject commit 0a93d6c105e7807bd520bf37b262e922e9817473 diff --git a/hecl/include/hecl/CVarManager.hpp b/hecl/include/hecl/CVarManager.hpp index 68854b0db..db22db5b9 100755 --- a/hecl/include/hecl/CVarManager.hpp +++ b/hecl/include/hecl/CVarManager.hpp @@ -71,9 +71,9 @@ public: static CVarManager* instance(); - void list(const std::vector& args); - void setCVar(const std::vector& args); - void getCVar(const std::vector& args); + void list(class Console* con, const std::vector& args); + void setCVar(class Console* con, const std::vector& args); + void getCVar(class Console* con, const std::vector& args); bool restartRequired() const; diff --git a/hecl/include/hecl/Console.hpp b/hecl/include/hecl/Console.hpp index ae9224128..2da4f9cf2 100644 --- a/hecl/include/hecl/Console.hpp +++ b/hecl/include/hecl/Console.hpp @@ -5,6 +5,7 @@ #include #include #include +#include "logvisor/logvisor.hpp" namespace hecl { @@ -14,11 +15,31 @@ struct SConsoleCommand std::string m_displayName; std::string m_helpString; std::string m_usage; - std::function&)> m_func; + std::function&)> 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 @@ -31,21 +52,29 @@ public: private: std::unordered_map m_commands; std::vector> 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&)>&& func); + void registerCommand(std::string_view name, std::string_view helpText, std::string_view usage, const std::function&)>&& func); void executeString(const std::string& strToExec); - void help(const std::vector& args); - void listCommands(const std::vector& args); + void help(Console* con, const std::vector& args); + void listCommands(Console* con, const std::vector& args); bool commandExists(std::string_view cmd); - - void print(Level level, const char *fmt, va_list list); - void print(Level, const char* fmt, ...); + 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); }; } diff --git a/hecl/lib/CVarManager.cpp b/hecl/lib/CVarManager.cpp index ccc19780a..2f4e2c729 100755 --- a/hecl/lib/CVarManager.cpp +++ b/hecl/lib/CVarManager.cpp @@ -176,19 +176,18 @@ CVarManager* CVarManager::instance() return m_instance; } -void CVarManager::list(const std::vector &args) +void CVarManager::list(Console* con, const std::vector &args) { } -void CVarManager::setCVar(const std::vector &args) +void CVarManager::setCVar(Console* con, const std::vector &args) { } -void CVarManager::getCVar(const std::vector &args) +void CVarManager::getCVar(Console* con, const std::vector &args) { - } bool CVarManager::restartRequired() const diff --git a/hecl/lib/Console.cpp b/hecl/lib/Console.cpp index 7890d0954..fb221df8c 100644 --- a/hecl/lib/Console.cpp +++ b/hecl/lib/Console.cpp @@ -9,14 +9,14 @@ Console* Console::m_instance = nullptr; Console::Console(CVarManager* cvarMgr) { m_instance = this; - registerCommand("help", "Prints information about a given function", "", std::bind(&Console::help, this, std::placeholders::_1)); - registerCommand("listCommands", "Prints a list of all available Commands", "", std::bind(&Console::listCommands, this, std::placeholders::_1)); - registerCommand("listCVars", "Lists all available CVars", "", std::bind(&CVarManager::list, cvarMgr, std::placeholders::_1)); - registerCommand("setCVar", "Sets a given Console Variable to the specified value", " ", std::bind(&CVarManager::setCVar, cvarMgr, std::placeholders::_1)); - registerCommand("getCVar", "Prints the value stored in the specified Console Variable", "", std::bind(&CVarManager::getCVar, cvarMgr, std::placeholders::_1)); + registerCommand("help", "Prints information about a given function", "", 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", " ", std::bind(&CVarManager::setCVar, cvarMgr, std::placeholders::_1, std::placeholders::_2)); + registerCommand("getCVar", "Prints the value stored in the specified Console Variable", "", 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 &)>&& func) +void Console::registerCommand(std::string_view name, std::string_view helpText, std::string_view usage, const std::function &)>&& func) { std::string lowName = name.data(); athena::utility::tolower(lowName); @@ -49,17 +49,17 @@ void Console::executeString(const std::string& str) std::string lowComName = commandName; athena::utility::tolower(lowComName); if (m_commands.find(lowComName) != m_commands.end()) - m_commands[lowComName].m_func(args); + m_commands[lowComName].m_func(this, args); else - print(Level::Error, "Command '%s' is not valid!", commandName.c_str()); + report(Level::Error, "Command '%s' is not valid!", commandName.c_str()); } } -void Console::help(const std::vector& args) +void Console::help(Console* /*con*/, const std::vector& args) { if (args.empty()) { - print(Level::Info, "Expected usage: help "); + report(Level::Info, "Expected usage: help "); return; } std::string cmd = args.front(); @@ -67,19 +67,19 @@ void Console::help(const std::vector& args) auto it = m_commands.find(cmd); if (it == m_commands.end()) { - print(Level::Error, "No such command '%s'", args.front().c_str()); + report(Level::Error, "No such command '%s'", args.front().c_str()); return; } - print(Level::Info, "%s: %s", it->second.m_displayName.c_str(), it->second.m_helpString.c_str()); + report(Level::Info, "%s: %s", it->second.m_displayName.c_str(), it->second.m_helpString.c_str()); if (!it->second.m_usage.empty()) - print(Level::Info, "Usage: %s %s", it->second.m_displayName.c_str(), it->second.m_usage.c_str()); + report(Level::Info, "Usage: %s %s", it->second.m_displayName.c_str(), it->second.m_usage.c_str()); } -void Console::listCommands(const std::vector& /*args*/) +void Console::listCommands(Console* /*con*/, const std::vector& /*args*/) { for (const auto& comPair : m_commands) - print(Level::Info, "'%s': %s", comPair.second.m_displayName.c_str(), comPair.second.m_helpString.c_str()); + report(Level::Info, "'%s': %s", comPair.second.m_displayName.c_str(), comPair.second.m_helpString.c_str()); } bool Console::commandExists(std::string_view cmd) @@ -90,21 +90,108 @@ bool Console::commandExists(std::string_view cmd) return m_commands.find(cmdName) != m_commands.end(); } -void Console::print(Level level, const char* fmt, va_list list) +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::print(Level level, const char* fmt, ...) +void Console::report(Level level, const char* fmt, ...) { va_list ap; va_start(ap, fmt); - print(level, fmt, ap); + 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) @@ -127,6 +214,19 @@ void Console::dumpLog() } } +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;