#pragma once #include "Base.hpp" #include #include #include #include namespace cru::log { enum class LogLevel { Debug, Info, Warn, Error }; struct CRU_BASE_API ILogSource : virtual Interface { // Write the string s. LogLevel is just a helper. It has no effect on the // content to write. virtual void Write(LogLevel level, const std::u16string& s) = 0; }; class CRU_BASE_API Logger : public Object { public: static Logger* GetInstance(); public: Logger() = default; CRU_DELETE_COPY(Logger) CRU_DELETE_MOVE(Logger) ~Logger() override = default; public: void AddSource(std::unique_ptr source); void RemoveSource(ILogSource* source); public: void Log(LogLevel level, std::u16string_view s); void Log(LogLevel level, std::u16string_view tag, std::u16string_view s); private: std::list> sources_; }; // TODO: Remove argument evaluation in Debug. template void Debug([[maybe_unused]] TArgs&&... args) { #ifdef CRU_DEBUG Logger::GetInstance()->Log(LogLevel::Debug, fmt::format(std::forward(args)...)); #endif } template void Info(TArgs&&... args) { Logger::GetInstance()->Log(LogLevel::Info, fmt::format(std::forward(args)...)); } template void Warn(TArgs&&... args) { Logger::GetInstance()->Log(LogLevel::Warn, fmt::format(std::forward(args)...)); } template void Error(TArgs&&... args) { Logger::GetInstance()->Log(LogLevel::Error, fmt::format(std::forward(args)...)); } // TODO: Remove argument evaluation in Debug. template void TagDebug([[maybe_unused]] std::u16string_view tag, [[maybe_unused]] TArgs&&... args) { #ifdef CRU_DEBUG Logger::GetInstance()->Log(LogLevel::Debug, tag, fmt::format(std::forward(args)...)); #endif } template void TagInfo(std::u16string_view tag, TArgs&&... args) { Logger::GetInstance()->Log(LogLevel::Info, tag, fmt::format(std::forward(args)...)); } template void TagWarn(std::u16string_view tag, TArgs&&... args) { Logger::GetInstance()->Log(LogLevel::Warn, tag, fmt::format(std::forward(args)...)); } template void TagError(std::u16string_view tag, TArgs&&... args) { Logger::GetInstance()->Log(LogLevel::Error, tag, fmt::format(std::forward(args)...)); } } // namespace cru::log