From 09830dde00b4aacd9df3ef01e7cd725ba43f0d01 Mon Sep 17 00:00:00 2001 From: dantmnf Date: Wed, 10 Jul 2024 17:11:52 +0800 Subject: [PATCH] feat: win32 console-aware debug logger [skip changelog] --- src/MaaCore/Utils/Locale.hpp | 60 ++++++++++++++++++++++++++++++++++++ src/MaaCore/Utils/Logger.hpp | 27 ++++++++-------- 2 files changed, 74 insertions(+), 13 deletions(-) diff --git a/src/MaaCore/Utils/Locale.hpp b/src/MaaCore/Utils/Locale.hpp index 68aceb29c5..a4a9bea973 100644 --- a/src/MaaCore/Utils/Locale.hpp +++ b/src/MaaCore/Utils/Locale.hpp @@ -2,6 +2,8 @@ #include #include +#include +#include #include #include #include @@ -9,6 +11,8 @@ #include "Meta.hpp" #ifdef _WIN32 +#include +#include #include "Platform/SafeWindows.h" #endif @@ -129,4 +133,60 @@ namespace asst::utils } return str; } + + class utf8_scope + { +#ifdef _WIN32 + bool active; + int thread_mode; + std::string old_locale; + + static bool is_console_ostream(std::ostream& ofs) + { + if (&ofs == &std::cout) { + return _isatty(_fileno(stdout)); + } + if (&ofs == &std::cerr) { + return _isatty(_fileno(stderr)); + } + return false; + } + + public: + utf8_scope(std::nullptr_t) + { + active = false; + thread_mode = 0; + } + + ~utf8_scope() + { + if (!active) return; + if (!old_locale.empty()) { + setlocale(LC_ALL, old_locale.c_str()); + } + _configthreadlocale(_DISABLE_PER_THREAD_LOCALE); + } + + utf8_scope(std::ostream& ofs) + { + if (is_console_ostream(ofs)) { + active = true; + thread_mode = _configthreadlocale(_ENABLE_PER_THREAD_LOCALE); + auto old_locale_ptr = setlocale(LC_ALL, ".UTF-8"); + if (old_locale_ptr) { + old_locale = old_locale_ptr; + } + } + else { + active = false; + } + } +#else + public: + utf8_scope(std::ostream&) + { + } +#endif + }; } // namespace asst::utils diff --git a/src/MaaCore/Utils/Logger.hpp b/src/MaaCore/Utils/Logger.hpp index 7ff6206dd7..cb65a6876b 100644 --- a/src/MaaCore/Utils/Logger.hpp +++ b/src/MaaCore/Utils/Logger.hpp @@ -248,32 +248,33 @@ private: }; } // namespace detail -class toansi_ostream +class console_ostream { std::reference_wrapper m_ofs; public: - toansi_ostream(toansi_ostream&&) = default; - toansi_ostream(const toansi_ostream&) = default; - toansi_ostream& operator=(toansi_ostream&&) = default; - toansi_ostream& operator=(const toansi_ostream&) = default; + console_ostream(console_ostream&&) = default; + console_ostream(const console_ostream&) = default; + console_ostream& operator=(console_ostream&&) = default; + console_ostream& operator=(const console_ostream&) = default; - toansi_ostream(std::ostream& stream) + console_ostream(std::ostream& stream) : m_ofs(stream) { } - toansi_ostream(std::reference_wrapper stream) + console_ostream(std::reference_wrapper stream) : m_ofs(stream) { } template requires has_stream_insertion_operator - toansi_ostream& operator<<(T&& v) + console_ostream& operator<<(T&& v) { if constexpr (std::convertible_to) { - m_ofs.get() << utils::utf8_to_ansi(std::forward(v)); + asst::utils::utf8_scope scope(m_ofs.get()); + m_ofs.get() << std::forward(v); } else { m_ofs.get() << std::forward(v); @@ -281,7 +282,7 @@ public: return *this; } - toansi_ostream& operator<<(std::ostream& (*pf)(std::ostream&)) + console_ostream& operator<<(std::ostream& (*pf)(std::ostream&)) { m_ofs.get() << pf; return *this; @@ -578,7 +579,7 @@ public: } if constexpr (std::same_as>) { #ifdef ASST_DEBUG - return LogStream(m_trace_mutex, ostreams { toansi_ostream(std::cout), m_ofs }, arg); + return LogStream(m_trace_mutex, ostreams { console_ostream(std::cout), m_ofs }, arg); #else return LogStream(m_trace_mutex, m_ofs, arg); #endif @@ -587,7 +588,7 @@ public: #ifdef ASST_DEBUG return LogStream( m_trace_mutex, - ostreams { toansi_ostream(std::cout), m_ofs }, + ostreams { console_ostream(std::cout), m_ofs }, level::trace, arg); #else @@ -665,7 +666,7 @@ public: (LogStream( std::move(lock), #ifdef ASST_DEBUG - ostreams { toansi_ostream(std::cout), m_ofs }, + ostreams { console_ostream(std::cout), m_ofs }, #else m_ofs, #endif