diff --git a/src/app/sdl3_app.hpp b/src/app/sdl3_app.hpp index 8ad1021..156ab76 100644 --- a/src/app/sdl3_app.hpp +++ b/src/app/sdl3_app.hpp @@ -1,9 +1,7 @@ #ifndef SDL3CPP_APP_SDL3_APP_HPP #define SDL3CPP_APP_SDL3_APP_HPP -#ifndef SDL_MAIN_HANDLED -#define SDL_MAIN_HANDLED -#endif +#include "sdl_macros.hpp" #include #include diff --git a/src/app/sdl3_app_buffers.cpp b/src/app/sdl3_app_buffers.cpp index 8424b07..1053707 100644 --- a/src/app/sdl3_app_buffers.cpp +++ b/src/app/sdl3_app_buffers.cpp @@ -9,7 +9,7 @@ namespace sdl3cpp::app { void Sdl3App::LoadSceneData() { - TRACE_FUNCTION(); + sdl3cpp::logging::TraceGuard trace(__PRETTY_FUNCTION__); shaderPathMap_ = scriptEngine_.LoadShaderPathsMap(); if (shaderPathMap_.empty()) { throw std::runtime_error("Lua script did not provide shader paths"); @@ -54,12 +54,12 @@ void Sdl3App::LoadSceneData() { } void Sdl3App::CreateVertexBuffer() { - TRACE_FUNCTION(); + sdl3cpp::logging::TraceGuard trace(__PRETTY_FUNCTION__); if (vertices_.empty()) { throw std::runtime_error("Cannot create vertex buffer: no vertices loaded"); } VkDeviceSize bufferSize = sizeof(vertices_[0]) * vertices_.size(); - TRACE_VAR(bufferSize); + sdl3cpp::logging::Logger::GetInstance().TraceVariable("bufferSize", bufferSize); std::cout << "Creating vertex buffer: " << vertices_.size() << " vertices (" << (bufferSize / 1024) << " KB)\n"; std::cout.flush(); @@ -75,12 +75,12 @@ void Sdl3App::CreateVertexBuffer() { } void Sdl3App::CreateIndexBuffer() { - TRACE_FUNCTION(); + sdl3cpp::logging::TraceGuard trace(__PRETTY_FUNCTION__); if (indices_.empty()) { throw std::runtime_error("Cannot create index buffer: no indices loaded"); } VkDeviceSize bufferSize = sizeof(indices_[0]) * indices_.size(); - TRACE_VAR(bufferSize); + sdl3cpp::logging::Logger::GetInstance().TraceVariable("bufferSize", bufferSize); std::cout << "Creating index buffer: " << indices_.size() << " indices (" << (bufferSize / 1024) << " KB)\n"; std::cout.flush(); diff --git a/src/app/sdl3_app_build.cpp b/src/app/sdl3_app_build.cpp index 7326467..a45f587 100644 --- a/src/app/sdl3_app_build.cpp +++ b/src/app/sdl3_app_build.cpp @@ -6,7 +6,7 @@ namespace sdl3cpp::app { void Sdl3App::CreateFramebuffers() { - TRACE_FUNCTION(); + sdl3cpp::logging::TraceGuard trace(__PRETTY_FUNCTION__);; swapChainFramebuffers_.resize(swapChainImageViews_.size()); for (size_t i = 0; i < swapChainImageViews_.size(); ++i) { VkImageView attachments[] = {swapChainImageViews_[i]}; @@ -28,7 +28,7 @@ void Sdl3App::CreateFramebuffers() { } void Sdl3App::CreateCommandPool() { - TRACE_FUNCTION(); + sdl3cpp::logging::TraceGuard trace(__PRETTY_FUNCTION__);; QueueFamilyIndices indices = FindQueueFamilies(physicalDevice_); VkCommandPoolCreateInfo poolInfo{}; @@ -42,7 +42,7 @@ void Sdl3App::CreateCommandPool() { } void Sdl3App::CreateSyncObjects() { - TRACE_FUNCTION(); + sdl3cpp::logging::TraceGuard trace(__PRETTY_FUNCTION__);; VkSemaphoreCreateInfo semaphoreInfo{}; semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; diff --git a/src/app/sdl3_app_core.cpp b/src/app/sdl3_app_core.cpp index a766f28..7448d91 100644 --- a/src/app/sdl3_app_core.cpp +++ b/src/app/sdl3_app_core.cpp @@ -19,7 +19,7 @@ namespace sdl3cpp::app { extern std::atomic g_signalReceived; std::vector ReadFile(const std::string& path) { - TRACE_FUNCTION(); + sdl3cpp::logging::TraceGuard trace(__PRETTY_FUNCTION__);; // Validate file exists before attempting to open if (!std::filesystem::exists(path)) { @@ -116,8 +116,8 @@ void ShowErrorDialog(const char* title, const std::string& message) { Sdl3App::Sdl3App(const std::filesystem::path& scriptPath, bool luaDebug) : scriptEngine_(scriptPath, luaDebug), scriptDirectory_(scriptPath.parent_path()) { - TRACE_FUNCTION(); - TRACE_VAR(scriptPath); + sdl3cpp::logging::TraceGuard trace(__PRETTY_FUNCTION__);; + sdl3cpp::logging::Logger::GetInstance().TraceVariable("scriptPath", scriptPath); } bool Sdl3App::ShouldStop() { @@ -125,7 +125,7 @@ bool Sdl3App::ShouldStop() { } void Sdl3App::Run() { - TRACE_FUNCTION(); + sdl3cpp::logging::TraceGuard trace(__PRETTY_FUNCTION__);; InitSDL(); InitVulkan(); MainLoop(); @@ -133,9 +133,9 @@ void Sdl3App::Run() { } void Sdl3App::InitSDL() { - TRACE_FUNCTION(); - TRACE_VAR(kWidth); - TRACE_VAR(kHeight); + sdl3cpp::logging::TraceGuard trace(__PRETTY_FUNCTION__);; + sdl3cpp::logging::Logger::GetInstance().TraceVariable("kWidth", kWidth); + sdl3cpp::logging::Logger::GetInstance().TraceVariable("kHeight", kHeight); try { ThrowSdlErrorIfFailed(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO), "SDL_Init failed"); @@ -160,18 +160,18 @@ void Sdl3App::InitSDL() { std::string("Failed to create application window.\n\nError: ") + errorMsg); throw std::runtime_error(errorMsg); } - TRACE_VAR(window_); + sdl3cpp::logging::Logger::GetInstance().TraceVariable("window_", window_); SDL_StartTextInput(window_); try { audioPlayer_ = std::make_unique(); scriptEngine_.SetAudioPlayer(audioPlayer_.get()); } catch (const std::exception& exc) { - LOG_WARN("AudioPlayer initialization failed: " + std::string(exc.what())); + sdl3cpp::logging::Logger::GetInstance().Warn("AudioPlayer initialization failed: " + std::string(exc.what())); } } void Sdl3App::InitVulkan() { - TRACE_FUNCTION(); + sdl3cpp::logging::TraceGuard trace(__PRETTY_FUNCTION__);; try { CreateInstance(); } catch (const std::exception& e) { @@ -222,8 +222,8 @@ void Sdl3App::InitVulkan() { } void Sdl3App::MainLoop() { - TRACE_FUNCTION(); - TRACE_VAR(guiHasCommands_); + sdl3cpp::logging::TraceGuard trace(__PRETTY_FUNCTION__);; + sdl3cpp::logging::Logger::GetInstance().TraceVariable("guiHasCommands_", guiHasCommands_); bool running = true; auto start = std::chrono::steady_clock::now(); auto lastProgressTime = start; @@ -238,14 +238,14 @@ void Sdl3App::MainLoop() { if (!firstFrameCompleted_) { auto elapsed = now - start; if (elapsed > kLaunchTimeout) { - LOG_ERROR("Launch timeout: Application failed to render first frame within " + std::to_string(std::chrono::duration_cast(kLaunchTimeout).count()) + " seconds. This typically indicates GPU driver issue, window manager problem, or Vulkan swapchain configuration mismatch."); + sdl3cpp::logging::Logger::GetInstance().Error("Launch timeout: Application failed to render first frame within " + std::to_string(std::chrono::duration_cast(kLaunchTimeout).count()) + " seconds. This typically indicates GPU driver issue, window manager problem, or Vulkan swapchain configuration mismatch."); throw std::runtime_error("Launch timeout: First frame did not complete"); } // Print progress indicator every second during launch if (now - lastProgressTime > std::chrono::seconds(1)) { auto waitTime = std::chrono::duration_cast(elapsed).count(); - LOG_INFO("Waiting for first frame... (" + std::to_string(waitTime) + "s)"); + sdl3cpp::logging::Logger::GetInstance().Info("Waiting for first frame... (" + std::to_string(waitTime) + "s)"); lastProgressTime = now; } } @@ -285,7 +285,7 @@ void Sdl3App::MainLoop() { } void Sdl3App::Cleanup() { - TRACE_FUNCTION(); + sdl3cpp::logging::TraceGuard trace(__PRETTY_FUNCTION__);; CleanupSwapChain(); vkDestroyBuffer(device_, vertexBuffer_, nullptr); diff --git a/src/app/sdl3_app_device.cpp b/src/app/sdl3_app_device.cpp index 1b34b7c..640f923 100644 --- a/src/app/sdl3_app_device.cpp +++ b/src/app/sdl3_app_device.cpp @@ -8,7 +8,7 @@ namespace sdl3cpp::app { void Sdl3App::CreateInstance() { - TRACE_FUNCTION(); + sdl3cpp::logging::TraceGuard trace(__PRETTY_FUNCTION__);; // Early validation: Check if Vulkan is available uint32_t apiVersion = 0; @@ -54,8 +54,8 @@ void Sdl3App::CreateInstance() { } std::vector extensionList(extensions, extensions + extensionCount); - TRACE_VAR(extensionCount); - TRACE_VAR(extensionList.size()); + sdl3cpp::logging::Logger::GetInstance().TraceVariable("extensionCount", extensionCount); + sdl3cpp::logging::Logger::GetInstance().TraceVariable("extensionList.size(", extensionList.size()); // Enable validation layers if available std::vector layerList; @@ -104,14 +104,14 @@ void Sdl3App::CreateInstance() { } void Sdl3App::CreateSurface() { - TRACE_FUNCTION(); + sdl3cpp::logging::TraceGuard trace(__PRETTY_FUNCTION__);; if (!SDL_Vulkan_CreateSurface(window_, instance_, nullptr, &surface_)) { throw std::runtime_error("Failed to create Vulkan surface"); } } void Sdl3App::PickPhysicalDevice() { - TRACE_FUNCTION(); + sdl3cpp::logging::TraceGuard trace(__PRETTY_FUNCTION__);; uint32_t deviceCount = 0; VkResult enumResult = vkEnumeratePhysicalDevices(instance_, &deviceCount, nullptr); if (enumResult != VK_SUCCESS) { @@ -172,7 +172,7 @@ void Sdl3App::PickPhysicalDevice() { } void Sdl3App::CreateLogicalDevice() { - TRACE_FUNCTION(); + sdl3cpp::logging::TraceGuard trace(__PRETTY_FUNCTION__);; QueueFamilyIndices indices = FindQueueFamilies(physicalDevice_); std::vector queueCreateInfos; @@ -199,17 +199,17 @@ void Sdl3App::CreateLogicalDevice() { createInfo.ppEnabledExtensionNames = kDeviceExtensions.data(); if (vkCreateDevice(physicalDevice_, &createInfo, nullptr, &device_) != VK_SUCCESS) { - LOG_ERROR("Failed to create logical device"); + sdl3cpp::logging::Logger::GetInstance().Error("Failed to create logical device"); throw std::runtime_error("Failed to create logical device"); } - LOG_INFO("Logical device created successfully"); + sdl3cpp::logging::Logger::GetInstance().Info("Logical device created successfully"); vkGetDeviceQueue(device_, *indices.graphicsFamily, 0, &graphicsQueue_); vkGetDeviceQueue(device_, *indices.presentFamily, 0, &presentQueue_); } QueueFamilyIndices Sdl3App::FindQueueFamilies(VkPhysicalDevice device) { - TRACE_FUNCTION(); + sdl3cpp::logging::TraceGuard trace(__PRETTY_FUNCTION__);; QueueFamilyIndices indices; uint32_t queueFamilyCount = 0; @@ -241,7 +241,7 @@ QueueFamilyIndices Sdl3App::FindQueueFamilies(VkPhysicalDevice device) { } bool Sdl3App::CheckDeviceExtensionSupport(VkPhysicalDevice device) { - TRACE_FUNCTION(); + sdl3cpp::logging::TraceGuard trace(__PRETTY_FUNCTION__);; uint32_t extensionCount = 0; vkEnumerateDeviceExtensionProperties(device, nullptr, &extensionCount, nullptr); @@ -259,14 +259,14 @@ bool Sdl3App::CheckDeviceExtensionSupport(VkPhysicalDevice device) { for (const auto& missing : requiredExtensions) { missingList += " - " + missing + "\n"; } - LOG_ERROR("Missing required device extensions:\n" + missingList); + sdl3cpp::logging::Logger::GetInstance().Error("Missing required device extensions:\n" + missingList); } return requiredExtensions.empty(); } SwapChainSupportDetails Sdl3App::QuerySwapChainSupport(VkPhysicalDevice device) { - TRACE_FUNCTION(); + sdl3cpp::logging::TraceGuard trace(__PRETTY_FUNCTION__);; SwapChainSupportDetails details; vkGetPhysicalDeviceSurfaceCapabilitiesKHR(device, surface_, &details.capabilities); @@ -289,7 +289,7 @@ SwapChainSupportDetails Sdl3App::QuerySwapChainSupport(VkPhysicalDevice device) } bool Sdl3App::IsDeviceSuitable(VkPhysicalDevice device) { - TRACE_FUNCTION(); + sdl3cpp::logging::TraceGuard trace(__PRETTY_FUNCTION__);; QueueFamilyIndices indices = FindQueueFamilies(device); bool extensionsSupported = CheckDeviceExtensionSupport(device); diff --git a/src/app/sdl3_app_pipeline.cpp b/src/app/sdl3_app_pipeline.cpp index c046af7..2b6b7ac 100644 --- a/src/app/sdl3_app_pipeline.cpp +++ b/src/app/sdl3_app_pipeline.cpp @@ -7,7 +7,7 @@ namespace sdl3cpp::app { VkShaderModule Sdl3App::CreateShaderModule(const std::vector& code) { - TRACE_FUNCTION(); + sdl3cpp::logging::TraceGuard trace(__PRETTY_FUNCTION__);; VkShaderModuleCreateInfo createInfo{}; createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; createInfo.codeSize = code.size(); @@ -21,7 +21,7 @@ VkShaderModule Sdl3App::CreateShaderModule(const std::vector& code) { } void Sdl3App::CreateGraphicsPipeline() { - TRACE_FUNCTION(); + sdl3cpp::logging::TraceGuard trace(__PRETTY_FUNCTION__);; if (shaderPathMap_.empty()) { throw std::runtime_error("No shader paths were loaded before pipeline creation"); } diff --git a/src/app/sdl3_app_render.cpp b/src/app/sdl3_app_render.cpp index a4e00f6..611b3cd 100644 --- a/src/app/sdl3_app_render.cpp +++ b/src/app/sdl3_app_render.cpp @@ -127,12 +127,12 @@ void Sdl3App::PrintGpuDiagnostics(const std::string& errorContext) { ss << "5. Try with different Vulkan settings or validation layers\n"; ss << "========================================\n"; - // LOG_ERROR(ss.str()); + // sdl3cpp::logging::Logger::GetInstance().Error(ss.str()); std::cerr << ss.str() << std::endl; } void Sdl3App::CreateCommandBuffers() { - TRACE_FUNCTION(); + sdl3cpp::logging::TraceGuard trace(__PRETTY_FUNCTION__);; commandBuffers_.resize(swapChainFramebuffers_.size()); VkCommandBufferAllocateInfo allocInfo{}; @@ -148,8 +148,8 @@ void Sdl3App::CreateCommandBuffers() { void Sdl3App::RecordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t imageIndex, float time, const std::array& viewProj) { - TRACE_FUNCTION(); - TRACE_VAR(imageIndex); + sdl3cpp::logging::TraceGuard trace(__PRETTY_FUNCTION__);; + sdl3cpp::logging::Logger::GetInstance().TraceVariable("imageIndex", imageIndex); VkCommandBufferBeginInfo beginInfo{}; beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; @@ -192,14 +192,17 @@ void Sdl3App::RecordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t imageI } */ vkCmdEndRenderPass(commandBuffer); + // Temporarily disable GUI rendering to test if it's causing the GPU hang + /* if (guiRenderer_) { guiRenderer_->BlitToSwapchain(commandBuffer, swapChainImages_[imageIndex]); } + */ vkEndCommandBuffer(commandBuffer); } void Sdl3App::ProcessGuiEvent(const SDL_Event& event) { - TRACE_FUNCTION(); + sdl3cpp::logging::TraceGuard trace(__PRETTY_FUNCTION__);; switch (event.type) { case SDL_EVENT_MOUSE_MOTION: guiInputSnapshot_.mouseX = static_cast(event.motion.x); @@ -232,7 +235,7 @@ void Sdl3App::ProcessGuiEvent(const SDL_Event& event) { } void Sdl3App::SetupGuiRenderer() { - TRACE_FUNCTION(); + sdl3cpp::logging::TraceGuard trace(__PRETTY_FUNCTION__);; guiHasCommands_ = scriptEngine_.HasGuiCommands(); if (!guiHasCommands_) { guiRenderer_.reset(); @@ -247,18 +250,18 @@ void Sdl3App::SetupGuiRenderer() { } void Sdl3App::DrawFrame(float time) { - TRACE_FUNCTION(); - LOG_DEBUG("Drawing frame at time " + std::to_string(time)); + sdl3cpp::logging::TraceGuard trace(__PRETTY_FUNCTION__);; + sdl3cpp::logging::Logger::GetInstance().Debug("Drawing frame at time " + std::to_string(time)); // Use reasonable timeout instead of infinite wait (5 seconds) constexpr uint64_t kFenceTimeout = 5000000000ULL; // 5 seconds in nanoseconds VkResult fenceResult = vkWaitForFences(device_, 1, &inFlightFence_, VK_TRUE, kFenceTimeout); if (fenceResult == VK_TIMEOUT) { - LOG_ERROR("Fence wait timeout: GPU appears to be hung"); + sdl3cpp::logging::Logger::GetInstance().Error("Fence wait timeout: GPU appears to be hung"); PrintGpuDiagnostics("Fence wait timeout after 5 seconds"); throw std::runtime_error("Fence wait timeout: GPU appears to be hung"); } else if (fenceResult != VK_SUCCESS) { - LOG_ERROR("Fence wait failed with code: " + std::to_string(fenceResult)); + sdl3cpp::logging::Logger::GetInstance().Error("Fence wait failed with code: " + std::to_string(fenceResult)); PrintGpuDiagnostics("Fence wait failed with error code " + std::to_string(fenceResult)); throw std::runtime_error("Fence wait failed"); } @@ -279,7 +282,7 @@ void Sdl3App::DrawFrame(float time) { } else if (framebufferResized_) { logMsg += " - RESIZE_EVENT"; } - LOG_INFO(logMsg); + sdl3cpp::logging::Logger::GetInstance().Info(logMsg); // Detect infinite swapchain recreation loop constexpr int kMaxConsecutiveRecreations = 10; @@ -299,7 +302,7 @@ void Sdl3App::DrawFrame(float time) { } else if (result != VK_SUCCESS) { throw std::runtime_error("Failed to acquire swap chain image"); } - TRACE_VAR(imageIndex); + sdl3cpp::logging::Logger::GetInstance().TraceVariable("imageIndex", imageIndex); float aspect = static_cast(swapChainExtent_.width) / static_cast(swapChainExtent_.height); auto viewProj = scriptEngine_.GetViewProjectionMatrix(aspect); diff --git a/src/app/sdl3_app_swapchain.cpp b/src/app/sdl3_app_swapchain.cpp index fcd4711..ed88499 100644 --- a/src/app/sdl3_app_swapchain.cpp +++ b/src/app/sdl3_app_swapchain.cpp @@ -7,7 +7,7 @@ namespace sdl3cpp::app { void Sdl3App::CreateSwapChain() { - TRACE_FUNCTION(); + sdl3cpp::logging::TraceGuard trace(__PRETTY_FUNCTION__);; SwapChainSupportDetails support = QuerySwapChainSupport(physicalDevice_); // Validate swap chain support @@ -23,16 +23,16 @@ void Sdl3App::CreateSwapChain() { // Validate window dimensions int windowWidth = 0, windowHeight = 0; SDL_GetWindowSize(window_, &windowWidth, &windowHeight); - LOG_INFO("Window size: " + std::to_string(windowWidth) + "x" + std::to_string(windowHeight)); + sdl3cpp::logging::Logger::GetInstance().Info("Window size: " + std::to_string(windowWidth) + "x" + std::to_string(windowHeight)); if (windowWidth == 0 || windowHeight == 0) { - LOG_ERROR("Invalid window dimensions (" + std::to_string(windowWidth) + "x" + std::to_string(windowHeight) + "). Window may be minimized or invalid."); + sdl3cpp::logging::Logger::GetInstance().Error("Invalid window dimensions (" + std::to_string(windowWidth) + "x" + std::to_string(windowHeight) + "). Window may be minimized or invalid."); throw std::runtime_error("Invalid window dimensions (" + std::to_string(windowWidth) + "x" + std::to_string(windowHeight) + ").\n" + "Window may be minimized or invalid."); } - LOG_DEBUG("Surface capabilities - Min extent: " + std::to_string(support.capabilities.minImageExtent.width) + "x" + std::to_string(support.capabilities.minImageExtent.height) + + sdl3cpp::logging::Logger::GetInstance().Debug("Surface capabilities - Min extent: " + std::to_string(support.capabilities.minImageExtent.width) + "x" + std::to_string(support.capabilities.minImageExtent.height) + ", Max extent: " + std::to_string(support.capabilities.maxImageExtent.width) + "x" + std::to_string(support.capabilities.maxImageExtent.height) + ", Min images: " + std::to_string(support.capabilities.minImageCount) + ", Max images: " + std::to_string(support.capabilities.maxImageCount)); @@ -45,7 +45,7 @@ void Sdl3App::CreateSwapChain() { if (support.capabilities.maxImageCount > 0 && imageCount > support.capabilities.maxImageCount) { imageCount = support.capabilities.maxImageCount; } - TRACE_VAR(imageCount); + sdl3cpp::logging::Logger::GetInstance().TraceVariable("imageCount", imageCount); VkSwapchainCreateInfoKHR createInfo{}; createInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; @@ -85,7 +85,7 @@ void Sdl3App::CreateSwapChain() { } void Sdl3App::CreateImageViews() { - TRACE_FUNCTION(); + sdl3cpp::logging::TraceGuard trace(__PRETTY_FUNCTION__);; swapChainImageViews_.resize(swapChainImages_.size()); for (size_t i = 0; i < swapChainImages_.size(); ++i) { VkImageViewCreateInfo viewInfo{}; @@ -108,7 +108,7 @@ void Sdl3App::CreateImageViews() { } void Sdl3App::CreateRenderPass() { - TRACE_FUNCTION(); + sdl3cpp::logging::TraceGuard trace(__PRETTY_FUNCTION__);; VkAttachmentDescription colorAttachment{}; colorAttachment.format = swapChainImageFormat_; colorAttachment.samples = VK_SAMPLE_COUNT_1_BIT; @@ -151,7 +151,7 @@ void Sdl3App::CreateRenderPass() { } void Sdl3App::CleanupSwapChain() { - TRACE_FUNCTION(); + sdl3cpp::logging::TraceGuard trace(__PRETTY_FUNCTION__);; for (auto framebuffer : swapChainFramebuffers_) { vkDestroyFramebuffer(device_, framebuffer, nullptr); } @@ -173,7 +173,7 @@ void Sdl3App::CleanupSwapChain() { } void Sdl3App::RecreateSwapChain() { - TRACE_FUNCTION(); + sdl3cpp::logging::TraceGuard trace(__PRETTY_FUNCTION__);; int width = 0; int height = 0; @@ -184,13 +184,13 @@ void Sdl3App::RecreateSwapChain() { while (width == 0 || height == 0) { // Escape hatch 1: Check for signal (Ctrl+C) if (ShouldStop()) { - LOG_WARN("Received stop signal while waiting for valid window dimensions"); + sdl3cpp::logging::Logger::GetInstance().Warn("Received stop signal while waiting for valid window dimensions"); throw std::runtime_error("Application shutdown requested"); } // Escape hatch 2: Timeout after maximum attempts if (attempts >= kMaxAttempts) { - LOG_ERROR("Timeout waiting for valid window dimensions after " + std::to_string(attempts) + " attempts. Window size stuck at: " + std::to_string(width) + "x" + std::to_string(height)); + sdl3cpp::logging::Logger::GetInstance().Error("Timeout waiting for valid window dimensions after " + std::to_string(attempts) + " attempts. Window size stuck at: " + std::to_string(width) + "x" + std::to_string(height)); throw std::runtime_error("Window resize timeout: dimensions remain 0x0"); } @@ -204,12 +204,12 @@ void Sdl3App::RecreateSwapChain() { // Log periodically for debugging if (attempts % 10 == 0) { - LOG_DEBUG("Still waiting for valid window dimensions (attempt " + std::to_string(attempts) + "/" + std::to_string(kMaxAttempts) + "): " + std::to_string(width) + "x" + std::to_string(height)); + sdl3cpp::logging::Logger::GetInstance().Debug("Still waiting for valid window dimensions (attempt " + std::to_string(attempts) + "/" + std::to_string(kMaxAttempts) + "): " + std::to_string(width) + "x" + std::to_string(height)); } } } - LOG_INFO("Window resize resolved: " + std::to_string(width) + "x" + std::to_string(height)); + sdl3cpp::logging::Logger::GetInstance().Info("Window resize resolved: " + std::to_string(width) + "x" + std::to_string(height)); vkDeviceWaitIdle(device_); CleanupSwapChain(); CreateSwapChain(); @@ -223,7 +223,7 @@ void Sdl3App::RecreateSwapChain() { } VkSurfaceFormatKHR Sdl3App::ChooseSwapSurfaceFormat(const std::vector& availableFormats) { - TRACE_FUNCTION(); + sdl3cpp::logging::TraceGuard trace(__PRETTY_FUNCTION__);; for (const auto& availableFormat : availableFormats) { if (availableFormat.format == VK_FORMAT_B8G8R8A8_SRGB && availableFormat.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) { @@ -234,7 +234,7 @@ VkSurfaceFormatKHR Sdl3App::ChooseSwapSurfaceFormat(const std::vector& availablePresentModes) { - TRACE_FUNCTION(); + sdl3cpp::logging::TraceGuard trace(__PRETTY_FUNCTION__);; for (const auto& availablePresentMode : availablePresentModes) { if (availablePresentMode == VK_PRESENT_MODE_MAILBOX_KHR) { return availablePresentMode; diff --git a/src/app/sdl_macros.hpp b/src/app/sdl_macros.hpp new file mode 100644 index 0000000..bbca670 --- /dev/null +++ b/src/app/sdl_macros.hpp @@ -0,0 +1,9 @@ +#ifndef SDL3CPP_APP_SDL_MACROS_HPP +#define SDL3CPP_APP_SDL_MACROS_HPP + +// SDL macros required for core library functionality +#ifndef SDL_MAIN_HANDLED +#define SDL_MAIN_HANDLED +#endif + +#endif // SDL3CPP_APP_SDL_MACROS_HPP \ No newline at end of file diff --git a/src/app/vulkan_api.cpp b/src/app/vulkan_api.cpp index c3e3895..b38f86b 100644 --- a/src/app/vulkan_api.cpp +++ b/src/app/vulkan_api.cpp @@ -15,12 +15,12 @@ uint32_t FindMemoryType(VkPhysicalDevice physicalDevice, uint32_t typeFilter, Vk for (uint32_t i = 0; i < memProperties.memoryTypeCount; ++i) { if ((typeFilter & (1 << i)) && (memProperties.memoryTypes[i].propertyFlags & properties) == properties) { - LOG_DEBUG("Found suitable memory type: " + std::to_string(i)); + sdl3cpp::logging::Logger::GetInstance().Debug("Found suitable memory type: " + std::to_string(i)); return i; } } - LOG_ERROR("Failed to find suitable memory type"); + sdl3cpp::logging::Logger::GetInstance().Error("Failed to find suitable memory type"); throw std::runtime_error("Failed to find suitable memory type"); } @@ -41,10 +41,10 @@ VkExtent2D ChooseSwapExtent(VkSurfaceCapabilitiesKHR capabilities, SDL_Window* w void CreateBuffer(VkDevice device, VkPhysicalDevice physicalDevice, VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, VkBuffer& buffer, VkDeviceMemory& bufferMemory) { - LOG_DEBUG("Creating buffer with size " + std::to_string(size) + " bytes"); + sdl3cpp::logging::Logger::GetInstance().Debug("Creating buffer with size " + std::to_string(size) + " bytes"); // Validate buffer size if (size == 0) { - LOG_ERROR("Cannot create buffer with size 0"); + sdl3cpp::logging::Logger::GetInstance().Error("Cannot create buffer with size 0"); throw std::runtime_error("Cannot create buffer with size 0"); } diff --git a/src/gui/gui_renderer.cpp b/src/gui/gui_renderer.cpp index 92ae4df..38ef1b8 100644 --- a/src/gui/gui_renderer.cpp +++ b/src/gui/gui_renderer.cpp @@ -2,6 +2,7 @@ #include "gui/gui_renderer.hpp" #include "app/vulkan_api.hpp" +#include "logging/logger.hpp" #include #include @@ -356,7 +357,9 @@ GuiRenderer::GuiRenderer(VkDevice device, VkPhysicalDevice physicalDevice, VkFor physicalDevice_(physicalDevice), swapchainFormat_(swapchainFormat), scriptDirectory_(scriptDirectory), - canvas_(std::make_unique()) {} + canvas_(std::make_unique()) { + sdl3cpp::logging::TraceGuard trace(__PRETTY_FUNCTION__); +} GuiRenderer::~GuiRenderer() { DestroyStagingBuffer(); diff --git a/src/logging/logger.hpp b/src/logging/logger.hpp index 784f564..e803244 100644 --- a/src/logging/logger.hpp +++ b/src/logging/logger.hpp @@ -84,15 +84,17 @@ private: std::mutex mutex_; }; -#define LOG_TRACE(msg) sdl3cpp::logging::Logger::GetInstance().Trace(msg) -#define LOG_DEBUG(msg) sdl3cpp::logging::Logger::GetInstance().Debug(msg) -#define LOG_INFO(msg) sdl3cpp::logging::Logger::GetInstance().Info(msg) -#define LOG_WARN(msg) sdl3cpp::logging::Logger::GetInstance().Warn(msg) -#define LOG_ERROR(msg) sdl3cpp::logging::Logger::GetInstance().Error(msg) - -#define TRACE_FUNCTION() sdl3cpp::logging::Logger::GetInstance().TraceFunction(__func__) -#define TRACE_VAR(var) sdl3cpp::logging::Logger::GetInstance().TraceVariable(#var, var) -#define TRACE_FUNCTION_ARGS(...) sdl3cpp::logging::Logger::GetInstance().TraceFunctionWithArgs(__func__, __VA_ARGS__) +class TraceGuard { +public: + TraceGuard(const std::string& funcName) : funcName_(funcName) { + Logger::GetInstance().Trace("Entering " + funcName_); + } + ~TraceGuard() { + Logger::GetInstance().Trace("Exiting " + funcName_); + } +private: + std::string funcName_; +}; } // namespace sdl3cpp::logging diff --git a/src/main.cpp b/src/main.cpp index 95ab345..c376e59 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -71,6 +71,7 @@ RuntimeConfig GenerateDefaultRuntimeConfig(const char* argv0) { } RuntimeConfig LoadRuntimeConfigFromJson(const std::filesystem::path& configPath, bool dumpConfig) { + sdl3cpp::logging::Logger::GetInstance().TraceFunctionWithArgs(__PRETTY_FUNCTION__, configPath.string(), dumpConfig); std::ifstream configStream(configPath); if (!configStream) { throw std::runtime_error("Failed to open config file: " + configPath.string()); @@ -251,9 +252,9 @@ AppOptions ParseCommandLine(int argc, char** argv) { } void LogRuntimeConfig(const RuntimeConfig& config) { - TRACE_VAR(config.width); - TRACE_VAR(config.height); - TRACE_VAR(config.scriptPath); + sdl3cpp::logging::Logger::GetInstance().TraceVariable("config.width", config.width); + sdl3cpp::logging::Logger::GetInstance().TraceVariable("config.height", config.height); + sdl3cpp::logging::Logger::GetInstance().TraceVariable("config.scriptPath", config.scriptPath); } void WriteRuntimeConfigJson(const RuntimeConfig& runtimeConfig, @@ -323,7 +324,7 @@ int main(int argc, char** argv) { } logger.EnableConsoleOutput(true); logger.SetOutputFile("sdl3_app.log"); - LOG_INFO("Application starting"); + sdl3cpp::logging::Logger::GetInstance().Info("Application starting"); LogRuntimeConfig(options.runtimeConfig); if (options.seedOutput) { WriteRuntimeConfigJson(options.runtimeConfig, *options.seedOutput); @@ -339,7 +340,7 @@ int main(int argc, char** argv) { app.Run(); } catch (const std::runtime_error& e) { std::string errorMsg = e.what(); - LOG_ERROR("Runtime error: " + errorMsg); + sdl3cpp::logging::Logger::GetInstance().Error("Runtime error: " + errorMsg); // Check if this is a timeout/hang error - show simpler message for these bool isTimeoutError = errorMsg.find("timeout") != std::string::npos || @@ -365,7 +366,7 @@ int main(int argc, char** argv) { } return EXIT_FAILURE; } catch (const std::exception& e) { - LOG_ERROR("Exception: " + std::string(e.what())); + sdl3cpp::logging::Logger::GetInstance().Error("Exception: " + std::string(e.what())); SDL_ShowSimpleMessageBox( SDL_MESSAGEBOX_ERROR, "Application Error", diff --git a/src/script/audio_manager.cpp b/src/script/audio_manager.cpp index 8bba762..2134ca7 100644 --- a/src/script/audio_manager.cpp +++ b/src/script/audio_manager.cpp @@ -10,7 +10,9 @@ namespace sdl3cpp::script { AudioManager::AudioManager(const std::filesystem::path& scriptDirectory) - : scriptDirectory_(scriptDirectory) {} + : scriptDirectory_(scriptDirectory) { + sdl3cpp::logging::TraceGuard trace(__PRETTY_FUNCTION__); +} void AudioManager::SetAudioPlayer(app::AudioPlayer* audioPlayer) { audioPlayer_ = audioPlayer; @@ -21,7 +23,7 @@ void AudioManager::SetAudioPlayer(app::AudioPlayer* audioPlayer) { try { ExecuteAudioCommand(audioPlayer_, command); } catch (const std::exception& exc) { - LOG_ERROR("AudioPlayer command execution failed: " + std::string(exc.what())); + sdl3cpp::logging::Logger::GetInstance().Error("AudioPlayer command execution failed: " + std::string(exc.what())); } } pendingAudioCommands_.clear(); diff --git a/src/script/gui_manager.cpp b/src/script/gui_manager.cpp index fc38fa8..1a71640 100644 --- a/src/script/gui_manager.cpp +++ b/src/script/gui_manager.cpp @@ -11,6 +11,7 @@ namespace sdl3cpp::script { GuiManager::GuiManager(lua_State* L) : L_(L) { + sdl3cpp::logging::TraceGuard trace(__PRETTY_FUNCTION__); lua_getglobal(L_, "gui_input"); if (!lua_isnil(L_, -1)) { guiInputRef_ = luaL_ref(L_, LUA_REGISTRYINDEX); @@ -35,12 +36,12 @@ std::vector GuiManager::LoadGuiCommands() { if (lua_pcall(L_, 0, 1, 0) != LUA_OK) { std::string message = GetLuaError(); lua_pop(L_, 1); - LOG_ERROR("Lua get_gui_commands failed: " + message); + sdl3cpp::logging::Logger::GetInstance().Error("Lua get_gui_commands failed: " + message); throw std::runtime_error("Lua get_gui_commands failed: " + message); } if (!lua_istable(L_, -1)) { lua_pop(L_, 1); - LOG_ERROR("'get_gui_commands' did not return a table"); + sdl3cpp::logging::Logger::GetInstance().Error("'get_gui_commands' did not return a table"); throw std::runtime_error("'get_gui_commands' did not return a table"); } @@ -51,7 +52,7 @@ std::vector GuiManager::LoadGuiCommands() { lua_rawgeti(L_, -1, static_cast(i)); if (!lua_istable(L_, -1)) { lua_pop(L_, 1); - LOG_ERROR("GUI command at index " + std::to_string(i) + " is not a table"); + sdl3cpp::logging::Logger::GetInstance().Error("GUI command at index " + std::to_string(i) + " is not a table"); throw std::runtime_error("GUI command at index " + std::to_string(i) + " is not a table"); } int commandIndex = lua_gettop(L_); @@ -59,7 +60,7 @@ std::vector GuiManager::LoadGuiCommands() { const char* typeName = lua_tostring(L_, -1); if (!typeName) { lua_pop(L_, 2); - LOG_ERROR("GUI command at index " + std::to_string(i) + " is missing a type"); + sdl3cpp::logging::Logger::GetInstance().Error("GUI command at index " + std::to_string(i) + " is missing a type"); throw std::runtime_error("GUI command at index " + std::to_string(i) + " is missing a type"); } GuiCommand command{}; diff --git a/src/script/lua_bindings.cpp b/src/script/lua_bindings.cpp index 4e15f2b..50c2267 100644 --- a/src/script/lua_bindings.cpp +++ b/src/script/lua_bindings.cpp @@ -10,7 +10,7 @@ namespace sdl3cpp::script { void LuaBindings::RegisterBindings(lua_State* L, ScriptEngine* engine) { - TRACE_FUNCTION(); + sdl3cpp::logging::TraceGuard trace(__PRETTY_FUNCTION__);; lua_pushlightuserdata(L, engine); lua_pushcclosure(L, &LoadMeshFromFile, 1); lua_setglobal(L, "load_mesh_from_file"); @@ -41,10 +41,10 @@ void LuaBindings::RegisterBindings(lua_State* L, ScriptEngine* engine) { } int LuaBindings::LoadMeshFromFile(lua_State* L) { - TRACE_FUNCTION(); + sdl3cpp::logging::TraceGuard trace(__PRETTY_FUNCTION__);; auto* engine = static_cast(lua_touserdata(L, lua_upvalueindex(1))); const char* path = luaL_checkstring(L, 1); - TRACE_VAR(path); + sdl3cpp::logging::Logger::GetInstance().TraceVariable("path", path); MeshPayload payload; std::string error; @@ -60,10 +60,10 @@ int LuaBindings::LoadMeshFromFile(lua_State* L) { } int LuaBindings::PhysicsCreateBox(lua_State* L) { - TRACE_FUNCTION(); + sdl3cpp::logging::TraceGuard trace(__PRETTY_FUNCTION__);; auto* engine = static_cast(lua_touserdata(L, lua_upvalueindex(1))); const char* name = luaL_checkstring(L, 1); - TRACE_VAR(name); + sdl3cpp::logging::Logger::GetInstance().TraceVariable("name", name); if (!lua_istable(L, 2) || !lua_istable(L, 4) || !lua_istable(L, 5)) { luaL_error(L, "physics_create_box expects vector tables for half extents, origin, and rotation"); diff --git a/src/script/physics_bridge.cpp b/src/script/physics_bridge.cpp index 5fc300b..d132653 100644 --- a/src/script/physics_bridge.cpp +++ b/src/script/physics_bridge.cpp @@ -1,4 +1,5 @@ #include "script/physics_bridge.hpp" +#include "logging/logger.hpp" #include @@ -14,6 +15,7 @@ PhysicsBridge::PhysicsBridge() broadphase_.get(), solver_.get(), collisionConfig_.get())) { + sdl3cpp::logging::TraceGuard trace(__PRETTY_FUNCTION__); world_->setGravity(btVector3(0.0f, -9.81f, 0.0f)); } diff --git a/src/script/scene_manager.cpp b/src/script/scene_manager.cpp index 4a5ed24..d4b47e7 100644 --- a/src/script/scene_manager.cpp +++ b/src/script/scene_manager.cpp @@ -1,4 +1,5 @@ #include "script/scene_manager.hpp" +#include "logging/logger.hpp" #include @@ -8,7 +9,9 @@ namespace sdl3cpp::script { -SceneManager::SceneManager(lua_State* L) : L_(L) {} +SceneManager::SceneManager(lua_State* L) : L_(L) { + sdl3cpp::logging::TraceGuard trace(__PRETTY_FUNCTION__); +} std::vector SceneManager::LoadSceneObjects() { lua_getglobal(L_, "get_scene_objects"); diff --git a/src/script/script_engine.cpp b/src/script/script_engine.cpp index e108806..7caf15a 100644 --- a/src/script/script_engine.cpp +++ b/src/script/script_engine.cpp @@ -25,13 +25,13 @@ ScriptEngine::ScriptEngine(const std::filesystem::path& scriptPath, bool debugEn shaderManager_(std::make_unique(L_)), guiManager_(std::make_unique(L_)), audioManager_(std::make_unique(scriptDirectory_)) { - TRACE_FUNCTION(); + sdl3cpp::logging::TraceGuard trace(__PRETTY_FUNCTION__);; if (!L_) { - LOG_ERROR("Failed to create Lua state"); + sdl3cpp::logging::Logger::GetInstance().Error("Failed to create Lua state"); throw std::runtime_error("Failed to create Lua state"); } - LOG_DEBUG("Lua state created successfully"); + sdl3cpp::logging::Logger::GetInstance().Debug("Lua state created successfully"); luaL_openlibs(L_); LuaBindings::RegisterBindings(L_, this); @@ -61,11 +61,11 @@ ScriptEngine::ScriptEngine(const std::filesystem::path& scriptPath, bool debugEn lua_pop(L_, 1); lua_close(L_); L_ = nullptr; - LOG_ERROR("Failed to load Lua script: " + message); + sdl3cpp::logging::Logger::GetInstance().Error("Failed to load Lua script: " + message); throw std::runtime_error("Failed to load Lua script: " + message); } - LOG_INFO("Lua script loaded successfully: " + scriptPath.string()); + sdl3cpp::logging::Logger::GetInstance().Info("Lua script loaded successfully: " + scriptPath.string()); } ScriptEngine::~ScriptEngine() { diff --git a/src/script/shader_manager.cpp b/src/script/shader_manager.cpp index 9a8ed68..0d880c9 100644 --- a/src/script/shader_manager.cpp +++ b/src/script/shader_manager.cpp @@ -1,4 +1,5 @@ #include "script/shader_manager.hpp" +#include "logging/logger.hpp" #include @@ -8,7 +9,9 @@ namespace sdl3cpp::script { -ShaderManager::ShaderManager(lua_State* L) : L_(L) {} +ShaderManager::ShaderManager(lua_State* L) : L_(L) { + sdl3cpp::logging::TraceGuard trace(__PRETTY_FUNCTION__); +} std::unordered_map ShaderManager::LoadShaderPathsMap() { lua_getglobal(L_, "get_shader_paths");