LUS Cleanup: Strips out the logging system created for the console

Properly routes SPDLog to the console.
Creates an API to be able to send command responses back to the console.
Cleans up the console UI, hiding options when not needed.
Removes stdout console sink for Windows.
This commit is contained in:
Kenix3
2022-08-09 21:47:39 -04:00
parent 1f351418e1
commit c7ccd6dbff
14 changed files with 309 additions and 282 deletions
+98 -60
View File
@@ -15,9 +15,9 @@ namespace Ship {
std::map<ImGuiKey, std::string> BindingToggle;
static bool HelpCommand(const std::vector<std::string>&) {
INFO("SoH Commands:");
SohImGui::console->SendInfoMessage("SoH Commands:");
for (const auto& cmd : SohImGui::console->Commands) {
INFO("%s", (" - " + cmd.first).c_str());
SohImGui::console->SendInfoMessage(" - " + cmd.first);
}
return CMD_SUCCESS;
}
@@ -45,7 +45,7 @@ namespace Ship {
std::ostringstream imploded;
std::copy(args.begin() + 2, args.end(), std::ostream_iterator<std::string>(imploded, delim));
Bindings[k] = imploded.str();
INFO("Binding '%s' to %s", args[1].c_str(), Bindings[k].c_str());
SohImGui::console->SendInfoMessage("Binding '%s' to %s", args[1], Bindings[k]);
break;
}
}
@@ -61,7 +61,7 @@ namespace Ship {
if (toLowerCase(args[1]) == toLowerCase(key)) {
BindingToggle[k] = args[2];
INFO("Binding toggle '%s' to %s", args[1].c_str(), BindingToggle[k].c_str());
SohImGui::console->SendInfoMessage("Binding toggle '%s' to %s", args[1].c_str(), BindingToggle[k].c_str());
break;
}
}
@@ -159,29 +159,39 @@ namespace Ship {
// Renders top bar filters
if (ImGui::Button("Clear")) this->Log[this->selected_channel].clear();
ImGui::SameLine();
ImGui::SetNextItemWidth(150);
if (ImGui::BeginCombo("##channel", this->selected_channel.c_str())) {
for (const auto& channel : log_channels) {
const bool is_selected = (channel == std::string(this->selected_channel));
if (ImGui::Selectable(channel.c_str(), is_selected))
this->selected_channel = channel;
if (is_selected) ImGui::SetItemDefaultFocus();
if (CVar_GetS32("gSinkEnabled", 0)) {
ImGui::SameLine();
ImGui::SetNextItemWidth(150);
if (ImGui::BeginCombo("##channel", this->selected_channel.c_str())) {
for (const auto& channel : log_channels) {
const bool is_selected = (channel == std::string(this->selected_channel));
if (ImGui::Selectable(channel.c_str(), is_selected))
this->selected_channel = channel;
if (is_selected) ImGui::SetItemDefaultFocus();
}
ImGui::EndCombo();
}
ImGui::EndCombo();
} else {
this->selected_channel = "Console";
}
ImGui::SameLine();
ImGui::SetNextItemWidth(150);
if (ImGui::BeginCombo("##level", this->level_filter.c_str())) {
for (const auto& filter : priority_filters) {
const bool is_selected = (filter == std::string(this->level_filter));
if (ImGui::Selectable(filter.c_str(), is_selected))
{
this->level_filter = filter;
if (is_selected) ImGui::SetItemDefaultFocus();
if (this->selected_channel != "Console") {
if (ImGui::BeginCombo("##level", spdlog::level::to_string_view(this->level_filter).data())) {
for (const auto& priority_filter : priority_filters) {
const bool is_selected = priority_filter == this->level_filter;
if (ImGui::Selectable(spdlog::level::to_string_view(priority_filter).data(), is_selected))
{
this->level_filter = priority_filter;
if (is_selected) ImGui::SetItemDefaultFocus();
}
}
ImGui::EndCombo();
}
ImGui::EndCombo();
} else {
this->level_filter = spdlog::level::trace;
}
ImGui::SameLine();
ImGui::PushItemWidth(-1);
@@ -203,7 +213,7 @@ namespace Ship {
for (int i = 0; i < static_cast<int>(channel.size()); i++) {
ConsoleLine line = channel[i];
if (!this->filter.empty() && line.text.find(this->filter) == std::string::npos) continue;
if (this->level_filter != NULLSTR && line.priority != (std::find(priority_filters.begin(), priority_filters.end(), this->level_filter) - priority_filters.begin()) - 1) continue;
if (this->level_filter > line.priority) continue;
std::string id = line.text + "##" + std::to_string(i);
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
@@ -226,54 +236,56 @@ namespace Ship {
ImGui::SetScrollHereY(1.0f);
ImGui::EndChild();
// Renders input textfield
constexpr ImGuiInputTextFlags flags = ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_CallbackEdit |
ImGuiInputTextFlags_CallbackCompletion | ImGuiInputTextFlags_CallbackHistory;
ImGui::PushItemWidth(-53);
if (ImGui::InputTextWithHint("##CMDInput", ">", this->InputBuffer, MAX_BUFFER_SIZE, flags, &Console::CallbackStub, this)) {
input_focus = true;
if (this->InputBuffer[0] != '\0' && this->InputBuffer[0] != ' ')
this->Dispatch(std::string(this->InputBuffer));
memset(this->InputBuffer, 0, MAX_BUFFER_SIZE);
}
if (this->CMDHint != NULLSTR) {
if (ImGui::IsItemFocused()) {
ImGui::SetNextWindowPos(ImVec2(pos.x, pos.y + size.y));
ImGui::SameLine();
ImGui::BeginTooltip();
ImGui::PushTextWrapPos(ImGui::GetFontSize() * 35.0f);
ImGui::TextUnformatted(this->CMDHint.c_str());
ImGui::PopTextWrapPos();
ImGui::EndTooltip();
if (this->selected_channel == "Console") {
// Renders input textfield
constexpr ImGuiInputTextFlags flags = ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_CallbackEdit |
ImGuiInputTextFlags_CallbackCompletion | ImGuiInputTextFlags_CallbackHistory;
ImGui::PushItemWidth(-53);
if (ImGui::InputTextWithHint("##CMDInput", ">", this->InputBuffer, MAX_BUFFER_SIZE, flags, &Console::CallbackStub, this)) {
input_focus = true;
if (this->InputBuffer[0] != '\0' && this->InputBuffer[0] != ' ')
this->Dispatch(std::string(this->InputBuffer));
memset(this->InputBuffer, 0, MAX_BUFFER_SIZE);
}
}
ImGui::SameLine();
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + ImGui::GetContentRegionAvail().x - 50);
if (ImGui::Button("Submit") && !input_focus && this->InputBuffer[0] != '\0' && this->InputBuffer[0] != ' ') {
this->Dispatch(std::string(this->InputBuffer));
memset(this->InputBuffer, 0, MAX_BUFFER_SIZE);
}
if (this->CMDHint != NULLSTR) {
if (ImGui::IsItemFocused()) {
ImGui::SetNextWindowPos(ImVec2(pos.x, pos.y + size.y));
ImGui::SameLine();
ImGui::BeginTooltip();
ImGui::PushTextWrapPos(ImGui::GetFontSize() * 35.0f);
ImGui::TextUnformatted(this->CMDHint.c_str());
ImGui::PopTextWrapPos();
ImGui::EndTooltip();
}
}
ImGui::SetItemDefaultFocus();
if (input_focus) ImGui::SetKeyboardFocusHere(-1);
ImGui::PopItemWidth();
ImGui::SameLine();
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + ImGui::GetContentRegionAvail().x - 50);
if (ImGui::Button("Submit") && !input_focus && this->InputBuffer[0] != '\0' && this->InputBuffer[0] != ' ') {
this->Dispatch(std::string(this->InputBuffer));
memset(this->InputBuffer, 0, MAX_BUFFER_SIZE);
}
ImGui::SetItemDefaultFocus();
if (input_focus) ImGui::SetKeyboardFocusHere(-1);
ImGui::PopItemWidth();
}
ImGui::End();
}
void Console::Dispatch(const std::string& line) {
this->CMDHint = NULLSTR;
this->History.push_back(line);
this->Log[this->selected_channel].push_back({ "> " + line });
SendInfoMessage("> " + line);
const std::vector<std::string> cmd_args = StringHelper::Split(line, " ");
if (this->Commands.contains(cmd_args[0])) {
const CommandEntry entry = this->Commands[cmd_args[0]];
if (!entry.handler(cmd_args) && !entry.arguments.empty())
this->Log[this->selected_channel].push_back({ "[SOH] Usage: " + cmd_args[0] + " " + BuildUsage(entry), ERROR_LVL });
SendErrorMessage("[SOH] Usage: " + cmd_args[0] + " " + BuildUsage(entry));
return;
}
this->Log[this->selected_channel].push_back({ "[SOH] Command not found", ERROR_LVL });
SendErrorMessage("[SOH] Command not found");
}
int Console::CallbackStub(ImGuiInputTextCallbackData* data) {
@@ -325,13 +337,39 @@ namespace Ship {
return 0;
}
void Console::Append(const std::string& channel, Priority priority, const char* fmt, ...) {
char buf[1024];
va_list args;
va_start(args, fmt);
void Console::Append(const std::string& channel, spdlog::level::level_enum priority, const char* fmt, va_list args) {
char buf[2048];
vsnprintf(buf, IM_ARRAYSIZE(buf), fmt, args);
buf[IM_ARRAYSIZE(buf) - 1] = 0;
va_end(args);
this->Log[channel].push_back({ std::string(buf), priority });
}
void Console::Append(const std::string& channel, spdlog::level::level_enum priority, const char* fmt, ...) {
va_list args;
va_start(args, fmt);
Append(channel, priority, fmt, args);
va_end(args);
}
void Console::SendInfoMessage(const char* fmt, ...) {
va_list args;
va_start(args, fmt);
Append("Console", spdlog::level::info, fmt, args);
va_end(args);
}
void Console::SendErrorMessage(const char* fmt, ...) {
va_list args;
va_start(args, fmt);
Append("Console", spdlog::level::err, fmt, args);
va_end(args);
}
void Console::SendInfoMessage(const std::string& str) {
Append("Console", spdlog::level::info, str.c_str());
}
void Console::SendErrorMessage(const std::string& str) {
Append("Console", spdlog::level::err, str.c_str());
}
}
+23 -21
View File
@@ -6,12 +6,11 @@
#include <functional>
#include "Lib/ImGui/imgui.h"
#define NOGDI
#define WIN32_LEAN_AND_MEAN
#include "spdlog/spdlog.h"
namespace Ship {
#define LOG(msg, ...) SohImGui::console->Append("Main", Ship::Priority::LOG_LVL, msg, ##__VA_ARGS__)
#define INFO(msg, ...) SohImGui::console->Append("Main", Ship::Priority::INFO_LVL, msg, ##__VA_ARGS__)
#define WARNING(msg, ...) SohImGui::console->Append("Main", Ship::Priority::WARNING_LVL, msg, ##__VA_ARGS__)
#define ERROR(msg, ...) SohImGui::console->Append("Main", Ship::Priority::ERROR_LVL, msg, ##__VA_ARGS__)
#define CMD_SUCCESS true
#define CMD_FAILED false
#define MAX_BUFFER_SIZE 255
@@ -19,13 +18,6 @@ namespace Ship {
typedef std::function<bool(std::vector<std::string> args)> CommandHandler;
enum Priority {
INFO_LVL,
LOG_LVL,
WARNING_LVL,
ERROR_LVL
};
enum class ArgumentType {
TEXT, NUMBER, PLAYER_POS, PLAYER_ROT
};
@@ -44,7 +36,7 @@ namespace Ship {
struct ConsoleLine {
std::string text;
Priority priority = Priority::INFO_LVL;
spdlog::level::level_enum priority = spdlog::level::info;
std::string channel = "Main";
};
@@ -52,15 +44,21 @@ namespace Ship {
int selectedId = -1;
std::vector<int> selectedEntries;
std::string filter;
std::string level_filter = NULLSTR;
std::vector<std::string> log_channels = { "Main", "SoH Logging" };
std::vector<std::string> priority_filters = { "None", "Info", "Log", "Warning", "Error" };
spdlog::level::level_enum level_filter = spdlog::level::trace;
std::vector<std::string> log_channels = { "Console", "Logs" };
std::vector<spdlog::level::level_enum> priority_filters = { spdlog::level::off, spdlog::level::critical, spdlog::level::err, spdlog::level::warn, spdlog::level::info, spdlog::level::debug, spdlog::level::trace };
std::vector<ImVec4> priority_colors = {
ImVec4(1.0f, 1.0f, 1.0f, 1.0f),
ImVec4(0.2f, 1.0f, 0.2f, 1.0f),
ImVec4(0.9f, 0.8f, 0.4f, 0.01f),
ImVec4(1.0f, 0.2f, 0.2f, 1.0f)
ImVec4(0.8f, 0.8f, 0.8f, 1.0f), // TRACE
ImVec4(0.9f, 0.9f, 0.9f, 1.0f), // DEBUG
ImVec4(1.0f, 1.0f, 1.0f, 1.0f), // INFO
ImVec4(1.0f, 0.875f, 0.125f, 1.0f), // WARN
ImVec4(0.65f, 0.18f, 0.25, 1.0f), // ERROR
ImVec4(0.95f, 0.11f, 0.25, 1.0f), // CRITICAL
ImVec4(0.0f, 0.0f, 0.0f, 0.0f) // OFF
};
protected:
void Append(const std::string& channel, spdlog::level::level_enum priority, const char* fmt, va_list args);
public:
std::map<std::string, std::vector<ConsoleLine>> Log;
std::map<std::string, CommandEntry> Commands;
@@ -71,13 +69,17 @@ namespace Ship {
char* InputBuffer = nullptr;
bool OpenAutocomplete = false;
int HistoryIndex = -1;
std::string selected_channel = "Main";
std::string selected_channel = "Console";
bool opened = false;
void Init();
void Update();
void Draw();
void Append(const std::string& channel, Priority priority, const char* fmt, ...) IM_FMTARGS(4);
void Dispatch(const std::string& line);
static int CallbackStub(ImGuiInputTextCallbackData* data);
void SendInfoMessage(const char* fmt, ...);
void SendErrorMessage(const char* fmt, ...);
void SendInfoMessage(const std::string& str);
void SendErrorMessage(const std::string& str);
void Append(const std::string& channel, spdlog::level::level_enum priority, const char* fmt, ...);
};
}
+1
View File
@@ -1,4 +1,5 @@
#include "Cutscene.h"
#include "spdlog/spdlog.h"
enum class CutsceneCommands
{
+5 -6
View File
@@ -4,7 +4,6 @@
#include "File.h"
#include "Archive.h"
#include "ResourceMgr.h"
#include "Console.h"
#include "ImGuiImpl.h"
#include "Lib/ImGui/imgui_internal.h"
#include "Utils/StringHelper.h"
@@ -209,24 +208,24 @@ namespace Ship {
if (args[1] == "add") {
if (!overlay->RegisteredOverlays.contains(key)) {
overlay->RegisteredOverlays[key] = new Overlay({ OverlayType::TEXT, ImStrdup(key), -1.0f });
INFO("Added overlay: %s ", key);
SPDLOG_INFO("Added overlay: {} ", key);
}
else {
ERROR("Overlay already exists: %s", key);
SPDLOG_ERROR("Overlay already exists: %s", key);
}
}
else if (args[1] == "remove") {
if (overlay->RegisteredOverlays.contains(key)) {
overlay->RegisteredOverlays.erase(key);
INFO("Removed overlay: %s ", key);
SPDLOG_INFO("Removed overlay: {} ", key);
}
else {
ERROR("Overlay not found: %s ", key);
SPDLOG_ERROR("Overlay not found: %s ", key);
}
}
}
else {
ERROR("CVar %s does not exist", args[2].c_str());
SPDLOG_ERROR("CVar %s does not exist", args[2].c_str());
}
return CMD_SUCCESS;
+11 -3
View File
@@ -90,12 +90,20 @@ namespace Ship {
// Setup Logging
spdlog::init_thread_pool(8192, 1);
auto SohConsoleSink = std::make_shared<spdlog::sinks::soh_sink_mt>();
auto ConsoleSink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
auto FileSink = std::make_shared<spdlog::sinks::rotating_file_sink_mt>(logPath, 1024 * 1024 * 10, 10);
SohConsoleSink->set_level(spdlog::level::trace);
#if defined(__linux__)
auto ConsoleSink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
ConsoleSink->set_level(spdlog::level::trace);
#endif
auto FileSink = std::make_shared<spdlog::sinks::rotating_file_sink_mt>(logPath, 1024 * 1024 * 10, 10);
FileSink->set_level(spdlog::level::trace);
std::vector<spdlog::sink_ptr> Sinks{ ConsoleSink, FileSink, SohConsoleSink };
std::vector<spdlog::sink_ptr> Sinks{
#if defined(__linux__)
ConsoleSink,
#endif
FileSink,
SohConsoleSink
};
Logger = std::make_shared<spdlog::async_logger>(GetName(), Sinks.begin(), Sinks.end(), spdlog::thread_pool(), spdlog::async_overflow_policy::block);
GetLogger()->set_level(spdlog::level::trace);
GetLogger()->set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%@] [%l] %v");
@@ -31,47 +31,24 @@ public:
{}
protected:
void sink_it_(const details::log_msg &msg) override
{
const Ship::Priority priority = convert_to_soh(msg.level);
void sink_it_(const details::log_msg &msg) override {
memory_buf_t formatted;
if (use_raw_msg_)
{
if (use_raw_msg_) {
details::fmt_helper::append_string_view(msg.payload, formatted);
}
else
{
else {
base_sink<Mutex>::formatter_->format(msg, formatted);
}
formatted.push_back('\0');
const char *msg_output = formatted.data();
if (CVar_GetS32("gSinkEnabled", 0) && SohImGui::console->opened)
SohImGui::console->Append("SoH Logging", priority, "%s", msg_output);
const char* msg_output = formatted.data();
if (CVar_GetS32("gSinkEnabled", 0) && SohImGui::console->opened) {
SohImGui::console->Append("Logs", msg.level, "%s", msg_output);
}
}
void flush_() override {}
private:
static Ship::Priority convert_to_soh(spdlog::level::level_enum level)
{
switch (level) {
case spdlog::level::trace:
return Ship::Priority::INFO_LVL;
case spdlog::level::debug:
return Ship::Priority::LOG_LVL;
case spdlog::level::info:
return Ship::Priority::LOG_LVL;
case spdlog::level::warn:
return Ship::Priority::WARNING_LVL;
case spdlog::level::err:
return Ship::Priority::ERROR_LVL;
case spdlog::level::critical:
return Ship::Priority::ERROR_LVL;
default:
break;
}
return Ship::Priority::LOG_LVL;
}
std::string tag_;
bool use_raw_msg_;
+1
View File
@@ -1,6 +1,7 @@
#include "Resource.h"
#include "DisplayList.h"
#include "ResourceMgr.h"
#include "spdlog/spdlog.h"
#include "Utils/BinaryReader.h"
#include "Lib/tinyxml2/tinyxml2.h"
#include "Lib/Fast3D/U64/PR/ultra64/gbi.h"