From c3d54d419499eba2dfed1664611925964f6f9193 Mon Sep 17 00:00:00 2001 From: kindem Date: Thu, 12 Feb 2026 18:48:27 +0800 Subject: [PATCH 1/3] feat: project hub dir selector --- Editor/Include/Editor/Widget/ProjectHub.h | 1 + Editor/Src/Widget/ProjectHub.cpp | 7 +++++++ Editor/Web/src/pages/project-hub.tsx | 13 ++++++++----- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/Editor/Include/Editor/Widget/ProjectHub.h b/Editor/Include/Editor/Widget/ProjectHub.h index 4d49d39c..0d864f0a 100644 --- a/Editor/Include/Editor/Widget/ProjectHub.h +++ b/Editor/Include/Editor/Widget/ProjectHub.h @@ -38,6 +38,7 @@ namespace Editor { public Q_SLOTS: void CreateProject() const; + QString BrowseDirectory() const; private: QString GetEngineVersion() const; diff --git a/Editor/Src/Widget/ProjectHub.cpp b/Editor/Src/Widget/ProjectHub.cpp index 71aad411..b081d4f4 100644 --- a/Editor/Src/Widget/ProjectHub.cpp +++ b/Editor/Src/Widget/ProjectHub.cpp @@ -2,6 +2,8 @@ // Created by johnk on 2025/8/3. // +#include + #include #include #include @@ -41,6 +43,11 @@ namespace Editor { LogInfo(ProjectHub, "ProjectHubBridge::CreateProject"); } + QString ProjectHubBackend::BrowseDirectory() const // NOLINT + { + return QFileDialog::getExistingDirectory(nullptr, "Select Project Directory", QDir::rootPath()); + } + QString ProjectHubBackend::GetEngineVersion() const { return QString::fromStdString(engineVersion); diff --git a/Editor/Web/src/pages/project-hub.tsx b/Editor/Web/src/pages/project-hub.tsx index 14d4e383..2dae091c 100644 --- a/Editor/Web/src/pages/project-hub.tsx +++ b/Editor/Web/src/pages/project-hub.tsx @@ -25,6 +25,7 @@ export default function ProjectHubPage() { const [engineVersion, setEngineVersion] = useState(''); const [recentProjects, setRecentProjects] = useState(Array); const [projectTemplates, setProjectTemplates] = useState(Array); + const [projectPath, setProjectPath] = useState(''); useEffect(() => { new QWebChannel(window.qt.webChannelTransport, (channel: QWebChannel): void => { @@ -47,10 +48,12 @@ export default function ProjectHubPage() { console.error('onOpenProject:', index); } - async function onBrowseProjectPath(): Promise { - // TODO - const dirHandle = await window.showDirectoryPicker({ startIn: 'desktop' }); - console.error(dirHandle); + function onBrowseProjectPath(): void { + window.backend.BrowseDirectory((path: string) => { + if (path) { + setProjectPath(path); + } + }); } return ( @@ -91,7 +94,7 @@ export default function ProjectHubPage() {
- + From 87909ad4f4e1425007b4e4a483d5070a1987acab Mon Sep 17 00:00:00 2001 From: kindem Date: Thu, 12 Feb 2026 18:48:48 +0800 Subject: [PATCH 2/3] fix: some bugs in qt json serializer --- Editor/Include/Editor/Qt/JsonSerialization.h | 29 ++++++++------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/Editor/Include/Editor/Qt/JsonSerialization.h b/Editor/Include/Editor/Qt/JsonSerialization.h index e72f2020..a8e296a2 100644 --- a/Editor/Include/Editor/Qt/JsonSerialization.h +++ b/Editor/Include/Editor/Qt/JsonSerialization.h @@ -24,9 +24,6 @@ #include #include -// TODO -#pragma optimize("", off) - namespace Editor { template struct QtJsonSerializer {}; template concept QtJsonSerializable = requires( @@ -320,7 +317,7 @@ namespace Editor { } if (jsonObject.contains("value")) { const QJsonValue jsonValue = jsonObject["value"]; - QtJsonSerializer::QtJsonDeserialize(jsonValue, outValue.second); + QtJsonSerializer::QtJsonDeserialize(jsonValue, outValue.second); } } }; @@ -378,7 +375,7 @@ namespace Editor { for (const auto& jsonElement : jsonArray) { T element; QtJsonSerializer::QtJsonDeserialize(jsonElement, element); - outValue.emplaceback(std::move(element)); + outValue.emplace_back(std::move(element)); } } }; @@ -404,7 +401,6 @@ namespace Editor { const QJsonArray jsonArray = inJsonValue.toArray(); outValue.clear(); - outValue.reserve(jsonArray.size()); for (const auto& jsonElement : jsonArray) { T element; QtJsonSerializer::QtJsonDeserialize(jsonElement, element); @@ -464,7 +460,6 @@ namespace Editor { const QJsonArray jsonArray = inJsonValue.toArray(); outValue.clear(); - outValue.reserve(jsonArray.size()); for (const auto& jsonElement : jsonArray) { T element; QtJsonSerializer::QtJsonDeserialize(jsonElement, element); @@ -497,7 +492,7 @@ namespace Editor { outValue.reserve(jsonArray.size()); for (const auto& jsonPair : jsonArray) { std::pair pair; - QtJsonSerializer>::QtJsonSerialize(jsonPair, pair); + QtJsonSerializer>::QtJsonDeserialize(jsonPair, pair); outValue.emplace(std::move(pair)); } } @@ -524,10 +519,9 @@ namespace Editor { const QJsonArray jsonArray = inJsonValue.toArray(); outValue.clear(); - outValue.reserve(jsonArray.size()); for (const auto& jsonPair : jsonArray) { std::pair pair; - QtJsonSerializer>::QtJsonSerialize(jsonPair, pair); + QtJsonSerializer>::QtJsonDeserialize(jsonPair, pair); outValue.emplace(std::move(pair)); } } @@ -553,7 +547,7 @@ namespace Editor { { (void) std::initializer_list { ([&]() -> void { const auto key = std::to_string(I); - const QJsonValue jsonValue = inJsonObject[key]; + const QJsonValue jsonValue = inJsonObject[QString::fromStdString(key)]; if (jsonValue.isNull()) { return; } @@ -623,7 +617,7 @@ namespace Editor { const QJsonValue jsonType = jsonObject["type"]; const QJsonValue jsonContent = jsonObject["content"]; - uint64_t aspectIndex; + uint64_t aspectIndex = 0; QtJsonSerializer::QtJsonDeserialize(jsonType, aspectIndex); QtJsonDeserializeInternal(jsonContent, outValue, aspectIndex, std::make_index_sequence {}); } @@ -652,8 +646,7 @@ namespace Editor { return; } for (auto i = 0; i < L; i++) { - QJsonValue jsonElement; - QtJsonSerializer::QtJsonDeserialize(jsonElement, jsonArray[i]); + QtJsonSerializer::QtJsonDeserialize(jsonArray[i], outValue[i]); } } }; @@ -903,7 +896,7 @@ namespace Editor { for (const auto& jsonElement : jsonArray) { T element; QtJsonSerializer::QtJsonDeserialize(jsonElement, element); - outValue.emplaceBack(std::move(element)); + outValue.insert(std::move(element)); } } }; @@ -1124,7 +1117,7 @@ namespace Editor { QJsonObject jsonObject; jsonObject["key"] = jsonKey; jsonObject["value"] = jsonValue; - outJsonValue = std::move(jsonValue); + outJsonValue = std::move(jsonObject); } static void DeserializeDynWithView(const QJsonValue& inJsonValue, const Mirror::StdPairView& inView) @@ -1404,14 +1397,14 @@ namespace Editor { return; } const QJsonObject jsonObject = inJsonValue.toObject(); - if (!jsonObject.contains("type") || jsonObject.contains("content")) { + if (!jsonObject.contains("type") || !jsonObject.contains("content")) { return; } const QJsonValue typeJson = jsonObject["type"]; const QJsonValue contentJson = jsonObject["content"]; - uint64_t type; + uint64_t type = 0; QtJsonSerializer::QtJsonDeserialize(typeJson, type); Mirror::Any tempObj = inView.CreateElement(type); From 4335f2970ec7f9af78125410a7c8d53ff2eeb2c8 Mon Sep 17 00:00:00 2001 From: kindem Date: Thu, 12 Feb 2026 18:49:09 +0800 Subject: [PATCH 3/3] refactor: modern cmake fix --- CMake/Common.cmake | 31 +++++++++-------- CMake/Target.cmake | 79 +++++++++---------------------------------- CMakeLists.txt | 2 +- Editor/CMakeLists.txt | 14 +++----- Sample/CMakeLists.txt | 1 - 5 files changed, 38 insertions(+), 89 deletions(-) diff --git a/CMake/Common.cmake b/CMake/Common.cmake index 4f51cf89..c2e33c98 100644 --- a/CMake/Common.cmake +++ b/CMake/Common.cmake @@ -2,27 +2,30 @@ option(USE_UNITY_BUILD "Use unity build" ON) option(EXPORT_COMPILE_COMMANDS "Whether to export all compile commands" OFF) set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_UNITY_BUILD ${USE_UNITY_BUILD}) set(CMAKE_EXPORT_COMPILE_COMMANDS ${EXPORT_COMPILE_COMMANDS}) -get_cmake_property(generator_is_multi_config GENERATOR_IS_MULTI_CONFIG) if (${CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT}) set(CMAKE_INSTALL_PREFIX ${CMAKE_SOURCE_DIR}/Installed CACHE PATH "" FORCE) endif() -add_definitions(-DBUILD_CONFIG_DEBUG=$,$>,1,0>) - -add_definitions(-DPLATFORM_WINDOWS=$,1,0>) -add_definitions(-DPLATFORM_LINUX=$,1,0>) -add_definitions(-DPLATFORM_MACOS=$,1,0>) - -add_definitions(-DCOMPILER_MSVC=$,1,0>) -add_definitions(-DCOMPILER_APPLE_CLANG=$,1,0>) -add_definitions(-DCOMPILER_GCC=$,1,0>) +add_compile_definitions( + BUILD_CONFIG_DEBUG=$,$>,1,0> + PLATFORM_WINDOWS=$,1,0> + PLATFORM_LINUX=$,1,0> + PLATFORM_MACOS=$,1,0> + COMPILER_MSVC=$,1,0> + COMPILER_APPLE_CLANG=$,1,0> + COMPILER_GCC=$,1,0> +) if (${MSVC}) - add_compile_options(/bigobj /MD) - add_definitions(-D_SILENCE_ALL_MS_EXT_DEPRECATION_WARNINGS=1) - add_definitions(-DWIN32_LEAN_AND_MEAN) - add_definitions(-DNOMINMAX=1) + set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreadedDLL") + add_compile_options(/bigobj) + add_compile_definitions( + _SILENCE_ALL_MS_EXT_DEPRECATION_WARNINGS=1 + WIN32_LEAN_AND_MEAN + NOMINMAX=1 + ) endif () diff --git a/CMake/Target.cmake b/CMake/Target.cmake index 10d879f0..4c469956 100644 --- a/CMake/Target.cmake +++ b/CMake/Target.cmake @@ -9,11 +9,13 @@ set(GENERATED_MIRROR_INFO_SRC_DIR ${GENERATED_DIR}/MirrorInfoSrc CACHE PATH "" F set(BASE_TARGETS_FOLDER "${SUB_PROJECT_NAME}" CACHE STRING "" FORCE) set(AUX_TARGETS_FOLDER "${BASE_TARGETS_FOLDER}/Aux" CACHE STRING "" FORCE) +get_cmake_property(with_multi_config_generator GENERATOR_IS_MULTI_CONFIG) + if (${BUILD_TEST}) enable_testing() - add_definitions(-DBUILD_TEST=1) + add_compile_definitions(BUILD_TEST=1) else() - add_definitions(-DBUILD_TEST=0) + add_compile_definitions(BUILD_TEST=0) endif() if ("${SUB_PROJECT_NAME}" STREQUAL "") @@ -107,7 +109,7 @@ function(exp_process_runtime_dependencies) endif () if (NOT ${arg_NOT_INSTALL} AND NOT "${runtime_deps}" STREQUAL "") install( - FILES ${runtime_deps} DESTINATION ${CMAKE_INSTALL_PREFIX}/${SUB_PROJECT_NAME}/Binaries + FILES ${runtime_deps} DESTINATION ${SUB_PROJECT_NAME}/Binaries ) endif () endfunction() @@ -141,8 +143,8 @@ function(exp_add_resources_copy_command) list(APPEND copy_commands COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src} $/${dst}) - get_filename_component(absolute_dst ${CMAKE_INSTALL_PREFIX}/${SUB_PROJECT_NAME}/Binaries/${dst} ABSOLUTE) - get_filename_component(dst_dir ${absolute_dst} DIRECTORY) + cmake_path(SET dst_path NORMALIZE "${SUB_PROJECT_NAME}/Binaries/${dst}") + cmake_path(GET dst_path PARENT_PATH dst_dir) if (NOT ${arg_NOT_INSTALL}) install(FILES ${src} DESTINATION ${dst_dir}) endif () @@ -166,6 +168,7 @@ function(exp_gather_target_libs) string(REGEX MATCH "\\$\\" match ${arg_NAME}) if (match) set(${arg_OUTPUT} "" PARENT_SCOPE) + return() endif () get_target_property(target_libs ${arg_NAME} LINK_LIBRARIES) @@ -309,8 +312,7 @@ function(exp_add_executable) set_target_properties(${arg_NAME} PROPERTIES FOLDER ${BASE_TARGETS_FOLDER}) endif () - get_cmake_property(generated_is_multi_config GENERATOR_IS_MULTI_CONFIG) - if (${generated_is_multi_config}) + if (${with_multi_config_generator}) set(runtime_output_dir ${CMAKE_BINARY_DIR}/Dist/$/${SUB_PROJECT_NAME}/Binaries) else () set(runtime_output_dir ${CMAKE_BINARY_DIR}/Dist/${SUB_PROJECT_NAME}/Binaries) @@ -411,8 +413,7 @@ function(exp_add_library) ${arg_NAME} PRIVATE ${arg_SRC} ${generated_src} ) - get_cmake_property(generator_is_multi_config GENERATOR_IS_MULTI_CONFIG) - if (${generator_is_multi_config}) + if (${with_multi_config_generator}) set(runtime_output_dir ${CMAKE_BINARY_DIR}/Targets/${SUB_PROJECT_NAME}/${arg_NAME}/$/Binaries) set(library_output_dir ${CMAKE_BINARY_DIR}/Targets/${SUB_PROJECT_NAME}/${arg_NAME}/$/Binaries) set(archive_output_directory ${CMAKE_BINARY_DIR}/Targets/${SUB_PROJECT_NAME}/${arg_NAME}/$/Lib) @@ -504,65 +505,17 @@ function(exp_add_test) set(multiValueArgs SRC INC LINK LIB DEP_TARGET RES REFLECT) cmake_parse_arguments(arg "${options}" "${singleValueArgs}" "${multiValueArgs}" ${ARGN}) - if (DEFINED arg_REFLECT) - exp_add_mirror_info_source_generation_target( - NAME ${arg_NAME} - OUTPUT_SRC generated_src - OUTPUT_TARGET_NAME generated_target - SEARCH_DIR ${arg_REFLECT} - PRIVATE_INC ${arg_INC} - LIB ${arg_LIB} - ) - endif() - - add_executable(${arg_NAME}) - set_target_properties(${arg_NAME} PROPERTIES FOLDER ${BASE_TARGETS_FOLDER}) - - target_sources( - ${arg_NAME} - PRIVATE ${arg_SRC} ${generated_src} - ) - get_cmake_property(generator_is_multi_config GENERATOR_IS_MULTI_CONFIG) - if (${generator_is_multi_config}) - set_target_properties( - ${arg_NAME} PROPERTIES - RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/Dist/$/${SUB_PROJECT_NAME}/Binaries - ) - else () - set_target_properties( - ${arg_NAME} PROPERTIES - RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/Dist/${SUB_PROJECT_NAME}/Binaries - ) - endif () - - target_include_directories( - ${arg_NAME} - PRIVATE ${arg_INC} - ) - target_link_directories( - ${arg_NAME} - PRIVATE ${arg_LINK} - ) - target_link_libraries( - ${arg_NAME} - PRIVATE Test ${arg_LIB} - ) - exp_process_runtime_dependencies( + exp_add_executable( NAME ${arg_NAME} + SRC ${arg_SRC} + INC ${arg_INC} + LINK ${arg_LINK} + LIB Test ${arg_LIB} DEP_TARGET ${arg_DEP_TARGET} - NOT_INSTALL - ) - exp_add_resources_copy_command( - NAME ${arg_NAME} RES ${arg_RES} + REFLECT ${arg_REFLECT} NOT_INSTALL ) - if (DEFINED arg_DEP_TARGET) - add_dependencies(${arg_NAME} ${arg_DEP_TARGET}) - endif() - if (DEFINED arg_REFLECT) - add_dependencies(${arg_NAME} ${generated_target}) - endif() add_test( NAME ${arg_NAME} diff --git a/CMakeLists.txt b/CMakeLists.txt index 6f3d1a80..e2d1bb8c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,7 +19,7 @@ set(CMAKE_MAP_IMPORTED_CONFIG_DEBUG "Release" CACHE STRING "" FORCE) set(CMAKE_MAP_IMPORTED_CONFIG_RELWITHDEBINFO "Release" CACHE STRING "" FORCE) set(CMAKE_MAP_IMPORTED_CONFIG_MINSIZEREL "Release" CACHE STRING "" FORCE) -add_definitions(-DBUILD_EDITOR=$) +add_compile_definitions(BUILD_EDITOR=$) include(CMake/Common.cmake) include(CMake/Target.cmake) diff --git a/Editor/CMakeLists.txt b/Editor/CMakeLists.txt index e2d13322..02d6c5e5 100644 --- a/Editor/CMakeLists.txt +++ b/Editor/CMakeLists.txt @@ -9,25 +9,19 @@ qt_standard_project_setup() if (${CMAKE_SYSTEM_NAME} STREQUAL "Darwin") set(platform_executable_hint MACOSX_BUNDLE) - set(bundle_install_dest BUNDLE DESTINATION ${CMAKE_INSTALL_PREFIX}/${SUB_PROJECT_NAME}/Binaries) + set(bundle_install_dest BUNDLE DESTINATION ${SUB_PROJECT_NAME}/Binaries) set(platform_fwk_dir ${QT_ROOT}/lib) endif () -set(editor_includes Include) set(editor_qt_libs Qt6::Core Qt6::Gui Qt6::Widgets Qt6::WebEngineWidgets) set(editor_libs Core RHI Runtime httplib::httplib ${editor_qt_libs}) -foreach (QT_LIB ${editor_qt_libs}) - string(REPLACE "::" "" QT_RAW_LIB ${QT_LIB}) - list(APPEND editor_includes ${${QT_RAW_LIB}_INCLUDE_DIRS}) -endforeach () - exp_add_mirror_info_source_generation_target( NAME Editor OUTPUT_SRC EDITOR_MIRROR_GENERATED_SRC OUTPUT_TARGET_NAME EDITOR_MIRROR_GENERATED_TARGET SEARCH_DIR Include - PRIVATE_INC ${editor_includes} + PRIVATE_INC Include LIB ${editor_libs} FRAMEWORK_DIR ${platform_fwk_dir} ) @@ -49,7 +43,7 @@ else () ) endif () -target_include_directories(Editor PRIVATE ${editor_includes}) +target_include_directories(Editor PRIVATE Include) target_link_libraries(Editor PRIVATE ${editor_libs}) if (${CMAKE_SYSTEM_NAME} STREQUAL "Windows") @@ -65,7 +59,7 @@ exp_process_runtime_dependencies( ) install( TARGETS Editor - RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/${SUB_PROJECT_NAME}/Binaries + RUNTIME DESTINATION ${SUB_PROJECT_NAME}/Binaries ${bundle_install_dest} ) export( diff --git a/Sample/CMakeLists.txt b/Sample/CMakeLists.txt index eb9fc4bb..601d90f8 100644 --- a/Sample/CMakeLists.txt +++ b/Sample/CMakeLists.txt @@ -41,7 +41,6 @@ function(add_sample) RES ${paths} NOT_INSTALL ) - add_dependencies(${arg_NAME} ${platform_dep_target}) endfunction() if (${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")