Extra2D/include/platform/window_module.h

182 lines
3.6 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#pragma once
#include <SDL.h>
#include <config/app_config.h>
#include <config/window_config.h>
#include <functional>
#include <module/module.h>
#include <module/module_registry.h>
#include <type_traits>
#include <types/math/size.h>
#include <types/math/vec2.h>
namespace extra2d {
/**
* @brief 窗口事件回调
*/
using ResizeCb = std::function<void(int32 w, int32 h)>;
using CloseCb = std::function<void()>;
/**
* @brief 窗口模块 - 简化版
*
* 管理 SDL2 窗口和 OpenGL 上下文
* 使用新的 Module 基类,支持自动注册
*/
class WindowModule : public Module {
// 自动注册到模块系统,优先级为 0最先初始化
E2D_REGISTER_MODULE(WindowModule, "Window", 0)
public:
WindowModule();
~WindowModule() override;
// 禁止拷贝
WindowModule(const WindowModule &) = delete;
WindowModule &operator=(const WindowModule &) = delete;
// 允许移动
WindowModule(WindowModule &&) noexcept;
WindowModule &operator=(WindowModule &&) noexcept;
// Module 接口实现
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);
/**
* @brief 监听模块配置事件
* @tparam ConfigT 配置类型
* @param config 配置对象
*
* 只处理 AppConfig 类型的配置
*/
template <typename ConfigT> void onModuleConfig(const ConfigT &config) {
// 只处理 AppConfig 类型
if constexpr (std::is_same_v<ConfigT, AppConfig>) {
WindowCfg cfg;
cfg.title = config.title;
cfg.width = config.width;
cfg.height = config.height;
cfg.fullscreen = config.fullscreen;
cfg.resizable = config.resizable;
cfg.vsync = config.vsync;
cfg.glMajor = config.glMajor;
cfg.glMinor = config.glMinor;
if (create(cfg)) {
setVisible(true);
}
}
}
SDL_Window *window_ = nullptr;
SDL_GLContext glCtx_ = nullptr;
bool shouldClose_ = false;
bool vsync_ = true;
CloseCb onClose_;
ResizeCb onResize_;
};
} // namespace extra2d