feat: Implement window factory and registry for managing window creation and lifecycle

- Added `window_factory` class to handle the creation of various window types (main, child, popup, dialog).
- Introduced `window_registry` class for managing window instances, their relationships, and states.
- Defined structures for window creation information including `popup_create_info`, `dialog_create_info`, and `child_window_create_info`.
- Implemented thread-safe mechanisms for window registration, unregistration, and querying.
- Added enumerations for window types and states with string conversion functions for better debugging and logging.
This commit is contained in:
2025-12-15 23:15:00 +08:00
parent 3629038519
commit 3da1b38387
18 changed files with 4063 additions and 991 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,5 @@
#include "application.h"
#include "window_manager.h"
#include "window_interface.h"
#include "window_common.h"
#include "event/event_types.h"
@@ -52,7 +51,7 @@ namespace mirage::app {
// 1. 创建窗口管理器和窗口
// ========================================================================
window_manager_ = std::make_unique<window_manager>();
window_manager_ = std::make_unique<unified_window_manager>();
window_create_info window_info{
.title = config.title,
@@ -67,13 +66,14 @@ namespace mirage::app {
window_info.flags = window_flag::VISIBLE | window_flag::DECORATED | window_flag::FOCUSED;
}
auto window_result = window_manager_->create_window(window_info);
auto window_result = window_manager_->create_main_window(window_info);
if (!window_result.has_value()) {
std::cerr << "[application] Failed to create window: " << window_result.error() << std::endl;
return false;
}
window_ = window_manager_->get_window(window_result.value());
main_window_id_ = window_result.value();
window_ = window_manager_->get_window(main_window_id_);
if (!window_) {
std::cerr << "[application] Failed to get window pointer" << std::endl;
return false;
@@ -508,7 +508,7 @@ namespace mirage::app {
void application::process_events() {
if (window_manager_) {
window_manager_->poll_all_events();
window_manager_->poll_events();
}
}

View File

@@ -16,6 +16,7 @@
#include "vulkan/vulkan_common.h"
#include "widget_context.h"
#include "window/main_window_widget.h"
#include "unified_window_manager.h"
#include "widget_event/widget_event_router.h"
@@ -36,7 +37,6 @@ namespace mirage {
// 前向声明
namespace mirage {
class window_interface;
class window_manager;
class render_pipeline;
class widget_base;
class render_context;
@@ -318,10 +318,13 @@ private:
// 核心组件
// ========================================================================
/// @brief 窗口管理器
std::unique_ptr<window_manager> window_manager_;
/// @brief 统一窗口管理器
std::unique_ptr<unified_window_manager> window_manager_;
/// @brief 窗口指针(由窗口管理器管理)
/// @brief 窗口ID
window_id main_window_id_{INVALID_WINDOW_ID};
/// @brief 窗口指针(由窗口管理器管理,兼容层)
window_interface* window_ = nullptr;
/// @brief GLFW 窗口指针(用于创建 Vulkan Surface

48
src/common/window_id.h Normal file
View File

@@ -0,0 +1,48 @@
#pragma once
#include <cstdint>
#include <atomic>
namespace mirage {
/// 窗口唯一标识符类型
/// 定义在 common 模块,供 render 和 window 模块共同使用
using window_id = uint64_t;
/// 无效窗口ID常量
constexpr window_id INVALID_WINDOW_ID = 0;
/// 检查窗口ID是否有效
/// @param id 要检查的窗口ID
/// @return 如果ID有效返回true否则返回false
[[nodiscard]] constexpr auto is_valid_window_id(window_id id) noexcept -> bool {
return id != INVALID_WINDOW_ID;
}
/// 线程安全的窗口ID生成器
/// 使用原子操作确保多线程环境下ID的唯一性
class window_id_generator {
public:
/// 生成下一个唯一的窗口ID
/// @return 新生成的窗口ID
[[nodiscard]] auto generate() noexcept -> window_id {
return ++next_id_;
}
/// 查看下一个将要生成的ID不消耗
/// @return 下一个将要生成的窗口ID
[[nodiscard]] auto peek_next() const noexcept -> window_id {
return next_id_.load(std::memory_order_relaxed) + 1;
}
/// 获取当前已生成的最大ID
/// @return 当前最大的窗口ID
[[nodiscard]] auto current() const noexcept -> window_id {
return next_id_.load(std::memory_order_relaxed);
}
private:
std::atomic<window_id> next_id_{0};
};
} // namespace mirage

View File

@@ -5,6 +5,7 @@
#include "vulkan/logical_device.h"
#include "vulkan/resource_manager.h"
#include "vulkan/swapchain.h"
#include "window_id.h"
#include <memory>
#include <vector>
@@ -12,8 +13,7 @@
#include <cstdint>
namespace mirage {
/// 窗口标识符类型
using window_id = uint64_t;
// window_id 类型已在 common/window_id.h 中定义于 mirage 命名空间
/// 窗口渲染上下文 - 封装每窗口独立的 Vulkan 资源
///

View File

@@ -4,6 +4,8 @@
#include <optional>
#include <string_view>
#include "window_id.h"
#ifdef DELETE
#undef DELETE
#endif
@@ -205,6 +207,7 @@ namespace mirage {
/// 通用事件结构
struct event {
event_type type{event_type::NONE};
window_id source_window{INVALID_WINDOW_ID}; ///< 事件来源窗口ID
union {
window_event_data window;
@@ -215,10 +218,14 @@ namespace mirage {
mouse_scroll_event_data mouse_scroll;
};
event() : type(event_type::NONE), window{} {
event() : type(event_type::NONE), source_window(INVALID_WINDOW_ID), window{} {
}
explicit event(event_type t) : type(t), window{} {
explicit event(event_type t) : type(t), source_window(INVALID_WINDOW_ID), window{} {
}
event(event_type t, window_id src_window)
: type(t), source_window(src_window), window{} {
}
};

View File

@@ -84,10 +84,10 @@ namespace mirage {
}
auto vulkan_surface_manager::collect_required_extensions(
const window_manager& manager
const unified_window_manager& manager
) -> std::vector<const char*> {
// 获取所有窗口ID
auto window_ids = manager.get_all_window_ids();
auto window_ids = manager.get_all_windows();
// 构建窗口指针列表
std::vector<const window_interface*> windows;

View File

@@ -2,8 +2,8 @@
#include "window_common.h"
#include "window_interface.h"
#include "window_manager.h"
#include "vulkan/vulkan_common.h"
#include "unified_window_manager.h"
#include <vector>
#include <unordered_set>
@@ -50,7 +50,7 @@ namespace mirage {
/// @param manager 窗口管理器引用
/// @return 扩展名称列表(已去重)
[[nodiscard]] static auto collect_required_extensions(
const window_manager& manager
const unified_window_manager& manager
) -> std::vector<const char*>;
/// 销毁 Vulkan Surface

View File

@@ -0,0 +1,409 @@
#include "unified_window_manager.h"
#include "window_interface.h"
#include <algorithm>
#include <ranges>
namespace mirage {
// =============================================================================
// 构造函数与析构函数
// =============================================================================
unified_window_manager::unified_window_manager() : id_generator_{}
, registry_{std::make_unique<window_registry>()}
, factory_{
std::make_unique<window_factory>(*registry_, id_generator_)
}
, event_callback_{}
, pending_destroy_{} {
}
unified_window_manager::~unified_window_manager() {
// 清理所有窗口
// 窗口实例由 registry_ 管理registry_ 析构时会自动清理
}
// =============================================================================
// 窗口创建
// =============================================================================
auto unified_window_manager::create_main_window(const mirage::window_create_info& info)
-> std::expected<window_id, std::string> {
auto result = factory_->create_main_window(info);
if (!result) {
return std::unexpected(result.error());
}
auto id = result.value();
// 设置窗口事件回调
setup_window_callbacks(id);
// 如果是第一个主窗口,自动设置为主窗口
if (!is_valid_window_id(registry_->get_main_window())) {
registry_->set_main_window(id);
}
return id;
}
auto unified_window_manager::create_child_window(window_id parent,
const child_window_create_info& info)
-> std::expected<window_id, std::string> {
auto result = factory_->create_child_window(parent, info);
if (!result) {
return std::unexpected(result.error());
}
auto id = result.value();
// 设置窗口事件回调
setup_window_callbacks(id);
return id;
}
auto unified_window_manager::create_popup(window_id owner, const popup_create_info& info)
-> std::expected<window_id, std::string> {
auto result = factory_->create_popup(owner, info);
if (!result) {
return std::unexpected(result.error());
}
auto id = result.value();
// 设置窗口事件回调
setup_window_callbacks(id);
return id;
}
auto unified_window_manager::create_dialog(window_id owner, const dialog_create_info& info)
-> std::expected<window_id, std::string> {
auto result = factory_->create_dialog(owner, info);
if (!result) {
return std::unexpected(result.error());
}
auto id = result.value();
// 设置窗口事件回调
setup_window_callbacks(id);
return id;
}
// =============================================================================
// 窗口销毁
// =============================================================================
auto unified_window_manager::destroy_window(window_id id) -> bool {
if (!registry_->contains(id)) {
return false;
}
// 先递归销毁所有子窗口
destroy_all_children(id);
// 注销窗口
return registry_->unregister_window(id);
}
auto unified_window_manager::destroy_all_children(window_id parent) -> size_t {
auto children = registry_->get_children(parent);
size_t count = 0;
for (auto child_id : children) {
// 递归销毁子窗口的子窗口
count += destroy_all_children(child_id);
// 销毁子窗口本身
if (registry_->unregister_window(child_id)) {
++count;
}
}
return count;
}
// =============================================================================
// 窗口查询
// =============================================================================
auto unified_window_manager::get_window(window_id id) -> mirage::window_interface* {
return registry_->get_window(id);
}
auto unified_window_manager::get_window(window_id id) const -> const mirage::window_interface* {
return registry_->get_window(id);
}
auto unified_window_manager::contains(window_id id) const -> bool {
return registry_->contains(id);
}
auto unified_window_manager::get_window_type(window_id id) const -> window_type {
auto type = registry_->get_type(id);
return type.value_or(window_type::MAIN_WINDOW);
}
auto unified_window_manager::get_window_state(window_id id) const -> window_state {
return registry_->get_state(id);
}
// =============================================================================
// 窗口关系
// =============================================================================
auto unified_window_manager::get_parent(window_id id) const -> window_id {
return registry_->get_parent(id);
}
auto unified_window_manager::get_children(window_id id) const -> std::vector<window_id> {
return registry_->get_children(id);
}
auto unified_window_manager::get_main_window() const -> window_id {
return registry_->get_main_window();
}
auto unified_window_manager::get_focused_window() const -> window_id {
return registry_->get_focused_window();
}
// =============================================================================
// 窗口状态
// =============================================================================
auto unified_window_manager::set_window_state(window_id id, window_state state) -> bool {
auto* window = registry_->get_window(id);
if (!window) {
return false;
}
// 更新注册表中的状态
if (!registry_->set_state(id, state)) {
return false;
}
// 同步窗口实际状态
switch (state) {
case window_state::NORMAL:
window->restore();
break;
case window_state::MINIMIZED:
window->minimize();
break;
case window_state::MAXIMIZED:
window->maximize();
break;
case window_state::HIDDEN:
window->hide();
break;
case window_state::FULLSCREEN:
window->set_mode(mirage::window_mode::FULLSCREEN);
break;
}
return true;
}
auto unified_window_manager::show_window(window_id id) -> bool {
auto* window = registry_->get_window(id);
if (!window) {
return false;
}
window->show();
registry_->set_state(id, window_state::NORMAL);
return true;
}
auto unified_window_manager::hide_window(window_id id) -> bool {
auto* window = registry_->get_window(id);
if (!window) {
return false;
}
window->hide();
registry_->set_state(id, window_state::HIDDEN);
return true;
}
auto unified_window_manager::focus_window(window_id id) -> bool {
auto* window = registry_->get_window(id);
if (!window) {
return false;
}
window->focus();
registry_->set_focused_window(id);
return true;
}
// =============================================================================
// 事件处理
// =============================================================================
void unified_window_manager::poll_events() {
// 处理之前累积的待销毁窗口
process_pending_destroys();
// 获取所有窗口ID
auto all_windows = registry_->get_all_windows();
// 遍历所有窗口调用 poll_events()
for (auto id : all_windows) {
auto* window = registry_->get_window(id);
if (window) {
window->poll_events();
// 检查窗口关闭状态
if (window->should_close()) {
handle_window_close(id);
}
}
}
// 处理本次轮询产生的待销毁窗口
process_pending_destroys();
}
void unified_window_manager::set_event_callback(window_event_callback callback) {
event_callback_ = std::move(callback);
// 为所有已存在的窗口重新设置回调
auto all_windows = registry_->get_all_windows();
for (auto id : all_windows) {
setup_window_callbacks(id);
}
}
// =============================================================================
// 批量查询
// =============================================================================
auto unified_window_manager::get_all_windows() const -> std::vector<window_id> {
return registry_->get_all_windows();
}
auto unified_window_manager::get_windows_by_type(window_type type) const
-> std::vector<window_id> {
return registry_->get_windows_by_type(type);
}
auto unified_window_manager::get_visible_windows() const -> std::vector<window_id> {
auto all_windows = registry_->get_all_windows();
std::vector<window_id> visible;
visible.reserve(all_windows.size());
// 使用 ranges 过滤可见窗口
auto is_visible = [this](window_id id) {
auto state = registry_->get_state(id);
return state != window_state::HIDDEN;
};
std::ranges::copy_if(all_windows, std::back_inserter(visible), is_visible);
return visible;
}
// =============================================================================
// 统计
// =============================================================================
auto unified_window_manager::window_count() const -> size_t {
return registry_->count();
}
auto unified_window_manager::has_windows() const -> bool {
return !registry_->empty();
}
// =============================================================================
// 组件访问
// =============================================================================
auto unified_window_manager::registry() -> window_registry& {
return *registry_;
}
auto unified_window_manager::registry() const -> const window_registry& {
return *registry_;
}
// =============================================================================
// 内部方法
// =============================================================================
void unified_window_manager::setup_window_callbacks(window_id id) {
auto* window = registry_->get_window(id);
if (!window) {
return;
}
// 为窗口设置事件回调
// 事件中填充 source_window 字段,转发到 event_callback_
window->set_event_callback([this, id](const mirage::event& e) {
// 创建带有源窗口信息的事件副本
mirage::event enhanced_event = e;
enhanced_event.source_window = id;
// 处理特殊事件
switch (e.type) {
case mirage::event_type::WINDOW_FOCUS:
registry_->set_focused_window(id);
break;
case mirage::event_type::WINDOW_LOST_FOCUS:
if (registry_->get_focused_window() == id) {
registry_->set_focused_window(INVALID_WINDOW_ID);
}
break;
case mirage::event_type::WINDOW_MINIMIZED:
registry_->set_state(id, window_state::MINIMIZED);
break;
case mirage::event_type::WINDOW_MAXIMIZED:
registry_->set_state(id, window_state::MAXIMIZED);
break;
case mirage::event_type::WINDOW_RESTORED:
registry_->set_state(id, window_state::NORMAL);
break;
default:
break;
}
// 转发到用户回调
if (event_callback_) {
event_callback_(id, enhanced_event);
}
});
}
void unified_window_manager::handle_window_close(window_id id) {
// 如果是主窗口关闭,可能需要特殊处理
auto main_window = registry_->get_main_window();
// 触发关闭事件
if (event_callback_) {
mirage::event close_event{mirage::event_type::WINDOW_CLOSE, id};
event_callback_(id, close_event);
}
// 将窗口添加到待销毁列表(延迟销毁,避免在遍历过程中修改容器)
pending_destroy_.push_back(id);
}
void unified_window_manager::process_pending_destroys() {
if (pending_destroy_.empty()) {
return;
}
// 复制列表以避免在销毁过程中产生新的待销毁窗口导致的问题
auto to_destroy = std::move(pending_destroy_);
pending_destroy_.clear();
for (auto id : to_destroy) {
destroy_window(id);
}
}
} // namespace mirage

View File

@@ -0,0 +1,275 @@
#pragma once
#include "window_id.h"
#include "window_type.h"
#include "window_types.h"
#include "window_common.h"
#include "window_registry.h"
#include "window_factory.h"
#include <expected>
#include <functional>
#include <memory>
#include <string>
#include <vector>
namespace mirage {
/// 窗口事件回调类型
/// @param id 事件来源窗口ID
/// @param e 事件对象
using window_event_callback = std::function<void(window_id, const mirage::event&)>;
/// 统一窗口管理器
///
/// 窗口管理框架的统一入口,整合:
/// - window_registry - 窗口注册表
/// - window_factory - 窗口工厂
/// - window_id_generator - ID生成器
/// - 事件轮询与分发
///
/// 使用示例:
/// @code
/// unified_window_manager manager;
///
/// // 创建主窗口
/// auto result = manager.create_main_window({.title = "My App", .width = 1280, .height = 720});
/// if (result) {
/// auto main_id = result.value();
///
/// // 设置事件回调
/// manager.set_event_callback([](window_id id, const event& e) {
/// // 处理事件
/// });
///
/// // 主循环
/// while (manager.has_windows()) {
/// manager.poll_events();
/// // 渲染...
/// }
/// }
/// @endcode
class unified_window_manager {
public:
/// 构造函数
/// 初始化 id_generator_, registry_, factory_
unified_window_manager();
/// 析构函数
~unified_window_manager();
// 禁止拷贝
unified_window_manager(const unified_window_manager&) = delete;
auto operator=(const unified_window_manager&) -> unified_window_manager& = delete;
// 允许移动
unified_window_manager(unified_window_manager&&) noexcept = default;
auto operator=(unified_window_manager&&) noexcept -> unified_window_manager& = default;
// =========================================================================
// 窗口创建
// =========================================================================
/// 创建主窗口
/// @param info 窗口创建信息
/// @return 成功返回窗口ID失败返回错误消息
[[nodiscard]] auto create_main_window(const mirage::window_create_info& info)
-> std::expected<window_id, std::string>;
/// 创建子窗口
/// @param parent 父窗口ID
/// @param info 子窗口创建信息
/// @return 成功返回窗口ID失败返回错误消息
[[nodiscard]] auto create_child_window(window_id parent,
const child_window_create_info& info)
-> std::expected<window_id, std::string>;
/// 创建弹出窗口
/// @param owner 所有者窗口ID
/// @param info 弹出窗口创建信息
/// @return 成功返回窗口ID失败返回错误消息
[[nodiscard]] auto create_popup(window_id owner, const popup_create_info& info)
-> std::expected<window_id, std::string>;
/// 创建对话框
/// @param owner 所有者窗口ID
/// @param info 对话框创建信息
/// @return 成功返回窗口ID失败返回错误消息
[[nodiscard]] auto create_dialog(window_id owner, const dialog_create_info& info)
-> std::expected<window_id, std::string>;
// =========================================================================
// 窗口销毁
// =========================================================================
/// 销毁窗口
/// @param id 窗口ID
/// @return 成功返回true失败返回false
auto destroy_window(window_id id) -> bool;
/// 销毁指定窗口的所有子窗口
/// @param parent 父窗口ID
/// @return 被销毁的子窗口数量
auto destroy_all_children(window_id parent) -> size_t;
// =========================================================================
// 窗口查询
// =========================================================================
/// 获取窗口实例
/// @param id 窗口ID
/// @return 窗口实例指针如不存在返回nullptr
[[nodiscard]] auto get_window(window_id id) -> mirage::window_interface*;
/// 获取窗口实例const版本
/// @param id 窗口ID
/// @return 窗口实例指针如不存在返回nullptr
[[nodiscard]] auto get_window(window_id id) const -> const mirage::window_interface*;
/// 检查窗口是否存在
/// @param id 窗口ID
/// @return 如果存在返回true否则返回false
[[nodiscard]] auto contains(window_id id) const -> bool;
/// 获取窗口类型
/// @param id 窗口ID
/// @return 窗口类型,如窗口不存在返回 MAIN_WINDOW 作为默认值
[[nodiscard]] auto get_window_type(window_id id) const -> window_type;
/// 获取窗口状态
/// @param id 窗口ID
/// @return 窗口状态,如窗口不存在返回 HIDDEN
[[nodiscard]] auto get_window_state(window_id id) const -> window_state;
// =========================================================================
// 窗口关系
// =========================================================================
/// 获取父窗口ID
/// @param id 窗口ID
/// @return 父窗口ID如无父窗口或窗口不存在返回 INVALID_WINDOW_ID
[[nodiscard]] auto get_parent(window_id id) const -> window_id;
/// 获取直接子窗口列表
/// @param id 窗口ID
/// @return 子窗口ID列表如窗口不存在返回空列表
[[nodiscard]] auto get_children(window_id id) const -> std::vector<window_id>;
/// 获取主窗口ID
/// @return 主窗口ID如无主窗口返回 INVALID_WINDOW_ID
[[nodiscard]] auto get_main_window() const -> window_id;
/// 获取当前焦点窗口ID
/// @return 焦点窗口ID如无焦点窗口返回 INVALID_WINDOW_ID
[[nodiscard]] auto get_focused_window() const -> window_id;
// =========================================================================
// 窗口状态
// =========================================================================
/// 设置窗口状态
/// @param id 窗口ID
/// @param state 新状态
/// @return 成功返回true失败返回false
auto set_window_state(window_id id, window_state state) -> bool;
/// 显示窗口
/// @param id 窗口ID
/// @return 成功返回true失败返回false
auto show_window(window_id id) -> bool;
/// 隐藏窗口
/// @param id 窗口ID
/// @return 成功返回true失败返回false
auto hide_window(window_id id) -> bool;
/// 使窗口获取焦点
/// @param id 窗口ID
/// @return 成功返回true失败返回false
auto focus_window(window_id id) -> bool;
// =========================================================================
// 事件处理
// =========================================================================
/// 轮询所有窗口的事件
/// 遍历所有窗口调用 poll_events(),检查窗口关闭状态,触发事件回调
void poll_events();
/// 设置事件回调函数
/// @param callback 事件回调函数
void set_event_callback(window_event_callback callback);
// =========================================================================
// 批量查询
// =========================================================================
/// 获取所有已注册的窗口ID
/// @return 所有窗口ID列表
[[nodiscard]] auto get_all_windows() const -> std::vector<window_id>;
/// 按类型获取所有窗口ID
/// @param type 窗口类型
/// @return 该类型的所有窗口ID列表
[[nodiscard]] auto get_windows_by_type(window_type type) const -> std::vector<window_id>;
/// 获取所有可见窗口ID
/// @return 所有可见窗口ID列表
[[nodiscard]] auto get_visible_windows() const -> std::vector<window_id>;
// =========================================================================
// 统计
// =========================================================================
/// 获取已注册窗口总数
/// @return 窗口数量
[[nodiscard]] auto window_count() const -> size_t;
/// 检查是否有任何窗口
/// @return 如果有窗口返回true否则返回false
[[nodiscard]] auto has_windows() const -> bool;
// =========================================================================
// 组件访问
// =========================================================================
/// 获取窗口注册表引用
/// @return 窗口注册表引用
[[nodiscard]] auto registry() -> window_registry&;
/// 获取窗口注册表引用const版本
/// @return 窗口注册表常量引用
[[nodiscard]] auto registry() const -> const window_registry&;
private:
/// 窗口ID生成器
window_id_generator id_generator_;
/// 窗口注册表
std::unique_ptr<window_registry> registry_;
/// 窗口工厂
std::unique_ptr<window_factory> factory_;
/// 事件回调函数
window_event_callback event_callback_;
/// 待销毁窗口列表(用于延迟销毁)
std::vector<window_id> pending_destroy_;
// =========================================================================
// 内部方法
// =========================================================================
/// 为窗口设置事件回调
/// 事件中填充 source_window 字段,转发到 event_callback_
/// @param id 窗口ID
void setup_window_callbacks(window_id id);
/// 处理窗口关闭事件
/// @param id 窗口ID
void handle_window_close(window_id id);
/// 处理待销毁的窗口
void process_pending_destroys();
};
} // namespace mirage

View File

@@ -0,0 +1,319 @@
#include "window_factory.h"
#include "window_registry.h"
#include "window_interface.h"
namespace mirage {
// =============================================================================
// 构造函数
// =============================================================================
window_factory::window_factory(window_registry& registry, window_id_generator& id_gen) : registry_(registry)
, id_generator_(id_gen) {
}
// =============================================================================
// 主窗口创建
// =============================================================================
auto window_factory::create_main_window(const mirage::window_create_info& info)
-> std::expected<window_id, std::string> {
// 准备创建信息
auto prepared_info = prepare_create_info(info, window_type::MAIN_WINDOW);
// 调用平台窗口创建函数
auto window_result = mirage::create_window(prepared_info);
if (!window_result) {
return std::unexpected("Failed to create main window: platform error " +
std::string(mirage::window_error_to_string(window_result.error())));
}
// 生成窗口ID
auto id = id_generator_.generate();
// 注册窗口到注册表
if (!registry_.register_window(id, window_type::MAIN_WINDOW,
std::move(window_result.value()), INVALID_WINDOW_ID)) {
return std::unexpected("Failed to register main window");
}
return id;
}
// =============================================================================
// 子窗口创建
// =============================================================================
auto window_factory::create_child_window(window_id parent, const child_window_create_info& info)
-> std::expected<window_id, std::string> {
// 验证父窗口存在
if (!registry_.contains(parent)) {
return std::unexpected("Parent window does not exist");
}
// 获取父窗口位置以计算子窗口的绝对位置
auto parent_pos_result = get_owner_position(parent);
if (!parent_pos_result) {
return std::unexpected(parent_pos_result.error());
}
auto [parent_x, parent_y] = parent_pos_result.value();
// 构建创建信息
mirage::window_create_info create_info;
create_info.title = info.title;
create_info.width = static_cast<int32_t>(info.width);
create_info.height = static_cast<int32_t>(info.height);
create_info.mode = mirage::window_mode::WINDOWED;
// 设置窗口标志
create_info.flags = mirage::window_flag::VISIBLE |
mirage::window_flag::DECORATED |
mirage::window_flag::FOCUSED;
if (info.resizable) {
create_info.flags = create_info.flags | mirage::window_flag::RESIZABLE;
}
// 准备创建信息
auto prepared_info = prepare_create_info(create_info, window_type::CHILD_WINDOW);
// 调用平台窗口创建函数
auto window_result = mirage::create_window(prepared_info);
if (!window_result) {
return std::unexpected("Failed to create child window: platform error " +
std::string(mirage::window_error_to_string(window_result.error())));
}
// 设置子窗口位置(相对于父窗口)
auto& window_ptr = window_result.value();
window_ptr->set_position(parent_x + info.x, parent_y + info.y);
// 生成窗口ID
auto id = id_generator_.generate();
// 注册窗口到注册表(带父窗口)
if (!registry_.register_window(id, window_type::CHILD_WINDOW,
std::move(window_ptr), parent)) {
return std::unexpected("Failed to register child window");
}
return id;
}
// =============================================================================
// 弹出窗口创建
// =============================================================================
auto window_factory::create_popup(window_id owner, const popup_create_info& info)
-> std::expected<window_id, std::string> {
// 验证所有者窗口存在
if (!registry_.contains(owner)) {
return std::unexpected("Owner window does not exist");
}
// 获取所有者窗口位置
auto owner_pos_result = get_owner_position(owner);
if (!owner_pos_result) {
return std::unexpected(owner_pos_result.error());
}
auto [owner_x, owner_y] = owner_pos_result.value();
// 构建创建信息 - 弹出窗口通常无边框
mirage::window_create_info create_info;
create_info.title = info.title;
create_info.width = static_cast<int32_t>(info.width);
create_info.height = static_cast<int32_t>(info.height);
create_info.mode = mirage::window_mode::WINDOWED;
// 弹出窗口标志:无边框、浮动
create_info.flags = mirage::window_flag::VISIBLE |
mirage::window_flag::FLOATING;
// 准备创建信息
auto prepared_info = prepare_create_info(create_info, window_type::POPUP);
// 调用平台窗口创建函数
auto window_result = mirage::create_window(prepared_info);
if (!window_result) {
return std::unexpected("Failed to create popup window: platform error " +
std::string(mirage::window_error_to_string(window_result.error())));
}
// 设置弹出窗口位置(相对于所有者)
auto& window_ptr = window_result.value();
window_ptr->set_position(owner_x + info.x, owner_y + info.y);
// 生成窗口ID
auto id = id_generator_.generate();
// 注册窗口到注册表(带所有者作为父窗口)
if (!registry_.register_window(id, window_type::POPUP,
std::move(window_ptr), owner)) {
return std::unexpected("Failed to register popup window");
}
return id;
}
// =============================================================================
// 对话框创建
// =============================================================================
auto window_factory::create_dialog(window_id owner, const dialog_create_info& info)
-> std::expected<window_id, std::string> {
// 验证所有者窗口存在
if (!registry_.contains(owner)) {
return std::unexpected("Owner window does not exist");
}
// 获取所有者窗口信息用于居中
auto* owner_window = registry_.get_window(owner);
if (!owner_window) {
return std::unexpected("Failed to get owner window");
}
auto [owner_width, owner_height] = owner_window->get_size();
auto [owner_x, owner_y] = owner_window->get_position();
// 构建创建信息
mirage::window_create_info create_info;
create_info.title = info.title;
create_info.width = static_cast<int32_t>(info.width);
create_info.height = static_cast<int32_t>(info.height);
create_info.mode = mirage::window_mode::WINDOWED;
// 对话框标志:有边框、浮动、获取焦点
create_info.flags = mirage::window_flag::VISIBLE |
mirage::window_flag::DECORATED |
mirage::window_flag::FLOATING |
mirage::window_flag::FOCUSED;
if (info.resizable) {
create_info.flags = create_info.flags | mirage::window_flag::RESIZABLE;
}
// 准备创建信息
auto prepared_info = prepare_create_info(create_info, window_type::DIALOG);
// 调用平台窗口创建函数
auto window_result = mirage::create_window(prepared_info);
if (!window_result) {
return std::unexpected("Failed to create dialog window: platform error " +
std::string(mirage::window_error_to_string(window_result.error())));
}
auto& window_ptr = window_result.value();
// 计算居中位置
int32_t dialog_x = owner_x + (owner_width - static_cast<int32_t>(info.width)) / 2;
int32_t dialog_y = owner_y + (owner_height - static_cast<int32_t>(info.height)) / 2;
window_ptr->set_position(dialog_x, dialog_y);
// 生成窗口ID
auto id = id_generator_.generate();
// 注册窗口到注册表(带所有者作为父窗口)
if (!registry_.register_window(id, window_type::DIALOG,
std::move(window_ptr), owner)) {
return std::unexpected("Failed to register dialog window");
}
return id;
}
// =============================================================================
// 通用窗口创建
// =============================================================================
auto window_factory::create_window(window_type type,
const mirage::window_create_info& info,
window_id parent)
-> std::expected<window_id, std::string> {
// 如果指定了父窗口,验证其存在
if (is_valid_window_id(parent) && !registry_.contains(parent)) {
return std::unexpected("Parent window does not exist");
}
// 准备创建信息
auto prepared_info = prepare_create_info(info, type);
// 调用平台窗口创建函数
auto window_result = mirage::create_window(prepared_info);
if (!window_result) {
return std::unexpected("Failed to create window: platform error " +
std::string(mirage::window_error_to_string(window_result.error())));
}
// 生成窗口ID
auto id = id_generator_.generate();
// 注册窗口到注册表
if (!registry_.register_window(id, type, std::move(window_result.value()), parent)) {
return std::unexpected("Failed to register window");
}
return id;
}
// =============================================================================
// 内部辅助方法
// =============================================================================
auto window_factory::prepare_create_info(const mirage::window_create_info& info,
window_type type) const
-> mirage::window_create_info {
mirage::window_create_info result = info;
// 根据窗口类型调整默认设置
switch (type) {
case window_type::MAIN_WINDOW:
// 主窗口保持原始设置
break;
case window_type::CHILD_WINDOW:
// 子窗口:确保有装饰
result.flags = result.flags | mirage::window_flag::DECORATED;
break;
case window_type::POPUP:
// 弹出窗口:无边框、浮动
// 移除装饰标志
result.flags = static_cast<mirage::window_flag>(
static_cast<uint32_t>(result.flags) &
~static_cast<uint32_t>(mirage::window_flag::DECORATED)
);
result.flags = result.flags | mirage::window_flag::FLOATING;
break;
case window_type::DIALOG:
// 对话框:有装饰、浮动
result.flags = result.flags |
mirage::window_flag::DECORATED |
mirage::window_flag::FLOATING;
break;
case window_type::TOOLTIP:
// 提示窗口:无边框、浮动、不获取焦点
result.flags = static_cast<mirage::window_flag>(
static_cast<uint32_t>(result.flags) &
~static_cast<uint32_t>(mirage::window_flag::DECORATED) &
~static_cast<uint32_t>(mirage::window_flag::FOCUSED)
);
result.flags = result.flags | mirage::window_flag::FLOATING;
break;
default:
break;
}
return result;
}
auto window_factory::get_owner_position(window_id owner_id) const
-> std::expected<std::pair<int32_t, int32_t>, std::string> {
auto* owner_window = registry_.get_window(owner_id);
if (!owner_window) {
return std::unexpected("Owner window not found");
}
return owner_window->get_position();
}
} // namespace mirage

165
src/window/window_factory.h Normal file
View File

@@ -0,0 +1,165 @@
#pragma once
#include "window_id.h"
#include "window_type.h"
#include "window_types.h"
#include "window_common.h"
#include <expected>
#include <memory>
#include <string>
namespace mirage {
// 前向声明
class window_registry;
/// 弹出窗口创建信息
struct popup_create_info {
/// 窗口标题
std::string title;
/// 窗口宽度
uint32_t width = 200;
/// 窗口高度
uint32_t height = 150;
/// 相对于owner的x偏移
int32_t x = 0;
/// 相对于owner的y偏移
int32_t y = 0;
/// 失去焦点时自动关闭
bool auto_close = true;
};
/// 对话框创建信息
struct dialog_create_info {
/// 窗口标题
std::string title;
/// 窗口宽度
uint32_t width = 400;
/// 窗口高度
uint32_t height = 300;
/// 是否模态
bool modal = true;
/// 是否可调整大小
bool resizable = false;
};
/// 子窗口创建信息
struct child_window_create_info {
/// 窗口标题
std::string title;
/// 窗口宽度
uint32_t width = 640;
/// 窗口高度
uint32_t height = 480;
/// 相对于父窗口的x偏移
int32_t x = 0;
/// 相对于父窗口的y偏移
int32_t y = 0;
/// 是否可调整大小
bool resizable = true;
};
/// 窗口工厂
/// 负责创建各类窗口并将其注册到窗口注册表
class window_factory {
public:
/// 构造函数
/// @param registry 窗口注册表引用
/// @param id_gen 窗口ID生成器引用
explicit window_factory(window_registry& registry, window_id_generator& id_gen);
~window_factory() = default;
// 禁止拷贝
window_factory(const window_factory&) = delete;
auto operator=(const window_factory&) -> window_factory& = delete;
// 禁止移动
window_factory(window_factory&&) = delete;
auto operator=(window_factory&&) -> window_factory& = delete;
// =========================================================================
// 窗口创建接口
// =========================================================================
/// 创建主窗口
/// @param info 窗口创建信息
/// @return 成功返回窗口ID失败返回错误消息
[[nodiscard]] auto create_main_window(const mirage::window_create_info& info)
-> std::expected<window_id, std::string>;
/// 创建子窗口
/// @param parent 父窗口ID
/// @param info 子窗口创建信息
/// @return 成功返回窗口ID失败返回错误消息
[[nodiscard]] auto create_child_window(window_id parent, const child_window_create_info& info)
-> std::expected<window_id, std::string>;
/// 创建弹出窗口
/// @param owner 所有者窗口ID
/// @param info 弹出窗口创建信息
/// @return 成功返回窗口ID失败返回错误消息
[[nodiscard]] auto create_popup(window_id owner, const popup_create_info& info)
-> std::expected<window_id, std::string>;
/// 创建对话框
/// @param owner 所有者窗口ID
/// @param info 对话框创建信息
/// @return 成功返回窗口ID失败返回错误消息
[[nodiscard]] auto create_dialog(window_id owner, const dialog_create_info& info)
-> std::expected<window_id, std::string>;
// =========================================================================
// 通用创建接口
// =========================================================================
/// 通用窗口创建方法
/// @param type 窗口类型
/// @param info 窗口创建信息
/// @param parent 父窗口ID可选
/// @return 成功返回窗口ID失败返回错误消息
[[nodiscard]] auto create_window(window_type type,
const mirage::window_create_info& info,
window_id parent = INVALID_WINDOW_ID)
-> std::expected<window_id, std::string>;
private:
/// 窗口注册表引用
window_registry& registry_;
/// 窗口ID生成器引用
window_id_generator& id_generator_;
// =========================================================================
// 内部辅助方法
// =========================================================================
/// 将 window_create_info 转换为适合特定窗口类型的配置
/// @param info 基础创建信息
/// @param type 窗口类型
/// @return 调整后的创建信息
[[nodiscard]] auto prepare_create_info(const mirage::window_create_info& info,
window_type type) const
-> mirage::window_create_info;
/// 获取所有者窗口的位置(用于计算弹出窗口的绝对位置)
/// @param owner_id 所有者窗口ID
/// @return 成功返回位置{x, y},失败返回错误消息
[[nodiscard]] auto get_owner_position(window_id owner_id) const
-> std::expected<std::pair<int32_t, int32_t>, std::string>;
};
} // namespace mirage

View File

@@ -1,103 +0,0 @@
#include "window_manager.h"
namespace mirage {
// ========== 窗口管理 ==========
auto window_manager::create_window(const window_create_info& info)
-> std::expected<window_id, std::string> {
// 使用全局工厂函数创建窗口
auto result = mirage::create_window(info);
if (!result.has_value()) {
// 将window_error转换为字符串
return std::unexpected(std::string(window_error_to_string(result.error())));
}
// 生成新的窗口ID
window_id id = next_window_id_++;
// 存储窗口
windows_[id] = std::move(result.value());
return id;
}
auto window_manager::destroy_window(window_id id) -> bool {
auto it = windows_.find(id);
if (it == windows_.end()) {
return false;
}
// 销毁窗口
windows_.erase(it);
return true;
}
auto window_manager::get_window(window_id id) -> window_interface* {
auto it = windows_.find(id);
if (it == windows_.end()) {
return nullptr;
}
return it->second.get();
}
auto window_manager::get_window(window_id id) const -> const window_interface* {
auto it = windows_.find(id);
if (it == windows_.end()) {
return nullptr;
}
return it->second.get();
}
auto window_manager::get_all_window_ids() const -> std::vector<window_id> {
std::vector<window_id> ids;
ids.reserve(windows_.size());
for (const auto& [id, window] : windows_) {
ids.push_back(id);
}
return ids;
}
auto window_manager::get_window_count() const -> size_t {
return windows_.size();
}
// ========== 事件处理 ==========
auto window_manager::poll_all_events() -> void {
// 遍历所有窗口并轮询事件
for (auto& [id, window] : windows_) {
if (window) {
window->poll_events();
}
}
}
auto window_manager::all_windows_closed() const -> bool {
// 如果没有窗口,认为所有窗口都已关闭
if (windows_.empty()) {
return true;
}
// 检查所有窗口是否都应该关闭
for (const auto& [id, window] : windows_) {
if (window && !window->should_close()) {
return false;
}
}
return true;
}
// ========== Vulkan设备管理 ==========
auto window_manager::set_shared_device(std::shared_ptr<logical_device> device) -> void {
shared_device_ = std::move(device);
}
auto window_manager::get_shared_device() const -> std::shared_ptr<logical_device> {
return shared_device_;
}
} // namespace mirage

View File

@@ -1,128 +0,0 @@
#pragma once
#include "window_common.h"
#include "window_interface.h"
#include "vulkan/logical_device.h"
#include <unordered_map>
#include <memory>
#include <vector>
namespace mirage {
/// 窗口管理器类
///
/// 用于管理多个窗口实例,支持桌面平台的多窗口应用。
/// 提供窗口的创建、销毁、查询和统一事件轮询功能。
class window_manager {
public:
/// 窗口ID类型
using window_id = uint32_t;
/// 窗口智能指针类型
using window_ptr = std::unique_ptr<window_interface>;
/// 默认构造函数
window_manager() = default;
/// 析构函数
~window_manager() = default;
// 禁止拷贝
window_manager(const window_manager&) = delete;
window_manager& operator=(const window_manager&) = delete;
// 允许移动
window_manager(window_manager&&) noexcept = default;
window_manager& operator=(window_manager&&) noexcept = default;
// ========== 窗口管理 ==========
/// 创建窗口
///
/// 根据提供的创建信息创建一个新窗口实例并返回窗口ID。
///
/// @param info 窗口创建信息
/// @return 成功返回窗口ID失败返回错误消息
[[nodiscard]] auto create_window(const window_create_info& info)
-> std::expected<window_id, std::string>;
/// 销毁窗口
///
/// 根据窗口ID销毁对应的窗口实例。
///
/// @param id 窗口ID
/// @return 成功返回true失败返回false
auto destroy_window(window_id id) -> bool;
/// 获取窗口
///
/// 根据窗口ID获取对应的窗口实例指针。
///
/// @param id 窗口ID
/// @return 成功返回窗口指针失败返回nullptr
[[nodiscard]] auto get_window(window_id id) -> window_interface*;
/// 获取窗口(常量版本)
///
/// 根据窗口ID获取对应的窗口实例指针。
///
/// @param id 窗口ID
/// @return 成功返回窗口指针失败返回nullptr
[[nodiscard]] auto get_window(window_id id) const -> const window_interface*;
/// 获取所有窗口ID
///
/// 返回当前管理的所有窗口的ID列表。
///
/// @return 窗口ID列表
[[nodiscard]] auto get_all_window_ids() const -> std::vector<window_id>;
/// 获取窗口数量
///
/// 返回当前管理的窗口总数。
///
/// @return 窗口数量
[[nodiscard]] auto get_window_count() const -> size_t;
// ========== 事件处理 ==========
/// 轮询所有窗口的事件
///
/// 遍历所有窗口并调用它们的poll_events()方法,
/// 处理所有待处理的窗口事件。
auto poll_all_events() -> void;
/// 检查是否所有窗口都已关闭
///
/// 检查所有窗口的should_close()状态。
///
/// @return 如果所有窗口都应该关闭返回true否则返回false
[[nodiscard]] auto all_windows_closed() const -> bool;
// ========== Vulkan设备管理 ==========
/// 设置共享的Vulkan逻辑设备
///
/// 为多窗口共享Vulkan资源设置共享的逻辑设备。
///
/// @param device 共享的逻辑设备智能指针
auto set_shared_device(std::shared_ptr<logical_device> device) -> void;
/// 获取共享的Vulkan逻辑设备
///
/// 返回当前设置的共享逻辑设备。
///
/// @return 共享的逻辑设备智能指针
[[nodiscard]] auto get_shared_device() const -> std::shared_ptr<logical_device>;
private:
/// 窗口存储映射表
std::unordered_map<window_id, window_ptr> windows_;
/// 下一个窗口ID自动递增
window_id next_window_id_ = 1;
/// 共享的Vulkan逻辑设备
std::shared_ptr<logical_device> shared_device_;
};
} // namespace mirage

View File

@@ -0,0 +1,432 @@
#include "window_registry.h"
#include <algorithm>
#include "window_interface.h"
namespace mirage {
// =============================================================================
// 窗口注册/注销
// =============================================================================
auto window_registry::register_window(window_id id, window_type type,
window_ptr instance,
window_id parent) -> bool {
std::unique_lock lock(mutex_);
// 检查ID是否已存在
if (windows_.find(id) != windows_.end()) {
return false;
}
// 如果指定了父窗口,检查父窗口是否存在
if (is_valid_window_id(parent) && windows_.find(parent) == windows_.end()) {
return false;
}
// 创建窗口条目
window_entry entry;
entry.id = id;
entry.type = type;
entry.state = window_state::NORMAL;
entry.parent_id = parent;
entry.children = {};
entry.instance = std::move(instance);
// 插入窗口条目
windows_.emplace(id, std::move(entry));
// 如果有父窗口,添加到父窗口的子窗口集合
if (is_valid_window_id(parent)) {
add_to_parent_impl(id, parent);
}
// 如果是第一个主窗口,自动设置为主窗口
if (type == window_type::MAIN_WINDOW && !is_valid_window_id(main_window_)) {
main_window_ = id;
}
return true;
}
auto window_registry::unregister_window(window_id id) -> bool {
std::unique_lock lock(mutex_);
auto it = windows_.find(id);
if (it == windows_.end()) {
return false;
}
auto& entry = it->second;
// 先递归注销所有子窗口
// 注意:需要复制子窗口集合,因为递归过程中会修改它
auto children_copy = entry.children;
for (auto child_id : children_copy) {
// 递归调用需要先释放锁,这里使用非递归方式处理
// 将子窗口的父窗口设为无效,然后删除
if (auto child_it = windows_.find(child_id); child_it != windows_.end()) {
child_it->second.parent_id = INVALID_WINDOW_ID;
}
}
// 从父窗口的子窗口集合中移除
if (is_valid_window_id(entry.parent_id)) {
remove_from_parent_impl(id, entry.parent_id);
}
// 如果是焦点窗口,清除焦点
if (focused_window_ == id) {
focused_window_ = INVALID_WINDOW_ID;
}
// 如果是主窗口,清除主窗口标记
if (main_window_ == id) {
main_window_ = INVALID_WINDOW_ID;
}
// 移除窗口条目
windows_.erase(it);
return true;
}
auto window_registry::contains(window_id id) const -> bool {
std::shared_lock lock(mutex_);
return windows_.find(id) != windows_.end();
}
// =============================================================================
// 窗口查询
// =============================================================================
auto window_registry::get_window(window_id id) -> mirage::window_interface* {
std::shared_lock lock(mutex_);
auto it = windows_.find(id);
if (it != windows_.end()) {
return it->second.instance.get();
}
return nullptr;
}
auto window_registry::get_window(window_id id) const -> const mirage::window_interface* {
std::shared_lock lock(mutex_);
auto it = windows_.find(id);
if (it != windows_.end()) {
return it->second.instance.get();
}
return nullptr;
}
auto window_registry::get_entry(window_id id) const -> std::optional<window_entry> {
std::shared_lock lock(mutex_);
auto it = windows_.find(id);
if (it != windows_.end()) {
// 创建条目副本不包含instance因为unique_ptr不可复制
window_entry copy;
copy.id = it->second.id;
copy.type = it->second.type;
copy.state = it->second.state;
copy.parent_id = it->second.parent_id;
copy.children = it->second.children;
copy.instance = nullptr; // 不复制实例
return copy;
}
return std::nullopt;
}
auto window_registry::get_type(window_id id) const -> std::optional<window_type> {
std::shared_lock lock(mutex_);
auto it = windows_.find(id);
if (it != windows_.end()) {
return it->second.type;
}
return std::nullopt;
}
// =============================================================================
// 窗口关系管理
// =============================================================================
auto window_registry::get_parent(window_id id) const -> window_id {
std::shared_lock lock(mutex_);
auto it = windows_.find(id);
if (it != windows_.end()) {
return it->second.parent_id;
}
return INVALID_WINDOW_ID;
}
auto window_registry::get_children(window_id id) const -> std::vector<window_id> {
std::shared_lock lock(mutex_);
auto it = windows_.find(id);
if (it != windows_.end()) {
const auto& children = it->second.children;
return std::vector<window_id>(children.begin(), children.end());
}
return {};
}
auto window_registry::get_all_descendants(window_id id) const -> std::vector<window_id> {
std::shared_lock lock(mutex_);
std::vector<window_id> result;
collect_descendants_impl(id, result);
return result;
}
auto window_registry::set_parent(window_id id, window_id new_parent) -> bool {
std::unique_lock lock(mutex_);
auto it = windows_.find(id);
if (it == windows_.end()) {
return false;
}
// 如果新父窗口有效,检查其是否存在
if (is_valid_window_id(new_parent) && windows_.find(new_parent) == windows_.end()) {
return false;
}
// 防止循环引用检查new_parent是否是id的后代
if (is_valid_window_id(new_parent)) {
std::vector<window_id> descendants;
collect_descendants_impl(id, descendants);
auto found = std::find(descendants.begin(), descendants.end(), new_parent);
if (found != descendants.end()) {
return false; // 会形成循环
}
}
auto old_parent = it->second.parent_id;
// 从旧父窗口移除
if (is_valid_window_id(old_parent)) {
remove_from_parent_impl(id, old_parent);
}
// 添加到新父窗口
if (is_valid_window_id(new_parent)) {
add_to_parent_impl(id, new_parent);
}
it->second.parent_id = new_parent;
return true;
}
auto window_registry::is_ancestor_of(window_id ancestor, window_id descendant) const -> bool {
std::shared_lock lock(mutex_);
if (!is_valid_window_id(ancestor) || !is_valid_window_id(descendant)) {
return false;
}
// 从descendant向上遍历父窗口链
auto current = descendant;
while (is_valid_window_id(current)) {
auto it = windows_.find(current);
if (it == windows_.end()) {
return false;
}
auto parent = it->second.parent_id;
if (parent == ancestor) {
return true;
}
current = parent;
}
return false;
}
// =============================================================================
// 窗口状态管理
// =============================================================================
auto window_registry::set_state(window_id id, window_state state) -> bool {
std::unique_lock lock(mutex_);
auto it = windows_.find(id);
if (it != windows_.end()) {
it->second.state = state;
return true;
}
return false;
}
auto window_registry::get_state(window_id id) const -> window_state {
std::shared_lock lock(mutex_);
auto it = windows_.find(id);
if (it != windows_.end()) {
return it->second.state;
}
return window_state::HIDDEN;
}
// =============================================================================
// 批量查询
// =============================================================================
auto window_registry::get_windows_by_type(window_type type) const -> std::vector<window_id> {
std::shared_lock lock(mutex_);
std::vector<window_id> result;
result.reserve(windows_.size());
for (const auto& [id, entry] : windows_) {
if (entry.type == type) {
result.push_back(id);
}
}
return result;
}
auto window_registry::get_all_windows() const -> std::vector<window_id> {
std::shared_lock lock(mutex_);
std::vector<window_id> result;
result.reserve(windows_.size());
for (const auto& [id, entry] : windows_) {
result.push_back(id);
}
return result;
}
auto window_registry::get_windows_by_state(window_state state) const -> std::vector<window_id> {
std::shared_lock lock(mutex_);
std::vector<window_id> result;
result.reserve(windows_.size());
for (const auto& [id, entry] : windows_) {
if (entry.state == state) {
result.push_back(id);
}
}
return result;
}
// =============================================================================
// 统计信息
// =============================================================================
auto window_registry::count() const -> size_t {
std::shared_lock lock(mutex_);
return windows_.size();
}
auto window_registry::count_by_type(window_type type) const -> size_t {
std::shared_lock lock(mutex_);
size_t count = 0;
for (const auto& [id, entry] : windows_) {
if (entry.type == type) {
++count;
}
}
return count;
}
auto window_registry::count_by_state(window_state state) const -> size_t {
std::shared_lock lock(mutex_);
size_t count = 0;
for (const auto& [id, entry] : windows_) {
if (entry.state == state) {
++count;
}
}
return count;
}
auto window_registry::empty() const -> bool {
std::shared_lock lock(mutex_);
return windows_.empty();
}
// =============================================================================
// 焦点和主窗口管理
// =============================================================================
auto window_registry::get_focused_window() const -> window_id {
std::shared_lock lock(mutex_);
return focused_window_;
}
auto window_registry::set_focused_window(window_id id) -> bool {
std::unique_lock lock(mutex_);
// 允许设置为无效ID清除焦点
if (!is_valid_window_id(id)) {
focused_window_ = INVALID_WINDOW_ID;
return true;
}
// 检查窗口是否存在
if (windows_.find(id) == windows_.end()) {
return false;
}
focused_window_ = id;
return true;
}
auto window_registry::get_main_window() const -> window_id {
std::shared_lock lock(mutex_);
return main_window_;
}
auto window_registry::set_main_window(window_id id) -> bool {
std::unique_lock lock(mutex_);
// 允许设置为无效ID清除主窗口
if (!is_valid_window_id(id)) {
main_window_ = INVALID_WINDOW_ID;
return true;
}
// 检查窗口是否存在
auto it = windows_.find(id);
if (it == windows_.end()) {
return false;
}
// 只有主窗口类型才能设置为主窗口
if (it->second.type != window_type::MAIN_WINDOW) {
return false;
}
main_window_ = id;
return true;
}
// =============================================================================
// 内部辅助方法
// =============================================================================
auto window_registry::remove_from_parent_impl(window_id child_id, window_id parent_id) -> void {
auto parent_it = windows_.find(parent_id);
if (parent_it != windows_.end()) {
parent_it->second.children.erase(child_id);
}
}
auto window_registry::add_to_parent_impl(window_id child_id, window_id parent_id) -> void {
auto parent_it = windows_.find(parent_id);
if (parent_it != windows_.end()) {
parent_it->second.children.insert(child_id);
}
}
auto window_registry::collect_descendants_impl(window_id id, std::vector<window_id>& result) const -> void {
auto it = windows_.find(id);
if (it == windows_.end()) {
return;
}
for (auto child_id : it->second.children) {
result.push_back(child_id);
collect_descendants_impl(child_id, result);
}
}
} // namespace mirage

View File

@@ -0,0 +1,236 @@
#pragma once
#include "window_id.h"
#include "window_type.h"
#include "window_common.h"
#include <optional>
#include <shared_mutex>
#include <unordered_map>
#include <unordered_set>
#include <vector>
namespace mirage {
/// 窗口元数据条目
/// 存储单个窗口的所有相关信息
struct window_entry {
/// 窗口唯一标识符
window_id id{INVALID_WINDOW_ID};
/// 窗口类型
window_type type{window_type::MAIN_WINDOW};
/// 窗口当前状态
window_state state{window_state::NORMAL};
/// 父窗口ID主窗口为 INVALID_WINDOW_ID
window_id parent_id{INVALID_WINDOW_ID};
/// 子窗口ID集合
std::unordered_set<window_id> children;
/// 实际窗口实例(通过 mirage::window_ptr
mirage::window_ptr instance;
};
/// 窗口注册表
/// 负责窗口实例存储与查询、窗口父子关系管理、窗口状态追踪
/// 线程安全,使用 std::shared_mutex 实现读写锁
class window_registry {
public:
window_registry() = default;
~window_registry() = default;
// 禁止拷贝
window_registry(const window_registry&) = delete;
auto operator=(const window_registry&) -> window_registry& = delete;
// 禁止移动(因为有互斥锁成员)
window_registry(window_registry&&) = delete;
auto operator=(window_registry&&) -> window_registry& = delete;
// =========================================================================
// 窗口注册/注销
// =========================================================================
/// 注册窗口
/// @param id 窗口ID
/// @param type 窗口类型
/// @param instance 窗口实例(所有权转移)
/// @param parent 父窗口ID默认为 INVALID_WINDOW_ID
/// @return 成功返回true失败返回false如ID已存在
[[nodiscard]] auto register_window(window_id id, window_type type,
mirage::window_ptr instance,
window_id parent = INVALID_WINDOW_ID) -> bool;
/// 注销窗口
/// @param id 窗口ID
/// @return 成功返回true失败返回false如ID不存在
[[nodiscard]] auto unregister_window(window_id id) -> bool;
/// 检查窗口是否已注册
/// @param id 窗口ID
/// @return 如果已注册返回true否则返回false
[[nodiscard]] auto contains(window_id id) const -> bool;
// =========================================================================
// 窗口查询
// =========================================================================
/// 获取窗口实例
/// @param id 窗口ID
/// @return 窗口实例指针如不存在返回nullptr
[[nodiscard]] auto get_window(window_id id) -> mirage::window_interface*;
/// 获取窗口实例const版本
/// @param id 窗口ID
/// @return 窗口实例指针如不存在返回nullptr
[[nodiscard]] auto get_window(window_id id) const -> const mirage::window_interface*;
/// 获取窗口条目的完整信息
/// @param id 窗口ID
/// @return 窗口条目副本如不存在返回nullopt
[[nodiscard]] auto get_entry(window_id id) const -> std::optional<window_entry>;
/// 获取窗口类型
/// @param id 窗口ID
/// @return 窗口类型如不存在返回nullopt
[[nodiscard]] auto get_type(window_id id) const -> std::optional<window_type>;
// =========================================================================
// 窗口关系管理
// =========================================================================
/// 获取父窗口ID
/// @param id 窗口ID
/// @return 父窗口ID如无父窗口或窗口不存在返回 INVALID_WINDOW_ID
[[nodiscard]] auto get_parent(window_id id) const -> window_id;
/// 获取直接子窗口列表
/// @param id 窗口ID
/// @return 子窗口ID列表如窗口不存在返回空列表
[[nodiscard]] auto get_children(window_id id) const -> std::vector<window_id>;
/// 获取所有后代窗口(递归获取所有子窗口)
/// @param id 窗口ID
/// @return 所有后代窗口ID列表如窗口不存在返回空列表
[[nodiscard]] auto get_all_descendants(window_id id) const -> std::vector<window_id>;
/// 设置窗口的父窗口
/// @param id 窗口ID
/// @param new_parent 新的父窗口ID
/// @return 成功返回true失败返回false
[[nodiscard]] auto set_parent(window_id id, window_id new_parent) -> bool;
/// 检查是否为祖先窗口
/// @param ancestor 可能的祖先窗口ID
/// @param descendant 可能的后代窗口ID
/// @return 如果ancestor是descendant的祖先返回true
[[nodiscard]] auto is_ancestor_of(window_id ancestor, window_id descendant) const -> bool;
// =========================================================================
// 窗口状态管理
// =========================================================================
/// 设置窗口状态
/// @param id 窗口ID
/// @param state 新状态
/// @return 成功返回true失败返回false如窗口不存在
[[nodiscard]] auto set_state(window_id id, window_state state) -> bool;
/// 获取窗口状态
/// @param id 窗口ID
/// @return 窗口状态,如窗口不存在返回 HIDDEN
[[nodiscard]] auto get_state(window_id id) const -> window_state;
// =========================================================================
// 批量查询
// =========================================================================
/// 按类型获取所有窗口ID
/// @param type 窗口类型
/// @return 该类型的所有窗口ID列表
[[nodiscard]] auto get_windows_by_type(window_type type) const -> std::vector<window_id>;
/// 获取所有已注册的窗口ID
/// @return 所有窗口ID列表
[[nodiscard]] auto get_all_windows() const -> std::vector<window_id>;
/// 按状态获取所有窗口ID
/// @param state 窗口状态
/// @return 该状态的所有窗口ID列表
[[nodiscard]] auto get_windows_by_state(window_state state) const -> std::vector<window_id>;
// =========================================================================
// 统计信息
// =========================================================================
/// 获取已注册窗口总数
/// @return 窗口数量
[[nodiscard]] auto count() const -> size_t;
/// 获取指定类型的窗口数量
/// @param type 窗口类型
/// @return 该类型的窗口数量
[[nodiscard]] auto count_by_type(window_type type) const -> size_t;
/// 获取指定状态的窗口数量
/// @param state 窗口状态
/// @return 该状态的窗口数量
[[nodiscard]] auto count_by_state(window_state state) const -> size_t;
/// 检查注册表是否为空
/// @return 如果没有注册任何窗口返回true
[[nodiscard]] auto empty() const -> bool;
// =========================================================================
// 焦点和主窗口管理
// =========================================================================
/// 获取当前焦点窗口ID
/// @return 焦点窗口ID如无焦点窗口返回 INVALID_WINDOW_ID
[[nodiscard]] auto get_focused_window() const -> window_id;
/// 设置焦点窗口
/// @param id 窗口ID
/// @return 成功返回true失败返回false如窗口不存在
[[nodiscard]] auto set_focused_window(window_id id) -> bool;
/// 获取主窗口ID
/// @return 主窗口ID如无主窗口返回 INVALID_WINDOW_ID
[[nodiscard]] auto get_main_window() const -> window_id;
/// 设置主窗口
/// @param id 窗口ID
/// @return 成功返回true失败返回false如窗口不存在
[[nodiscard]] auto set_main_window(window_id id) -> bool;
private:
/// 读写互斥锁
mutable std::shared_mutex mutex_;
/// 窗口存储映射表 (id -> entry)
std::unordered_map<window_id, window_entry> windows_;
/// 当前焦点窗口ID
window_id focused_window_{INVALID_WINDOW_ID};
/// 主窗口ID
window_id main_window_{INVALID_WINDOW_ID};
// =========================================================================
// 内部辅助方法
// =========================================================================
/// 从父窗口的子窗口集合中移除指定窗口(不加锁)
auto remove_from_parent_impl(window_id child_id, window_id parent_id) -> void;
/// 添加到父窗口的子窗口集合(不加锁)
auto add_to_parent_impl(window_id child_id, window_id parent_id) -> void;
/// 递归收集所有后代窗口(不加锁)
auto collect_descendants_impl(window_id id, std::vector<window_id>& result) const -> void;
};
} // namespace mirage

66
src/window/window_type.h Normal file
View File

@@ -0,0 +1,66 @@
#pragma once
#include <cstdint>
#include <string_view>
namespace mirage {
/// 窗口类型枚举
enum class window_type : uint8_t {
MAIN_WINDOW, ///< 主窗口
CHILD_WINDOW, ///< 子窗口
POPUP, ///< 弹出窗口
DIALOG, ///< 对话框
TOOLTIP ///< 提示窗口
};
/// 窗口状态枚举
enum class window_state : uint8_t {
NORMAL, ///< 正常状态
MINIMIZED, ///< 最小化
MAXIMIZED, ///< 最大化
FULLSCREEN, ///< 全屏
HIDDEN ///< 隐藏
};
/// 将窗口类型转换为字符串表示
/// @param type 窗口类型
/// @return 窗口类型的字符串表示
[[nodiscard]] constexpr auto to_string(window_type type) noexcept -> std::string_view {
switch (type) {
case window_type::MAIN_WINDOW:
return "MAIN_WINDOW";
case window_type::CHILD_WINDOW:
return "CHILD_WINDOW";
case window_type::POPUP:
return "POPUP";
case window_type::DIALOG:
return "DIALOG";
case window_type::TOOLTIP:
return "TOOLTIP";
default:
return "UNKNOWN";
}
}
/// 将窗口状态转换为字符串表示
/// @param state 窗口状态
/// @return 窗口状态的字符串表示
[[nodiscard]] constexpr auto to_string(window_state state) noexcept -> std::string_view {
switch (state) {
case window_state::NORMAL:
return "NORMAL";
case window_state::MINIMIZED:
return "MINIMIZED";
case window_state::MAXIMIZED:
return "MAXIMIZED";
case window_state::FULLSCREEN:
return "FULLSCREEN";
case window_state::HIDDEN:
return "HIDDEN";
default:
return "UNKNOWN";
}
}
} // namespace mirage