13 changed files with 471 additions and 134 deletions
			
			
		@ -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
 | 
				
			||||||
 | 
				
			|||||||
@ -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; | 
							stream.write(value, strlen(value)); | 
				
			||||||
 | 
							return stream; | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						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; | 
				
			||||||
 | 
							} | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
// -----------------------------------------
 | 
					// -----------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void Log::initialize() | 
						DebugLogStream dbg() | 
				
			||||||
	{ | 
						{ | 
				
			||||||
		// Create engine Logger
 | 
							return {}; | 
				
			||||||
		m_coreLogger = std::make_shared<Logger>("Inferno"); | 
						} | 
				
			||||||
		// Create game Logger
 | 
					
 | 
				
			||||||
		m_gameLogger = std::make_shared<Logger>("Game"); | 
						DebugLogStream dbg(bool newline) | 
				
			||||||
 | 
						{ | 
				
			||||||
 | 
							return DebugLogStream(newline); | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
		NF_CORE_INFO("Log initialized"); | 
						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; | 
				
			||||||
	} | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
// -----------------------------------------
 | 
					// -----------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Logger::Logger(const char* name) : | 
						DebugLogStream::~DebugLogStream() | 
				
			||||||
		m_name(name) | 
					 | 
				
			||||||
	{ | 
						{ | 
				
			||||||
 | 
							if (m_type != Log::Log) { | 
				
			||||||
 | 
								write("\033[0m", 4); | 
				
			||||||
 | 
							} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (m_newline) { | 
				
			||||||
 | 
								char newline = '\n'; | 
				
			||||||
 | 
								write(&newline, 1); | 
				
			||||||
 | 
							} | 
				
			||||||
	} | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
	Logger::~Logger() | 
						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); | 
				
			||||||
 | 
							} | 
				
			||||||
	} | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
} | 
					} | 
				
			||||||
 | 
				
			|||||||
@ -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 <string>      // std::string | 
				
			||||||
#include <memory>  // std::shared_ptr | 
					#include <string_view> // std::string_view | 
				
			||||||
#include <string>  // std::string | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
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 { | 
					// ----------------------------------------
 | 
				
			||||||
	public: | 
					 | 
				
			||||||
		Logger(const char* name); | 
					 | 
				
			||||||
		~Logger(); | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		template<typename ...A> | 
					 | 
				
			||||||
		void print(const char* color, const char* format, A... arguments) | 
					 | 
				
			||||||
		{ | 
					 | 
				
			||||||
			char buffer[10 + strlen(color) + strlen(m_name) + strlen(format)]; | 
					 | 
				
			||||||
			sprintf(buffer, "%s%s: %s\033[0m\n", color, m_name, format); | 
					 | 
				
			||||||
			printf(buffer, arguments...); | 
					 | 
				
			||||||
		} | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		template<typename ...A> | 
						class LogStream { | 
				
			||||||
		void log(const char* format, A... arguments) | 
						public: | 
				
			||||||
		{ | 
							LogStream() {} | 
				
			||||||
			this->print("", format, arguments...); | 
							virtual ~LogStream() {} | 
				
			||||||
		} | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		template<typename ...A> | 
							virtual void write(const char* characters, int length) const = 0; | 
				
			||||||
		void info(const char* format, A... arguments) | 
							virtual void write(const unsigned char* characters, int length) const = 0; | 
				
			||||||
		{ | 
						}; | 
				
			||||||
			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> | 
						class DebugLogStream final : public LogStream{ | 
				
			||||||
		void danger(const char* format, A... arguments) | 
						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 | 
				
			||||||
		{ | 
							{ | 
				
			||||||
			this->print("\x1B[31m", format, arguments...); | 
								for (int i = 0; i < length; i++) { | 
				
			||||||
 | 
									printf("%c", characters[i]); | 
				
			||||||
 | 
								} | 
				
			||||||
		} | 
							} | 
				
			||||||
 | 
					
 | 
				
			||||||
		template<typename ...A> | 
							virtual void write(const unsigned char* characters, int length) const override | 
				
			||||||
		void success(const char* format, A... arguments) | 
					 | 
				
			||||||
		{ | 
							{ | 
				
			||||||
			this->print("\x1B[32m", format, arguments...); | 
								for (int i = 0; i < length; i++) { | 
				
			||||||
 | 
									printf("%c", characters[i]); | 
				
			||||||
 | 
								} | 
				
			||||||
		} | 
							} | 
				
			||||||
 | 
					
 | 
				
			||||||
	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...); | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						template<typename T, typename... P> | 
				
			||||||
 | 
						void dbgln(Log type, const char* format, T value, const P&... parameters) | 
				
			||||||
 | 
						{ | 
				
			||||||
 | 
							dbgln(type, true, format, value, parameters...); | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// https://en.cppreference.com/w/cpp/language/parameter_pack#Example
 | 
				
			||||||
 | 
						template<typename T, typename... P> | 
				
			||||||
 | 
						void dbgln(Log type, bool newline, const char* format, T value, const P&... parameters) | 
				
			||||||
 | 
						{ | 
				
			||||||
 | 
							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...); | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
#define NF_CORE_LOG(...)     Inferno::Log::getCoreLogger()->log(__VA_ARGS__) | 
					} | 
				
			||||||
#define NF_CORE_INFO(...)    Inferno::Log::getCoreLogger()->info(__VA_ARGS__) | 
					 | 
				
			||||||
#define NF_CORE_WARN(...)    Inferno::Log::getCoreLogger()->warn(__VA_ARGS__) | 
					 | 
				
			||||||
#define NF_CORE_DANGER(...)  Inferno::Log::getCoreLogger()->danger(__VA_ARGS__) | 
					 | 
				
			||||||
#define NF_CORE_SUCCESS(...) Inferno::Log::getCoreLogger()->success(__VA_ARGS__) | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define NF_LOG(...)          Inferno::Log::getGameLogger()->log(__VA_ARGS__) | 
					 | 
				
			||||||
#define NF_INFO(...)         Inferno::Log::getGameLogger()->info(__VA_ARGS__) | 
					 | 
				
			||||||
#define NF_WARN(...)         Inferno::Log::getGameLogger()->warn(__VA_ARGS__) | 
					 | 
				
			||||||
#define NF_DANGER(...)       Inferno::Log::getGameLogger()->danger(__VA_ARGS__) | 
					 | 
				
			||||||
#define NF_SUCCESS(...)      Inferno::Log::getGameLogger()->success(__VA_ARGS__) | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif // LOG_H
 | 
					#endif // LOG_H
 | 
				
			||||||
 | 
				
			|||||||
					Loading…
					
					
				
		Reference in new issue