diff --git a/CMakeLists.txt b/CMakeLists.txt index 101f88b..37826ab 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -139,6 +139,7 @@ if(BUILD_SDL3_APP) src/services/impl/render_command_service.cpp src/services/impl/sdl_audio_service.cpp src/services/impl/crash_recovery_service.cpp + src/services/impl/gui_renderer_service.cpp src/services/impl/vulkan_gui_service.cpp src/services/impl/bullet_physics_service.cpp src/services/impl/scene_service.cpp diff --git a/src/app/service_based_app.cpp b/src/app/service_based_app.cpp index d13776a..79802ce 100644 --- a/src/app/service_based_app.cpp +++ b/src/app/service_based_app.cpp @@ -21,6 +21,7 @@ #include "services/impl/physics_bridge_service.hpp" #include "services/impl/mesh_service.hpp" #include "services/impl/scene_service.hpp" +#include "services/impl/gui_renderer_service.hpp" #include "services/impl/sdl_audio_service.hpp" #include "services/impl/vulkan_gui_service.hpp" #include "services/impl/bullet_physics_service.hpp" @@ -280,10 +281,14 @@ void ServiceBasedApp::RegisterServices() { registry_.GetService()); // GUI service - registry_.RegisterService( + registry_.RegisterService( registry_.GetService(), registry_.GetService()); + registry_.RegisterService( + registry_.GetService(), + registry_.GetService()); + // Physics service registry_.RegisterService( registry_.GetService()); diff --git a/src/app/service_based_app.hpp b/src/app/service_based_app.hpp index 8554d24..38e31b6 100644 --- a/src/app/service_based_app.hpp +++ b/src/app/service_based_app.hpp @@ -6,6 +6,7 @@ #include "di/service_registry.hpp" #include "controllers/lifecycle_controller.hpp" #include "controllers/application_controller.hpp" +#include "services/interfaces/i_application_service.hpp" #include "services/interfaces/i_logger.hpp" #include "services/interfaces/i_crash_recovery_service.hpp" @@ -16,7 +17,7 @@ namespace sdl3cpp::app { * * Replaces the monolithic Sdl3App with a clean dependency injection architecture. */ -class ServiceBasedApp { +class ServiceBasedApp : public services::IApplicationService { public: explicit ServiceBasedApp(const std::filesystem::path& scriptPath); ~ServiceBasedApp(); @@ -27,7 +28,7 @@ public: /** * @brief Run the application main loop. */ - void Run(); + void Run() override; /** * @brief Configure the logger service. @@ -36,14 +37,14 @@ public: * @param enableConsole Whether to enable console output * @param outputFile Path to the log file (optional) */ - void ConfigureLogging(services::LogLevel level, bool enableConsole, const std::string& outputFile = ""); + void ConfigureLogging(services::LogLevel level, bool enableConsole, const std::string& outputFile = "") override; /** * @brief Get the logger service for external configuration. * * @return Shared pointer to the logger service */ - std::shared_ptr GetLogger() const { return logger_; } + std::shared_ptr GetLogger() const override { return logger_; } private: void RegisterServices(); @@ -57,4 +58,4 @@ private: std::shared_ptr crashRecoveryService_; }; -} // namespace sdl3cpp::app \ No newline at end of file +} // namespace sdl3cpp::app diff --git a/src/services/impl/gui_renderer_service.cpp b/src/services/impl/gui_renderer_service.cpp new file mode 100644 index 0000000..75afd6d --- /dev/null +++ b/src/services/impl/gui_renderer_service.cpp @@ -0,0 +1,68 @@ +#include "gui_renderer_service.hpp" + +#include +#include + +namespace sdl3cpp::services::impl { + +GuiRendererService::GuiRendererService(std::shared_ptr logger, + std::shared_ptr bufferService) + : logger_(std::move(logger)), + bufferService_(std::move(bufferService)) { +} + +void GuiRendererService::Initialize(VkDevice device, + VkPhysicalDevice physicalDevice, + VkFormat format, + const std::filesystem::path& resourcePath) { + if (logger_) { + logger_->TraceFunction(__func__); + } + renderer_ = std::make_unique( + device, physicalDevice, format, resourcePath, bufferService_); +} + +void GuiRendererService::PrepareFrame(const std::vector& commands, + uint32_t width, + uint32_t height) { + if (logger_) { + logger_->TraceFunction(__func__); + } + if (!renderer_) { + throw std::runtime_error("GuiRenderer service not initialized"); + } + renderer_->Prepare(commands, width, height); +} + +void GuiRendererService::RenderToSwapchain(VkCommandBuffer commandBuffer, VkImage image) { + if (logger_) { + logger_->TraceFunction(__func__); + } + if (!renderer_) { + throw std::runtime_error("GuiRenderer service not initialized"); + } + renderer_->BlitToSwapchain(commandBuffer, image); +} + +void GuiRendererService::Resize(uint32_t width, uint32_t height, VkFormat format) { + if (logger_) { + logger_->TraceFunction(__func__); + } + if (!renderer_) { + return; + } + renderer_->Resize(width, height, format); +} + +void GuiRendererService::Shutdown() noexcept { + if (logger_) { + logger_->TraceFunction(__func__); + } + renderer_.reset(); +} + +bool GuiRendererService::IsReady() const { + return renderer_ && renderer_->IsReady(); +} + +} // namespace sdl3cpp::services::impl diff --git a/src/services/impl/gui_renderer_service.hpp b/src/services/impl/gui_renderer_service.hpp new file mode 100644 index 0000000..a1df583 --- /dev/null +++ b/src/services/impl/gui_renderer_service.hpp @@ -0,0 +1,41 @@ +#pragma once + +#include "../interfaces/i_buffer_service.hpp" +#include "../interfaces/i_gui_renderer_service.hpp" +#include "../interfaces/i_logger.hpp" +#include "../../di/lifecycle.hpp" +#include "../../gui/gui_renderer.hpp" +#include + +namespace sdl3cpp::services::impl { + +class GuiRendererService : public IGuiRendererService, public di::IShutdownable { +public: + GuiRendererService(std::shared_ptr logger, + std::shared_ptr bufferService); + ~GuiRendererService() override = default; + + void Initialize(VkDevice device, + VkPhysicalDevice physicalDevice, + VkFormat format, + const std::filesystem::path& resourcePath) override; + + void PrepareFrame(const std::vector& commands, + uint32_t width, + uint32_t height) override; + + void RenderToSwapchain(VkCommandBuffer commandBuffer, VkImage image) override; + + void Resize(uint32_t width, uint32_t height, VkFormat format) override; + + void Shutdown() noexcept override; + + bool IsReady() const override; + +private: + std::shared_ptr logger_; + std::shared_ptr bufferService_; + std::unique_ptr renderer_; +}; + +} // namespace sdl3cpp::services::impl diff --git a/src/services/impl/vulkan_gui_service.cpp b/src/services/impl/vulkan_gui_service.cpp index 2b857ea..fa5fc7c 100644 --- a/src/services/impl/vulkan_gui_service.cpp +++ b/src/services/impl/vulkan_gui_service.cpp @@ -5,9 +5,9 @@ namespace sdl3cpp::services::impl { VulkanGuiService::VulkanGuiService(std::shared_ptr logger, - std::shared_ptr bufferService) + std::shared_ptr rendererService) : logger_(std::move(logger)), - bufferService_(std::move(bufferService)) { + rendererService_(std::move(rendererService)) { } VulkanGuiService::~VulkanGuiService() { @@ -26,7 +26,10 @@ void VulkanGuiService::Initialize(VkDevice device, return; } - renderer_ = std::make_unique(device, physicalDevice, format, resourcePath, bufferService_); + if (!rendererService_) { + throw std::runtime_error("GUI renderer service not available"); + } + rendererService_->Initialize(device, physicalDevice, format, resourcePath); initialized_ = true; logger_->Info("GUI service initialized"); @@ -37,32 +40,28 @@ void VulkanGuiService::PrepareFrame(const std::vector& commands, uint32_t height) { logger_->TraceFunction(__func__); - if (!renderer_) { - throw std::runtime_error("GUI service not initialized"); + if (!rendererService_) { + throw std::runtime_error("GUI renderer service not available"); } - - // GuiRenderer doesn't have a PrepareFrame method in the current implementation - // Commands would be processed during RenderToSwapchain + rendererService_->PrepareFrame(commands, width, height); } void VulkanGuiService::RenderToSwapchain(VkCommandBuffer commandBuffer, VkImage image) { logger_->TraceFunction(__func__); - if (!renderer_) { - throw std::runtime_error("GUI service not initialized"); + if (!rendererService_) { + throw std::runtime_error("GUI renderer service not available"); } - renderer_->BlitToSwapchain(commandBuffer, image); + rendererService_->RenderToSwapchain(commandBuffer, image); } void VulkanGuiService::Resize(uint32_t width, uint32_t height, VkFormat format) { logger_->TraceFunction(__func__); - if (!renderer_) { - return; + if (rendererService_) { + rendererService_->Resize(width, height, format); } - - renderer_->Resize(width, height, format); } void VulkanGuiService::Shutdown() noexcept { @@ -72,7 +71,9 @@ void VulkanGuiService::Shutdown() noexcept { return; } - renderer_.reset(); + if (rendererService_) { + rendererService_->Shutdown(); + } initialized_ = false; logger_->Info("GUI service shutdown"); diff --git a/src/services/impl/vulkan_gui_service.hpp b/src/services/impl/vulkan_gui_service.hpp index 8f894c2..c2d87ed 100644 --- a/src/services/impl/vulkan_gui_service.hpp +++ b/src/services/impl/vulkan_gui_service.hpp @@ -1,9 +1,8 @@ #pragma once #include "../interfaces/i_gui_service.hpp" -#include "../interfaces/i_buffer_service.hpp" +#include "../interfaces/i_gui_renderer_service.hpp" #include "../interfaces/i_logger.hpp" -#include "../../gui/gui_renderer.hpp" #include "../../di/lifecycle.hpp" #include @@ -19,7 +18,7 @@ class VulkanGuiService : public IGuiService, public di::IShutdownable { public: VulkanGuiService(std::shared_ptr logger, - std::shared_ptr bufferService); + std::shared_ptr rendererService); ~VulkanGuiService() override; // IGuiService interface @@ -40,8 +39,7 @@ public: private: std::shared_ptr logger_; - std::shared_ptr bufferService_; - std::unique_ptr renderer_; + std::shared_ptr rendererService_; bool initialized_ = false; }; diff --git a/src/services/interfaces/i_application_service.hpp b/src/services/interfaces/i_application_service.hpp new file mode 100644 index 0000000..469ce0c --- /dev/null +++ b/src/services/interfaces/i_application_service.hpp @@ -0,0 +1,18 @@ +#pragma once + +#include "i_logger.hpp" +#include +#include + +namespace sdl3cpp::services { + +class IApplicationService { +public: + virtual ~IApplicationService() = default; + + virtual void Run() = 0; + virtual void ConfigureLogging(LogLevel level, bool enableConsole, const std::string& outputFile = "") = 0; + virtual std::shared_ptr GetLogger() const = 0; +}; + +} // namespace sdl3cpp::services diff --git a/src/services/interfaces/i_gui_renderer_service.hpp b/src/services/interfaces/i_gui_renderer_service.hpp new file mode 100644 index 0000000..941e7d5 --- /dev/null +++ b/src/services/interfaces/i_gui_renderer_service.hpp @@ -0,0 +1,32 @@ +#pragma once + +#include "../../script/gui_types.hpp" +#include +#include +#include + +namespace sdl3cpp::services { + +class IGuiRendererService { +public: + virtual ~IGuiRendererService() = default; + + virtual void Initialize(VkDevice device, + VkPhysicalDevice physicalDevice, + VkFormat format, + const std::filesystem::path& resourcePath) = 0; + + virtual void PrepareFrame(const std::vector& commands, + uint32_t width, + uint32_t height) = 0; + + virtual void RenderToSwapchain(VkCommandBuffer commandBuffer, VkImage image) = 0; + + virtual void Resize(uint32_t width, uint32_t height, VkFormat format) = 0; + + virtual void Shutdown() noexcept = 0; + + virtual bool IsReady() const = 0; +}; + +} // namespace sdl3cpp::services