// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. #pragma once #include "Engine/Core/Singleton.h" #include "Engine/Core/Delegate.h" #include "Engine/Core/Types/String.h" #include "Engine/Core/Types/StringView.h" // Enable/disable auto flush function #define LOG_ENABLE_AUTO_FLUSH 1 /// /// Sends a formatted message to the log file (message type - describes level of the log (see LogType enum)) /// #define LOG(messageType, format, ...) Log::Logger::Write(LogType::messageType, ::String::Format(TEXT(format), ##__VA_ARGS__)) /// /// Sends a string message to the log file (message type - describes level of the log (see LogType enum)) /// #define LOG_STR(messageType, str) Log::Logger::Write(LogType::messageType, str) #if LOG_ENABLE_AUTO_FLUSH // Flushes the log file buffer #define LOG_FLUSH() Log::Logger::Flush() #else #define LOG_FLUSH() #endif /// /// The log message types. /// API_ENUM() enum class LogType { /// /// The information log message. /// Info = 1, /// /// The warning message. /// Warning = 2, /// /// The error message. /// Error = 4, /// /// The fatal error. /// Fatal = 8, }; extern const Char* ToString(LogType e); namespace Log { class Exception; /// /// Singleton logger class /// /// class FLAXENGINE_API Logger : public Singleton { public: /// /// Current log file path. Empty if not used. /// static String LogFilePath; /// /// Action fired on new log message. /// static Delegate OnMessage; /// /// Action fired on new log error message. /// static Delegate OnError; public: /// /// Initializes a logging service. /// /// True if cannot init logging service, otherwise false. static bool Init(); /// /// Disposes a logging service. /// static void Dispose(); public: FORCE_INLINE static bool IsError(const LogType type) { return type == LogType::Fatal || type == LogType::Error; } public: /// /// Determines whether logging to file is enabled. /// /// true if log is enabled; otherwise, false. static bool IsLogEnabled(); /// /// Flushes log file with a memory buffer. /// static void Flush(); /// /// Writes a series of '=' chars to the log to end a section. /// static void WriteFloor(); /// /// Writes a message to the log file. /// /// The message type. /// The message text. template FORCE_INLINE static void Write(LogType type, const Char* msg) { Write(type, StringView(msg)); } /// /// Writes a formatted message to the log file. /// /// The message type. /// The message format string. /// The format arguments. template FORCE_INLINE static void Write(LogType type, const Char* format, const Args& ... args) { Write(type, String::Format(format, args...)); } /// /// Write a message to the log. /// /// The message type. /// The message text. static void Write(LogType type, const StringView& msg); /// /// Writes a custom message to the log. /// /// The message text. FORCE_INLINE static void Write(const Char* msg) { Write(StringView(msg)); } /// /// Writes a custom message to the log. /// /// The message text. FORCE_INLINE static void Write(const String& msg) { Write(StringView(msg)); } /// /// Writes a custom message to the log. /// /// The message text. static void Write(const StringView& msg); /// /// Writes an exception formatted message to log file. /// /// The exception to write to the file. static void Write(const Exception& exception); private: static void ProcessLogMessage(LogType type, const StringView& msg, fmt_flax::memory_buffer& w); }; }