Skip to content

Commit

Permalink
Merge pull request #44 from X-R-G-B/feature/logger
Browse files Browse the repository at this point in the history
ECS: Add logger
  • Loading branch information
TTENSHII authored Oct 4, 2023
2 parents 47bfd17 + a1f793a commit 5ae4ff9
Show file tree
Hide file tree
Showing 6 changed files with 355 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/ECS/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ target_sources(
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/Registry.cpp
${CMAKE_CURRENT_SOURCE_DIR}/Clock.cpp
${CMAKE_CURRENT_SOURCE_DIR}/Logger.cpp
)
189 changes: 189 additions & 0 deletions src/ECS/Logger.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
/*
** EPITECH PROJECT, 2023
** Raytracer
** File description:
** Logger.cpp
*/

#include "Logger.hpp"
#include <chrono>
#include <ctime>
#include <format>
#include <iostream>
#include "Registry.hpp"

namespace Logger {
void fatal(const std::string &message)
{
Registry::getInstance().getLogger().fatal(message);
}
void error(const std::string &message)
{
Registry::getInstance().getLogger().error(message);
}
void warn(const std::string &message)
{
Registry::getInstance().getLogger().warn(message);
}
void info(const std::string &message)
{
Registry::getInstance().getLogger().info(message);
}
void debug(const std::string &message)
{
Registry::getInstance().getLogger().debug(message);
}
void trace(const std::string &message)
{
Registry::getInstance().getLogger().trace(message);
}

Logger::Logger(LogLevel logLevel) : _logLevel(logLevel)
{
}

void Logger::fatal(const std::string &message)
{
if (_logLevel < LogLevel::Fatal) {
return;
}
Logger::print(LogLevel::Fatal, "FATAL", message);
}

void Logger::error(const std::string &message)
{
if (_logLevel < LogLevel::Error) {
return;
}
Logger::print(LogLevel::Error, "ERROR", message);
}

void Logger::warn(const std::string &message)
{
if (_logLevel < LogLevel::Warn) {
return;
}
Logger::print(LogLevel::Warn, "WARN", message);
}

void Logger::info(const std::string &message)
{
if (_logLevel < LogLevel::Info) {
return;
}
Logger::print(LogLevel::Info, "INFO", message);
}

void Logger::debug(const std::string &message)
{
#ifdef NDEBUG
return;
#else
if (_logLevel < LogLevel::Debug) {
return;
}
Logger::print(LogLevel::Debug, "DEBUG", message);
#endif
}

void Logger::trace(const std::string &message)
{
#ifdef NDEBUG
return;
#else
if (_logLevel < LogLevel::Trace) {
return;
}
Logger::print(LogLevel::Trace, "TRACE", message);
#endif
}

void Logger::print(
LogLevel levelT,
const std::string &level,
const std::string &message)
{
#ifdef __linux__
static std::map<LogLevel, std::string> colors = {
{LogLevel::Fatal, "\033[31m"},
{LogLevel::Error, "\033[33m"},
{LogLevel::Warn, "\033[34m"},
{LogLevel::Info, "\033[32m"},
{LogLevel::Debug, "\033[38m"},
{LogLevel::Trace, "\033[30m"},
{LogLevel::MAXLOGLEVEL, "\033[0m" },
};
#elif __APPLE__
static std::map<int, std::string> colors = {
{LogLevel::Fatal, "\033[31m"},
{LogLevel::Error, "\033[33m"},
{LogLevel::Warn, "\033[34m"},
{LogLevel::Info, "\033[32m"},
{LogLevel::Debug, "\033[38m"},
{LogLevel::Trace, "\033[30m"},
{LogLevel::MAXLOGLEVEL, "\033[0m" },
};
#else
static std::map<int, std::string> colors = {
{LogLevel::Fatal, ""},
{LogLevel::Error, ""},
{LogLevel::Warn,""},
{LogLevel::Info, ""},
{LogLevel::Debug, ""},
{LogLevel::Trace, ""},
{LogLevel::MAXLOG ""},
};
#endif

auto const now = std::chrono::current_zone()->to_local(
std::chrono::system_clock::now());
std::string mes;
auto it = _callbacks.find(levelT);

mes = std::format("{:%Y-%m-%d %H:%M:%S}", now) + " [" + level + "] "
+ message;
std::cerr << colors[levelT] << mes << colors[LogLevel::MAXLOGLEVEL]
<< std::endl;
if (it != _callbacks.end()) {
for (auto &it1 : it->second) {
it1.second(mes);
}
}
}

void Logger::subscribeCallback(
LogLevel type,
const std::string &name,
std::function<void(const std::string &)> callback)
{
if (_callbacks.find(type) == _callbacks.end()) {
_callbacks.emplace(
type,
std::map<
std::string,
std::function<void(const std::string &)>>());
}
_callbacks[type].emplace(name, callback);
}

void Logger::unsubscribeCallback(LogLevel type, const std::string &name)
{
if (_callbacks.find(type) == _callbacks.end()) {
return;
}
if (_callbacks[type].find(name) == _callbacks[type].end()) {
return;
}
_callbacks[type].erase(name);
}

void Logger::setLogLevel(LogLevel logLevel)
{
_logLevel = logLevel;
}

LogLevel Logger::getLogLevel() const
{
return _logLevel;
}
} // namespace Logger
154 changes: 154 additions & 0 deletions src/ECS/Logger.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
/*
** EPITECH PROJECT, 2023
** Raytracer
** File description:
** Logger.hpp
*/

