#pragma once #include #include #include #include #include #include #include #include namespace extra2d { /** * @brief 窗口配置 */ struct WindowCfg { std::string title = "Extra2D"; int32 width = 1280; int32 height = 720; bool fullscreen = false; bool resizable = true; bool vsync = true; int32 glMajor = 3; int32 glMinor = 3; }; /** * @brief 窗口事件回调 */ using ResizeCb = std::function; using CloseCb = std::function; /** * @brief 窗口模块 * * 管理 SDL2 窗口和 OpenGL 上下文 * 非单例设计,通过 Context 管理生命周期 */ class WindowModule : public IModule { public: WindowModule(); ~WindowModule() override; // 禁止拷贝 WindowModule(const WindowModule&) = delete; WindowModule& operator=(const WindowModule&) = delete; // 允许移动 WindowModule(WindowModule&&) noexcept; WindowModule& operator=(WindowModule&&) noexcept; // IModule 接口实现 const char* name() const override { return "Window"; } ModuleType type() const override { return ModuleType::System; } int priority() const override { return Pri::Window; } bool init() override; void shutdown() override; /** * @brief 使用配置创建窗口 */ bool create(const WindowCfg& cfg); /** * @brief 处理窗口事件 * @return true 继续运行,false 应退出 */ bool pollEvents(); /** * @brief 交换缓冲区 */ void swapBuffers(); /** * @brief 获取 SDL 窗口句柄 */ SDL_Window* handle() const { return window_; } /** * @brief 获取 OpenGL 上下文 */ SDL_GLContext glContext() const { return glCtx_; } /** * @brief 获取窗口尺寸 */ Size getSize() const; /** * @brief 获取窗口位置 */ Vec2 getPosition() const; /** * @brief 设置窗口尺寸 */ void setSize(int32 w, int32 h); /** * @brief 设置窗口标题 */ void setTitle(const std::string& title); /** * @brief 设置全屏模式 */ void setFullscreen(bool fullscreen); /** * @brief 检查是否全屏 */ bool isFullscreen() const; /** * @brief 设置垂直同步 */ void setVsync(bool vsync); /** * @brief 检查是否垂直同步 */ bool isVsync() const; /** * @brief 显示/隐藏窗口 */ void setVisible(bool visible); /** * @brief 检查窗口是否可见 */ bool isVisible() const; /** * @brief 设置窗口关闭回调 */ void setOnClose(CloseCb cb) { onClose_ = std::move(cb); } /** * @brief 设置窗口大小改变回调 */ void setOnResize(ResizeCb cb) { onResize_ = std::move(cb); } /** * @brief 请求关闭窗口 */ void requestClose() { shouldClose_ = true; } /** * @brief 检查是否应该关闭 */ bool shouldClose() const { return shouldClose_; } private: void handleWindowEvent(const SDL_WindowEvent& evt); SDL_Window* window_ = nullptr; SDL_GLContext glCtx_ = nullptr; bool shouldClose_ = false; bool vsync_ = true; CloseCb onClose_; ResizeCb onResize_; }; } // namespace extra2d