Improve on the logging system, add assertions.h
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
#include "inferno/application.h"
|
#include "inferno/application.h"
|
||||||
|
#include "inferno/assertions.h"
|
||||||
#include "inferno/core.h"
|
#include "inferno/core.h"
|
||||||
#include "inferno/event/applicationevent.h"
|
#include "inferno/event/applicationevent.h"
|
||||||
#include "inferno/event/event.h"
|
#include "inferno/event/event.h"
|
||||||
@@ -19,7 +20,7 @@ namespace Inferno {
|
|||||||
|
|
||||||
Application::Application()
|
Application::Application()
|
||||||
{
|
{
|
||||||
NF_CORE_ASSERT(!s_instance, "Application already exists!");
|
ASSERT(!s_instance, "Application already exists!");
|
||||||
s_instance = this;
|
s_instance = this;
|
||||||
|
|
||||||
// Initialize Settings
|
// Initialize Settings
|
||||||
@@ -62,7 +63,7 @@ namespace Inferno {
|
|||||||
|
|
||||||
void Application::run()
|
void Application::run()
|
||||||
{
|
{
|
||||||
NF_CORE_LOG("Application startup");
|
dbg() << "Application startup";
|
||||||
|
|
||||||
while(!glfwWindowShouldClose(m_window->getWindow())) {
|
while(!glfwWindowShouldClose(m_window->getWindow())) {
|
||||||
|
|
||||||
@@ -81,7 +82,7 @@ namespace Inferno {
|
|||||||
m_window->update();
|
m_window->update();
|
||||||
}
|
}
|
||||||
|
|
||||||
NF_CORE_LOG("Application shutdown");
|
dbg() << "Application shutdown";
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::onEvent(Event &e)
|
void Application::onEvent(Event &e)
|
||||||
@@ -96,7 +97,7 @@ namespace Inferno {
|
|||||||
// Suppress unused warning
|
// Suppress unused warning
|
||||||
(void)e;
|
(void)e;
|
||||||
|
|
||||||
NF_CORE_INFO("WindowCloseEvent triggered");
|
dbg(Log::Info) << "WindowCloseEvent triggered";
|
||||||
|
|
||||||
glfwSetWindowShouldClose(m_window->getWindow(), GL_TRUE);
|
glfwSetWindowShouldClose(m_window->getWindow(), GL_TRUE);
|
||||||
|
|
||||||
@@ -108,7 +109,7 @@ namespace Inferno {
|
|||||||
// Suppress unused warning
|
// Suppress unused warning
|
||||||
(void)e;
|
(void)e;
|
||||||
|
|
||||||
NF_CORE_INFO("WindowResizeEvent %dx%d triggered", e.getWidth(), e.getHeight());
|
dbg(Log::Info) << "WindowResizeEvent %dx%d triggered", e.getWidth(), e.getHeight();
|
||||||
|
|
||||||
m_window->getContext()->setViewport(0, 0, e.getWidth(), e.getHeight());
|
m_window->getContext()->setViewport(0, 0, e.getWidth(), e.getHeight());
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,62 @@
|
|||||||
|
#ifndef ASSERTIONS_H
|
||||||
|
#define ASSERTIONS_H
|
||||||
|
|
||||||
|
#include <csignal> // raise
|
||||||
|
|
||||||
|
#include "inferno/core.h"
|
||||||
|
#include "inferno/log.h"
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
#define NF_ENABLE_ASSERTS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Asserts
|
||||||
|
#ifdef NF_ENABLE_ASSERTS
|
||||||
|
// Check if SIGTRAP is available
|
||||||
|
#ifdef SIGTRAP
|
||||||
|
#define ABORT_SIGNAL SIGTRAP
|
||||||
|
#else
|
||||||
|
#define ABORT_SIGNAL SIGABRT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Non-standard function macro
|
||||||
|
#ifdef GCC
|
||||||
|
#define FUNCTION_MACRO __PRETTY_FUNCTION__
|
||||||
|
#elif MSVC
|
||||||
|
#define FUNCTION_MACRO __FUNCSIG__
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ##__VA_ARGS__ is a non-standard GCC extension, C++20 introduces __VA_OPT__
|
||||||
|
// https://stackoverflow.com/questions/52891546/what-does-va-args-mean
|
||||||
|
#define ASSERT(cond, ...) static_cast<bool>(cond) ? (void)0 : __assertion_failed(#cond, __FILE__, __LINE__, FUNCTION_MACRO, ##__VA_ARGS__)
|
||||||
|
#define ASSERT_NOT_REACHED() ASSERT(false)
|
||||||
|
#else
|
||||||
|
#define ASSERT(cond, ...)
|
||||||
|
#define ASSERT_NOT_REACHED() CRASH()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define CRASH() raise(SIGABRT)
|
||||||
|
|
||||||
|
namespace Inferno {
|
||||||
|
|
||||||
|
#ifdef NF_ENABLE_ASSERTS
|
||||||
|
template<typename... P>
|
||||||
|
void __assertion_failed(const char* message, const char* file, unsigned line, const char* function, const P&... parameters)
|
||||||
|
{
|
||||||
|
dbg(Log::Danger, false) << "ASSERTION FAILED: " << message;
|
||||||
|
|
||||||
|
if (sizeof...(P) > 0) {
|
||||||
|
dbg(Log::Danger, false) << ", \"";
|
||||||
|
dbgln(Log::Danger, false, parameters...);
|
||||||
|
dbg(Log::Danger, false) << "\"";
|
||||||
|
}
|
||||||
|
|
||||||
|
dbg(Log::Danger) << "\n\t" << file << ":" << line << ": " << function;
|
||||||
|
|
||||||
|
raise(ABORT_SIGNAL);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // ASSERTIONS_H
|
||||||
@@ -1,40 +1,21 @@
|
|||||||
#ifndef CORE_H
|
#ifndef CORE_H
|
||||||
#define CORE_H
|
#define CORE_H
|
||||||
|
|
||||||
#include <csignal> // raise
|
|
||||||
#include <cstdio> // sprintf
|
|
||||||
#include <cstring> // strlen
|
|
||||||
#include <functional> // std::bind
|
#include <functional> // std::bind
|
||||||
|
|
||||||
#define BIT(x) (1 << x)
|
#define BIT(x) (1 << x)
|
||||||
|
|
||||||
#define NF_BIND_EVENT(f) std::bind(&f, this, std::placeholders::_1)
|
#define NF_BIND_EVENT(f) std::bind(&f, this, std::placeholders::_1)
|
||||||
|
|
||||||
// Debugging defines
|
// Compiler
|
||||||
#ifndef NDEBUG
|
#if defined(__clang__)
|
||||||
#define NF_ENABLE_ASSERTS
|
#define GCC
|
||||||
#endif
|
#elif defined(__INTEL_COMPILER) // Supports some GCC extensions
|
||||||
|
#define GCC
|
||||||
// Asserts
|
#elif defined(__GNUG__) || (defined(__GNUC__) && defined(__cplusplus))
|
||||||
#ifdef NF_ENABLE_ASSERTS
|
#define GCC
|
||||||
// Check if SIGTRAP is available
|
#elif defined(_MSC_VER)
|
||||||
#ifdef SIGTRAP
|
#define MSVC
|
||||||
#define ABORT_SIGNAL SIGTRAP
|
|
||||||
#else
|
|
||||||
#define ABORT_SIGNAL SIGABRT
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define NF_ASSERT(x, y, ...) if(!(x)) { \
|
|
||||||
char buffer[15 + strlen(y)]; \
|
|
||||||
sprintf(buffer, "Assert: {%%s}, %s", y); \
|
|
||||||
NF_DANGER(buffer, #x, ##__VA_ARGS__); raise(ABORT_SIGNAL); }
|
|
||||||
#define NF_CORE_ASSERT(x, y, ...) if(!(x)) { \
|
|
||||||
char buffer[15 + strlen(y)]; \
|
|
||||||
sprintf(buffer, "Assert: {%%s}, %s", y); \
|
|
||||||
NF_CORE_DANGER(buffer, #x, ##__VA_ARGS__); raise(ABORT_SIGNAL); }
|
|
||||||
#else
|
|
||||||
#define NF_ASSERT(x, y)
|
|
||||||
#define NF_CORE_ASSERT(x, y)
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // CORE_H
|
#endif // CORE_H
|
||||||
|
|||||||
@@ -16,9 +16,6 @@ int main(int argc, char* argv[])
|
|||||||
(void)argc;
|
(void)argc;
|
||||||
(void)argv;
|
(void)argv;
|
||||||
|
|
||||||
// Initialize Log
|
|
||||||
Inferno::Log::initialize();
|
|
||||||
|
|
||||||
// Start application
|
// Start application
|
||||||
auto app = Inferno::createApplication();
|
auto app = Inferno::createApplication();
|
||||||
app->run();
|
app->run();
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include <iostream> // std::ios
|
#include <iostream> // std::ios
|
||||||
#include <memory> // std::make_unique
|
#include <memory> // std::make_unique
|
||||||
|
|
||||||
|
#include "inferno/assertions.h"
|
||||||
#include "inferno/file.h"
|
#include "inferno/file.h"
|
||||||
|
|
||||||
namespace Inferno {
|
namespace Inferno {
|
||||||
@@ -9,7 +10,7 @@ namespace Inferno {
|
|||||||
{
|
{
|
||||||
// Create input stream object and open file
|
// Create input stream object and open file
|
||||||
std::ifstream file(path.c_str());
|
std::ifstream file(path.c_str());
|
||||||
NF_CORE_ASSERT(file.is_open(), "File could not open! %s", path.c_str());
|
ASSERT(file.is_open(), "File could not open! {}", path.c_str());
|
||||||
|
|
||||||
// Check if file exists
|
// Check if file exists
|
||||||
if (!file.is_open()) {
|
if (!file.is_open()) {
|
||||||
@@ -20,7 +21,7 @@ namespace Inferno {
|
|||||||
file.seekg(0, std::ios::end);
|
file.seekg(0, std::ios::end);
|
||||||
int length = file.tellg();
|
int length = file.tellg();
|
||||||
file.seekg(0, std::ios::beg);
|
file.seekg(0, std::ios::beg);
|
||||||
NF_CORE_ASSERT(length != -1, "File could not determine length! %s", path.c_str());
|
ASSERT(length != -1, "File could not determine length! {}", path.c_str());
|
||||||
|
|
||||||
// Check for valid file length
|
// Check for valid file length
|
||||||
if (length == -1) {
|
if (length == -1) {
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include <iomanip> // std::setfill, std::setw
|
#include <iomanip> // std::setfill, std::setw
|
||||||
#include <string> // std::string
|
#include <string> // std::string
|
||||||
|
|
||||||
|
#include "inferno/assertions.h"
|
||||||
#include "inferno/core.h"
|
#include "inferno/core.h"
|
||||||
#include "inferno/log.h"
|
#include "inferno/log.h"
|
||||||
|
|
||||||
@@ -18,7 +19,7 @@ namespace Inferno {
|
|||||||
static void ioRead(T &t, const std::string &path)
|
static void ioRead(T &t, const std::string &path)
|
||||||
{
|
{
|
||||||
std::ifstream file(path);
|
std::ifstream file(path);
|
||||||
NF_CORE_ASSERT(file.is_open(), "File could not open! %s", path.c_str());
|
ASSERT(file.is_open(), "File could not open! {}", path.c_str());
|
||||||
|
|
||||||
if (file.is_open()) {
|
if (file.is_open()) {
|
||||||
file >> t;
|
file >> t;
|
||||||
@@ -30,7 +31,7 @@ namespace Inferno {
|
|||||||
static void ioWrite(T &t, const std::string &path)
|
static void ioWrite(T &t, const std::string &path)
|
||||||
{
|
{
|
||||||
std::ofstream file (path);
|
std::ofstream file (path);
|
||||||
NF_CORE_ASSERT(file.is_open(), "File could not open! %s", path.c_str());
|
ASSERT(file.is_open(), "File could not open! {}", path.c_str());
|
||||||
|
|
||||||
if (file.is_open()) {
|
if (file.is_open()) {
|
||||||
// Write file with single tabs, nicely formatted
|
// Write file with single tabs, nicely formatted
|
||||||
|
|||||||
+225
-15
@@ -1,32 +1,242 @@
|
|||||||
|
#include "inferno/assertions.h"
|
||||||
#include "inferno/log.h"
|
#include "inferno/log.h"
|
||||||
|
|
||||||
|
#include <cstring> // strlen
|
||||||
|
#include <string> // std::string
|
||||||
|
#include <string_view> // std::string_view
|
||||||
|
|
||||||
namespace Inferno {
|
namespace Inferno {
|
||||||
|
|
||||||
// Reserve memory
|
const LogStream& operator<<(const LogStream& stream, const char* value)
|
||||||
std::shared_ptr<Logger> Log::m_coreLogger;
|
|
||||||
std::shared_ptr<Logger> Log::m_gameLogger;
|
|
||||||
|
|
||||||
// -----------------------------------------
|
|
||||||
|
|
||||||
void Log::initialize()
|
|
||||||
{
|
{
|
||||||
// Create engine Logger
|
stream.write(value, strlen(value));
|
||||||
m_coreLogger = std::make_shared<Logger>("Inferno");
|
return stream;
|
||||||
// Create game Logger
|
}
|
||||||
m_gameLogger = std::make_shared<Logger>("Game");
|
|
||||||
|
|
||||||
NF_CORE_INFO("Log initialized");
|
const LogStream& operator<<(const LogStream& stream, const unsigned char* value)
|
||||||
|
{
|
||||||
|
stream.write(value, strlen((const char*)value));
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
const LogStream& operator<<(const LogStream& stream, const std::string& value)
|
||||||
|
{
|
||||||
|
stream.write(value.c_str(), value.length());
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
const LogStream& operator<<(const LogStream& stream, const std::string_view& value)
|
||||||
|
{
|
||||||
|
stream.write(value.data(), value.length());
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
const LogStream& operator<<(const LogStream& stream, char value)
|
||||||
|
{
|
||||||
|
stream.write(&value, 1);
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
const LogStream& operator<<(const LogStream& stream, unsigned char value)
|
||||||
|
{
|
||||||
|
stream.write(&value, 1);
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
const LogStream& operator<<(const LogStream& stream, int value)
|
||||||
|
{
|
||||||
|
// return stream << std::to_string(value);
|
||||||
|
|
||||||
|
char buffer[32];
|
||||||
|
snprintf(buffer, sizeof(buffer), "%d", value);
|
||||||
|
return stream << buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
const LogStream& operator<<(const LogStream& stream, long int value)
|
||||||
|
{
|
||||||
|
char buffer[32];
|
||||||
|
snprintf(buffer, sizeof(buffer), "%ld", value);
|
||||||
|
return stream << buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
const LogStream& operator<<(const LogStream& stream, long long int value)
|
||||||
|
{
|
||||||
|
char buffer[32];
|
||||||
|
snprintf(buffer, sizeof(buffer), "%lld", value);
|
||||||
|
return stream << buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
const LogStream& operator<<(const LogStream& stream, unsigned int value)
|
||||||
|
{
|
||||||
|
char buffer[32];
|
||||||
|
snprintf(buffer, sizeof(buffer), "%u", value);
|
||||||
|
return stream << buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
const LogStream& operator<<(const LogStream& stream, long unsigned int value)
|
||||||
|
{
|
||||||
|
char buffer[32];
|
||||||
|
snprintf(buffer, sizeof(buffer), "%lu", value);
|
||||||
|
return stream << buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
const LogStream& operator<<(const LogStream& stream, long long unsigned int value)
|
||||||
|
{
|
||||||
|
char buffer[32];
|
||||||
|
snprintf(buffer, sizeof(buffer), "%llu", value);
|
||||||
|
return stream << buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
const LogStream& operator<<(const LogStream& stream, double value)
|
||||||
|
{
|
||||||
|
char buffer[32];
|
||||||
|
snprintf(buffer, sizeof(buffer), "%.4f", value);
|
||||||
|
return stream << buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
const LogStream& operator<<(const LogStream& stream, float value)
|
||||||
|
{
|
||||||
|
char buffer[32];
|
||||||
|
snprintf(buffer, sizeof(buffer), "%.4f", value);
|
||||||
|
return stream << buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
const LogStream& operator<<(const LogStream& stream, const void* value)
|
||||||
|
{
|
||||||
|
char buffer[32];
|
||||||
|
snprintf(buffer, sizeof(buffer), "%p", value);
|
||||||
|
return stream << buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
const LogStream& operator<<(const LogStream& stream, bool value)
|
||||||
|
{
|
||||||
|
return stream << (value ? "true": "false");
|
||||||
|
}
|
||||||
|
|
||||||
|
const LogStream& operator<<(const LogStream& stream, Log value)
|
||||||
|
{
|
||||||
|
switch (value) {
|
||||||
|
case Log::Log:
|
||||||
|
return stream << "Log";
|
||||||
|
case Log::Info:
|
||||||
|
return stream << "Info";
|
||||||
|
case Log::Warn:
|
||||||
|
return stream << "Warn";
|
||||||
|
case Log::Danger:
|
||||||
|
return stream << "Danger";
|
||||||
|
case Log::Success:
|
||||||
|
return stream << "Success";
|
||||||
|
default:
|
||||||
|
ASSERT_NOT_REACHED();
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
|
|
||||||
Logger::Logger(const char* name) :
|
DebugLogStream dbg()
|
||||||
m_name(name)
|
|
||||||
{
|
{
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger::~Logger()
|
DebugLogStream dbg(bool newline)
|
||||||
{
|
{
|
||||||
|
return DebugLogStream(newline);
|
||||||
|
}
|
||||||
|
|
||||||
|
DebugLogStream dbg(Log type)
|
||||||
|
{
|
||||||
|
return DebugLogStream(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
DebugLogStream dbg(Log type, bool newline)
|
||||||
|
{
|
||||||
|
return DebugLogStream(type, newline);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dbgln(Log type, bool newline) {
|
||||||
|
(void)type;
|
||||||
|
dbg(newline);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dbgln(const char* format)
|
||||||
|
{
|
||||||
|
dbg() << format;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dbgln(Log type, const char* format)
|
||||||
|
{
|
||||||
|
dbg(type) << format;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dbgln(Log type, bool newline, const char* format)
|
||||||
|
{
|
||||||
|
dbg(type, newline) << format;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dbgln(std::string format)
|
||||||
|
{
|
||||||
|
dbg() << format;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dbgln(Log type, std::string format)
|
||||||
|
{
|
||||||
|
dbg(type) << format;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dbgln(Log type, bool newline, std::string format)
|
||||||
|
{
|
||||||
|
dbg(type, newline) << format;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dbgln(std::string_view format)
|
||||||
|
{
|
||||||
|
dbg() << format;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dbgln(Log type, std::string_view format)
|
||||||
|
{
|
||||||
|
dbg(type) << format;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dbgln(Log type, bool newline, std::string_view format)
|
||||||
|
{
|
||||||
|
dbg(type, newline) << format;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------
|
||||||
|
|
||||||
|
DebugLogStream::~DebugLogStream()
|
||||||
|
{
|
||||||
|
if (m_type != Log::Log) {
|
||||||
|
write("\033[0m", 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_newline) {
|
||||||
|
char newline = '\n';
|
||||||
|
write(&newline, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DebugLogStream::color() const
|
||||||
|
{
|
||||||
|
const char* color = "";
|
||||||
|
if (m_type == Log::Info) {
|
||||||
|
color = "\x1B[34m";
|
||||||
|
}
|
||||||
|
else if (m_type == Log::Warn) {
|
||||||
|
color = "\x1B[33m";
|
||||||
|
}
|
||||||
|
else if (m_type == Log::Danger) {
|
||||||
|
color = "\x1B[31m";
|
||||||
|
}
|
||||||
|
else if (m_type == Log::Success) {
|
||||||
|
color = "\x1B[32m";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (color[0] != '\0') {
|
||||||
|
write(color, 5);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+145
-65
@@ -1,91 +1,171 @@
|
|||||||
#ifndef LOG_H
|
#ifndef LOG_H
|
||||||
#define LOG_H
|
#define LOG_H
|
||||||
|
|
||||||
#include <cstdio> // printf, sprintf
|
#include <cstdio> // printf
|
||||||
#include <cstring> // strlen
|
|
||||||
#include <memory> // std::shared_ptr
|
|
||||||
#include <string> // std::string
|
#include <string> // std::string
|
||||||
|
#include <string_view> // std::string_view
|
||||||
|
|
||||||
namespace Inferno {
|
namespace Inferno {
|
||||||
|
|
||||||
class Logger;
|
enum class Log {
|
||||||
|
Log,
|
||||||
class Log {
|
Info,
|
||||||
public:
|
Warn,
|
||||||
|
Danger,
|
||||||
// -----------------------------------------
|
Success,
|
||||||
|
|
||||||
static void initialize();
|
|
||||||
|
|
||||||
// -----------------------------------------
|
|
||||||
|
|
||||||
inline static std::shared_ptr<Logger> &getCoreLogger() { return m_coreLogger; }
|
|
||||||
inline static std::shared_ptr<Logger> &getGameLogger() { return m_gameLogger; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
static std::shared_ptr<Logger> m_coreLogger;
|
|
||||||
static std::shared_ptr<Logger> m_gameLogger;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class Logger {
|
// ----------------------------------------
|
||||||
|
|
||||||
|
class LogStream {
|
||||||
public:
|
public:
|
||||||
Logger(const char* name);
|
LogStream() {}
|
||||||
~Logger();
|
virtual ~LogStream() {}
|
||||||
|
|
||||||
template<typename ...A>
|
virtual void write(const char* characters, int length) const = 0;
|
||||||
void print(const char* color, const char* format, A... arguments)
|
virtual void write(const unsigned char* characters, int length) const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ----------------------------------------
|
||||||
|
|
||||||
|
class DebugLogStream final : public LogStream{
|
||||||
|
public:
|
||||||
|
DebugLogStream():
|
||||||
|
m_newline(true), m_type(Log::Log) {}
|
||||||
|
DebugLogStream(bool newline):
|
||||||
|
m_newline(newline), m_type(Log::Log) {}
|
||||||
|
DebugLogStream(Log type):
|
||||||
|
m_newline(true), m_type(type) { color(); }
|
||||||
|
DebugLogStream(Log type, bool newline):
|
||||||
|
m_newline(newline), m_type(type) { color(); }
|
||||||
|
virtual ~DebugLogStream() override;
|
||||||
|
|
||||||
|
void color() const;
|
||||||
|
|
||||||
|
virtual void write(const char* characters, int length) const override
|
||||||
{
|
{
|
||||||
char buffer[10 + strlen(color) + strlen(m_name) + strlen(format)];
|
for (int i = 0; i < length; i++) {
|
||||||
sprintf(buffer, "%s%s: %s\033[0m\n", color, m_name, format);
|
printf("%c", characters[i]);
|
||||||
printf(buffer, arguments...);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename ...A>
|
virtual void write(const unsigned char* characters, int length) const override
|
||||||
void log(const char* format, A... arguments)
|
|
||||||
{
|
{
|
||||||
this->print("", format, arguments...);
|
for (int i = 0; i < length; i++) {
|
||||||
|
printf("%c", characters[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename ...A>
|
|
||||||
void info(const char* format, A... arguments)
|
|
||||||
{
|
|
||||||
this->print("\x1B[34m", format, arguments...);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename ...A>
|
|
||||||
void warn(const char* format, A... arguments)
|
|
||||||
{
|
|
||||||
this->print("\x1B[33m", format, arguments...);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename ...A>
|
|
||||||
void danger(const char* format, A... arguments)
|
|
||||||
{
|
|
||||||
this->print("\x1B[31m", format, arguments...);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename ...A>
|
|
||||||
void success(const char* format, A... arguments)
|
|
||||||
{
|
|
||||||
this->print("\x1B[32m", format, arguments...);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const char* m_name;
|
bool m_newline;
|
||||||
|
Log m_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ----------------------------------------
|
||||||
|
|
||||||
|
const LogStream& operator<<(const LogStream& stream, const char* value);
|
||||||
|
const LogStream& operator<<(const LogStream& stream, const std::string& value);
|
||||||
|
const LogStream& operator<<(const LogStream& stream, const std::string_view& value);
|
||||||
|
const LogStream& operator<<(const LogStream& stream, char value);
|
||||||
|
const LogStream& operator<<(const LogStream& stream, unsigned char value);
|
||||||
|
const LogStream& operator<<(const LogStream& stream, const unsigned char* value);
|
||||||
|
const LogStream& operator<<(const LogStream& stream, int value);
|
||||||
|
const LogStream& operator<<(const LogStream& stream, long int value);
|
||||||
|
const LogStream& operator<<(const LogStream& stream, long long int value);
|
||||||
|
const LogStream& operator<<(const LogStream& stream, unsigned int value);
|
||||||
|
const LogStream& operator<<(const LogStream& stream, long unsigned int value);
|
||||||
|
const LogStream& operator<<(const LogStream& stream, long long unsigned int value);
|
||||||
|
const LogStream& operator<<(const LogStream& stream, double value);
|
||||||
|
const LogStream& operator<<(const LogStream& stream, float value);
|
||||||
|
const LogStream& operator<<(const LogStream& stream, const void* value);
|
||||||
|
const LogStream& operator<<(const LogStream& stream, bool value);
|
||||||
|
const LogStream& operator<<(const LogStream& stream, Log value);
|
||||||
|
|
||||||
|
// ----------------------------------------
|
||||||
|
|
||||||
|
DebugLogStream dbg();
|
||||||
|
DebugLogStream dbg(bool newline);
|
||||||
|
DebugLogStream dbg(Log type);
|
||||||
|
DebugLogStream dbg(Log type, bool newline);
|
||||||
|
|
||||||
|
void dbgln(Log type, bool newline);
|
||||||
|
void dbgln(const char* format);
|
||||||
|
void dbgln(Log type, const char* format);
|
||||||
|
void dbgln(Log type, bool newline, const char* format);
|
||||||
|
void dbgln(std::string format);
|
||||||
|
void dbgln(Log type, std::string format);
|
||||||
|
void dbgln(Log type, bool newline, std::string format);
|
||||||
|
void dbgln(std::string_view format);
|
||||||
|
void dbgln(Log type, std::string_view format);
|
||||||
|
void dbgln(Log type, bool newline, std::string_view format);
|
||||||
|
|
||||||
|
template<typename T, typename... P>
|
||||||
|
void dbgln(const char* format, T value, const P&... parameters)
|
||||||
|
{
|
||||||
|
dbgln(Log::Log, true, format, value, parameters...);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define NF_CORE_LOG(...) Inferno::Log::getCoreLogger()->log(__VA_ARGS__)
|
template<typename T, typename... P>
|
||||||
#define NF_CORE_INFO(...) Inferno::Log::getCoreLogger()->info(__VA_ARGS__)
|
void dbgln(Log type, const char* format, T value, const P&... parameters)
|
||||||
#define NF_CORE_WARN(...) Inferno::Log::getCoreLogger()->warn(__VA_ARGS__)
|
{
|
||||||
#define NF_CORE_DANGER(...) Inferno::Log::getCoreLogger()->danger(__VA_ARGS__)
|
dbgln(type, true, format, value, parameters...);
|
||||||
#define NF_CORE_SUCCESS(...) Inferno::Log::getCoreLogger()->success(__VA_ARGS__)
|
}
|
||||||
|
|
||||||
#define NF_LOG(...) Inferno::Log::getGameLogger()->log(__VA_ARGS__)
|
// https://en.cppreference.com/w/cpp/language/parameter_pack#Example
|
||||||
#define NF_INFO(...) Inferno::Log::getGameLogger()->info(__VA_ARGS__)
|
template<typename T, typename... P>
|
||||||
#define NF_WARN(...) Inferno::Log::getGameLogger()->warn(__VA_ARGS__)
|
void dbgln(Log type, bool newline, const char* format, T value, const P&... parameters)
|
||||||
#define NF_DANGER(...) Inferno::Log::getGameLogger()->danger(__VA_ARGS__)
|
{
|
||||||
#define NF_SUCCESS(...) Inferno::Log::getGameLogger()->success(__VA_ARGS__)
|
std::string_view view { format };
|
||||||
|
|
||||||
|
uint32_t i = 0;
|
||||||
|
while(format[i] != '\0') {
|
||||||
|
|
||||||
|
if (format[i] == '{' && format[i + 1] == '}') {
|
||||||
|
dbg(type, false) << view.substr(0, i) << value;
|
||||||
|
dbgln(type, newline, format + i + 2, parameters...);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, typename... P>
|
||||||
|
void dbgln(std::string format, T value, const P&... parameters)
|
||||||
|
{
|
||||||
|
dbgln(format.c_str(), value, parameters...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, typename... P>
|
||||||
|
void dbgln(Log type, std::string format, T value, const P&... parameters)
|
||||||
|
{
|
||||||
|
dbgln(type, format.c_str(), value, parameters...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, typename... P>
|
||||||
|
void dbgln(Log type, bool newline, std::string format, T value, const P&... parameters)
|
||||||
|
{
|
||||||
|
dbgln(type, newline, format.c_str(), value, parameters...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, typename... P>
|
||||||
|
void dbgln(std::string_view format, T value, const P&... parameters)
|
||||||
|
{
|
||||||
|
dbgln(format.data(), value, parameters...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, typename... P>
|
||||||
|
void dbgln(Log type, std::string_view format, T value, const P&... parameters)
|
||||||
|
{
|
||||||
|
dbgln(type, format.data(), value, parameters...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, typename... P>
|
||||||
|
void dbgln(Log type, bool newline, std::string_view format, T value, const P&... parameters)
|
||||||
|
{
|
||||||
|
dbgln(type, newline, format.data(), value, parameters...);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
#endif // LOG_H
|
#endif // LOG_H
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#include <glad/glad.h>
|
#include <glad/glad.h>
|
||||||
|
|
||||||
|
#include "inferno/assertions.h"
|
||||||
#include "inferno/core.h"
|
#include "inferno/core.h"
|
||||||
#include "inferno/log.h"
|
#include "inferno/log.h"
|
||||||
#include "inferno/render/buffer.h"
|
#include "inferno/render/buffer.h"
|
||||||
@@ -48,7 +49,7 @@ namespace Inferno {
|
|||||||
case BufferElementType::Vec4: return sizeof(float) * 4;
|
case BufferElementType::Vec4: return sizeof(float) * 4;
|
||||||
};
|
};
|
||||||
|
|
||||||
NF_CORE_ASSERT(false, "BufferElement unknown BufferElementType size!");
|
ASSERT(false, "BufferElement unknown BufferElementType size!");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,7 +69,7 @@ namespace Inferno {
|
|||||||
case BufferElementType::Vec4: return 4;
|
case BufferElementType::Vec4: return 4;
|
||||||
};
|
};
|
||||||
|
|
||||||
NF_CORE_ASSERT(false, "BufferElement unknown BufferElementType count!");
|
ASSERT(false, "BufferElement unknown BufferElementType count!");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,7 +89,7 @@ namespace Inferno {
|
|||||||
case BufferElementType::Vec4: return GL_FLOAT;
|
case BufferElementType::Vec4: return GL_FLOAT;
|
||||||
};
|
};
|
||||||
|
|
||||||
NF_CORE_ASSERT(false, "BufferElement unknown BufferElementType GL!");
|
ASSERT(false, "BufferElement unknown BufferElementType GL!");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include <glad/glad.h>
|
#include <glad/glad.h>
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
|
#include "inferno/assertions.h"
|
||||||
#include "inferno/core.h"
|
#include "inferno/core.h"
|
||||||
#include "inferno/log.h"
|
#include "inferno/log.h"
|
||||||
#include "inferno/render/context.h"
|
#include "inferno/render/context.h"
|
||||||
@@ -20,13 +21,13 @@ namespace Inferno {
|
|||||||
// Initialize glad
|
// Initialize glad
|
||||||
glfwMakeContextCurrent(m_window);
|
glfwMakeContextCurrent(m_window);
|
||||||
int glad = gladLoadGLLoader((GLADloadproc)glfwGetProcAddress);
|
int glad = gladLoadGLLoader((GLADloadproc)glfwGetProcAddress);
|
||||||
NF_CORE_ASSERT(glad, "Failed to initialize glad!");
|
ASSERT(glad, "Failed to initialize glad!");
|
||||||
|
|
||||||
// Log OpenGL properties
|
// Log OpenGL properties
|
||||||
NF_CORE_INFO("OpenGL Info:");
|
dbg(Log::Info) << "OpenGL Info:";
|
||||||
NF_CORE_INFO(" Vendor: %s", glGetString(GL_VENDOR));
|
dbg(Log::Info) << " Vendor: " << glGetString(GL_VENDOR);
|
||||||
NF_CORE_INFO(" Renderer: %s", glGetString(GL_RENDERER));
|
dbg(Log::Info) << " Renderer: " << glGetString(GL_RENDERER);
|
||||||
NF_CORE_INFO(" Version: %s", glGetString(GL_VERSION));
|
dbg(Log::Info) << " Version: " << glGetString(GL_VERSION);
|
||||||
|
|
||||||
Window &w = *(Window*)glfwGetWindowUserPointer(m_window);
|
Window &w = *(Window*)glfwGetWindowUserPointer(m_window);
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <glad/glad.h>
|
#include <glad/glad.h>
|
||||||
|
|
||||||
|
#include "inferno/assertions.h"
|
||||||
#include "inferno/core.h"
|
#include "inferno/core.h"
|
||||||
#include "inferno/file.h"
|
#include "inferno/file.h"
|
||||||
#include "inferno/log.h"
|
#include "inferno/log.h"
|
||||||
@@ -129,10 +130,10 @@ namespace Inferno {
|
|||||||
? glGetShaderInfoLog(check, maxLength, nullptr, &infoLog[0])
|
? glGetShaderInfoLog(check, maxLength, nullptr, &infoLog[0])
|
||||||
: glGetProgramInfoLog(check, maxLength, nullptr, &infoLog[0]);
|
: glGetProgramInfoLog(check, maxLength, nullptr, &infoLog[0]);
|
||||||
|
|
||||||
NF_CORE_WARN("Shader %s", infoLog.data());
|
dbg(Log::Warn) << "Shader " << infoLog.data();
|
||||||
}
|
}
|
||||||
|
|
||||||
NF_CORE_ASSERT(success == GL_TRUE, "Shader program creation failed!")
|
ASSERT(success == GL_TRUE, "Shader program creation failed!");
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ namespace Inferno {
|
|||||||
m_properties.window.vsync = json["window"]["vsync"].get<bool>();
|
m_properties.window.vsync = json["window"]["vsync"].get<bool>();
|
||||||
}
|
}
|
||||||
catch (...) {
|
catch (...) {
|
||||||
NF_CORE_WARN("Settings syntax error: using default values");
|
dbg(Log::Warn) << "Settings syntax error: using default values";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,7 +50,7 @@ namespace Inferno {
|
|||||||
nlohmann::json json;
|
nlohmann::json json;
|
||||||
|
|
||||||
File::ioRead(json, m_path);
|
File::ioRead(json, m_path);
|
||||||
NF_CORE_INFO("Settings loaded");
|
dbg(Log::Info) << "Settings loaded";
|
||||||
|
|
||||||
return json;
|
return json;
|
||||||
}
|
}
|
||||||
@@ -65,7 +65,7 @@ namespace Inferno {
|
|||||||
json["window"]["vsync"] = m_properties.window.vsync;
|
json["window"]["vsync"] = m_properties.window.vsync;
|
||||||
|
|
||||||
File::ioWrite(json, m_path);
|
File::ioWrite(json, m_path);
|
||||||
NF_CORE_INFO("Settings saved");
|
dbg(Log::Info) << "Settings saved";
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
|
#include "inferno/assertions.h"
|
||||||
#include "inferno/core.h"
|
#include "inferno/core.h"
|
||||||
#include "inferno/event/applicationevent.h"
|
#include "inferno/event/applicationevent.h"
|
||||||
#include "inferno/event/keyevent.h"
|
#include "inferno/event/keyevent.h"
|
||||||
@@ -55,7 +56,7 @@ namespace Inferno {
|
|||||||
// Create GLFW window
|
// Create GLFW window
|
||||||
m_window = glfwCreateWindow(width, height, title, nullptr, nullptr);
|
m_window = glfwCreateWindow(width, height, title, nullptr, nullptr);
|
||||||
s_windowCount++;
|
s_windowCount++;
|
||||||
NF_CORE_ASSERT(m_window, "Failed to create GLFW window!");
|
ASSERT(m_window, "Failed to create GLFW window!");
|
||||||
|
|
||||||
// Set windowed/fullscreen/borderless
|
// Set windowed/fullscreen/borderless
|
||||||
this->setWindowMonitor();
|
this->setWindowMonitor();
|
||||||
@@ -72,7 +73,7 @@ namespace Inferno {
|
|||||||
|
|
||||||
// Error callback
|
// Error callback
|
||||||
glfwSetErrorCallback([](int error, const char* description) {
|
glfwSetErrorCallback([](int error, const char* description) {
|
||||||
NF_CORE_LOG("GLFW Error %d: %s", error, description);
|
dbgln("GLFW Error {}: {}", error, description);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Window close callback
|
// Window close callback
|
||||||
|
|||||||
Reference in New Issue
Block a user