feat: Added built-in logging console

This commit is contained in:
WerWolv 2023-07-23 23:37:47 +02:00
parent aa66d4b9e7
commit b8d5e1e9c5
8 changed files with 152 additions and 13 deletions

View File

@ -20,12 +20,20 @@ namespace hex::log {
bool isRedirected();
[[maybe_unused]] void redirectToFile();
extern std::mutex s_loggerMutex;
extern std::mutex g_loggerMutex;
struct LogEntry {
std::string project;
std::string level;
std::string message;
};
std::vector<LogEntry>& getLogEntries();
}
namespace {
[[maybe_unused]] void printPrefix(FILE *dest, const fmt::text_style &ts, const std::string &level) {
const auto now = fmt::localtime(std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()));
@ -41,22 +49,25 @@ namespace hex::log {
template<typename... T>
[[maybe_unused]] void print(const fmt::text_style &ts, const std::string &level, const std::string &fmt, auto... args) {
std::scoped_lock lock(impl::s_loggerMutex);
std::scoped_lock lock(impl::g_loggerMutex);
auto dest = impl::getDestination();
printPrefix(dest, ts, level);
fmt::print(dest, fmt::runtime(fmt), args...);
fmt::print(dest, "\n");
auto message = fmt::format(fmt::runtime(fmt), args...);
fmt::print(dest, "{}\n", message);
impl::getLogEntries().push_back({ IMHEX_PROJECT_NAME, level, std::move(message) });
}
}
[[maybe_unused]] void debug(const std::string &fmt, auto &&...args) {
#if defined(DEBUG)
hex::log::print(fg(fmt::color::light_green) | fmt::emphasis::bold, "[DEBUG]", fmt, args...);
#else
hex::unused(fmt, args...);
#endif
#if defined(DEBUG)
hex::log::print(fg(fmt::color::light_green) | fmt::emphasis::bold, "[DEBUG]", fmt, args...);
#else
impl::getLogEntries().push_back({ IMHEX_PROJECT_NAME, "[DEBUG]", fmt::format(fmt::runtime(fmt), args...) });
#endif
}
[[maybe_unused]] void info(const std::string &fmt, auto &&...args) {

View File

@ -7,7 +7,7 @@
namespace hex::log::impl {
static wolv::io::File s_loggerFile;
std::mutex s_loggerMutex;
std::mutex g_loggerMutex;
FILE *getDestination() {
if (s_loggerFile.isValid())
@ -36,4 +36,10 @@ namespace hex::log::impl {
}
}
std::vector<LogEntry>& getLogEntries() {
static std::vector<LogEntry> logEntries;
return logEntries;
}
}

View File

@ -61,6 +61,7 @@ add_library(${PROJECT_NAME} SHARED
source/content/views/view_provider_settings.cpp
source/content/views/view_find.cpp
source/content/views/view_theme_manager.cpp
source/content/views/view_logs.cpp
source/content/helpers/math_evaluator.cpp
source/content/helpers/notification.cpp

View File

@ -0,0 +1,28 @@
#pragma once
#include <hex.hpp>
#include <hex/api/content_registry.hpp>
#include <hex/ui/view.hpp>
#include <array>
#include <string>
namespace hex::plugin::builtin {
class ViewLogs : public View {
public:
ViewLogs();
~ViewLogs() override = default;
void drawContent() override;
[[nodiscard]] bool isAvailable() const override { return true; }
[[nodiscard]] bool hasViewMenuItemEntry() const override { return false; }
private:
int m_logLevel = 1;
bool m_viewOpen = false;
};
}

View File

@ -828,6 +828,10 @@
"hex.builtin.view.information.plain_text": "This data is most likely plain text.",
"hex.builtin.view.information.plain_text_percentage": "Plain text percentage",
"hex.builtin.view.information.provider_information": "Provider Information",
"hex.builtin.view.logs.component": "Component",
"hex.builtin.view.logs.log_level": "Log Level",
"hex.builtin.view.logs.message": "Message",
"hex.builtin.view.logs.name": "Log Console",
"hex.builtin.view.patches.name": "Patches",
"hex.builtin.view.patches.offset": "Offset",
"hex.builtin.view.patches.orig": "Original value",

View File

@ -19,6 +19,7 @@
#include "content/views/view_provider_settings.hpp"
#include "content/views/view_find.hpp"
#include "content/views/view_theme_manager.hpp"
#include "content/views/view_logs.hpp"
namespace hex::plugin::builtin {
@ -44,6 +45,7 @@ namespace hex::plugin::builtin {
ContentRegistry::Views::add<ViewProviderSettings>();
ContentRegistry::Views::add<ViewFind>();
ContentRegistry::Views::add<ViewThemeManager>();
ContentRegistry::Views::add<ViewLogs>();
}
}

View File

@ -0,0 +1,87 @@
#include "content/views/view_logs.hpp"
#include <hex/helpers/logger.hpp>
namespace hex::plugin::builtin {
ViewLogs::ViewLogs() : View("hex.builtin.view.logs.name") {
ContentRegistry::Interface::addMenuItem({ "hex.builtin.menu.extras", "hex.builtin.view.logs.name" }, 2500, Shortcut::None, [&, this] {
this->m_viewOpen = true;
this->getWindowOpenState() = true;
});
}
static ImColor getColor(std::string_view level) {
if (level.contains("DEBUG"))
return ImGui::GetCustomColorVec4(ImGuiCustomCol_ToolbarGreen);
else if (level.contains("INFO"))
return ImGui::GetCustomColorVec4(ImGuiCustomCol_ToolbarBlue);
else if (level.contains("WARN"))
return ImGui::GetCustomColorVec4(ImGuiCustomCol_ToolbarYellow);
else if (level.contains("ERROR"))
return ImGui::GetCustomColorVec4(ImGuiCustomCol_ToolbarRed);
else if (level.contains("FATAL"))
return ImGui::GetCustomColorVec4(ImGuiCustomCol_ToolbarPurple);
return ImGui::GetStyleColorVec4(ImGuiCol_Text);
}
static bool shouldDisplay(std::string_view messageLevel, int currLevel) {
if (currLevel == 0)
return true;
else if (currLevel == 1 && messageLevel.contains("INFO"))
return true;
else if (currLevel == 2 && messageLevel.contains("WARN"))
return true;
else if (currLevel == 3 && messageLevel.contains("ERROR"))
return true;
else if (currLevel == 4 && messageLevel.contains("FATAL"))
return true;
return false;
}
void ViewLogs::drawContent() {
if (ImGui::Begin(View::toWindowName("hex.builtin.view.logs.name").c_str(), &this->m_viewOpen, ImGuiWindowFlags_NoCollapse)) {
ImGui::Combo("hex.builtin.view.logs.log_level"_lang, &this->m_logLevel, "DEBUG\0INFO\0WARNING\0ERROR\0FATAL\0");
if (ImGui::BeginTable("##logs", 2, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg | ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_ScrollY)) {
ImGui::TableSetupColumn("hex.builtin.view.logs.component"_lang, ImGuiTableColumnFlags_WidthFixed, 100_scaled);
ImGui::TableSetupColumn("hex.builtin.view.logs.message"_lang);
ImGui::TableSetupScrollFreeze(0, 1);
ImGui::TableHeadersRow();
const auto &logs = log::impl::getLogEntries();
ImGuiListClipper clipper;
clipper.Begin(logs.size());
while (clipper.Step()) {
auto end = 0;
for (size_t i = clipper.DisplayStart; i < std::min<size_t>(clipper.DisplayEnd + end, logs.size()); i++) {
const auto &log = logs[i];
if (!shouldDisplay(log.level, this->m_logLevel)) {
end++;
clipper.ItemsCount--;
continue;
}
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::TextUnformatted(log.project.c_str());
ImGui::TableNextColumn();
ImGui::PushStyleColor(ImGuiCol_Text, getColor(log.level).Value);
ImGui::TextUnformatted(log.message.c_str());
ImGui::PopStyleColor();
}
}
ImGui::EndTable();
}
}
ImGui::End();
this->getWindowOpenState() = this->m_viewOpen;
}
}

View File

@ -28,11 +28,11 @@
inkscape:deskcolor="#505050"
inkscape:document-units="mm"
inkscape:zoom="0.25"
inkscape:cx="-426"
inkscape:cx="-428"
inkscape:cy="1558"
inkscape:window-width="2560"
inkscape:window-height="1369"
inkscape:window-x="2552"
inkscape:window-height="1417"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" /><defs

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 44 KiB