diff --git a/src/services/interfaces/i_audio_service.hpp b/src/services/interfaces/i_audio_service.hpp new file mode 100644 index 0000000..9dc7aff --- /dev/null +++ b/src/services/interfaces/i_audio_service.hpp @@ -0,0 +1,84 @@ +#pragma once + +#include + +namespace sdl3cpp::services { + +/** + * @brief Audio playback service interface. + * + * Handles background music and sound effect playback using SDL audio. + * Wraps the AudioPlayer class with a clean service interface. + */ +class IAudioService { +public: + virtual ~IAudioService() = default; + + /** + * @brief Initialize the audio subsystem. + * + * @throws std::runtime_error if audio initialization fails + */ + virtual void Initialize() = 0; + + /** + * @brief Shutdown the audio subsystem and stop all playback. + */ + virtual void Shutdown() = 0; + + /** + * @brief Play a background music track. + * + * Only one background track can play at a time. Calling this + * method will stop any currently playing background music. + * + * @param path Path to the audio file (OGG, WAV, etc.) + * @param loop Whether to loop the track + * @throws std::runtime_error if file cannot be loaded + */ + virtual void PlayBackground(const std::filesystem::path& path, bool loop = true) = 0; + + /** + * @brief Play a sound effect. + * + * Multiple sound effects can play simultaneously. + * + * @param path Path to the audio file + * @param loop Whether to loop the effect (usually false) + * @throws std::runtime_error if file cannot be loaded + */ + virtual void PlayEffect(const std::filesystem::path& path, bool loop = false) = 0; + + /** + * @brief Stop background music playback. + */ + virtual void StopBackground() = 0; + + /** + * @brief Stop all audio playback (background and effects). + */ + virtual void StopAll() = 0; + + /** + * @brief Set master volume. + * + * @param volume Volume level from 0.0 (silent) to 1.0 (full) + */ + virtual void SetVolume(float volume) = 0; + + /** + * @brief Get the current master volume. + * + * @return Volume level from 0.0 to 1.0 + */ + virtual float GetVolume() const = 0; + + /** + * @brief Check if background music is currently playing. + * + * @return true if playing, false otherwise + */ + virtual bool IsBackgroundPlaying() const = 0; +}; + +} // namespace sdl3cpp::services diff --git a/src/services/interfaces/i_config_service.hpp b/src/services/interfaces/i_config_service.hpp new file mode 100644 index 0000000..2ab2608 --- /dev/null +++ b/src/services/interfaces/i_config_service.hpp @@ -0,0 +1,56 @@ +#pragma once + +#include +#include +#include + +namespace sdl3cpp::services { + +/** + * @brief Configuration service interface. + * + * Provides access to application configuration loaded from JSON or defaults. + * Similar to Spring's @ConfigurationProperties. + */ +class IConfigService { +public: + virtual ~IConfigService() = default; + + /** + * @brief Get the configured window width. + * @return Window width in pixels + */ + virtual uint32_t GetWindowWidth() const = 0; + + /** + * @brief Get the configured window height. + * @return Window height in pixels + */ + virtual uint32_t GetWindowHeight() const = 0; + + /** + * @brief Get the path to the Lua script to execute. + * @return Path to the script file + */ + virtual std::filesystem::path GetScriptPath() const = 0; + + /** + * @brief Check if Lua debug mode is enabled. + * @return true if debug mode is enabled, false otherwise + */ + virtual bool IsLuaDebugEnabled() const = 0; + + /** + * @brief Get the window title. + * @return Window title string + */ + virtual std::string GetWindowTitle() const = 0; + + /** + * @brief Get required Vulkan device extensions. + * @return List of extension names + */ + virtual std::vector GetDeviceExtensions() const = 0; +}; + +} // namespace sdl3cpp::services diff --git a/src/services/interfaces/i_graphics_service.hpp b/src/services/interfaces/i_graphics_service.hpp new file mode 100644 index 0000000..ef79022 --- /dev/null +++ b/src/services/interfaces/i_graphics_service.hpp @@ -0,0 +1,184 @@ +#pragma once + +#include "../../core/vertex.hpp" +#include +#include +#include +#include +#include +#include + +// Forward declare SDL type +struct SDL_Window; + +namespace sdl3cpp::services { + +/** + * @brief Graphics service configuration. + */ +struct GraphicsConfig { + std::vector deviceExtensions; + VkFormat preferredFormat = VK_FORMAT_B8G8R8A8_SRGB; + bool enableValidationLayers = false; +}; + +/** + * @brief Shader file paths for a shader program. + */ +struct ShaderPaths { + std::string vertex; + std::string fragment; +}; + +/** + * @brief Render command for a single draw call. + */ +struct RenderCommand { + uint32_t indexOffset; + uint32_t indexCount; + int32_t vertexOffset; + std::string shaderKey; + std::array modelMatrix; +}; + +/** + * @brief Graphics service interface (Vulkan rendering). + * + * Abstracts all Vulkan rendering operations including device management, + * swapchain, pipelines, buffers, and rendering. + * + * This is the largest service, consolidating ~1,500 lines of Vulkan code + * from the original Sdl3App class. + */ +class IGraphicsService { +public: + virtual ~IGraphicsService() = default; + + /** + * @brief Initialize the Vulkan instance, device, and queues. + * + * @param window The SDL window to create a surface for + * @param config Graphics configuration + * @throws std::runtime_error if device initialization fails + */ + virtual void InitializeDevice(SDL_Window* window, const GraphicsConfig& config) = 0; + + /** + * @brief Initialize the swapchain for presenting rendered images. + * + * Must be called after InitializeDevice(). + * + * @throws std::runtime_error if swapchain creation fails + */ + virtual void InitializeSwapchain() = 0; + + /** + * @brief Recreate the swapchain (e.g., after window resize). + * + * @throws std::runtime_error if swapchain recreation fails + */ + virtual void RecreateSwapchain() = 0; + + /** + * @brief Shutdown and release all Vulkan resources. + */ + virtual void Shutdown() = 0; + + /** + * @brief Load and compile shader programs. + * + * @param shaders Map of shader key to shader file paths + * @throws std::runtime_error if shader compilation fails + */ + virtual void LoadShaders(const std::unordered_map& shaders) = 0; + + /** + * @brief Upload vertex data to GPU buffer. + * + * @param vertices Vector of vertex data + * @throws std::runtime_error if buffer creation fails + */ + virtual void UploadVertexData(const std::vector& vertices) = 0; + + /** + * @brief Upload index data to GPU buffer. + * + * @param indices Vector of index data + * @throws std::runtime_error if buffer creation fails + */ + virtual void UploadIndexData(const std::vector& indices) = 0; + + /** + * @brief Begin a new frame and acquire the next swapchain image. + * + * @return true if successful, false if swapchain needs recreation + */ + virtual bool BeginFrame() = 0; + + /** + * @brief Render the scene with the given render commands. + * + * @param commands List of render commands to execute + * @param viewProj View-projection matrix + */ + virtual void RenderScene(const std::vector& commands, + const std::array& viewProj) = 0; + + /** + * @brief End the frame and present the rendered image. + * + * @return true if successful, false if swapchain needs recreation + */ + virtual bool EndFrame() = 0; + + /** + * @brief Wait for all GPU operations to complete. + * + * Called before cleanup or when synchronization is needed. + */ + virtual void WaitIdle() = 0; + + /** + * @brief Get the Vulkan logical device. + * + * @return VkDevice handle (needed for GUI renderer, etc.) + */ + virtual VkDevice GetDevice() const = 0; + + /** + * @brief Get the Vulkan physical device. + * + * @return VkPhysicalDevice handle + */ + virtual VkPhysicalDevice GetPhysicalDevice() const = 0; + + /** + * @brief Get the current swapchain extent (framebuffer size). + * + * @return VkExtent2D with width and height + */ + virtual VkExtent2D GetSwapchainExtent() const = 0; + + /** + * @brief Get the swapchain image format. + * + * @return VkFormat of swapchain images + */ + virtual VkFormat GetSwapchainFormat() const = 0; + + /** + * @brief Get the current command buffer being recorded. + * + * @return VkCommandBuffer (needed for GUI rendering) + */ + virtual VkCommandBuffer GetCurrentCommandBuffer() const = 0; + + /** + * @brief Get the graphics queue. + * + * @return VkQueue handle + */ + virtual VkQueue GetGraphicsQueue() const = 0; +}; + +} // namespace sdl3cpp::services diff --git a/src/services/interfaces/i_gui_service.hpp b/src/services/interfaces/i_gui_service.hpp new file mode 100644 index 0000000..ba5b111 --- /dev/null +++ b/src/services/interfaces/i_gui_service.hpp @@ -0,0 +1,77 @@ +#pragma once + +#include +#include +#include +#include + +namespace sdl3cpp::services { + +// Forward declare GUI types +struct GuiCommand; + +/** + * @brief GUI rendering service interface. + * + * Handles 2D GUI overlay rendering using Vulkan. + * Wraps the GuiRenderer class with support for SVG, text, and shapes. + */ +class IGuiService { +public: + virtual ~IGuiService() = default; + + /** + * @brief Initialize the GUI renderer. + * + * @param device Vulkan logical device + * @param physicalDevice Vulkan physical device + * @param format Swapchain image format + * @param resourcePath Path to GUI resources (fonts, SVG files, etc.) + * @throws std::runtime_error if initialization fails + */ + virtual void Initialize(VkDevice device, + VkPhysicalDevice physicalDevice, + VkFormat format, + const std::filesystem::path& resourcePath) = 0; + + /** + * @brief Prepare GUI commands for rendering. + * + * Processes GUI commands from Lua and prepares rendering data. + * + * @param commands Vector of GUI commands to render + * @param width Viewport width in pixels + * @param height Viewport height in pixels + */ + virtual void PrepareFrame(const std::vector& commands, + uint32_t width, + uint32_t height) = 0; + + /** + * @brief Render GUI overlay to swapchain image. + * + * Records rendering commands into the provided command buffer. + * + * @param commandBuffer Vulkan command buffer to record into + * @param image Target swapchain image + */ + virtual void RenderToSwapchain(VkCommandBuffer commandBuffer, VkImage image) = 0; + + /** + * @brief Handle window resize. + * + * Recreates internal resources for the new window size. + * + * @param width New width in pixels + * @param height New height in pixels + * @param format Swapchain image format + */ + virtual void Resize(uint32_t width, uint32_t height, VkFormat format) = 0; + + /** + * @brief Shutdown and release GPU resources. + */ + virtual void Shutdown() = 0; +}; + +} // namespace sdl3cpp::services diff --git a/src/services/interfaces/i_input_service.hpp b/src/services/interfaces/i_input_service.hpp new file mode 100644 index 0000000..5d93e7d --- /dev/null +++ b/src/services/interfaces/i_input_service.hpp @@ -0,0 +1,81 @@ +#pragma once + +#include +#include +#include + +namespace sdl3cpp::services { + +/** + * @brief Input state snapshot for a single frame. + */ +struct InputState { + float mouseX = 0.0f; + float mouseY = 0.0f; + float mouseWheelDeltaX = 0.0f; + float mouseWheelDeltaY = 0.0f; + std::unordered_set keysPressed; + std::unordered_set mouseButtonsPressed; + std::string textInput; +}; + +/** + * @brief Input handling service interface. + * + * Subscribes to input events from the event bus and maintains + * the current input state for queries by other services. + */ +class IInputService { +public: + virtual ~IInputService() = default; + + /** + * @brief Process an SDL event and update input state. + * + * Called by the window service when events are polled. + * Updates internal state and publishes events to the event bus. + * + * @param event The SDL event to process + */ + virtual void ProcessEvent(const SDL_Event& event) = 0; + + /** + * @brief Reset per-frame input state. + * + * Called at the beginning of each frame to clear transient state + * like mouse wheel delta and text input. + */ + virtual void ResetFrameState() = 0; + + /** + * @brief Get the current input state. + * + * @return Reference to the current input state + */ + virtual const InputState& GetState() const = 0; + + /** + * @brief Check if a key is currently pressed. + * + * @param key The SDL keycode to check + * @return true if the key is pressed, false otherwise + */ + virtual bool IsKeyPressed(SDL_Keycode key) const = 0; + + /** + * @brief Check if a mouse button is currently pressed. + * + * @param button The mouse button (SDL_BUTTON_LEFT, SDL_BUTTON_RIGHT, etc.) + * @return true if the button is pressed, false otherwise + */ + virtual bool IsMouseButtonPressed(uint8_t button) const = 0; + + /** + * @brief Get the current mouse position. + * + * @return Pair of (x, y) coordinates in pixels + */ + virtual std::pair GetMousePosition() const = 0; +}; + +} // namespace sdl3cpp::services diff --git a/src/services/interfaces/i_physics_service.hpp b/src/services/interfaces/i_physics_service.hpp new file mode 100644 index 0000000..7aeb793 --- /dev/null +++ b/src/services/interfaces/i_physics_service.hpp @@ -0,0 +1,133 @@ +#pragma once + +#include +#include +#include + +namespace sdl3cpp::services { + +/** + * @brief Physics simulation service interface. + * + * Provides rigid body physics simulation using Bullet Physics. + * Wraps the PhysicsBridge class with a clean service interface. + */ +class IPhysicsService { +public: + virtual ~IPhysicsService() = default; + + /** + * @brief Initialize the physics world. + * + * @param gravity Gravity vector (default: {0, -9.8, 0}) + */ + virtual void Initialize(const btVector3& gravity = btVector3(0, -9.8f, 0)) = 0; + + /** + * @brief Shutdown and release physics resources. + */ + virtual void Shutdown() = 0; + + /** + * @brief Add a box-shaped rigid body to the simulation. + * + * @param name Unique identifier for this body + * @param halfExtents Half-extents of the box (half width/height/depth) + * @param mass Mass in kg (0 for static objects) + * @param transform Initial position and rotation + * @return true if added successfully, false if name already exists + */ + virtual bool AddBoxRigidBody(const std::string& name, + const btVector3& halfExtents, + float mass, + const btTransform& transform) = 0; + + /** + * @brief Add a sphere-shaped rigid body to the simulation. + * + * @param name Unique identifier for this body + * @param radius Sphere radius + * @param mass Mass in kg (0 for static objects) + * @param transform Initial position and rotation + * @return true if added successfully, false if name already exists + */ + virtual bool AddSphereRigidBody(const std::string& name, + float radius, + float mass, + const btTransform& transform) = 0; + + /** + * @brief Remove a rigid body from the simulation. + * + * @param name Identifier of the body to remove + * @return true if removed, false if not found + */ + virtual bool RemoveRigidBody(const std::string& name) = 0; + + /** + * @brief Step the physics simulation forward in time. + * + * @param deltaTime Time step in seconds (typically 1/60) + * @param maxSubSteps Maximum number of sub-steps for stability + */ + virtual void StepSimulation(float deltaTime, int maxSubSteps = 10) = 0; + + /** + * @brief Get the current transform of a rigid body. + * + * @param name Identifier of the body + * @param outTransform Output parameter for the transform + * @return true if body exists, false otherwise + */ + virtual bool GetTransform(const std::string& name, btTransform& outTransform) const = 0; + + /** + * @brief Set the transform of a rigid body. + * + * @param name Identifier of the body + * @param transform New position and rotation + * @return true if body exists, false otherwise + */ + virtual bool SetTransform(const std::string& name, const btTransform& transform) = 0; + + /** + * @brief Apply a force to a rigid body. + * + * @param name Identifier of the body + * @param force Force vector in Newtons + * @return true if body exists, false otherwise + */ + virtual bool ApplyForce(const std::string& name, const btVector3& force) = 0; + + /** + * @brief Apply an impulse to a rigid body. + * + * @param name Identifier of the body + * @param impulse Impulse vector + * @return true if body exists, false otherwise + */ + virtual bool ApplyImpulse(const std::string& name, const btVector3& impulse) = 0; + + /** + * @brief Set the linear velocity of a rigid body. + * + * @param name Identifier of the body + * @param velocity Velocity vector in m/s + * @return true if body exists, false otherwise + */ + virtual bool SetLinearVelocity(const std::string& name, const btVector3& velocity) = 0; + + /** + * @brief Get the number of rigid bodies in the simulation. + * + * @return Body count + */ + virtual size_t GetBodyCount() const = 0; + + /** + * @brief Clear all rigid bodies from the simulation. + */ + virtual void Clear() = 0; +}; + +} // namespace sdl3cpp::services diff --git a/src/services/interfaces/i_scene_service.hpp b/src/services/interfaces/i_scene_service.hpp new file mode 100644 index 0000000..506f83d --- /dev/null +++ b/src/services/interfaces/i_scene_service.hpp @@ -0,0 +1,58 @@ +#pragma once + +#include "i_graphics_service.hpp" +#include "i_script_service.hpp" +#include + +namespace sdl3cpp::services { + +/** + * @brief Scene management service interface. + * + * Maintains the scene graph and generates render commands for the graphics service. + * Separated from script service to decouple scene state from Lua execution. + */ +class ISceneService { +public: + virtual ~ISceneService() = default; + + /** + * @brief Load a scene from scene objects. + * + * Replaces the current scene with new objects. + * + * @param objects Vector of scene objects to load + */ + virtual void LoadScene(const std::vector& objects) = 0; + + /** + * @brief Update scene state (animations, transformations, etc.). + * + * @param deltaTime Time since last update in seconds + */ + virtual void UpdateScene(float deltaTime) = 0; + + /** + * @brief Generate render commands for the current scene. + * + * Evaluates model matrices and prepares draw calls. + * + * @param time Current time in seconds + * @return Vector of render commands for the graphics service + */ + virtual std::vector GetRenderCommands(float time) const = 0; + + /** + * @brief Clear the scene (remove all objects). + */ + virtual void Clear() = 0; + + /** + * @brief Get the number of objects in the scene. + * + * @return Object count + */ + virtual size_t GetObjectCount() const = 0; +}; + +} // namespace sdl3cpp::services diff --git a/src/services/interfaces/i_script_service.hpp b/src/services/interfaces/i_script_service.hpp new file mode 100644 index 0000000..df036e0 --- /dev/null +++ b/src/services/interfaces/i_script_service.hpp @@ -0,0 +1,126 @@ +#pragma once + +#include "../../core/vertex.hpp" +#include "i_graphics_service.hpp" +#include +#include +#include +#include +#include +#include + +namespace sdl3cpp::services { + +/** + * @brief Scene object data structure. + */ +struct SceneObject { + std::string id; + std::vector vertices; + std::vector indices; + std::string shaderKey; + int modelMatrixFuncRef; // Lua function reference +}; + +/** + * @brief GUI input snapshot for Lua. + */ +struct GuiInputSnapshot { + float mouseX; + float mouseY; + float mouseWheelDelta; + bool mouseLeftPressed; + bool mouseRightPressed; + std::string textInput; +}; + +// Forward declare GUI types (defined in script/gui_types.hpp) +struct GuiCommand; + +/** + * @brief Script service interface (Lua integration). + * + * Provides a clean API for Lua script execution and data exchange. + * Wraps the ScriptEngine and its internal managers (SceneManager, + * ShaderManager, GuiManager, AudioManager). + */ +class IScriptService { +public: + virtual ~IScriptService() = default; + + /** + * @brief Load and execute a Lua script. + * + * @param path Path to the Lua script file + * @param debug Whether to enable Lua debug mode + * @throws std::runtime_error if script loading fails + */ + virtual void LoadScript(const std::filesystem::path& path, bool debug) = 0; + + /** + * @brief Load scene objects from Lua. + * + * Calls the Lua function that generates the scene graph. + * + * @return Vector of scene objects with geometry and metadata + */ + virtual std::vector LoadSceneObjects() = 0; + + /** + * @brief Compute model matrix for an object using Lua function. + * + * @param funcRef Lua function reference (from SceneObject) + * @param time Current time in seconds + * @return 4x4 model transformation matrix (column-major) + */ + virtual std::array ComputeModelMatrix(int funcRef, float time) = 0; + + /** + * @brief Get view-projection matrix from Lua. + * + * @param aspect Window aspect ratio (width/height) + * @return 4x4 view-projection matrix (column-major) + */ + virtual std::array GetViewProjectionMatrix(float aspect) = 0; + + /** + * @brief Load shader paths from Lua configuration. + * + * @return Map of shader key to shader file paths + */ + virtual std::unordered_map LoadShaderPaths() = 0; + + /** + * @brief Update GUI input state in Lua. + * + * Sends current input state to Lua for GUI processing. + * + * @param input Input snapshot for this frame + */ + virtual void UpdateGuiInput(const GuiInputSnapshot& input) = 0; + + /** + * @brief Get GUI rendering commands from Lua. + * + * Retrieves the list of GUI commands generated by Lua scripts. + * + * @return Vector of GUI commands to render + */ + virtual std::vector GetGuiCommands() = 0; + + /** + * @brief Check if there are pending GUI commands. + * + * @return true if GUI commands are available, false otherwise + */ + virtual bool HasGuiCommands() const = 0; + + /** + * @brief Update physics simulation (calls Lua if needed). + * + * @param deltaTime Time since last update in seconds + */ + virtual void UpdatePhysics(float deltaTime) = 0; +}; + +} // namespace sdl3cpp::services diff --git a/src/services/interfaces/i_shader_service.hpp b/src/services/interfaces/i_shader_service.hpp new file mode 100644 index 0000000..3682b03 --- /dev/null +++ b/src/services/interfaces/i_shader_service.hpp @@ -0,0 +1,72 @@ +#pragma once + +#include "i_graphics_service.hpp" +#include +#include +#include + +namespace sdl3cpp::services { + +/** + * @brief Shader management service interface. + * + * Handles shader compilation, pipeline creation, and shader program management. + * Wraps the ShaderManager from the script module. + */ +class IShaderService { +public: + virtual ~IShaderService() = default; + + /** + * @brief Register a shader program. + * + * @param key Unique identifier for this shader program + * @param paths Vertex and fragment shader file paths + * @throws std::runtime_error if shader files don't exist + */ + virtual void RegisterShader(const std::string& key, const ShaderPaths& paths) = 0; + + /** + * @brief Compile all registered shaders and create pipelines. + * + * Must be called after all shaders are registered and before rendering. + * + * @throws std::runtime_error if compilation fails + */ + virtual void CompileAll() = 0; + + /** + * @brief Get the Vulkan pipeline for a shader program. + * + * @param key Shader program identifier + * @return VkPipeline handle + * @throws std::out_of_range if shader key doesn't exist + */ + virtual VkPipeline GetPipeline(const std::string& key) const = 0; + + /** + * @brief Check if a shader program exists. + * + * @param key Shader program identifier + * @return true if registered, false otherwise + */ + virtual bool HasShader(const std::string& key) const = 0; + + /** + * @brief Get the number of registered shader programs. + * + * @return Shader count + */ + virtual size_t GetShaderCount() const = 0; + + /** + * @brief Reload all shaders (for hot-reload support). + * + * Recompiles all shaders from their source files. + * + * @throws std::runtime_error if compilation fails + */ + virtual void ReloadAll() = 0; +}; + +} // namespace sdl3cpp::services diff --git a/src/services/interfaces/i_window_service.hpp b/src/services/interfaces/i_window_service.hpp new file mode 100644 index 0000000..318a771 --- /dev/null +++ b/src/services/interfaces/i_window_service.hpp @@ -0,0 +1,95 @@ +#pragma once + +#include +#include +#include + +// Forward declare SDL types to avoid including SDL headers +struct SDL_Window; + +namespace sdl3cpp::services { + +/** + * @brief Window configuration structure. + */ +struct WindowConfig { + uint32_t width; + uint32_t height; + std::string title; + bool resizable; +}; + +/** + * @brief Window management service interface. + * + * Handles SDL window creation, event polling, and window state management. + * Decouples SDL-specific details from the rest of the application. + */ +class IWindowService { +public: + virtual ~IWindowService() = default; + + /** + * @brief Create and show the application window. + * + * @param config Window configuration (size, title, flags) + * @throws std::runtime_error if window creation fails + */ + virtual void CreateWindow(const WindowConfig& config) = 0; + + /** + * @brief Destroy the window and release resources. + */ + virtual void DestroyWindow() = 0; + + /** + * @brief Get the native SDL window handle. + * + * Required for Vulkan surface creation and other low-level operations. + * + * @return Pointer to SDL_Window, or nullptr if no window exists + */ + virtual SDL_Window* GetNativeHandle() const = 0; + + /** + * @brief Get the current window size. + * + * @return Pair of (width, height) in pixels + */ + virtual std::pair GetSize() const = 0; + + /** + * @brief Check if the window should close. + * + * Returns true when the user clicks the close button or + * a quit event is received. + * + * @return true if the application should exit, false otherwise + */ + virtual bool ShouldClose() const = 0; + + /** + * @brief Poll SDL events and publish them to the event bus. + * + * This should be called once per frame to process user input + * and window events. Events are converted to application events + * and published via the event bus. + */ + virtual void PollEvents() = 0; + + /** + * @brief Set the window title. + * + * @param title New window title + */ + virtual void SetTitle(const std::string& title) = 0; + + /** + * @brief Check if the window is minimized. + * + * @return true if minimized, false otherwise + */ + virtual bool IsMinimized() const = 0; +}; + +} // namespace sdl3cpp::services