// 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, 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);
};
}