From 9d9fa0e0b29b5e21f73e4abba05c766f6367c6a3 Mon Sep 17 00:00:00 2001 From: Jun Date: Sun, 18 Sep 2022 16:11:59 -0300 Subject: [PATCH] Initial logging utility implementation - Add basic Application logging --- src/application/shared/application/log.h | 57 ++++++++++++++++++++++++ src/application/src/application.cpp | 9 ++++ src/application/src/log.cpp | 26 +++++++++++ 3 files changed, 92 insertions(+) create mode 100644 src/application/shared/application/log.h create mode 100644 src/application/src/log.cpp diff --git a/src/application/shared/application/log.h b/src/application/shared/application/log.h new file mode 100644 index 0000000..d3725a0 --- /dev/null +++ b/src/application/shared/application/log.h @@ -0,0 +1,57 @@ +#pragma once + +#include + +/** + * @brief Basic logging class + * + * Defines helper functions for logging facility. Configured in Application::init() + * + */ +class Log +{ +public: + enum LogLevel + { + FATAL, + ERROR, + WARN, + INFO, + DEBUG, + }; + + LogLevel level = WARN; ///< Default logging level + + /** + * @brief Prints message to stdout + * + * TODO: write to configurable stream, be it stdout, stderr or even a file + * + * @param level the message level + * @param fmt the message format + * @param ... variable parameters + */ + void log(LogLevel level, const std::string &fmt, ...); + +private: + inline std::string _getLabel(LogLevel level) + { + switch (level) + { + case DEBUG: return "DEBUG"; + case INFO: return "INFO "; + case WARN: return "WARN "; + case ERROR: return "ERROR"; + case FATAL: return "FATAL"; + default: return "UNK "; + } + } +}; + +extern Log LOG; /// Global variable :( + +#define INFO(fmt, ...) LOG.log(Log::INFO, fmt, ##__VA_ARGS__) +#define WARN(fmt, ...) LOG.log(Log::WARN, fmt, ##__VA_ARGS__) +#define ERROR(fmt, ...) LOG.log(Log::ERROR, fmt, ##__VA_ARGS__) +#define FATAL(fmt, ...) LOG.log(Log::FATAL, fmt, ##__VA_ARGS__) +#define DEBUG(fmt, ...) LOG.log(Log::DEBUG, fmt, ##__VA_ARGS__) diff --git a/src/application/src/application.cpp b/src/application/src/application.cpp index 337559b..da11ffb 100644 --- a/src/application/src/application.cpp +++ b/src/application/src/application.cpp @@ -1,4 +1,5 @@ #include "application/application.h" +#include "application/log.h" #include "core/gameevent.h" #include "core/editor.h" @@ -9,8 +10,13 @@ #include "classicmode/classicfactory.h" +Log LOG; + bool Application::init() { + LOG.level = Log::DEBUG; + DEBUG("Initializing Application"); + if (!_core_factory) return false; @@ -48,6 +54,8 @@ void Application::update(const kku::microsec& dt) void Application::pushState(GUIState::Tag new_state) { + DEBUG("Pushing state %d", new_state); + if (!_state_stack.empty()) _state_stack.back()->leave(); @@ -57,6 +65,7 @@ void Application::pushState(GUIState::Tag new_state) void Application::popState() { + DEBUG("Popping state"); _state_stack.back()->leave(); _state_stack.pop_back(); _state_stack.back()->enter(); diff --git a/src/application/src/log.cpp b/src/application/src/log.cpp new file mode 100644 index 0000000..aada004 --- /dev/null +++ b/src/application/src/log.cpp @@ -0,0 +1,26 @@ +#include +#include +#include + +#include "application/log.h" + +void Log::log(LogLevel level, const std::string &fmt, ...) { + if (level > this->level) + return; + + va_list args; + + // First va_start: count how many characters are needed for formatting + va_start(args, fmt); + size_t len = std::vsnprintf(NULL, 0, fmt.c_str(), args); + va_end(args); + + std::vector buf(len + 1); + + // Second va_start: actually write formatted message to buffer + va_start(args, fmt); + std::vsnprintf(&buf[0], len + 1, fmt.c_str(), args); + va_end(args); + + std::cout << this->_getLabel(level) << " " << &buf[0] << std::endl; +} \ No newline at end of file