#pragma once

#include <functional>
#include <map>
#include <string>

namespace Logger {
enum class LogLevel : int {
NOLOG = -1,
Fatal = 0,
Error = 1,
Warn = 2,
Info = 3,
Debug = 4,
Trace = 5,
MAXLOGLEVEL = 6,
};

void fatal(const std::string &message);
void error(const std::string &message);
void warn(const std::string &message);
void info(const std::string &message);
void debug(const std::string &message);
void trace(const std::string &message);

/**
* @brief Logger
*
* LogLevel:
* LogLevel::NOLOG - no messages
* LogLevel::Fatal - only `fatal` are displayed
* LogLevel::Error - `error` and `fatal` are displayed
* LogLevel::Warn - `warn`, `error` and `fatal` are displayed
* LogLevel::Info - `info`, `warn`, `error` and `fatal` are displayed
* LogLevel::Debug - `debug`, `info`, `warn`, `error` and `fatal` are
* displayed LogLevel::Trace - `trace`, `debug`, `info`, `warn`, `error` and
* `fatal` are displayed
*
* Attention:
* `debug` and `trace` will only do something in debug mode compilation.
* (`set(CMAKE_BUILD_TYPE Debug)` in `CMakeLists.txt`)
*/
class Logger {
public:
Logger(LogLevel logLevel = LogLevel::Info);
/**
* @brief Logger fata
*
* Means that something critical is broken, and the application
* cannot continue to do any more useful work without the
* intervention of an engineer.
*
* @param message the message
*/
void fatal(const std::string &message);
/**
* @brief Logger error
*
* The ERROR log level is used to represent error conditions in
* an application that prevent a specific operation from running,
* but the application itself can continue working even if it is
* at a reduced level of functionality or performance.
*
* @param message the message
*/
void error(const std::string &message);
/**
* @brief Logger warn
*
* Messages logged at the WARN level typically indicate that
* something unexpected happened, but the application can recover
* and continue to function normally.
*
* @param message the message
*/
void warn(const std::string &message);
/**
* @brief Logger info
*
* INFO-level messages indicate events in the system that are
* significant to the business purpose of the application. Such
* events are logged to show that the system is operating normally.
*
* @param message the message
*/
void info(const std::string &message);
/**
* @brief Logger debug
*
* The DEBUG level is used for logging messages that help
* developers find out what went wrong during a debugging session.
*
* @param message the message
*/
void debug(const std::string &message);
/**
* @brief Logger trace
*
* The TRACE level is used for tracing the path of code execution
* in a program.
*
* @param message the message
*/
void trace(const std::string &message);
/**
* @brief Logger subscribe
*
* @param type the type to subscribe for
* @param name the name
* @param callback the callback
*/
void subscribeCallback(
LogLevel type,
const std::string &name,
std::function<void(const std::string &)> callback);
/**
* @brief Logger remove
*
* @param type the type
* @param name the name
*/
void unsubscribeCallback(LogLevel type, const std::string &name);
/**
* @brief set log level
*
* @param logLevel the log level
*/
void setLogLevel(LogLevel logLevel);
/**
* @brief get log level
*
* @return the log level
*/
[[nodiscard]] LogLevel getLogLevel() const;

private:
void print(
LogLevel levelT,
const std::string &level,
const std::string &message);
std::map<
LogLevel,
std::map<std::string, std::function<void(const std::string &)>>>
_callbacks;
LogLevel _logLevel;
};
} // namespace Logger
5 changes: 5 additions & 0 deletions src/ECS/Registry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,3 +152,8 @@ Clock &Registry::getClock()
{
return _clock;
}

Logger::Logger &Registry::getLogger()
{
return _logger;
}
4 changes: 4 additions & 0 deletions src/ECS/Registry.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <unordered_map>
#include <vector>
#include "Clock.hpp"
#include "Logger.hpp"
#include "SceneManager.hpp"
#include "SparseArray.hpp"

Expand Down Expand Up @@ -76,10 +77,13 @@ class Registry {

Clock &getClock();

Logger::Logger &getLogger();

private:
Registry();

Clock _clock;
Logger::Logger _logger;

void initLayers(bool back);

Expand Down
2 changes: 2 additions & 0 deletions src/main_client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@
** main
*/

#include "Logger.hpp"
#include "SceneManager.hpp"

int main()
{
SceneManager &sceneManager = SceneManager::getInstance();

Logger::info("Starting Game...");
int res = sceneManager.run();

return res;
Expand Down

0 comments on commit 5ae4ff9

Please sign in to comment.