refactor: Introduce GUI renderer service and update application service architecture

This commit is contained in:
2026-01-04 18:19:27 +00:00
parent 00a359d85f
commit 3a0707cceb
9 changed files with 192 additions and 27 deletions

View File

@@ -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

View File

@@ -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<services::ILogger>());
// GUI service
registry_.RegisterService<services::IGuiService, services::impl::VulkanGuiService>(
registry_.RegisterService<services::IGuiRendererService, services::impl::GuiRendererService>(
registry_.GetService<services::ILogger>(),
registry_.GetService<services::IBufferService>());
registry_.RegisterService<services::IGuiService, services::impl::VulkanGuiService>(
registry_.GetService<services::ILogger>(),
registry_.GetService<services::IGuiRendererService>());
// Physics service
registry_.RegisterService<services::IPhysicsService, services::impl::BulletPhysicsService>(
registry_.GetService<services::ILogger>());

View File

@@ -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<services::ILogger> GetLogger() const { return logger_; }
std::shared_ptr<services::ILogger> GetLogger() const override { return logger_; }
private:
void RegisterServices();
@@ -57,4 +58,4 @@ private:
std::shared_ptr<services::ICrashRecoveryService> crashRecoveryService_;
};
} // namespace sdl3cpp::app
} // namespace sdl3cpp::app

View File

@@ -0,0 +1,68 @@
#include "gui_renderer_service.hpp"
#include <stdexcept>
#include <utility>
namespace sdl3cpp::services::impl {
GuiRendererService::GuiRendererService(std::shared_ptr<ILogger> logger,
std::shared_ptr<IBufferService> 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<sdl3cpp::gui::GuiRenderer>(
device, physicalDevice, format, resourcePath, bufferService_);
}
void GuiRendererService::PrepareFrame(const std::vector<script::GuiCommand>& 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

View File

@@ -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 <memory>
namespace sdl3cpp::services::impl {
class GuiRendererService : public IGuiRendererService, public di::IShutdownable {
public:
GuiRendererService(std::shared_ptr<ILogger> logger,
std::shared_ptr<IBufferService> bufferService);
~GuiRendererService() override = default;
void Initialize(VkDevice device,
VkPhysicalDevice physicalDevice,
VkFormat format,
const std::filesystem::path& resourcePath) override;
void PrepareFrame(const std::vector<script::GuiCommand>& 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<ILogger> logger_;
std::shared_ptr<IBufferService> bufferService_;
std::unique_ptr<sdl3cpp::gui::GuiRenderer> renderer_;
};
} // namespace sdl3cpp::services::impl

View File

@@ -5,9 +5,9 @@
namespace sdl3cpp::services::impl {
VulkanGuiService::VulkanGuiService(std::shared_ptr<ILogger> logger,
std::shared_ptr<IBufferService> bufferService)
std::shared_ptr<IGuiRendererService> 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<gui::GuiRenderer>(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<GuiCommand>& 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");

View File

@@ -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 <memory>
@@ -19,7 +18,7 @@ class VulkanGuiService : public IGuiService,
public di::IShutdownable {
public:
VulkanGuiService(std::shared_ptr<ILogger> logger,
std::shared_ptr<IBufferService> bufferService);
std::shared_ptr<IGuiRendererService> rendererService);
~VulkanGuiService() override;
// IGuiService interface
@@ -40,8 +39,7 @@ public:
private:
std::shared_ptr<ILogger> logger_;
std::shared_ptr<IBufferService> bufferService_;
std::unique_ptr<gui::GuiRenderer> renderer_;
std::shared_ptr<IGuiRendererService> rendererService_;
bool initialized_ = false;
};

View File

@@ -0,0 +1,18 @@
#pragma once
#include "i_logger.hpp"
#include <memory>
#include <string>
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<ILogger> GetLogger() const = 0;
};
} // namespace sdl3cpp::services

View File

@@ -0,0 +1,32 @@
#pragma once
#include "../../script/gui_types.hpp"
#include <filesystem>
#include <vector>
#include <vulkan/vulkan.h>
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<script::GuiCommand>& 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