#pragma once namespace Feather::Logging { const int MAX_LOG_MESSAGE_LENGTH = 2048; const int MAX_LOGGING_CHANNEL_COUNT = 256; /*==== Severity Levels ==============================*/ enum class Level { // Serious problems Error = -2, // Potential problems of note Warning = -1, // General messages for end-users Info = 0, // More advanced information for problem-solving Debug = 1, // Fine grained spew Trace = 2, // These are an inclusve interval MinLevel = Error, MaxLevel = Trace, }; /*==== Channels ==============================*/ typedef int ChannelID; class Channel { const char* m_name; public: Channel(const char* name) : m_name(name) {} inline const char* GetName() { return m_name; } }; extern ChannelID LOG_GENERAL; /*==== Logger ==============================*/ class Logger { public: Logger(); void LogDirect(ChannelID channel, Level level, const char* message, ...); ChannelID RegisterChannel(const char* name); private: Channel* m_channels[MAX_LOGGING_CHANNEL_COUNT]; ChannelID m_channelCount = 0; }; extern Logger GlobalLogger; } #define REGISTER_LOGGING_CHANNEL(Name) ::Feather::Logging::GlobalLogger.RegisterChannel(Name); // Logs a message, specifying a channel and log level #define Log_Msg(_Channel, _Level, _Message, ...) ::Feather::Logging::GlobalLogger.LogDirect(::Feather::Logging::_Channel, ::Feather::Logging::Level::_Level, _Message, ##__VA_ARGS__) // Logs a general message for end-users #define Log_Info(Message, ...) Log_Msg(LOG_GENERAL, Info, Message, ##__VA_ARGS__) // Logs a potential problem of note #define Log_Warn(Message, ...) Log_Msg(LOG_GENERAL, Warning, Message, ##__VA_ARGS__) // Logs a serious problem #define Log_Error(Message, ...) Log_Msg(LOG_GENERAL, Error, Message, ##__VA_ARGS__) // Logs debug information for developers #define Log_Debug(Message, ...) Log_Msg(LOG_GENERAL, Debug, Message, ##__VA_ARGS__) // Logs fine grained debug information #define Log_Trace(Message, ...) Log_Msg(LOG_GENERAL, Trace, Message, ##__VA_ARGS__)