diff options
Diffstat (limited to 'src/Core')
| -rw-r--r-- | src/Core/Application.cpp | 30 | ||||
| -rw-r--r-- | src/Core/Application.h | 6 | ||||
| -rw-r--r-- | src/Core/Log.cpp | 155 | ||||
| -rw-r--r-- | src/Core/Log.h | 154 | ||||
| -rw-r--r-- | src/Core/Window.cpp | 13 | ||||
| -rw-r--r-- | src/Core/Window.h | 1 |
6 files changed, 339 insertions, 20 deletions
diff --git a/src/Core/Application.cpp b/src/Core/Application.cpp index 4db79a5..1736396 100644 --- a/src/Core/Application.cpp +++ b/src/Core/Application.cpp @@ -22,6 +22,7 @@ namespace Donut s_Instance = this; m_Window = std::make_unique<Window>(name, width, height); + m_Window->SetEventCallback([this](Event& event) { OnEvent(event); @@ -68,9 +69,13 @@ namespace Donut dispatcher.Dispatch<WindowResizeEvent>([this, &event](WindowResizeEvent& e) { if (e.GetWidth() == 0 || e.GetHeight() == 0) + { m_Minimized = true; + } else + { m_Minimized = false; + } Renderer::OnWindowResize(e.GetWidth(), e.GetHeight()); @@ -152,7 +157,9 @@ namespace Donut void Application::OnInit() { + Logger::Init(); Renderer::Init(); + Renderer::OnWindowResize(1280, 720); RenderCommand::SetFaceCulling(false); @@ -229,30 +236,23 @@ namespace Donut if (!m_ComputeShader) { - std::cout << "Failed to create compute shader! Falling back to CPU texture generation." << std::endl; + DONUT_WARN("Failed to create compute shader! Falling back to CPU texture generation."); m_UseComputeShader = false; } else - std::cout << "Compute shader created successfully!" << std::endl; + DONUT_INFO("Compute shader created successfully!"); m_ProcessedTexture = Texture2D::Create(256, 256); m_ComputeBrightness = 0.0f; m_ComputeContrast = 1.0f; m_ComputeSaturation = 1.0f; m_UseComputeShader = true; - - std::cout << "=== Compute Shader Test ===" << std::endl; - std::cout << "C - Toggle compute shader on/off" << std::endl; - std::cout << "Arrow Keys - Adjust brightness (Up/Down) and contrast (Left/Right)" << std::endl; - std::cout << "Q/E - Adjust saturation" << std::endl; - std::cout << "WASD - Move camera" << std::endl; - std::cout << "Mouse - Look around" << std::endl; - std::cout << "==========================" << std::endl; } void Application::OnShutdown() { Renderer::Shutdown(); + Logger::Shutdown(); } void Application::OnUpdate() @@ -281,7 +281,7 @@ namespace Donut if (m_Keys[GLFW_KEY_C] && !cKeyPressed) { m_UseComputeShader = !m_UseComputeShader; - std::cout << "Compute shader: " << (m_UseComputeShader ? "ON" : "OFF") << std::endl; + DONUT_INFO("Compute shader: {}", (m_UseComputeShader ? "ON" : "OFF")); cKeyPressed = true; } if (!m_Keys[GLFW_KEY_C]) @@ -307,9 +307,8 @@ namespace Donut statusTimer += m_DeltaTime; if (statusTimer > 2.0f) { - std::cout << "Compute Shader Status - Brightness: " << m_ComputeBrightness - << ", Contrast: " << m_ComputeContrast - << ", Saturation: " << m_ComputeSaturation << std::endl; + DONUT_INFO("Compute Shader Status:\nBrightness: {}\nContrast: {}\nSaturation: {}", + m_ComputeBrightness, m_ComputeContrast, m_ComputeSaturation); statusTimer = 0.0f; } @@ -321,7 +320,8 @@ namespace Donut Renderer::SetClearColor({ 0.0f, 0.0f, 0.0f, 1.0f }); Renderer::Clear(); - if (m_UseComputeShader && m_ProcessedTexture) + if (m_UseComputeShader && + m_ProcessedTexture) { m_ProcessedTexture->Bind(0); m_Shader->SetInt("u_Texture", 0); diff --git a/src/Core/Application.h b/src/Core/Application.h index e384e71..890df0f 100644 --- a/src/Core/Application.h +++ b/src/Core/Application.h @@ -1,10 +1,12 @@ #pragma once +#include <memory> +#include <functional> + #include "Window.h" #include "Event.h" #include "Camera.h" -#include <memory> -#include <functional> +#include "Log.h" #include "Rendering/VertexArray.h" #include "Rendering/VertexBuffer.h" diff --git a/src/Core/Log.cpp b/src/Core/Log.cpp new file mode 100644 index 0000000..90c7094 --- /dev/null +++ b/src/Core/Log.cpp @@ -0,0 +1,155 @@ +#include "Log.h" +#include <filesystem> + +#if defined(DONUT_WINDOWS) + #include <windows.h> +#endif + +namespace Donut +{ + std::shared_ptr<Logger> Logger::s_Logger; + + void Logger::Init() + { + s_Logger = std::make_shared<Logger>(); + s_Logger->SetLogLevel(LogLevel::INFO); + s_Logger->EnableConsoleOutput(true); + s_Logger->EnableFileOutput(true); + s_Logger->SetLogFile("logs/donut.log"); + + s_Logger->LogMessage(LogLevel::INFO, "Logging system initialized"); + } + + void Logger::Shutdown() + { + if (s_Logger) + s_Logger->LogMessage(LogLevel::INFO, "Shutting down logging system"); + s_Logger.reset(); + } + + std::shared_ptr<Logger> Logger::GetLogger() + { + return s_Logger; + } + + Logger::Logger() + : m_LogLevel(LogLevel::INFO), + m_ConsoleOutput(true), + m_FileOutput(false) { } + + Logger::~Logger() + { + if (m_LogFile.is_open()) + m_LogFile.close(); + } + + void Logger::SetLogFile(const std::string& filename) + { + std::filesystem::path logPath(filename); + std::filesystem::create_directories(logPath.parent_path()); + + m_LogFile.open(filename, std::ios::app); + if (!m_LogFile.is_open()) + std::cerr << "Failed to open log file: " << filename << std::endl; + } + + std::string Logger::GetTimeStamp() + { + auto now = std::chrono::system_clock::now(); + auto time_t = std::chrono::system_clock::to_time_t(now); + + std::stringstream ss; + ss << std::put_time(std::localtime(&time_t), "%Y-%m-%d %H:%M:%S"); + + return ss.str(); + } + + std::string Logger::GetLogLevelString(LogLevel level) + { + switch (level) + { + case LogLevel::TRACE: return "TRACE"; + case LogLevel::INFO: return "INFO"; + case LogLevel::WARN: return "WARN"; + case LogLevel::ERR: return "ERROR"; + case LogLevel::FATAL: return "FATAL"; + default: return "UNKNOWN"; + } + } + + void Logger::SetConsoleColor(LogLevel level) + { +#if defined(DONUT_WINDOWS) + HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); + WORD color; + + switch (level) { + case LogLevel::TRACE: + color = FOREGROUND_RED | + FOREGROUND_GREEN | + FOREGROUND_BLUE; + break; + case LogLevel::INFO: + color = FOREGROUND_GREEN | + FOREGROUND_INTENSITY; + break; + case LogLevel::WARN: + color = FOREGROUND_RED | + FOREGROUND_GREEN | + FOREGROUND_INTENSITY; + break; + case LogLevel::ERR: + color = FOREGROUND_RED | + FOREGROUND_INTENSITY; + break; + case LogLevel::FATAL: + color = FOREGROUND_RED | + FOREGROUND_BLUE | + FOREGROUND_INTENSITY; + break; + default: + color = FOREGROUND_RED | + FOREGROUND_GREEN | + FOREGROUND_BLUE; + break; + } + + SetConsoleTextAttribute(hConsole, color); +#else + const char* colorCode; + switch (level) { + case LogLevel::TRACE: + colorCode = "\033[37m"; + break; + case LogLevel::INFO: + colorCode = "\033[32;1m"; + break; + case LogLevel::WARN: + colorCode = "\033[33;1m"; + break; + case LogLevel::ERR: + colorCode = "\033[31;1m"; + break; + case LogLevel::FATAL: + colorCode = "\033[35;1m"; + break; + default: + colorCode = "\033[37m"; + break; + } + std::cout << colorCode; +#endif + } + + void Logger::ResetConsoleColor() + { +#if defined(DONUT_WINDOWS) + HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); + SetConsoleTextAttribute(hConsole, FOREGROUND_RED | + FOREGROUND_GREEN | + FOREGROUND_BLUE); +#else + std::cout << "\033[0m"; +#endif + } +} diff --git a/src/Core/Log.h b/src/Core/Log.h new file mode 100644 index 0000000..ad1b959 --- /dev/null +++ b/src/Core/Log.h @@ -0,0 +1,154 @@ +#pragma once + +#include <string> +#include <memory> +#include <vector> +#include <sstream> +#include <iostream> +#include <fstream> +#include <chrono> +#include <iomanip> +#include <mutex> +#include <string_view> + +namespace Donut +{ + enum class LogLevel + { + TRACE = 0, + INFO = 2, + WARN = 3, + ERR = 4, + FATAL = 5 + }; + + class Logger + { + public: + static void Init(); + static void Shutdown(); + + static std::shared_ptr<Logger> GetLogger(); + + template<typename... Args> + static void Trace(const std::string_view& format, const Args&... args) + { + auto logger = GetLogger(); + if (logger) logger->LogMessage(LogLevel::TRACE, format, args...); + } + + template<typename... Args> + static void Info(const std::string_view& format, const Args&... args) + { + auto logger = GetLogger(); + if (logger) logger->LogMessage(LogLevel::INFO, format, args...); + } + + template<typename... Args> + static void Warn(const std::string_view& format, const Args&... args) + { + auto logger = GetLogger(); + if (logger) logger->LogMessage(LogLevel::WARN, format, args...); + } + + template<typename... Args> + static void Error(const std::string_view& format, const Args&... args) + { + auto logger = GetLogger(); + if (logger) logger->LogMessage(LogLevel::ERR, format, args...); + } + + template<typename... Args> + static void Fatal(const std::string_view& format, const Args&... args) + { + auto logger = GetLogger(); + if (logger) logger->LogMessage(LogLevel::FATAL, format, args...); + } + + template<typename... Args> + void LogMessage(LogLevel level, const std::string_view& format, const Args&... args) + { + if (level < m_LogLevel) + return; + + std::lock_guard<std::mutex> lock(m_Mutex); + std::string message = FormatString(format, args...); + std::string fullMessage = GetTimeStamp() + " [" + GetLogLevelString(level) + "] " + message; + + if (m_ConsoleOutput) + { + SetConsoleColor(level); + std::cout << fullMessage << std::endl; + ResetConsoleColor(); + } + + if (m_FileOutput && m_LogFile.is_open()) + { + m_LogFile << fullMessage << std::endl; + m_LogFile.flush(); + } + } + + template<typename... Args> + std::string FormatString(const std::string_view& format, const Args&... args) + { + std::string result = format.data(); + std::vector<std::string> argStrings = { ToString(args)... }; + + size_t argIndex = 0; + size_t pos = 0; + + while ((pos = result.find("{}", pos)) != std::string::npos && argIndex < argStrings.size()) + { + result.replace(pos, 2, argStrings[argIndex]); + pos += argStrings[argIndex].length(); + argIndex++; + } + + return result; + } + + template<typename T> + std::string ToString(const T& value) + { + std::stringstream ss; + ss << value; + return ss.str(); + } + + void SetLogLevel(LogLevel level) { m_LogLevel = level; } + void EnableConsoleOutput(bool enable) { m_ConsoleOutput = enable; } + void EnableFileOutput(bool enable) { m_FileOutput = enable; } + void SetLogFile(const std::string& filename); + public: + Logger(); + ~Logger(); + + std::string GetTimeStamp(); + std::string GetLogLevelString(LogLevel level); + void SetConsoleColor(LogLevel level); + void ResetConsoleColor(); + private: + LogLevel m_LogLevel; + bool m_ConsoleOutput; + bool m_FileOutput; + std::ofstream m_LogFile; + std::mutex m_Mutex; + + static std::shared_ptr<Logger> s_Logger; + }; +} + +#if defined(DONUT_DEBUG) + #define DONUT_TRACE(format, ...) ::Donut::Logger::Trace(format, ##__VA_ARGS__) + #define DONUT_INFO(format, ...) ::Donut::Logger::Info(format, ##__VA_ARGS__) + #define DONUT_WARN(format, ...) ::Donut::Logger::Warn(format, ##__VA_ARGS__) + #define DONUT_ERROR(format, ...) ::Donut::Logger::Error(format, ##__VA_ARGS__) + #define DONUT_FATAL(format, ...) ::Donut::Logger::Fatal(format, ##__VA_ARGS__) +#else + #define DONUT_TRACE(format, ...) {} + #define DONUT_INFO(format, ...) {} + #define DONUT_WARN(format, ...) {} + #define DONUT_ERROR(format, ...) {} + #define DONUT_FATAL(format, ...) {} +#endif
\ No newline at end of file diff --git a/src/Core/Window.cpp b/src/Core/Window.cpp index 853abb0..832235a 100644 --- a/src/Core/Window.cpp +++ b/src/Core/Window.cpp @@ -21,25 +21,30 @@ namespace Donut void Window::Init() { + DONUT_INFO("Initializing window: ", m_Title, " (", m_Width, "x", m_Height, ")"); + if (!s_GLFWInitialized) { int success = glfwInit(); if (!success) { - std::cout << "Could not initialize GLFW!" << std::endl; + DONUT_ERROR("Could not initialize GLFW!"); return; } s_GLFWInitialized = true; + DONUT_INFO("GLFW initialized successfully"); } m_Window = glfwCreateWindow(m_Width, m_Height, m_Title.c_str(), nullptr, nullptr); if (!m_Window) { - std::cout << "Could not create GLFW window!" << std::endl; + DONUT_ERROR("Could not create GLFW window!"); glfwTerminate(); return; } + + DONUT_INFO("GLFW window created successfully"); glfwMakeContextCurrent(m_Window); glfwSetWindowUserPointer(m_Window, this); @@ -60,6 +65,7 @@ namespace Donut void Window::Shutdown() { + DONUT_INFO("Shutting down window: ", m_Title); glfwDestroyWindow(m_Window); s_GLFWWindowCount--; @@ -67,6 +73,7 @@ namespace Donut { glfwTerminate(); s_GLFWInitialized = false; + DONUT_INFO("GLFW terminated (no more windows)"); } } @@ -97,7 +104,7 @@ namespace Donut void Window::GLFWErrorCallback(int error, const char* description) { - std::cout << "GLFW Error (" << error << "): " << description << std::endl; + DONUT_ERROR("GLFW Error (", error, "): ", description); } void Window::GLFWWindowCloseCallback(GLFWwindow* window) diff --git a/src/Core/Window.h b/src/Core/Window.h index 64cde32..97bbbe2 100644 --- a/src/Core/Window.h +++ b/src/Core/Window.h @@ -3,6 +3,7 @@ #include <GLFW/glfw3.h> #include <string> #include "Event.h" +#include "Log.h" namespace Donut { |
