diff --git a/source/mijin/logging/debug_output_sink.hpp b/source/mijin/logging/debug_output_sink.hpp new file mode 100644 index 0000000..54c900e --- /dev/null +++ b/source/mijin/logging/debug_output_sink.hpp @@ -0,0 +1,67 @@ + +#pragma once + +#if !defined(MIJIN_LOGGING_DEBUG_OUTPUT_SINK_HPP_INCLUDED) +#define MIJIN_LOGGING_DEBUG_OUTPUT_SINK_HPP_INCLUDED 1 + +#include "./formatting.hpp" +#include "../detect.hpp" +#include "../util/traits.hpp" + +#if MIJIN_TARGET_OS == MIJIN_OS_WINDOWS +#pragma comment(lib, "Kernel32.lib") + +extern "C" void OutputDebugStringA(const char* lpOutputString); +extern "C" void OutputDebugStringW(const wchar_t* lpOutputString); + +namespace mijin +{ +template + requires(allocator_type>) +class BaseDebugOutputSink : public BaseFormattingLogSink +{ +public: + using base_t = BaseFormattingLogSink; + using typename base_t::char_t; + using typename base_t::allocator_t; + using typename base_t::formatter_ptr_t; + using typename base_t::message_t; +public: + explicit BaseDebugOutputSink(formatter_ptr_t formatter, allocator_t allocator = {}) + MIJIN_NOEXCEPT_IF(std::is_nothrow_move_constructible_v) + : base_t(std::move(formatter), std::move(allocator)) {} + + void handleMessageFormatted(const message_t&, const char_t* formatted) MIJIN_NOEXCEPT override + { + if constexpr (std::is_same_v) + { + OutputDebugStringA(formatted); + OutputDebugStringA("\n"); + } + else if constexpr (std::is_same_v) + { + OutputDebugStringW(formatted); + OutputDebugStringW(L"\n"); + } + else if constexpr (sizeof(char_t) == sizeof(char)) + { + // char8_t etc. + OutputDebugStringA(std::bit_cast(formatted)); + OutputDebugStringA("\n"); + } + else + { + static_assert(always_false_v, "Character type not supported."); + } + } +}; + +#define SINK_SET_ARGS(chr_type) chr_type, std::char_traits, TAllocator, TDeleter + +MIJIN_DEFINE_CHAR_VERSIONS_TMPL(DebugOutputSink, MIJIN_FORMATTING_SINK_COMMON_ARGS, SINK_SET_ARGS) + +#undef SINK_SET_ARGS +} // namespace mijin + +#endif // MIJIN_TARGET_OS == MIJIN_OS_WINDOWS +#endif // !defined(MIJIN_LOGGING_DEBUG_OUTPUT_SINK_HPP_INCLUDED) diff --git a/source/mijin/logging/formatting.hpp b/source/mijin/logging/formatting.hpp index ad3a6f8..cae956d 100644 --- a/source/mijin/logging/formatting.hpp +++ b/source/mijin/logging/formatting.hpp @@ -92,10 +92,10 @@ public: using string_t = formatter_t::string_t; using typename base_t::message_t; private: - not_null_t mFormatter; + formatter_ptr_t mFormatter; string_t mBuffer; public: - explicit BaseFormattingLogSink(not_null_t formatter, allocator_t allocator = {}) + explicit BaseFormattingLogSink(formatter_ptr_t formatter, allocator_t allocator = {}) MIJIN_NOEXCEPT_IF(std::is_nothrow_move_constructible_v) : mFormatter(std::move(formatter)), mBuffer(std::move(allocator)) {} diff --git a/source/mijin/logging/logger.hpp b/source/mijin/logging/logger.hpp index 4904ae7..5de4045 100644 --- a/source/mijin/logging/logger.hpp +++ b/source/mijin/logging/logger.hpp @@ -254,10 +254,14 @@ MIJIN_DEFINE_LOG_LEVEL(ERROR, MIJIN_LOG_LEVEL_VALUE_ERROR) #define MIJIN_LOG_ALWAYS(level, channel, ...) MIJIN_FUNCNAME_GET_LOGGER().log( \ MIJIN_LOG_LEVEL_OBJECT(level), MIJIN_LOG_CHANNEL_OBJECT(channel), std::source_location::current(), __VA_ARGS__ \ ) -#define MIJIN_LOG(level, channel, ...) \ +#define MIJIN_LOG(level, channel, ...) \ if constexpr (MIJIN_LOG_LEVEL_OBJECT(level).value < MIJIN_FUNCNAME_MIN_LOG_LEVEL_COMPILE()) {} \ else MIJIN_LOG_ALWAYS(level, channel, __VA_ARGS__) +#define MIJIN_LOG_IF(cond, level, channel, ...) \ +if constexpr (MIJIN_LOG_LEVEL_OBJECT(level).value < MIJIN_FUNCNAME_MIN_LOG_LEVEL_COMPILE()) {} \ +else if (cond) MIJIN_LOG_ALWAYS(level, channel, __VA_ARGS__) + #define MIJIN_SET_CLASS_LOGGER(loggerExpr) \ const auto& MIJIN_FUNCNAME_GET_LOGGER() const noexcept \ { \ @@ -268,6 +272,11 @@ auto MIJIN_FUNCNAME_GET_LOGGER = [&]() -> const auto& \ { \ return loggerExpr; \ }; +#define MIJIN_SET_NS_LOGGER(loggerExpr) \ +inline const mijin::Logger& MIJIN_FUNCNAME_GET_LOGGER() \ +{ \ + return loggerExpr; \ +} #define MIJIN_SET_CLASS_MIN_LOG_LEVEL_COMPILE(level) \ int MIJIN_FUNCNAME_MIN_LOG_LEVEL_COMPILE() MIJIN_NOEXCEPT \ { \ diff --git a/source/mijin/logging/stdio_sink.hpp b/source/mijin/logging/stdio_sink.hpp index 7aa1e8c..423806a 100644 --- a/source/mijin/logging/stdio_sink.hpp +++ b/source/mijin/logging/stdio_sink.hpp @@ -22,7 +22,7 @@ public: private: int mMinStderrLevel = MIJIN_LOG_LEVEL_VALUE_WARNING; public: - explicit BaseStdioSink(not_null_t formatter, allocator_t allocator = {}) + explicit BaseStdioSink(formatter_ptr_t formatter, allocator_t allocator = {}) MIJIN_NOEXCEPT_IF(std::is_nothrow_move_constructible_v) : base_t(std::move(formatter), std::move(allocator)) {}