From 057967a5c9785679e780c95b756830bb1ca6e96d Mon Sep 17 00:00:00 2001 From: Nanako <469449812@qq.com> Date: Mon, 21 Apr 2025 23:29:13 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B6=88=E9=99=A4=E8=AD=A6=E5=91=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 2 +- cmake/compile_shaders.cmake | 72 +- cmake/detect_os.cmake | 172 ++-- cmake/project_cpp_standard.cmake | 77 +- cmake/retrieve_files.cmake | 1 - src/mirage_app/mirage.h | 2 - src/mirage_core/src/misc/angle_literals.h | 6 +- src/mirage_core/src/misc/delegates.h | 767 +++++++----------- .../src/misc/mapped_file/unix/mapped_file.cpp | 2 +- .../misc/mapped_file/windows/mapped_file.cpp | 2 +- src/mirage_core/src/misc/mirage_type.h | 14 +- src/mirage_render/src/font/atlas/font_atlas.h | 10 +- .../windows/windows_window.cpp | 110 +-- .../render/windows/windows_render_context.cpp | 363 ++++----- .../src/widget/compound_widget/mbutton.cpp | 4 +- .../src/widget/compound_widget/mbutton.h | 18 +- src/mirage_widget/src/widget/mwidget.h | 2 +- src/mirage_widget/src/widget/slot_util.h | 4 +- 18 files changed, 776 insertions(+), 852 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f457afd..b1d8f3b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,7 +23,7 @@ add_definitions(-DMIRAGE_HDR_FORMAT=${MIRAGE_HDR_FORMAT} -DMIRAGE_PIXEL_FORMAT=$ # CMAKE_CURRENT_SOURCE_DIR 在根 CMakeLists.txt 中即为项目源代码的根目录 # 使用 PARENT_SCOPE 使该变量在调用此函数的 CMakeLists.txt 文件中也可用 set(MIRAGE_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}) -message(STATUS "mirage 项目根源目录 (MIRAGE_ROOT_DIR) 设置为: ${MIRAGE_ROOT_DIR}") +message(STATUS "mirage 项目根源目录 (MIRAGE_ROOT_DIR) 设置为: ${MIRAGE_ROOT_DIR}") include(cmake/retrieve_files.cmake) include(cmake/detect_os.cmake) diff --git a/cmake/compile_shaders.cmake b/cmake/compile_shaders.cmake index 59376df..dbc936e 100644 --- a/cmake/compile_shaders.cmake +++ b/cmake/compile_shaders.cmake @@ -12,22 +12,76 @@ file(REMOVE ${SHADER_PATH_FILE}) file(WRITE ${SHADER_PATH_FILE} "") # 添加着色器目录的函数 +# 参数: +# path: 要添加的包含 .slang 着色器文件的目录路径 +# 功能: +# 1. 将路径转换为适合目标系统的格式 (特别是处理 Cygwin)。 +# 2. 将路径追加到 SHADER_PATH_FILE 指定的文件中。 +# 3. 查找指定路径下的所有 .slang 文件。 +# 4. 将找到的 .slang 文件添加为 CMake 配置的依赖项, +# 以便在这些文件更改时触发重新配置。 +# 注意: +# - 需要在使用此函数前定义 CMAKE_BINARY_DIR 和 SHADER_PATH_FILE 变量。 +# 例如: set(SHADER_PATH_FILE ${CMAKE_BINARY_DIR}/shader_paths.txt) +# - 假定 SHADER_PATH_FILE 的使用者期望接收适合其环境的路径格式 +# (此处在 Cygwin 下转换为 Windows 格式)。 function(add_mirage_shader_directory path) - # 将路径写入shader_paths.txt - file(APPEND ${SHADER_PATH_FILE} "${path}\n") + # 检查 SHADER_PATH_FILE 变量是否已定义 + if(NOT DEFINED SHADER_PATH_FILE) + message(FATAL_ERROR "**错误**: SHADER_PATH_FILE 变量未定义。请在使用 add_mirage_shader_directory 前设置此变量。") + endif() - # 观察目录文件是否修改, 触发compile_shaders目标重新编译 - file(GLOB_RECURSE SHADER_FILES "${path}/*.slang") + # 获取绝对路径以确保一致性 + get_filename_component(abs_path ${path} ABSOLUTE) - # 设置依赖关系,当shader文件变化时重新编译 + # 保存用于文件操作和写入文件的路径变量 + set(path_to_write ${abs_path}) + + # 如果是cygwin环境, 需要转换路径为Windows格式 + if (CYGWIN) + message(STATUS "检测到 Cygwin 环境,尝试使用 cygpath 转换路径: ${abs_path}") + # **关键点**: 使用 cygpath -w 将 Cygwin 路径转换为 Windows 路径 + execute_process( + COMMAND cygpath -w ${abs_path} + OUTPUT_VARIABLE path_windows + OUTPUT_STRIP_TRAILING_WHITESPACE # 去除可能的尾随空格 + RESULT_VARIABLE cygpath_result + ERROR_QUIET # 如果 cygpath 不存在或失败,则不显示错误,但检查 result + ) + + if(cygpath_result EQUAL 0 AND path_windows) # 检查 cygpath 是否成功执行并有输出 + # 更新用于写入文件的路径 + set(path_to_write ${path_windows}) + message(STATUS "路径已成功转换为 Windows 格式: ${path_to_write}") + else() + # 如果 cygpath 失败或未找到,发出警告,并回退到原始路径 + message(WARNING "无法使用 cygpath 转换路径 ${abs_path}。将使用原始路径。请确保 cygpath 在系统 PATH 中。") + # path_to_write 保持为 abs_path + endif() + endif() + + # 将(可能已转换的)路径写入shader_paths.txt + # **关键点**: 追加路径到 ${SHADER_PATH_FILE} + file(APPEND ${SHADER_PATH_FILE} "${path_to_write}\n") + + # 查找目录下的所有 .slang 文件,包括子目录 + # **关键点**: 递归查找 ${abs_path} 目录下的 *.slang 文件 + file(GLOB_RECURSE SHADER_FILES LIST_DIRECTORIES false "${abs_path}/*.slang") + + # 设置依赖关系,当shader文件变化时重新运行CMake配置 + # **关键点**: 将着色器文件添加为 CMake 配置依赖项 foreach(SHADER_FILE ${SHADER_FILES}) - set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${SHADER_FILE}) + get_filename_component(ABS_SHADER_FILE ${SHADER_FILE} ABSOLUTE) + set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${ABS_SHADER_FILE}) endforeach() + + # **关键点**: 输出状态消息,告知用户已添加目录 + message(STATUS "添加着色器源文件目录: ${path_to_write}") endfunction() set(SHADER_COMPILE_ARGS "") set(SHADER_SHDC "") -if (WIN32) +if (WIN32 OR CYGWIN) list(APPEND SHADER_COMPILE_ARGS "--hlsl") set(SHADER_SHDC ${MIRAGE_ROOT_DIR}/tools/win_mirage_shdc.exe) elseif (APPLE) @@ -38,6 +92,8 @@ else() set(SHADER_SHDC ${MIRAGE_ROOT_DIR}/tools/linux_mirage_shdc) endif() +message(STATUS "使用着色器编译器: ${SHADER_SHDC}") + # 如果是Debug模式, 添加--debug选项 if (CMAKE_BUILD_TYPE STREQUAL "Debug") list(APPEND SHADER_COMPILE_ARGS "--debug") @@ -53,7 +109,7 @@ add_custom_target(compile_shaders ALL VERBATIM ) -# 定义一个宏,将编译着色器作为其他目标的依赖 +# 定义一个函数,将编译着色器作为其他目标的依赖 function(add_shader_dependencies target) add_dependencies(${target} compile_shaders) endfunction() diff --git a/cmake/detect_os.cmake b/cmake/detect_os.cmake index b1ac348..7ff84be 100644 --- a/cmake/detect_os.cmake +++ b/cmake/detect_os.cmake @@ -1,73 +1,131 @@ -# DetectOS.cmake +# 定义一个函数,为指定的目标添加操作系统和架构相关的预处理器定义 function(add_os_definitions target) - # 初始化所有平台宏为 0 - set(PLATFORMS MIRAGE_PLATFORM_WINDOWS MIRAGE_PLATFORM_MACOS MIRAGE_PLATFORM_LINUX MIRAGE_PLATFORM_FREEBSD MIRAGE_PLATFORM_IOS MIRAGE_PLATFORM_ANDROID) + # 检查 target 参数是否提供 + if(NOT target) + message(FATAL_ERROR "函数 add_os_definitions 需要一个 target 参数。") + return() + endif() - # 检测操作系统并设置相应的宏为 1 - if(WIN32) - target_compile_definitions(${target} PUBLIC MIRAGE_PLATFORM_WINDOWS=1) - message(STATUS "检测到 Windows 操作系统") - list(REMOVE_ITEM PLATFORMS MIRAGE_PLATFORM_WINDOWS) - elseif(APPLE AND NOT IOS) - target_compile_definitions(${target} PUBLIC MIRAGE_PLATFORM_MACOS=1) - message(STATUS "检测到 macOS 操作系统") - list(REMOVE_ITEM PLATFORMS MIRAGE_PLATFORM_MACOS) - elseif(UNIX) - if(${CMAKE_SYSTEM_NAME} MATCHES "Linux") - target_compile_definitions(${target} PUBLIC MIRAGE_PLATFORM_LINUX=1) - message(STATUS "检测到 Linux 操作系统") - list(REMOVE_ITEM PLATFORMS MIRAGE_PLATFORM_LINUX) - elseif(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD") - target_compile_definitions(${target} PUBLIC MIRAGE_PLATFORM_FREEBSD=1) - message(STATUS "检测到 FreeBSD 操作系统") - list(REMOVE_ITEM PLATFORMS MIRAGE_PLATFORM_FREEBSD) - else() - message(WARNING "检测到未知的 类Unix 操作系统") - endif() + # --- 阶段 1: 确定宏的值 --- + + # 初始化所有平台、架构和特性宏的值为 0 + set(mirage_def_windows 0) + set(mirage_def_macos 0) + set(mirage_def_linux 0) + set(mirage_def_freebsd 0) + set(mirage_def_ios 0) + set(mirage_def_android 0) + set(mirage_def_cygwin 0) + set(mirage_def_unix 0) + set(mirage_def_posix 0) + set(mirage_def_mobile 0) + set(mirage_def_arch_64bit 0) + set(mirage_def_arch_32bit 0) + + # -- 操作系统检测与赋值 -- + # 注意检测顺序:优先检测更具体的平台 + if(CYGWIN) + # Cygwin 环境比较特殊,它在 Windows 上模拟 Unix + set(mirage_def_windows 1) # 基础是 Windows + set(mirage_def_cygwin 1) # 明确是 Cygwin + set(mirage_def_unix 1) # 提供 Unix API + set(mirage_def_posix 1) # 提供 POSIX API + message(STATUS "检测到 **Cygwin** 环境 (运行于 Windows)") + elseif(WIN32) + # 非 Cygwin 的 Windows 环境 (MSVC, MinGW, etc.) + set(mirage_def_windows 1) + message(STATUS "检测到 **Windows** 操作系统 (非 Cygwin)") elseif(ANDROID) - target_compile_definitions(${target} PUBLIC MIRAGE_PLATFORM_ANDROID=1) - message(STATUS "检测到 Android 操作系统") - list(REMOVE_ITEM PLATFORMS MIRAGE_PLATFORM_ANDROID) + # Android 平台 (通常需要特定工具链设置 ANDROID 变量) + set(mirage_def_android 1) + set(mirage_def_unix 1) # Android NDK 基于 Unix + set(mirage_def_posix 1) # NDK 提供 POSIX API + set(mirage_def_mobile 1) # 移动平台 + message(STATUS "检测到 **Android** 操作系统") elseif(IOS) - target_compile_definitions(${target} PUBLIC MIRAGE_PLATFORM_IOS=1) - message(STATUS "检测到 iOS 操作系统") - list(REMOVE_ITEM PLATFORMS MIRAGE_PLATFORM_IOS) + # iOS 平台 (通常需要特定工具链设置 IOS 变量) + # 需要在 APPLE 之前判断,因为 iOS 下 APPLE 也为 TRUE + set(mirage_def_ios 1) + set(mirage_def_unix 1) # iOS (Darwin) 基于 Unix + set(mirage_def_posix 1) # 提供 POSIX API + set(mirage_def_mobile 1) # 移动平台 + message(STATUS "检测到 **iOS** 操作系统") + elseif(APPLE) + # 此时排除了 iOS,确定是 macOS + set(mirage_def_macos 1) + set(mirage_def_unix 1) # macOS (Darwin) 基于 Unix + set(mirage_def_posix 1) # 提供 POSIX API + message(STATUS "检测到 **macOS** 操作系统") + elseif(UNIX) + # 此时排除了 Apple, Android, Cygwin 的其他 Unix-like 系统 + set(mirage_def_unix 1) + set(mirage_def_posix 1) + if(CMAKE_SYSTEM_NAME MATCHES "Linux") + set(mirage_def_linux 1) + message(STATUS "检测到 **Linux** 操作系统") + elseif(CMAKE_SYSTEM_NAME MATCHES "FreeBSD") + set(mirage_def_freebsd 1) + message(STATUS "检测到 **FreeBSD** 操作系统") + else() + message(WARNING "检测到未知的 类Unix 操作系统: ${CMAKE_SYSTEM_NAME}") + endif() else() - message(WARNING "检测到未知的操作系统") + message(WARNING "检测到未知的操作系统: ${CMAKE_SYSTEM_NAME}") endif() - foreach(PLATFORM ${PLATFORMS}) - target_compile_definitions(${target} PUBLIC ${PLATFORM}=0) - endforeach() - - # 检测并设置架构宏 + # -- 架构检测与赋值 -- if(CMAKE_SIZEOF_VOID_P EQUAL 8) - target_compile_definitions(${target} PUBLIC MIRAGE_PLATFORM_ARCH_64BIT=1 MIRAGE_PLATFORM_ARCH_32BIT=0) - message(STATUS "检测到 64-bit 架构") + set(mirage_def_arch_64bit 1) + set(mirage_def_arch_32bit 0) # 明确设置为 0 + message(STATUS "检测到 **64-bit** 架构") + elseif(CMAKE_SIZEOF_VOID_P EQUAL 4) + set(mirage_def_arch_64bit 0) # 明确设置为 0 + set(mirage_def_arch_32bit 1) + message(STATUS "检测到 **32-bit** 架构") else() - target_compile_definitions(${target} PUBLIC MIRAGE_PLATFORM_ARCH_64BIT=0 MIRAGE_PLATFORM_ARCH_32BIT=1) - message(STATUS "检测到 32-bit 架构") + # 对于未知或未定义的指针大小,两者都保持 0 + message(WARNING "无法明确检测到 32-bit 或 64-bit 架构 (CMAKE_SIZEOF_VOID_P = ${CMAKE_SIZEOF_VOID_P})。将两者都设置为 0。") endif() - # 设置通用的 UNIX 宏 - if(UNIX) - target_compile_definitions(${target} PUBLIC MIRAGE_PLATFORM_UNIX=1) - else() - target_compile_definitions(${target} PUBLIC MIRAGE_PLATFORM_UNIX=0) + # --- 阶段 2: 组装定义列表 --- + set(definitions_list "") # 初始化空列表 + + # 添加平台定义 + list(APPEND definitions_list "MIRAGE_PLATFORM_WINDOWS=${mirage_def_windows}") + list(APPEND definitions_list "MIRAGE_PLATFORM_MACOS=${mirage_def_macos}") + list(APPEND definitions_list "MIRAGE_PLATFORM_LINUX=${mirage_def_linux}") + list(APPEND definitions_list "MIRAGE_PLATFORM_FREEBSD=${mirage_def_freebsd}") + list(APPEND definitions_list "MIRAGE_PLATFORM_IOS=${mirage_def_ios}") + list(APPEND definitions_list "MIRAGE_PLATFORM_ANDROID=${mirage_def_android}") + list(APPEND definitions_list "MIRAGE_PLATFORM_CYGWIN=${mirage_def_cygwin}") + + # 添加架构定义 + list(APPEND definitions_list "MIRAGE_PLATFORM_ARCH_64BIT=${mirage_def_arch_64bit}") + list(APPEND definitions_list "MIRAGE_PLATFORM_ARCH_32BIT=${mirage_def_arch_32bit}") + + # 添加特性定义 + list(APPEND definitions_list "MIRAGE_PLATFORM_UNIX=${mirage_def_unix}") + list(APPEND definitions_list "MIRAGE_PLATFORM_POSIX=${mirage_def_posix}") + list(APPEND definitions_list "MIRAGE_PLATFORM_IS_MOBILE=${mirage_def_mobile}") + + # --- 阶段 3: 应用所有定义 --- + # **关键:使用一次调用将所有定义添加到目标** + if(definitions_list) # 确保列表非空 + target_compile_definitions(${target} PUBLIC ${definitions_list}) endif() - # 设置通用的 POSIX 宏 - if(UNIX OR APPLE) - target_compile_definitions(${target} PUBLIC MIRAGE_PLATFORM_POSIX=1) - else() - target_compile_definitions(${target} PUBLIC MIRAGE_PLATFORM_POSIX=0) - endif() + # 函数作用域结束时,mirage_def_* 变量会自动销毁,无需显式 unset - # 设置IS_MOBILE宏 - if(ANDROID OR IOS) - target_compile_definitions(${target} PUBLIC MIRAGE_PLATFORM_IS_MOBILE=1) - else() - target_compile_definitions(${target} PUBLIC MIRAGE_PLATFORM_IS_MOBILE=0) - endif() endfunction() + +# --- 使用示例 --- +# project(MyProject) +# add_executable(my_app main.c) +# +# # 调用函数为 my_app 添加平台定义 +# add_os_definitions(my_app) +# +# # 你也可以为库调用 +# # add_library(my_lib STATIC my_lib.c) +# # add_os_definitions(my_lib) diff --git a/cmake/project_cpp_standard.cmake b/cmake/project_cpp_standard.cmake index 521273a..8b698fb 100644 --- a/cmake/project_cpp_standard.cmake +++ b/cmake/project_cpp_standard.cmake @@ -1,56 +1,85 @@ - +# 函数:设置 C++ 标准及相关编译选项 +# 参数 standard: 需要设置的 C++ 标准版本 (例如 11, 14, 17, 20, 23) function(set_cpp_standard standard) - # 参数验证 - set(VALID_STANDARDS 11 14 17 20 23) - if(NOT ${standard} IN_LIST VALID_STANDARDS) - message(WARNING "非标准 C++ 版本: ${standard},支持的版本有: ${VALID_STANDARDS}") + # --- 参数验证 --- + set(VALID_STANDARDS 11 14 17 20 23) # 定义支持的 C++ 标准列表 + list(FIND VALID_STANDARDS ${standard} _standard_index) # 查找 standard 是否在列表中 + if(_standard_index EQUAL -1) # 如果未找到 + message(WARNING "**非标准 C++ 版本**: ${standard}。支持的版本有: ${VALID_STANDARDS}") + # 可选:可以设置为一个默认值或停止配置 + # message(FATAL_ERROR "不支持的 C++ 标准: ${standard}") + # set(standard 17) # 或者设置为默认值,例如 C++17 + # message(WARNING "已将 C++ 标准设置为默认值: ${standard}") endif() - # 指定需要的 C++ 标准,设置到父作用域 + # --- 设置 C++ 标准 --- + # 指定需要的 C++ 标准,设置到父作用域,使其对调用者定义的 target 生效 set(CMAKE_CXX_STANDARD ${standard} PARENT_SCOPE) - # 强制要求此标准,如果编译器不支持则配置时报错 + # **强制要求此标准**,如果编译器不支持则配置时报错 set(CMAKE_CXX_STANDARD_REQUIRED ON PARENT_SCOPE) - # 可选:禁用编译器特定的扩展,使用纯粹的标准 + # **禁用编译器特定的扩展**,使用更纯粹的标准 C++ set(CMAKE_CXX_EXTENSIONS OFF PARENT_SCOPE) + # --- 平台特定设置 --- if(WIN32) - # 定义Windows版本宏 + # 为 Windows 定义 UNICODE 宏 add_definitions(-DUNICODE -D_UNICODE) - # 可选:添加 WIN32_LEAN_AND_MEAN 以减少 Windows 头文件包含 + # 可选:添加 WIN32_LEAN_AND_MEAN 以减少 Windows 头文件包含,加快编译速度 # add_definitions(-DWIN32_LEAN_AND_MEAN) + message(STATUS "为 Windows 添加 UNICODE 定义") endif() + # --- 编译器特定设置 --- if(MSVC) - # 设置utf-8编码 + # **设置源代码和执行字符集为 UTF-8** add_compile_options(/utf-8) - # 强制 MSVC 正确设置 __cplusplus 宏 + # **强制 MSVC 正确设置 __cplusplus 宏**,以便代码能准确判断 C++ 标准 add_compile_options(/Zc:__cplusplus) - # 可选:增加 MSVC 警告级别 + # **设置警告级别为 W4** (较高警告级别) add_compile_options(/W4) - # **禁用未使用的形参警告 (C4100)** + # **禁用特定警告:C4100 未使用的形参** (有时用于接口兼容性) add_compile_options(/wd4100) + # 禁用特定警告:C4996 使用了被标记为否决的函数或变量 (例如一些旧的 CRT 函数) + add_compile_options(/wd4996) + message(STATUS "为 MSVC 添加特定编译选项: /utf-8 /Zc:__cplusplus /W4 /wd4100 /wd4996") endif() # GCC/Clang 特定选项 if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") + # **启用常用警告** add_compile_options(-Wall -Wextra) - # 禁用未使用参数的警告 + # **禁用未使用参数的警告** (与 MSVC 的 /wd4100 对应) add_compile_options(-Wno-unused-parameter) - # 根据 C++ 标准添加特定选项 - if(${standard} GREATER 14) # 更兼容的写法,避免使用 GREATER_EQUAL + # **设置输入和执行字符集为 UTF-8** (对应 MSVC 的 /utf-8) + # 这有助于处理源代码中的 UTF-8 字符,并影响运行时字符编码,但控制台本身的显示需要环境配合 + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -finput-charset=UTF-8 -fexec-charset=UTF-8") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -finput-charset=UTF-8 -fexec-charset=UTF-8") + + # 根据 C++ 标准添加特定警告 (C++17 及以上) + if(${standard} GREATER 14) + # **启用阴影变量警告和非虚析构函数警告** add_compile_options(-Wshadow -Wnon-virtual-dtor) + message(STATUS "为 GCC/Clang (C++${CMAKE_CXX_STANDARD}) 添加额外警告: -Wshadow -Wnon-virtual-dtor") endif() + message(STATUS "为 GCC/Clang 添加特定编译选项: -Wall -Wextra -Wno-unused-parameter -finput-charset=UTF-8 -fexec-charset=UTF-8") + # 注意: 控制台/终端的 UTF-8 输出显示通常还需要操作系统环境的配合 (例如 Linux/macOS 终端本身设置,Windows下 chcp 65001) endif() - # 如果是MinGW, 并且使用了C++17或更高版本, 则添加libstdc++exp库 + # MinGW 特定设置 (通常在 Windows 上使用 GCC 工具链) if(MINGW) - message(STATUS "检测到MinGW编译器") - # 更兼容的版本比较 - if(${standard} GREATER 14) # C++17及以上 - message(STATUS "为C++${standard}添加libstdc++exp库支持") - link_libraries(-lstdc++exp) + message(STATUS "检测到 MinGW 编译器") + # 如果使用了 C++17 或更高版本, 可能需要链接 libstdc++exp 以支持 等特性 + if(${standard} GREATER 14) + message(STATUS "**为 MinGW C++${CMAKE_CXX_STANDARD} 添加 libstdc++fs 库依赖** (用于 )") + # 注意:较新版本的 MinGW 可能不再需要显式链接,或者需要链接的是 -lstdc++fs + # link_libraries() 会影响后续所有 target,更推荐使用 target_link_libraries() + # 这里暂时保留 link_libraries(),但建议后续根据具体 target 调整 + # 尝试链接 stdc++fs,这在较新的 MinGW 中更常见用于 + link_libraries(-lstdc++fs) + # 如果链接 -lstdc++fs 失败,可以尝试回退到 -lstdc++exp +# link_libraries(-lstdc++exp) endif() endif() - message(STATUS "已设置C++${standard}标准") + message(STATUS "**C++ 标准已设置为: c++${standard}**") endfunction() diff --git a/cmake/retrieve_files.cmake b/cmake/retrieve_files.cmake index ac0f49a..31c9449 100644 --- a/cmake/retrieve_files.cmake +++ b/cmake/retrieve_files.cmake @@ -314,4 +314,3 @@ function(add_resource_file) endif() endfunction() - diff --git a/src/mirage_app/mirage.h b/src/mirage_app/mirage.h index f59863e..00d44f7 100644 --- a/src/mirage_app/mirage.h +++ b/src/mirage_app/mirage.h @@ -1,6 +1,4 @@ #pragma once -#include - #include "misc/mirage_type.h" #include "render/render_context.h" diff --git a/src/mirage_core/src/misc/angle_literals.h b/src/mirage_core/src/misc/angle_literals.h index f33d2eb..1ec6008 100644 --- a/src/mirage_core/src/misc/angle_literals.h +++ b/src/mirage_core/src/misc/angle_literals.h @@ -14,7 +14,7 @@ * * 示例用法: auto angle = 45.5_deg; */ -consteval auto operator"" _deg(const long double in_degree) { +consteval auto operator""_deg(const long double in_degree) { return in_degree * 3.1415926 / 180.0; } @@ -25,6 +25,6 @@ consteval auto operator"" _deg(const long double in_degree) { * * 示例用法: auto angle = 90_deg; */ -consteval auto operator"" _deg(const unsigned long long in_degree) { - return in_degree * 3.1415926 / 180.0; +consteval auto operator""_deg(const unsigned long long in_degree) { + return static_cast(in_degree) * 3.1415926 / 180.0; } diff --git a/src/mirage_core/src/misc/delegates.h b/src/mirage_core/src/misc/delegates.h index 0c3dc6e..6cb219e 100644 --- a/src/mirage_core/src/misc/delegates.h +++ b/src/mirage_core/src/misc/delegates.h @@ -82,6 +82,8 @@ Raw delegate payload: 10 #ifndef CPP_DELEGATES #define CPP_DELEGATES +#include +#include #include #include #include @@ -91,7 +93,7 @@ Raw delegate payload: 10 /////////////////////////////////////////////////////////////// #ifndef DELEGATE_ASSERT -#include +#include #define DELEGATE_ASSERT(expression, ...) assert(expression) #endif @@ -139,57 +141,51 @@ private: \ #define NO_DISCARD #endif -namespace _DelegatesInteral -{ - template +namespace _DelegatesInteral { + template struct MemberFunction; - template - struct MemberFunction - { + template + struct MemberFunction { using Type = RetVal(Object::*)(Args...) const; }; - template - struct MemberFunction - { + template + struct MemberFunction { using Type = RetVal(Object::*)(Args...); }; static void* (*Alloc)(size_t size) = [](size_t size) { return malloc(size); }; - static void(*Free)(void* pPtr) = [](void* pPtr) { free(pPtr); }; + static void (* Free)(void* pPtr) = [](void* pPtr) { free(pPtr); }; + template - void DelegateDeleteFunc(T* pPtr) - { + void DelegateDeleteFunc(T* pPtr) { pPtr->~T(); DelegateFreeFunc(pPtr); } } -namespace Delegates -{ +namespace Delegates { using AllocateCallback = void* (*)(size_t size); - using FreeCallback = void(*)(void* pPtr); - inline void SetAllocationCallbacks(AllocateCallback allocateCallback, FreeCallback freeCallback) - { + using FreeCallback = void(*)(void* pPtr); + + inline void SetAllocationCallbacks(AllocateCallback allocateCallback, FreeCallback freeCallback) { _DelegatesInteral::Alloc = allocateCallback; - _DelegatesInteral::Free = freeCallback; + _DelegatesInteral::Free = freeCallback; } } -class i_delegate_base -{ +class i_delegate_base { public: - i_delegate_base() = default; - virtual ~i_delegate_base() noexcept = default; - virtual const void* get_owner() const { return nullptr; } - virtual void clone(void* pDestination) = 0; + i_delegate_base() = default; + virtual ~i_delegate_base() noexcept = default; + [[nodiscard]] virtual const void* get_owner() const { return nullptr; } + virtual void clone(void* pDestination) = 0; }; //Base type for delegates template -class i_delegate : public i_delegate_base -{ +class i_delegate : public i_delegate_base { public: virtual RetVal execute(Args&&... args) = 0; }; @@ -198,37 +194,31 @@ template class static_delegate; template -class static_delegate : public i_delegate -{ +class static_delegate : public i_delegate { public: - using DelegateFunction = RetVal(*)(Args..., Args2...); + using delegate_function = RetVal(*)(Args..., Args2...); - static_delegate(DelegateFunction function, Args2&&... payload) - : function_(function), payload_(std::forward(payload)...) - {} + explicit static_delegate(delegate_function function, Args2&&... payload) : + function_(function), + payload_(std::forward(payload)...) {} - static_delegate(DelegateFunction function, const std::tuple& payload) - : function_(function), payload_(payload) - {} + static_delegate(delegate_function function, const std::tuple& payload) : + function_(function), + payload_(payload) {} - virtual RetVal execute(Args&&... args) override - { + RetVal execute(Args&&... args) override { return execute_internal(std::forward(args)..., std::index_sequence_for()); } - virtual void clone(void* pDestination) override - { - new (pDestination) static_delegate(function_, payload_); - } + void clone(void* pDestination) override { new(pDestination) static_delegate(function_, payload_); } private: template - RetVal execute_internal(Args&&... args, std::index_sequence) - { + RetVal execute_internal(Args&&... args, std::index_sequence) { return function_(std::forward(args)..., std::get(payload_)...); } - DelegateFunction function_; + delegate_function function_; std::tuple payload_; }; @@ -236,42 +226,36 @@ template class raw_delegate; template -class raw_delegate : public i_delegate -{ +class raw_delegate : public i_delegate { public: using DelegateFunction = typename _DelegatesInteral::MemberFunction::Type; - raw_delegate(T* pObject, DelegateFunction function, Args2&&... payload) - : object_(pObject), function_(function), payload_(std::forward(payload)...) - {} + raw_delegate(T* pObject, DelegateFunction function, Args2&&... payload) : + object_(pObject), + function_(function), + payload_(std::forward(payload)...) {} - raw_delegate(T* pObject, DelegateFunction function, const std::tuple& payload) - : object_(pObject), function_(function), payload_(payload) - {} + raw_delegate(T* pObject, DelegateFunction function, const std::tuple& payload) : + object_(pObject), + function_(function), + payload_(payload) {} - virtual RetVal execute(Args&&... args) override - { + RetVal execute(Args&&... args) override { return execute_internal(std::forward(args)..., std::index_sequence_for()); } - virtual const void* get_owner() const override - { - return object_; - } - virtual void clone(void* pDestination) override - { - new (pDestination) raw_delegate(object_, function_, payload_); - } + const void* get_owner() const override { return object_; } + + void clone(void* pDestination) override { new(pDestination) raw_delegate(object_, function_, payload_); } private: template - RetVal execute_internal(Args&&... args, std::index_sequence) - { + RetVal execute_internal(Args&&... args, std::index_sequence) { return (object_->*function_)(std::forward(args)..., std::get(payload_)...); } - T* object_; - DelegateFunction function_; + T* object_; + DelegateFunction function_; std::tuple payload_; }; @@ -279,37 +263,29 @@ template class lambda_delegate; template -class lambda_delegate : public i_delegate -{ +class lambda_delegate : public i_delegate { public: - explicit lambda_delegate(TLambda&& lambda, Args2&&... payload) - : lambda_(std::forward(lambda)), - payload_(std::forward(payload)...) - {} + explicit lambda_delegate(TLambda&& lambda, Args2&&... payload) : + lambda_(std::forward(lambda)), + payload_(std::forward(payload)...) {} - explicit lambda_delegate(const TLambda& lambda, const std::tuple& payload) - : lambda_(lambda), - payload_(payload) - {} + explicit lambda_delegate(const TLambda& lambda, const std::tuple& payload) : + lambda_(lambda), + payload_(payload) {} - RetVal execute(Args&&... args) override - { + RetVal execute(Args&&... args) override { return execute_internal(std::forward(args)..., std::index_sequence_for()); } - virtual void clone(void* pDestination) override - { - new (pDestination) lambda_delegate(lambda_, payload_); - } + void clone(void* pDestination) override { new(pDestination) lambda_delegate(lambda_, payload_); } private: template - RetVal execute_internal(Args&&... args, std::index_sequence) - { - return (RetVal)((lambda_)(std::forward(args)..., std::get(payload_)...)); + RetVal execute_internal(Args&&... args, std::index_sequence) { + return (RetVal) ((lambda_)(std::forward(args)..., std::get(payload_)...)); } - TLambda lambda_; + TLambda lambda_; std::tuple payload_; }; @@ -317,298 +293,199 @@ template class sp_delegate; template -class sp_delegate : public i_delegate -{ +class sp_delegate : public i_delegate { public: - using DelegateFunction = typename _DelegatesInteral::MemberFunction::Type; + using delegate_function = typename _DelegatesInteral::MemberFunction::Type; - sp_delegate(std::shared_ptr pObject, DelegateFunction pFunction, Args2&&... payload) - : object_(pObject), + sp_delegate(std::shared_ptr pObject, delegate_function pFunction, Args2&&... payload) : + object_(pObject), function_(pFunction), - payload_(std::forward(payload)...) - {} + payload_(std::forward(payload)...) {} - sp_delegate(std::weak_ptr pObject, DelegateFunction pFunction, const std::tuple& payload) - : object_(pObject), + sp_delegate(std::weak_ptr pObject, delegate_function pFunction, const std::tuple& payload) : + object_(pObject), function_(pFunction), - payload_(payload) - {} + payload_(payload) {} - virtual RetVal execute(Args&&... args) override - { + RetVal execute(Args&&... args) override { return execute_internal(std::forward(args)..., std::index_sequence_for()); } - virtual const void* get_owner() const override - { - return object_.expired() ? nullptr : object_.lock().get(); - } + const void* get_owner() const override { return object_.expired() ? nullptr : object_.lock().get(); } - virtual void clone(void* pDestination) override - { - new (pDestination) sp_delegate(object_, function_, payload_); - } + void clone(void* pDestination) override { new(pDestination) sp_delegate(object_, function_, payload_); } private: template - RetVal execute_internal(Args&&... args, std::index_sequence) - { - if (object_.expired()) - { - return RetVal(); - } - else - { + RetVal execute_internal(Args&&... args, std::index_sequence) { + if (object_.expired()) { return RetVal(); } + else { std::shared_ptr pPinned = object_.lock(); return (pPinned.get()->*function_)(std::forward(args)..., std::get(payload_)...); } } - std::weak_ptr object_; - DelegateFunction function_; + std::weak_ptr object_; + delegate_function function_; std::tuple payload_; }; //A handle to a delegate used for a multicast delegate //Static ID so that every handle is unique -class delegate_handle -{ +class delegate_handle { public: - constexpr delegate_handle() noexcept - : id_(INVALID_ID) - { - } + constexpr delegate_handle() noexcept : + id_(INVALID_ID) {} - explicit delegate_handle(bool /*generateId*/) noexcept - : id_(get_new_id()) - { - } + explicit delegate_handle(bool /*generateId*/) noexcept : + id_(get_new_id()) {} - ~delegate_handle() noexcept = default; - delegate_handle(const delegate_handle& other) = default; + ~delegate_handle() noexcept = default; + delegate_handle(const delegate_handle& other) = default; delegate_handle& operator=(const delegate_handle& other) = default; - delegate_handle(delegate_handle&& other) noexcept - : id_(other.id_) - { - other.reset(); - } + delegate_handle(delegate_handle&& other) noexcept : + id_(other.id_) { other.reset(); } - delegate_handle& operator=(delegate_handle&& other) noexcept - { + delegate_handle& operator=(delegate_handle&& other) noexcept { id_ = other.id_; other.reset(); return *this; } - operator bool() const noexcept - { - return is_valid(); - } + operator bool() const noexcept { return is_valid(); } - bool operator==(const delegate_handle& other) const noexcept - { - return id_ == other.id_; - } + bool operator==(const delegate_handle& other) const noexcept { return id_ == other.id_; } - bool operator<(const delegate_handle& other) const noexcept - { - return id_ < other.id_; - } + bool operator<(const delegate_handle& other) const noexcept { return id_ < other.id_; } - bool is_valid() const noexcept - { - return id_ != INVALID_ID; - } + [[nodiscard]] bool is_valid() const noexcept { return id_ != INVALID_ID; } - void reset() noexcept - { - id_ = INVALID_ID; - } + void reset() noexcept { id_ = INVALID_ID; } + + constexpr static const unsigned int INVALID_ID = static_cast(~0); - constexpr static const unsigned int INVALID_ID = (unsigned int)~0; private: - unsigned int id_; + unsigned int id_; inline static unsigned int CURRENT_ID = 0; - static int get_new_id() - { - unsigned int output = ++CURRENT_ID; - if (CURRENT_ID == INVALID_ID) - { - CURRENT_ID = 0; - } + static unsigned int get_new_id() { + const unsigned int output = ++CURRENT_ID; + if (CURRENT_ID == INVALID_ID) { CURRENT_ID = 0; } return output; } }; template -class inline_allocator -{ +class inline_allocator { public: //Constructor - constexpr inline_allocator() noexcept - : size_(0) - { - DELEGATE_STATIC_ASSERT(MaxStackSize > sizeof(void*), "MaxStackSize is smaller or equal to the size of a pointer. This will make the use of an InlineAllocator pointless. Please increase the MaxStackSize."); + constexpr inline_allocator() noexcept : + pPtr(nullptr), + size_(0) { + DELEGATE_STATIC_ASSERT(MaxStackSize > sizeof(void*), + "MaxStackSize is smaller or equal to the size of a pointer. This will make the use of an InlineAllocator pointless. Please increase the MaxStackSize.") } //Destructor - ~inline_allocator() noexcept - { - free(); - } + ~inline_allocator() noexcept { free(); } //Copy constructor - inline_allocator(const inline_allocator& other) - : size_(0) - { - if (other.has_allocation()) - { - memcpy(allocate(other.size_), other.get_allocation(), other.size_); - } + inline_allocator(const inline_allocator& other) : + size_(0) { + if (other.has_allocation()) { memcpy(allocate(other.size_), other.get_allocation(), other.size_); } size_ = other.size_; } //Copy assignment operator - inline_allocator& operator=(const inline_allocator& other) - { - if (other.has_allocation()) - { - memcpy(allocate(other.size_), other.get_allocation(), other.size_); - } + inline_allocator& operator=(const inline_allocator& other) { + if (other.has_allocation()) { memcpy(allocate(other.size_), other.get_allocation(), other.size_); } size_ = other.size_; return *this; } //Move constructor - inline_allocator(inline_allocator&& other) noexcept - : size_(other.size_) - { + inline_allocator(inline_allocator&& other) noexcept : + size_(other.size_) { other.size_ = 0; - if (size_ > MaxStackSize) - { - std::swap(pPtr, other.pPtr); - } - else - { - memcpy(Buffer, other.Buffer, size_); - } + if (size_ > MaxStackSize) { std::swap(pPtr, other.pPtr); } + else { memcpy(Buffer, other.Buffer, size_); } } //Move assignment operator - inline_allocator& operator=(inline_allocator&& other) noexcept - { + inline_allocator& operator=(inline_allocator&& other) noexcept { free(); - size_ = other.size_; + size_ = other.size_; other.size_ = 0; - if (size_ > MaxStackSize) - { - std::swap(pPtr, other.pPtr); - } - else - { - memcpy(Buffer, other.Buffer, size_); - } + if (size_ > MaxStackSize) { std::swap(pPtr, other.pPtr); } + else { memcpy(Buffer, other.Buffer, size_); } return *this; } //Allocate memory of given size //If the size is over the predefined threshold, it will be allocated on the heap - void* allocate(const size_t size) - { - if (size_ != size) - { + void* allocate(const size_t size) { + if (size_ != size) { free(); size_ = size; - if (size > MaxStackSize) - { + if (size > MaxStackSize) { pPtr = _DelegatesInteral::Alloc(size); return pPtr; } } - return (void*)Buffer; + return (void*) Buffer; } //Free the allocated memory - void free() - { - if (size_ > MaxStackSize) - { - _DelegatesInteral::Free(pPtr); - } + void free() { + if (size_ > MaxStackSize) { _DelegatesInteral::Free(pPtr); } size_ = 0; } //Return the allocated memory either on the stack or on the heap - void* get_allocation() const - { - if (has_allocation()) - { - return has_heap_allocation() ? pPtr : (void*)Buffer; - } - else - { - return nullptr; - } + [[nodiscard]] void* get_allocation() const { + if (has_allocation()) { return has_heap_allocation() ? pPtr : (void*) Buffer; } + else { return nullptr; } } - size_t get_size() const - { - return size_; - } + [[nodiscard]] size_t get_size() const { return size_; } - bool has_allocation() const - { - return size_ > 0; - } + [[nodiscard]] bool has_allocation() const { return size_ > 0; } - bool has_heap_allocation() const - { - return size_ > MaxStackSize; - } + [[nodiscard]] bool has_heap_allocation() const { return size_ > MaxStackSize; } private: //If the allocation is smaller than the threshold, Buffer is used //Otherwise pPtr is used together with a separate dynamic allocation - union - { - char Buffer[MaxStackSize]; + union { + char Buffer[MaxStackSize]; void* pPtr; }; + size_t size_; }; -class delegate_base -{ +class delegate_base { public: //Default constructor - constexpr delegate_base() noexcept - : allocator_() - {} + constexpr delegate_base() noexcept : + allocator_() {} //Default destructor - virtual ~delegate_base() noexcept - { - release(); - } + virtual ~delegate_base() noexcept { release(); } //Copy contructor - delegate_base(const delegate_base& other) - { - if (other.allocator_.has_allocation()) - { + delegate_base(const delegate_base& other) { + if (other.allocator_.has_allocation()) { allocator_.allocate(other.allocator_.get_size()); other.get_delegate()->clone(allocator_.get_allocation()); } } //Copy assignment operator - delegate_base& operator=(const delegate_base& other) - { + delegate_base& operator=(const delegate_base& other) { release(); - if (other.allocator_.has_allocation()) - { + if (other.allocator_.has_allocation()) { allocator_.allocate(other.allocator_.get_size()); other.get_delegate()->clone(allocator_.get_allocation()); } @@ -616,13 +493,11 @@ public: } //Move constructor - delegate_base(delegate_base&& other) noexcept - : allocator_(std::move(other.allocator_)) - {} + delegate_base(delegate_base&& other) noexcept : + allocator_(std::move(other.allocator_)) {} //Move assignment operator - delegate_base& operator=(delegate_base&& other) noexcept - { + delegate_base& operator=(delegate_base&& other) noexcept { release(); allocator_ = std::move(other.allocator_); return *this; @@ -631,63 +506,37 @@ public: //Gets the owner of the deletage //Only valid for SPDelegate and RawDelegate. //Otherwise returns nullptr by default - const void* get_owner() const - { - if (allocator_.has_allocation()) - { - return get_delegate()->get_owner(); - } + [[nodiscard]] const void* get_owner() const { + if (allocator_.has_allocation()) { return get_delegate()->get_owner(); } return nullptr; } - size_t get_size() const - { - return allocator_.get_size(); - } + [[nodiscard]] virtual size_t get_size() const { return allocator_.get_size(); } //Clear the bound delegate if it is bound to the given object. //Ignored when pObject is a nullptr - void clear_if_bound_to(void* pObject) - { - if (pObject != nullptr && is_bound_to(pObject)) - { - release(); - } - } + void clear_if_bound_to(void* pObject) { if (pObject != nullptr && is_bound_to(pObject)) { release(); } } //Clear the bound delegate if it exists - void clear() - { - release(); - } + void clear() { release(); } //If the allocator has a size, it means it's bound to something - bool is_bound() const - { - return allocator_.has_allocation(); - } + [[nodiscard]] bool is_bound() const { return allocator_.has_allocation(); } - bool is_bound_to(void* pObject) const - { - if (pObject == nullptr || allocator_.has_allocation() == false) - { - return false; - } + bool is_bound_to(void* pObject) const { + if (pObject == nullptr || allocator_.has_allocation() == false) { return false; } return get_delegate()->get_owner() == pObject; } protected: - void release() - { - if (allocator_.has_allocation()) - { + void release() { + if (allocator_.has_allocation()) { get_delegate()->~i_delegate_base(); allocator_.free(); } } - i_delegate_base* get_delegate() const - { + [[nodiscard]] i_delegate_base* get_delegate() const { return static_cast(allocator_.get_allocation()); } @@ -699,153 +548,158 @@ protected: //Delegate that can be bound to by just ONE object template -class delegate : public delegate_base -{ +class delegate : public delegate_base { private: template using ConstMemberFunction = typename _DelegatesInteral::MemberFunction::Type; template - using NonConstMemberFunction = typename _DelegatesInteral::MemberFunction::Type; + using NonConstMemberFunction = typename _DelegatesInteral::MemberFunction::Type + ; public: using IDelegateT = i_delegate; //Create delegate using member function template - NO_DISCARD static delegate create_raw(T* pObj, NonConstMemberFunction pFunction, Args2... args) - { + NO_DISCARD static delegate create_raw(T* pObj, NonConstMemberFunction pFunction, Args2... args) { delegate handler; - handler.bind>(pObj, pFunction, std::forward(args)...); + handler.template bind>( + pObj, + pFunction, + std::forward(args)...); return handler; } template - NO_DISCARD static delegate create_raw(T* pObj, ConstMemberFunction pFunction, Args2... args) - { + NO_DISCARD static delegate create_raw(T* pObj, ConstMemberFunction pFunction, Args2... args) { delegate handler; - handler.bind>(pObj, pFunction, std::forward(args)...); + handler.template bind>( + pObj, + pFunction, + std::forward(args)...); return handler; } //Create delegate using global/static function template - NO_DISCARD static delegate create_static(RetVal(*pFunction)(Args..., Args2...), Args2... args) - { + NO_DISCARD static delegate create_static(RetVal (*pFunction)(Args..., Args2...), Args2... args) { delegate handler; - handler.bind>(pFunction, std::forward(args)...); + handler.template bind>(pFunction, std::forward(args)...); return handler; } //Create delegate using std::shared_ptr template - NO_DISCARD static delegate create_sp(const std::shared_ptr& pObject, NonConstMemberFunction pFunction, Args2... args) - { + NO_DISCARD static delegate create_sp(const std::shared_ptr& pObject, + NonConstMemberFunction pFunction, Args2... args) { delegate handler; - handler.bind>(pObject, pFunction, std::forward(args)...); + handler.template bind>( + pObject, + pFunction, + std::forward(args)...); return handler; } template - NO_DISCARD static delegate create_sp(const std::shared_ptr& pObject, ConstMemberFunction pFunction, Args2... args) - { + NO_DISCARD static delegate create_sp(const std::shared_ptr& pObject, ConstMemberFunction pFunction, + Args2... args) { delegate handler; - handler.bind>(pObject, pFunction, std::forward(args)...); + handler.template bind>( + pObject, + pFunction, + std::forward(args)...); return handler; } //Create delegate using a lambda template - NO_DISCARD static delegate create_lambda(TLambda&& lambda, Args2... args) - { + NO_DISCARD static delegate create_lambda(TLambda&& lambda, Args2... args) { delegate handler; - handler.bind>(std::forward(lambda), std::forward(args)...); + handler.template bind>( + std::forward(lambda), + std::forward(args)...); return handler; } //Bind a member function template - void bind_raw(T* pObject, NonConstMemberFunction pFunction, Args2&&... args) - { + void bind_raw(T* pObject, NonConstMemberFunction pFunction, Args2&&... args) { DELEGATE_STATIC_ASSERT(!std::is_const::value, "Cannot bind a non-const function on a const object"); - *this = create_raw(pObject, pFunction, std::forward(args)...); + *this = create_raw(pObject, pFunction, std::forward(args)...); } template - void bind_raw(T* pObject, ConstMemberFunction pFunction, Args2&&... args) - { - *this = create_raw(pObject, pFunction, std::forward(args)...); + void bind_raw(T* pObject, ConstMemberFunction pFunction, Args2&&... args) { + *this = create_raw(pObject, pFunction, std::forward(args)...); } //Bind a static/global function template - void bind_static(RetVal(*pFunction)(Args..., Args2...), Args2&&... args) - { - *this = create_static(pFunction, std::forward(args)...); + void bind_static(RetVal (*pFunction)(Args..., Args2...), Args2&&... args) { + *this = create_static(pFunction, std::forward(args)...); } //Bind a lambda template - void bind_lambda(LambdaType&& lambda, Args2&&... args) - { - *this = create_lambda(std::forward(lambda), std::forward(args)...); + void bind_lambda(LambdaType&& lambda, Args2&&... args) { + *this = create_lambda(std::forward(lambda), std::forward(args)...); } //Bind a member function with a shared_ptr object template - void bind_sp(std::shared_ptr pObject, NonConstMemberFunction pFunction, Args2&&... args) - { + void bind_sp(std::shared_ptr pObject, NonConstMemberFunction pFunction, Args2&&... args) { DELEGATE_STATIC_ASSERT(!std::is_const::value, "Cannot bind a non-const function on a const object"); - *this = create_sp(pObject, pFunction, std::forward(args)...); + *this = create_sp(pObject, pFunction, std::forward(args)...); } template - void bind_sp(std::shared_ptr pObject, ConstMemberFunction pFunction, Args2&&... args) - { - *this = create_sp(pObject, pFunction, std::forward(args)...); + void bind_sp(std::shared_ptr pObject, ConstMemberFunction pFunction, Args2&&... args) { + *this = create_sp(pObject, pFunction, std::forward(args)...); } //Execute the delegate with the given parameters - RetVal execute(Args... args) const - { + RetVal execute(Args... args) const { DELEGATE_ASSERT(allocator_.has_allocation(), "Delegate is not bound"); - return ((IDelegateT*)get_delegate())->execute(std::forward(args)...); + return ((IDelegateT*) get_delegate())->execute(std::forward(args)...); } - RetVal execute_if_bound(Args... args) const - { - if (is_bound()) - { - return ((IDelegateT*)get_delegate())->execute(std::forward(args)...); - } + RetVal execute_if_bound(Args... args) const { + if (is_bound()) { return ((IDelegateT*) get_delegate())->execute(std::forward(args)...); } return RetVal(); } private: template - void bind(Args3&&... args) - { + void bind(Args3&&... args) { release(); void* pAlloc = allocator_.allocate(sizeof(T)); - new (pAlloc) T(std::forward(args)...); + new(pAlloc) T(std::forward(args)...); } }; //Delegate that can be bound to by MULTIPLE objects template -class multicast_delegate : public delegate_base -{ +class multicast_delegate : public delegate_base { public: using DelegateT = delegate; private: - struct delegate_handler_pair - { + struct delegate_handler_pair { delegate_handle handle; - DelegateT callback; - delegate_handler_pair() : handle(false) {} - delegate_handler_pair(const delegate_handle& handle, const DelegateT& callback) : handle(handle), callback(callback) {} - delegate_handler_pair(const delegate_handle& handle, DelegateT&& callback) : handle(handle), callback(std::move(callback)) {} + DelegateT callback; + + delegate_handler_pair() : + handle(false) {} + + delegate_handler_pair(delegate_handle in_handle, const DelegateT& in_callback) : + handle(std::move(in_handle)), + callback(in_callback) {} + + delegate_handler_pair(delegate_handle in_handle, DelegateT&& in_callback) : + handle(std::move(in_handle)), + callback(std::move(in_callback)) {} }; + template using ConstMemberFunction = typename _DelegatesInteral::MemberFunction::Type; template @@ -853,10 +707,8 @@ private: public: //Default constructor - constexpr multicast_delegate() - : locks_(0) - { - } + constexpr multicast_delegate() : + locks_(0) {} //Default destructor ~multicast_delegate() noexcept = default; @@ -868,45 +720,30 @@ public: multicast_delegate& operator=(const multicast_delegate& other) = default; //Move constructor - multicast_delegate(multicast_delegate&& other) noexcept - : events_(std::move(other.events_)), - locks_(std::move(other.locks_)) - { - } + multicast_delegate(multicast_delegate&& other) noexcept : + events_(std::move(other.events_)), + locks_(other.locks_) {} //Move assignment operator - multicast_delegate& operator=(multicast_delegate&& other) noexcept - { + multicast_delegate& operator=(multicast_delegate&& other) noexcept { events_ = std::move(other.events_); - locks_ = std::move(other.locks_); + locks_ = other.locks_; return *this; } template - delegate_handle operator+=(T&& l) - { - return add(DelegateT::create_lambda(std::move(l))); - } + delegate_handle operator+=(T&& l) { return add(DelegateT::create_lambda(std::forward(l))); } //Add delegate with the += operator - delegate_handle operator+=(DelegateT&& handler) noexcept - { - return add(std::forward(handler)); - } + delegate_handle operator+=(DelegateT&& handler) noexcept { return add(std::forward(handler)); } //Remove a delegate using its DelegateHandle - bool operator-=(delegate_handle& handle) - { - return remove(handle); - } + bool operator-=(delegate_handle& handle) { return remove(handle); } - delegate_handle add(DelegateT&& handler) noexcept - { + delegate_handle add(DelegateT&& handler) noexcept { //Favour an empty space over a possible array reallocation - for (size_t i = 0; i < events_.size(); ++i) - { - if (events_[i].handle.is_valid() == false) - { + for (size_t i = 0; i < events_.size(); ++i) { + if (events_[i].handle.is_valid() == false) { events_[i] = delegate_handler_pair(delegate_handle(true), std::move(handler)); return events_[i].handle; } @@ -917,61 +754,47 @@ public: //Bind a member function template - delegate_handle add_raw(T* pObject, NonConstMemberFunction pFunction, Args2&&... args) - { + delegate_handle add_raw(T* pObject, NonConstMemberFunction pFunction, Args2&&... args) { return add(DelegateT::create_raw(pObject, pFunction, std::forward(args)...)); } template - delegate_handle add_raw(T* pObject, ConstMemberFunction pFunction, Args2&&... args) - { + delegate_handle add_raw(T* pObject, ConstMemberFunction pFunction, Args2&&... args) { return add(DelegateT::create_raw(pObject, pFunction, std::forward(args)...)); } //Bind a static/global function template - delegate_handle add_static(void(*pFunction)(Args..., Args2...), Args2&&... args) - { + delegate_handle add_static(void (*pFunction)(Args..., Args2...), Args2&&... args) { return add(DelegateT::create_static(pFunction, std::forward(args)...)); } //Bind a lambda template - delegate_handle add_lambda(LambdaType&& lambda, Args2&&... args) - { + delegate_handle add_lambda(LambdaType&& lambda, Args2&&... args) { return add(DelegateT::create_lambda(std::forward(lambda), std::forward(args)...)); } //Bind a member function with a shared_ptr object template - delegate_handle add_sp(std::shared_ptr pObject, NonConstMemberFunction pFunction, Args2&&... args) - { + delegate_handle add_sp(std::shared_ptr pObject, NonConstMemberFunction pFunction, Args2&&... args) { return add(DelegateT::create_sp(pObject, pFunction, std::forward(args)...)); } template - delegate_handle add_sp(std::shared_ptr pObject, ConstMemberFunction pFunction, Args2&&... args) - { + delegate_handle add_sp(std::shared_ptr pObject, ConstMemberFunction pFunction, Args2&&... args) { return add(DelegateT::create_sp(pObject, pFunction, std::forward(args)...)); } //Removes all handles that are bound from a specific object //Ignored when pObject is null //Note: Only works on Raw and SP bindings - void remove_object(void* pObject) - { - if (pObject != nullptr) - { - for (size_t i = 0; i < events_.size(); ++i) - { - if (events_[i].callback.get_owner() == pObject) - { - if (is_locked()) - { - events_[i].callback.clear(); - } - else - { + void remove_object(void* pObject) { + if (pObject != nullptr) { + for (size_t i = 0; i < events_.size(); ++i) { + if (events_[i].callback.get_owner() == pObject) { + if (is_locked()) { events_[i].callback.clear(); } + else { std::swap(events_[i], events_[events_.size() - 1]); events_.pop_back(); } @@ -981,20 +804,12 @@ public: } //Remove a function from the event list by the handle - bool remove(delegate_handle& handle) - { - if (handle.is_valid()) - { - for (size_t i = 0; i < events_.size(); ++i) - { - if (events_[i].handle == handle) - { - if (is_locked()) - { - events_[i].callback.clear(); - } - else - { + bool remove(delegate_handle& handle) { + if (handle.is_valid()) { + for (size_t i = 0; i < events_.size(); ++i) { + if (events_[i].handle == handle) { + if (is_locked()) { events_[i].callback.clear(); } + else { std::swap(events_[i], events_[events_.size() - 1]); events_.pop_back(); } @@ -1006,84 +821,47 @@ public: return false; } - bool is_bound_to(const delegate_handle& handle) const - { - if (handle.is_valid()) - { - for (size_t i = 0; i < events_.size(); ++i) - { - if (events_[i].handle == handle) - { - return true; - } - } + [[nodiscard]] bool is_bound_to(const delegate_handle& handle) const { + if (handle.is_valid()) { + for (size_t i = 0; i < events_.size(); ++i) { if (events_[i].handle == handle) { return true; } } } return false; } //Remove all the functions bound to the delegate - void remove_all() - { - if (is_locked()) - { - for (delegate_handler_pair& handler : events_) - { - handler.callback.clear(); - } - } - else - { - events_.clear(); - } + void remove_all() { + if (is_locked()) { for (delegate_handler_pair& handler: events_) { handler.callback.clear(); } } + else { events_.clear(); } } - void compress(const size_t maxSpace = 0) - { - if (is_locked() == false) - { + void compress(const size_t maxSpace = 0) { + if (is_locked() == false) { size_t toDelete = 0; - for (size_t i = 0; i < events_.size() - toDelete; ++i) - { - if (events_[i].handle.is_valid() == false) - { + for (size_t i = 0; i < events_.size() - toDelete; ++i) { + if (events_[i].handle.is_valid() == false) { std::swap(events_[i], events_[toDelete]); ++toDelete; } } - if (toDelete > maxSpace) - { - events_.resize(events_.size() - toDelete); - } + if (toDelete > maxSpace) { events_.resize(events_.size() - toDelete); } } } //Execute all functions that are bound - void broadcast(Args ...args) - { + void broadcast(Args... args) { lock(); - for (size_t i = 0; i < events_.size(); ++i) - { - if (events_[i].handle.is_valid()) - { - events_[i].callback.execute(std::forward(args)...); - } + for (size_t i = 0; i < events_.size(); ++i) { + if (events_[i].handle.is_valid()) { events_[i].callback.execute(std::forward(args)...); } } unlock(); } - size_t get_size() const - { - return events_.size(); - } + [[nodiscard]] size_t get_size() const override { return events_.size(); } private: - void lock() - { - ++locks_; - } + void lock() { ++locks_; } - void unlock() - { + void unlock() { //Unlock() should never be called more than Lock()! DELEGATE_ASSERT(locks_ > 0); --locks_; @@ -1091,13 +869,10 @@ private: //Returns true is the delegate is currently broadcasting //If this is true, the order of the array should not be changed otherwise this causes undefined behaviour - bool is_locked() const - { - return locks_ > 0; - } + [[nodiscard]] bool is_locked() const { return locks_ > 0; } std::vector events_; - unsigned int locks_; + unsigned int locks_; }; #endif diff --git a/src/mirage_core/src/misc/mapped_file/unix/mapped_file.cpp b/src/mirage_core/src/misc/mapped_file/unix/mapped_file.cpp index d928252..6819c13 100644 --- a/src/mirage_core/src/misc/mapped_file/unix/mapped_file.cpp +++ b/src/mirage_core/src/misc/mapped_file/unix/mapped_file.cpp @@ -64,7 +64,7 @@ mapped_file_unix& mapped_file_unix::operator=(mapped_file_unix&& other) noexcept bool mapped_file_unix::map_file(const std::filesystem::path& filename) { cleanup(); - std::string utf8_filename(filename.begin(), filename.end()); + const std::string& utf8_filename = filename.string(); fd = open(utf8_filename.c_str(), O_RDONLY); if (fd == -1) { // 无法打开文件 diff --git a/src/mirage_core/src/misc/mapped_file/windows/mapped_file.cpp b/src/mirage_core/src/misc/mapped_file/windows/mapped_file.cpp index 069db46..627080b 100644 --- a/src/mirage_core/src/misc/mapped_file/windows/mapped_file.cpp +++ b/src/mirage_core/src/misc/mapped_file/windows/mapped_file.cpp @@ -71,7 +71,7 @@ mapped_file_win& mapped_file_win::operator=(mapped_file_win&& other) noexcept { bool mapped_file_win::map_file(const std::filesystem::path& filename) { cleanup(); - file_handle_ = CreateFileW( + file_handle_ = CreateFile( filename.c_str(), GENERIC_READ, FILE_SHARE_READ, diff --git a/src/mirage_core/src/misc/mirage_type.h b/src/mirage_core/src/misc/mirage_type.h index 83b700c..f8a3db0 100644 --- a/src/mirage_core/src/misc/mirage_type.h +++ b/src/mirage_core/src/misc/mirage_type.h @@ -113,7 +113,7 @@ enum class flow_direction_preference_t { /** * @brief 全局默认流动方向设置 */ -inline static auto g_flow_direction = flow_direction_t::left_to_right; +// inline static auto g_flow_direction = flow_direction_t::left_to_right; //-------------- 几何和渲染结构体 -------------- @@ -304,16 +304,16 @@ struct mirage_vertex_param_t { /** * @brief 两容器构造函数 - 从两个容器构造,前两个元素到x,y,后两个元素到z,w - * @param a 第一个容器,提供x和y分量 - * @param b 第二个容器,提供z和w分量 + * @param in_a 第一个容器,提供x和y分量 + * @param in_b 第二个容器,提供z和w分量 */ template()[0]), typename = decltype(std::declval()[0])> - mirage_vertex_param_t(const A& a, const B& b) : x(static_cast(a[0])), - y(static_cast(a[1])), - z(static_cast(b[0])), - w(static_cast(b[1])) { + mirage_vertex_param_t(const A& in_a, const B& in_b) : x(static_cast(in_a[0])), + y(static_cast(in_a[1])), + z(static_cast(in_b[0])), + w(static_cast(in_b[1])) { } //-------------- 辅助类型特征检测 -------------- diff --git a/src/mirage_render/src/font/atlas/font_atlas.h b/src/mirage_render/src/font/atlas/font_atlas.h index f8bf0e6..a76a8bc 100644 --- a/src/mirage_render/src/font/atlas/font_atlas.h +++ b/src/mirage_render/src/font/atlas/font_atlas.h @@ -49,11 +49,11 @@ struct char_key_t { template<> struct std::hash { size_t operator()(const char_key_t& in_key) const { - std::hash hash_fn; - size_t hash = hash_fn(in_key.glyph_index); - hash ^= (uint64_t)in_key.font_face.get(); - hash ^= std::hash{}(in_key.font_size); - return hash; + constexpr std::hash hash_fn; + size_t hash_key = hash_fn(in_key.glyph_index); + hash_key ^= reinterpret_cast(in_key.font_face.get()); + hash_key ^= std::hash{}(in_key.font_size); + return hash_key; } }; diff --git a/src/mirage_render/src/platform_window/windows/windows_window.cpp b/src/mirage_render/src/platform_window/windows/windows_window.cpp index 54a48aa..38509e9 100644 --- a/src/mirage_render/src/platform_window/windows/windows_window.cpp +++ b/src/mirage_render/src/platform_window/windows/windows_window.cpp @@ -11,11 +11,7 @@ bool mouse_tracking_ = FALSE; std::vector windows; platform_window* get_window_from_hwnd(const HWND hwnd) { - for (const auto& window: windows) { - if (window->get_window_handle() == hwnd) { - return window; - } - } + for (const auto& window: windows) { if (window->get_window_handle() == hwnd) { return window; } } return nullptr; } @@ -23,13 +19,14 @@ LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) bool processed = false; // 窗口关闭事件 if (uMsg == WM_CLOSE) { - std::erase_if(windows, [hwnd](platform_window* window) { - if (window->get_window_handle() == hwnd) { - window->close(); - return true; - } - return false; - }); + std::erase_if(windows, + [hwnd](platform_window* window) { + if (window->get_window_handle() == hwnd) { + window->close(); + return true; + } + return false; + }); processed = true; } @@ -41,7 +38,9 @@ LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) // 窗口移动事件 if (uMsg == WM_MOVE) { - if (const auto window = get_window_from_hwnd(hwnd)) { window->on_move(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); } + if (const auto window = get_window_from_hwnd(hwnd)) { + window->on_move(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); + } processed = true; } @@ -56,16 +55,16 @@ LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) // 鼠标移动事件 if (uMsg == WM_MOUSEMOVE) { if (const auto window = get_window_from_hwnd(hwnd)) { - const int x = GET_X_LPARAM(lParam); - const int y = GET_Y_LPARAM(lParam); + const int x = GET_X_LPARAM(lParam); + const int y = GET_Y_LPARAM(lParam); const Eigen::Vector2f pos(static_cast(x), static_cast(y)); window->handle_mouse_move(pos); } if (!mouse_tracking_) { TRACKMOUSEEVENT tme; - tme.cbSize = sizeof(TRACKMOUSEEVENT); - tme.dwFlags = TME_LEAVE; - tme.hwndTrack = hwnd; + tme.cbSize = sizeof(TRACKMOUSEEVENT); + tme.dwFlags = TME_LEAVE; + tme.hwndTrack = hwnd; tme.dwHoverTime = HOVER_DEFAULT; TrackMouseEvent(&tme); mouse_tracking_ = TRUE; @@ -75,14 +74,14 @@ LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) // 鼠标按键事件 const auto lmr_button = uMsg >= WM_LBUTTONDOWN && uMsg <= WM_MBUTTONDBLCLK; - const auto x_button = uMsg >= WM_XBUTTONDOWN && uMsg <= WM_XBUTTONDBLCLK; + const auto x_button = uMsg >= WM_XBUTTONDOWN && uMsg <= WM_XBUTTONDBLCLK; if (lmr_button || x_button) { if (const auto window = get_window_from_hwnd(hwnd)) { - const int x = GET_X_LPARAM(lParam); - const int y = GET_Y_LPARAM(lParam); + const int x = GET_X_LPARAM(lParam); + const int y = GET_Y_LPARAM(lParam); const Eigen::Vector2f pos(static_cast(x), static_cast(y)); - const auto action = platform_event_to_mouse_action(uMsg, wParam); - const auto button = platform_event_to_mouse_button(uMsg, wParam); + const auto action = platform_event_to_mouse_action(uMsg, wParam); + const auto button = platform_event_to_mouse_button(uMsg, wParam); if (action == mouse_action::press) window->handle_mouse_button_down(pos, button); else if (action == mouse_action::release) @@ -96,9 +95,9 @@ LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) // 鼠标滚轮事件 if (uMsg == WM_MOUSEWHEEL || uMsg == WM_MOUSEHWHEEL) { if (const auto window = get_window_from_hwnd(hwnd)) { - const int x = GET_X_LPARAM(lParam); - const int y = GET_Y_LPARAM(lParam); - POINT screen_point = { x, y }; + const int x = GET_X_LPARAM(lParam); + const int y = GET_Y_LPARAM(lParam); + POINT screen_point = { x, y }; ScreenToClient(hwnd, &screen_point); // 现在 screen_point.x 和 screen_point.y 包含相对于窗口客户区的坐标 @@ -113,9 +112,7 @@ LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) if (uMsg == WM_MOUSELEAVE) { mouse_tracking_ = FALSE; - if (const auto window = get_window_from_hwnd(hwnd)) { - window->handle_mouse_leave(); - } + if (const auto window = get_window_from_hwnd(hwnd)) { window->handle_mouse_leave(); } processed = true; } @@ -136,13 +133,19 @@ platform_window::platform_window(int32_t in_width, int32_t in_height, const wcha RECT rect = { 0, 0, in_width, in_height }; AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, FALSE); - window_handle_ = (void*)CreateWindowW( - L"mirage_window_class", in_title, - WS_OVERLAPPEDWINDOW | WS_VISIBLE, - CW_USEDEFAULT, CW_USEDEFAULT, - rect.right - rect.left, rect.bottom - rect.top, - NULL, NULL, GetModuleHandleW(NULL), NULL - ); + window_handle_ = static_cast(CreateWindowW( + L"mirage_window_class", + in_title, + WS_OVERLAPPEDWINDOW | WS_VISIBLE, + CW_USEDEFAULT, + CW_USEDEFAULT, + rect.right - rect.left, + rect.bottom - rect.top, + nullptr, + nullptr, + GetModuleHandleW(nullptr), + nullptr + )); if (!window_handle_) { std::cerr << "Failed to create window" << std::endl; @@ -190,9 +193,9 @@ Eigen::Vector2i platform_window::get_window_size() const { if (GetWindowRect(WINDOW_HANDLE, &rect)) { int width = rect.right - rect.left; int height = rect.bottom - rect.top; - return Eigen::Vector2i(width, height); + return { width, height }; } - return Eigen::Vector2i(0, 0); + return { 0, 0 }; } Eigen::Vector2i platform_window::get_window_frame_size() const { @@ -201,14 +204,12 @@ Eigen::Vector2i platform_window::get_window_frame_size() const { if (GetClientRect(WINDOW_HANDLE, &rect)) { int width = rect.right - rect.left; int height = rect.bottom - rect.top; - return Eigen::Vector2i(width, height); + return { width, height }; } - return Eigen::Vector2i(0, 0); + return { 0, 0 }; } -float platform_window::get_window_dpi_scale() const { - return 1.f; -} +float platform_window::get_window_dpi_scale() const { return 1.f; } Eigen::Vector2i platform_window::get_window_position() const { RECT rect; @@ -219,55 +220,62 @@ Eigen::Vector2i platform_window::get_window_position() const { void* platform_window::get_window_handle() const { return window_handle_; } platform_window& platform_window::set_title(const wchar_t* title) { - SetWindowText(WINDOW_HANDLE, title); + SetWindowTextW(WINDOW_HANDLE, title); return *this; } platform_window& platform_window::set_has_minimize_button(bool has_minimize_button) { auto style = GetWindowLong(WINDOW_HANDLE, GWL_STYLE); - if (has_minimize_button) { style |= WS_MINIMIZEBOX; } else { style &= ~WS_MINIMIZEBOX; } + if (has_minimize_button) { style |= WS_MINIMIZEBOX; } + else { style &= ~WS_MINIMIZEBOX; } SetWindowLong(WINDOW_HANDLE, GWL_STYLE, style); return *this; } platform_window& platform_window::set_has_maximize_button(bool has_maximize_button) { auto style = GetWindowLong(WINDOW_HANDLE, GWL_STYLE); - if (has_maximize_button) { style |= WS_MAXIMIZEBOX; } else { style &= ~WS_MAXIMIZEBOX; } + if (has_maximize_button) { style |= WS_MAXIMIZEBOX; } + else { style &= ~WS_MAXIMIZEBOX; } SetWindowLong(WINDOW_HANDLE, GWL_STYLE, style); return *this; } platform_window& platform_window::set_has_close_button(bool has_close_button) { auto style = GetWindowLong(WINDOW_HANDLE, GWL_STYLE); - if (has_close_button) { style |= WS_SYSMENU; } else { style &= ~WS_SYSMENU; } + if (has_close_button) { style |= WS_SYSMENU; } + else { style &= ~WS_SYSMENU; } SetWindowLong(WINDOW_HANDLE, GWL_STYLE, style); return *this; } platform_window& platform_window::set_has_border(bool has_border) { auto style = GetWindowLong(WINDOW_HANDLE, GWL_STYLE); - if (has_border) { style |= WS_BORDER; } else { style &= ~WS_BORDER; } + if (has_border) { style |= WS_BORDER; } + else { style &= ~WS_BORDER; } SetWindowLong(WINDOW_HANDLE, GWL_STYLE, style); return *this; } platform_window& platform_window::set_has_caption(bool has_caption) { auto style = GetWindowLong(WINDOW_HANDLE, GWL_STYLE); - if (has_caption) { style |= WS_CAPTION; } else { style &= ~WS_CAPTION; } + if (has_caption) { style |= WS_CAPTION; } + else { style &= ~WS_CAPTION; } SetWindowLong(WINDOW_HANDLE, GWL_STYLE, style); return *this; } platform_window& platform_window::set_has_resizable_border(bool has_resizable_border) { auto style = GetWindowLong(WINDOW_HANDLE, GWL_STYLE); - if (has_resizable_border) { style |= WS_THICKFRAME; } else { style &= ~WS_THICKFRAME; } + if (has_resizable_border) { style |= WS_THICKFRAME; } + else { style &= ~WS_THICKFRAME; } SetWindowLong(WINDOW_HANDLE, GWL_STYLE, style); return *this; } platform_window& platform_window::set_topmost(bool is_topmost) { auto style = GetWindowLong(WINDOW_HANDLE, GWL_EXSTYLE); - if (is_topmost) { style |= WS_EX_TOPMOST; } else { style &= ~WS_EX_TOPMOST; } + if (is_topmost) { style |= WS_EX_TOPMOST; } + else { style &= ~WS_EX_TOPMOST; } SetWindowLong(WINDOW_HANDLE, GWL_EXSTYLE, style); return *this; } diff --git a/src/mirage_render/src/render/windows/windows_render_context.cpp b/src/mirage_render/src/render/windows/windows_render_context.cpp index d1fe4cb..31f2d21 100644 --- a/src/mirage_render/src/render/windows/windows_render_context.cpp +++ b/src/mirage_render/src/render/windows/windows_render_context.cpp @@ -11,197 +11,201 @@ #include "windows_render_state.h" bool windows_mirage_render_context::init() { - try { - // 定义支持的特性级别(从高到低排序) - D3D_FEATURE_LEVEL feature_levels[] = { - D3D_FEATURE_LEVEL_11_1, - D3D_FEATURE_LEVEL_11_0, - D3D_FEATURE_LEVEL_10_1, - D3D_FEATURE_LEVEL_10_0 - }; + try { + // 定义支持的特性级别(从高到低排序) + D3D_FEATURE_LEVEL feature_levels[] = { + D3D_FEATURE_LEVEL_11_1, + D3D_FEATURE_LEVEL_11_0, + D3D_FEATURE_LEVEL_10_1, + D3D_FEATURE_LEVEL_10_0 + }; - // 设置设备创建标志 - // UINT device_flags = D3D11_CREATE_DEVICE_BGRA_SUPPORT | D3D11_CREATE_DEVICE_SINGLETHREADED; // BGRA支持和单线程模式 - UINT device_flags = D3D11_CREATE_DEVICE_BGRA_SUPPORT; // BGRA支持和单线程模式 + // 设置设备创建标志 + // UINT device_flags = D3D11_CREATE_DEVICE_BGRA_SUPPORT | D3D11_CREATE_DEVICE_SINGLETHREADED; // BGRA支持和单线程模式 + UINT device_flags = D3D11_CREATE_DEVICE_BGRA_SUPPORT; // BGRA支持和单线程模式 #if DEBUG - device_flags |= D3D11_CREATE_DEVICE_DEBUG; // 在Debug模式下启用调试层 + device_flags |= D3D11_CREATE_DEVICE_DEBUG; // 在Debug模式下启用调试层 #endif - // 定义要尝试的驱动类型数组 - constexpr D3D_DRIVER_TYPE driver_types[] = { - D3D_DRIVER_TYPE_HARDWARE, // 首选硬件加速 - D3D_DRIVER_TYPE_WARP, // 其次是WARP软件渲染器 - D3D_DRIVER_TYPE_REFERENCE // 最后是参考软件渲染器 - }; + // 定义要尝试的驱动类型数组 + constexpr D3D_DRIVER_TYPE driver_types[] = { + D3D_DRIVER_TYPE_HARDWARE, // 首选硬件加速 + D3D_DRIVER_TYPE_WARP, // 其次是WARP软件渲染器 + D3D_DRIVER_TYPE_REFERENCE // 最后是参考软件渲染器 + }; - // 尝试按优先级创建设备 - HRESULT hr = E_FAIL; - D3D_DRIVER_TYPE used_driver_type = D3D_DRIVER_TYPE_UNKNOWN; - SetProcessDPIAware(); + // 尝试按优先级创建设备 + HRESULT hr = E_FAIL; + D3D_DRIVER_TYPE used_driver_type = D3D_DRIVER_TYPE_UNKNOWN; + SetProcessDPIAware(); - for (const auto& driver_type : driver_types) { - hr = D3D11CreateDevice( - nullptr, // 使用默认适配器 - driver_type, // 驱动类型 - nullptr, // 软件栅格化模块句柄(仅用于软件设备) - device_flags, // 设备创建标志 - feature_levels, // 特性级别数组 - ARRAYSIZE(feature_levels), // 特性级别数量 - D3D11_SDK_VERSION, // SDK版本 - &device, // 输出设备 - &feature_level, // 输出获取的特性级别 - &device_context // 输出设备上下文 - ); + for (const auto& driver_type: driver_types) { + hr = D3D11CreateDevice( + nullptr, + // 使用默认适配器 + driver_type, + // 驱动类型 + nullptr, + // 软件栅格化模块句柄(仅用于软件设备) + device_flags, + // 设备创建标志 + feature_levels, + // 特性级别数组 + std::size(feature_levels), + // 特性级别数量 + D3D11_SDK_VERSION, + // SDK版本 + &device, + // 输出设备 + &feature_level, + // 输出获取的特性级别 + &device_context // 输出设备上下文 + ); - if (SUCCEEDED(hr)) { - used_driver_type = driver_type; - break; - } - } + if (SUCCEEDED(hr)) { + used_driver_type = driver_type; + break; + } + } - // 检查是否成功创建设备 - if (FAILED(hr)) { - std::println(std::cerr, "mirage: 所有的 D3D11 设备类型都创建失败. HRESULT: 0x{:#06x}", hr); - cleanup(); - return false; - } + // 检查是否成功创建设备 + if (FAILED(hr)) { + std::println(std::cerr, "mirage: 所有的 D3D11 设备类型都创建失败. HRESULT: 0x{:#06x}", hr); + cleanup(); + return false; + } - // **获取DXGI设备以访问适配器** - IDXGIDevice* dxgi_device = nullptr; - hr = device->QueryInterface(__uuidof(IDXGIDevice), reinterpret_cast(&dxgi_device)); - if (FAILED(hr)) { - std::println(std::cerr, "mirage: 获取 DXGI 设备失败. HRESULT: 0x{:#06x}", hr); - cleanup(); - return false; - } + // **获取DXGI设备以访问适配器** + IDXGIDevice* dxgi_device = nullptr; + hr = device->QueryInterface(__uuidof(IDXGIDevice), reinterpret_cast(&dxgi_device)); + if (FAILED(hr)) { + std::println(std::cerr, "mirage: 获取 DXGI 设备失败. HRESULT: 0x{:#06x}", hr); + cleanup(); + return false; + } - // **获取适配器** - IDXGIAdapter* dxgi_adapter = nullptr; - hr = dxgi_device->GetAdapter(&dxgi_adapter); - dxgi_device->Release(); + // **获取适配器** + IDXGIAdapter* dxgi_adapter = nullptr; + hr = dxgi_device->GetAdapter(&dxgi_adapter); + dxgi_device->Release(); - if (FAILED(hr)) { - std::println(std::cerr, "mirage: 无法获取 DXGI 适配器. HRESULT: 0x{:#06x}", hr); - cleanup(); - return false; - } + if (FAILED(hr)) { + std::println(std::cerr, "mirage: 无法获取 DXGI 适配器. HRESULT: 0x{:#06x}", hr); + cleanup(); + return false; + } - // **获取适配器描述信息** - DXGI_ADAPTER_DESC adapter_desc; - hr = dxgi_adapter->GetDesc(&adapter_desc); - if (FAILED(hr)) { - std::println(std::cerr, "mirage: 无法获取 DXGI 适配器描述信息. HRESULT: 0x{:#06x}", hr); - } + // **获取适配器描述信息** + DXGI_ADAPTER_DESC adapter_desc; + hr = dxgi_adapter->GetDesc(&adapter_desc); + if (FAILED(hr)) { std::println(std::cerr, "mirage: 无法获取 DXGI 适配器描述信息. HRESULT: 0x{:#06x}", hr); } - // **尝试获取最新的DXGI工厂版本 - 从最新的Factory6开始尝试** - // Windows 10 Fall Creators Update (1709)或更高版本支持 - hr = dxgi_adapter->GetParent(__uuidof(IDXGIFactory6), reinterpret_cast(&dxgi_factory)); - if (SUCCEEDED(hr)) { - std::println(std::cout, "mirage: 使用 DXGI Factory6"); - } else { - // 尝试Factory5 - Windows 10 Anniversary Update (1607)或更高版本 - hr = dxgi_adapter->GetParent(__uuidof(IDXGIFactory5), reinterpret_cast(&dxgi_factory)); - if (SUCCEEDED(hr)) { - std::println(std::cout, "mirage: 使用 DXGI Factory5"); - } else { - // 尝试Factory4 - Windows 10初始版本 - hr = dxgi_adapter->GetParent(__uuidof(IDXGIFactory4), reinterpret_cast(&dxgi_factory)); - if (SUCCEEDED(hr)) { - std::println(std::cout, "mirage: 使用 DXGI Factory4"); - } else { - // 尝试Factory3 - Windows 8.1 - hr = dxgi_adapter->GetParent(__uuidof(IDXGIFactory3), reinterpret_cast(&dxgi_factory)); - if (SUCCEEDED(hr)) { - std::println(std::cout, "mirage: 使用 DXGI Factory3"); - } else { - // 尝试Factory2 - Windows 8,支持FLIP模式交换链 - hr = dxgi_adapter->GetParent(__uuidof(IDXGIFactory2), reinterpret_cast(&dxgi_factory)); - if (SUCCEEDED(hr)) { - std::println(std::cout, "mirage: 使用 DXGI Factory2"); - } else { - // 回退到基本Factory1 - Windows 7 - hr = dxgi_adapter->GetParent(__uuidof(IDXGIFactory1), reinterpret_cast(&dxgi_factory)); - if (SUCCEEDED(hr)) { - std::println(std::cout, "mirage: 使用 DXGI Factory1"); - } else { - // 最后尝试原始Factory - hr = dxgi_adapter->GetParent(__uuidof(IDXGIFactory), reinterpret_cast(&dxgi_factory)); - if (SUCCEEDED(hr)) { - std::println(std::cout, "mirage: 使用 DXGI Factory"); - } else { - std::println(std::cerr, "mirage: 无法获取 DXGI Factory. HRESULT: 0x{:#06x}", hr); - dxgi_adapter->Release(); - cleanup(); - return false; - } - } - } - } - } - } - } + struct dxgi_factory_func_data { + IID iid{}; + std::string name; + }; +#define DXGI_FUNC_DATA(dxgi_class) dxgi_factory_func_data{ __uuidof(dxgi_class), #dxgi_class } + const std::array func_datas = { + // **尝试获取最新的DXGI工厂版本 - 从最新的Factory6开始尝试** + // Windows 10 Fall Creators Update (1709)或更高版本支持 + DXGI_FUNC_DATA(IDXGIFactory6), + // 尝试Factory5 - Windows 10 Anniversary Update (1607)或更高版本 + DXGI_FUNC_DATA(IDXGIFactory5), + // 尝试Factory4 - Windows 10初始版本 + DXGI_FUNC_DATA(IDXGIFactory4), + // 尝试Factory3 - Windows 8.1 + DXGI_FUNC_DATA(IDXGIFactory3), + // 尝试Factory2 - Windows 8,支持FLIP模式交换链 + DXGI_FUNC_DATA(IDXGIFactory2), + // 回退到基本Factory1 - Windows 7 + DXGI_FUNC_DATA(IDXGIFactory1), + // 最后尝试原始Factory + DXGI_FUNC_DATA(IDXGIFactory), + }; +#undef DXGI_FUNC_DATA - // **检查是否支持撕裂(tearing)功能** - BOOL allow_tearing = FALSE; - // IDXGIFactory5及以上版本支持CheckFeatureSupport - IDXGIFactory5* factory5 = nullptr; - if (SUCCEEDED(dxgi_factory->QueryInterface(__uuidof(IDXGIFactory5), (void**)&factory5))) { - if (SUCCEEDED(factory5->CheckFeatureSupport( - DXGI_FEATURE_PRESENT_ALLOW_TEARING, - &allow_tearing, - sizeof(allow_tearing)))) { - std::println(std::cout, "mirage: 防撕裂支持: {}", (bool)allow_tearing); - } - factory5->Release(); - } - tearing_supported = allow_tearing == TRUE; + // **获取DXGI工厂** + for (const auto& data: func_datas) { + hr = dxgi_adapter->GetParent(data.iid, reinterpret_cast(&dxgi_factory)); + if (SUCCEEDED(hr)) { + std::println(std::cout, "mirage: 使用 {}", data.name); + break; + } + } + if (FAILED(hr)) { + std::println(std::cerr, "mirage: 无法获取 DXGI Factory. HRESULT: 0x{:#06x}", hr); + dxgi_adapter->Release(); + cleanup(); + return false; + } - dxgi_adapter->Release(); + // **检查是否支持撕裂(tearing)功能** + BOOL allow_tearing = FALSE; + // IDXGIFactory5及以上版本支持CheckFeatureSupport + IDXGIFactory5* factory5 = nullptr; + if (SUCCEEDED(dxgi_factory->QueryInterface(__uuidof(IDXGIFactory5), (void**)&factory5))) { + if (SUCCEEDED(factory5->CheckFeatureSupport( + DXGI_FEATURE_PRESENT_ALLOW_TEARING, + &allow_tearing, + sizeof(allow_tearing)))) { std::println(std::cout, "mirage: 防撕裂支持: {}", (bool) allow_tearing); } + factory5->Release(); + } + tearing_supported = allow_tearing == TRUE; + + dxgi_adapter->Release(); - // 输出初始化成功信息 - std::println(std::cout, "mirage: 成功创建 D3D11 设备"); - { - std::u16string adapter_desc_str((const char16_t*)adapter_desc.Description); - auto str = utf8::utf16to8(adapter_desc_str); - std::println(std::cout, "mirage: 适配器名称: {}", str); - } - std::println(std::cout, "mirage: 适配器 VRAM: {} MB", adapter_desc.DedicatedVideoMemory / 1024 / 1024); + // 输出初始化成功信息 + std::println(std::cout, "mirage: 成功创建 D3D11 设备"); + { + const std::u16string adapter_desc_str(reinterpret_cast(adapter_desc.Description)); + auto str = utf8::utf16to8(adapter_desc_str); + std::println(std::cout, "mirage: 适配器名称: {}", str); + } + std::println(std::cout, "mirage: 适配器 VRAM: {} MB", adapter_desc.DedicatedVideoMemory / 1024 / 1024); - // 输出驱动类型信息 - auto driver_type_str = "Unknown"; - switch (used_driver_type) { - case D3D_DRIVER_TYPE_HARDWARE: driver_type_str = "Hardware"; - break; - case D3D_DRIVER_TYPE_WARP: driver_type_str = "WARP"; - break; - case D3D_DRIVER_TYPE_REFERENCE: driver_type_str = "Reference"; - break; - default: ; - } - std::println(std::cout, "mirage: 使用驱动类型: {}", driver_type_str); + // 输出驱动类型信息 + auto driver_type_str = "Unknown"; + switch (used_driver_type) { + case D3D_DRIVER_TYPE_HARDWARE: + driver_type_str = "Hardware"; + break; + case D3D_DRIVER_TYPE_WARP: + driver_type_str = "WARP"; + break; + case D3D_DRIVER_TYPE_REFERENCE: + driver_type_str = "Reference"; + break; + default: ; + } + std::println(std::cout, "mirage: 使用驱动类型: {}", driver_type_str); - // 输出特性级别信息 - auto feature_level_str = "Unknown"; - switch (feature_level) { - case D3D_FEATURE_LEVEL_11_1: feature_level_str = "11.1"; - break; - case D3D_FEATURE_LEVEL_11_0: feature_level_str = "11.0"; - break; - case D3D_FEATURE_LEVEL_10_1: feature_level_str = "10.1"; - break; - case D3D_FEATURE_LEVEL_10_0: feature_level_str = "10.0"; - break; - default: ; - } - std::println(std::cout, "mirage: 使用特性级别: {}", feature_level_str); + // 输出特性级别信息 + auto feature_level_str = "Unknown"; + switch (feature_level) { + case D3D_FEATURE_LEVEL_11_1: + feature_level_str = "11.1"; + break; + case D3D_FEATURE_LEVEL_11_0: + feature_level_str = "11.0"; + break; + case D3D_FEATURE_LEVEL_10_1: + feature_level_str = "10.1"; + break; + case D3D_FEATURE_LEVEL_10_0: + feature_level_str = "10.0"; + break; + default: ; + } + std::println(std::cout, "mirage: 使用特性级别: {}", feature_level_str); - return true; - } catch (const std::exception& e) { - std::println(std::cerr, "mirage: D3D11初始化失败: {}", e.what()); - cleanup(); - return false; - } + return true; + } + catch (const std::exception& e) { + std::println(std::cerr, "mirage: D3D11初始化失败: {}", e.what()); + cleanup(); + return false; + } } // 资源清理函数 @@ -224,19 +228,16 @@ void windows_mirage_render_context::cleanup() { } sg_environment windows_mirage_render_context::get_environment() { - return { - .d3d11 = { - .device = device, - .device_context = device_context - } - }; + sg_environment env{}; + env.d3d11.device = device; + env.d3d11.device_context = device_context; + return env; } -std::unique_ptr windows_mirage_render_context::create_window_state(const Eigen::Vector2i& in_window_frame_size, void* in_window_handle) { +std::unique_ptr windows_mirage_render_context::create_window_state( + const Eigen::Vector2i& in_window_frame_size, void* in_window_handle) { auto state = std::make_unique(); - if (!state->init(device, dxgi_factory, in_window_frame_size, in_window_handle)) { - return {}; - } + if (!state->init(device, dxgi_factory, in_window_frame_size, in_window_handle)) { return {}; } return state; } diff --git a/src/mirage_widget/src/widget/compound_widget/mbutton.cpp b/src/mirage_widget/src/widget/compound_widget/mbutton.cpp index 6ab8716..c52d10f 100644 --- a/src/mirage_widget/src/widget/compound_widget/mbutton.cpp +++ b/src/mirage_widget/src/widget/compound_widget/mbutton.cpp @@ -40,7 +40,7 @@ void mbutton::on_paint(mirage_paint_context& in_context) { void mbutton::on_click(const Eigen::Vector2f& in_position, mouse_button in_button) { mborder::on_click(in_position, in_button); std::println(std::cout, "点击 Button: {}, {}", in_position.x(), in_position.y()); - color_ = normal_color_; + color_ = hover_color_; invalidate(invalidate_reason::paint); } @@ -75,7 +75,7 @@ hit_test_handle mbutton::on_mouse_button_down(const Eigen::Vector2f& in_position hit_test_handle mbutton::on_mouse_button_up(const Eigen::Vector2f& in_position, mouse_button in_button) { mborder::on_mouse_button_up(in_position, in_button); std::println(std::cout, "鼠标释放 Button: {}, {}", in_position.x(), in_position.y()); - color_ = normal_color_; + color_ = hover_color_; invalidate(invalidate_reason::paint); return hit_test_handle::handled(); } diff --git a/src/mirage_widget/src/widget/compound_widget/mbutton.h b/src/mirage_widget/src/widget/compound_widget/mbutton.h index 30caf1d..4c9a6bd 100644 --- a/src/mirage_widget/src/widget/compound_widget/mbutton.h +++ b/src/mirage_widget/src/widget/compound_widget/mbutton.h @@ -4,23 +4,23 @@ struct button_args { WARG(linear_color, normal_color, linear_color(0.2f, 0.2f, 0.2f, 1)) WARG(linear_color, hover_color, linear_color(0.1f, 0.1f, 0.1f, 1)) - WARG(linear_color, pressed_color, linear_color(0.1f, 0.1f, 0.1f, 1)) + WARG(linear_color, pressed_color, linear_color(0.05f, 0.05f, 0.05f, 1)) }; class mbutton : public mborder { public: mbutton(); - virtual void init() override; + void init() override; void setup_widget(const button_args& in_args) override; - virtual void on_paint(mirage_paint_context& in_context) override; + void on_paint(mirage_paint_context& in_context) override; - virtual void on_click(const Eigen::Vector2f& in_position, mouse_button in_button) override; - virtual void on_double_click(const Eigen::Vector2f& in_position, mouse_button in_button) override; + void on_click(const Eigen::Vector2f& in_position, mouse_button in_button) override; + void on_double_click(const Eigen::Vector2f& in_position, mouse_button in_button) override; hit_test_handle on_mouse_move(const Eigen::Vector2f& in_position) override { return hit_test_handle::handled(); } - virtual void on_mouse_enter() override; - virtual void on_mouse_leave() override; - virtual hit_test_handle on_mouse_button_down(const Eigen::Vector2f& in_position, mouse_button in_button) override; - virtual hit_test_handle on_mouse_button_up(const Eigen::Vector2f& in_position, mouse_button in_button) override; + void on_mouse_enter() override; + void on_mouse_leave() override; + hit_test_handle on_mouse_button_down(const Eigen::Vector2f& in_position, mouse_button in_button) override; + hit_test_handle on_mouse_button_up(const Eigen::Vector2f& in_position, mouse_button in_button) override; private: linear_color normal_color_; linear_color hover_color_; diff --git a/src/mirage_widget/src/widget/mwidget.h b/src/mirage_widget/src/widget/mwidget.h index f166d2c..f176ced 100644 --- a/src/mirage_widget/src/widget/mwidget.h +++ b/src/mirage_widget/src/widget/mwidget.h @@ -150,4 +150,4 @@ public: auto& name(const type* in_value) { \ name##_ = *in_value; \ return *this; \ - } \ + } diff --git a/src/mirage_widget/src/widget/slot_util.h b/src/mirage_widget/src/widget/slot_util.h index b9cb8b9..4b88240 100644 --- a/src/mirage_widget/src/widget/slot_util.h +++ b/src/mirage_widget/src/widget/slot_util.h @@ -22,7 +22,7 @@ const auto& name() const { return name##_.value(); } \ auto has_##name() const { return name##_.has_value(); } \ protected: \ - std::optional name##_; \ + std::optional name##_; #define SLOT_CONTENT() \ public: \ @@ -56,4 +56,4 @@ return size_; \ } \ protected: \ - widget_size size_ = widget_size::auto_size(); \ No newline at end of file + widget_size size_ = widget_size::auto_size();