Checkpoint 2: integrate native Editor, MCP, gameplay builds and standalone export

This commit is contained in:
Emil
2026-09-18 03:40:15 +03:00
parent 5c6b24d34d
commit 999686a896
125 changed files with 16086 additions and 1714 deletions
+5 -1
View File
@@ -1,9 +1,13 @@
add_library(faset_asset_data STATIC ${PROJECT_SOURCE_DIR}/src/assets/asset_data.cpp)
target_compile_features(faset_asset_data PUBLIC cxx_std_20)
target_include_directories(faset_asset_data PUBLIC ${PROJECT_SOURCE_DIR}/include)
target_link_libraries(faset_asset_data PUBLIC faset_core nlohmann_json::nlohmann_json)
add_library(faset_assets
${PROJECT_SOURCE_DIR}/src/assets/asset_pipeline.cpp
${PROJECT_SOURCE_DIR}/src/assets/cgltf.cpp)
target_compile_features(faset_assets PUBLIC cxx_std_20)
target_include_directories(faset_assets PUBLIC ${PROJECT_SOURCE_DIR}/include)
target_link_libraries(faset_assets PUBLIC faset_core nlohmann_json::nlohmann_json PRIVATE faset_cgltf)
target_link_libraries(faset_assets PUBLIC faset_asset_data PRIVATE faset_cgltf faset_stb)
if(BUILD_TESTING)
add_executable(faset_assets_tests ${PROJECT_SOURCE_DIR}/tests/assets_pipeline.cpp)
target_link_libraries(faset_assets_tests PRIVATE faset_assets)
+1 -1
View File
@@ -1,4 +1,4 @@
add_library(faset_authoring STATIC src/authoring/schema.cpp src/authoring/service.cpp src/authoring/templates.cpp)
add_library(faset_authoring STATIC src/authoring/schema.cpp src/authoring/service.cpp src/authoring/templates.cpp src/authoring/transforms.cpp)
target_include_directories(faset_authoring PUBLIC "${PROJECT_SOURCE_DIR}/include")
target_link_libraries(faset_authoring PUBLIC faset_core)
if(BUILD_TESTING)
+10
View File
@@ -0,0 +1,10 @@
add_library(faset_build_service STATIC ${PROJECT_SOURCE_DIR}/src/editor/build_service.cpp)
target_include_directories(faset_build_service PUBLIC ${PROJECT_SOURCE_DIR}/include)
target_compile_features(faset_build_service PUBLIC cxx_std_20)
target_link_libraries(faset_build_service PUBLIC faset_core PRIVATE faset_asset_data Threads::Threads)
if(BUILD_TESTING)
add_executable(faset_build_service_tests ${PROJECT_SOURCE_DIR}/tests/build_service_tests.cpp)
target_link_libraries(faset_build_service_tests PRIVATE faset_build_service faset_assets)
target_compile_definitions(faset_build_service_tests PRIVATE FASET_ENGINE_SOURCE="${PROJECT_SOURCE_DIR}")
add_test(NAME process_and_cook COMMAND faset_build_service_tests)
endif()
+8
View File
@@ -0,0 +1,8 @@
add_library(faset_editor_commands STATIC src/editor/commands.cpp src/editor/mcp.cpp)
target_link_libraries(faset_editor_commands PUBLIC faset_authoring)
target_include_directories(faset_editor_commands PUBLIC include)
if(BUILD_TESTING)
add_executable(faset_mcp_tests tests/mcp_tests.cpp)
target_link_libraries(faset_mcp_tests PRIVATE faset_editor_commands)
add_test(NAME editor_mcp COMMAND faset_mcp_tests)
endif()
+15
View File
@@ -0,0 +1,15 @@
if(TARGET faset_ui AND TARGET faset_editor_session AND TARGET faset_scene_view)
add_library(faset_editor_ui STATIC ${PROJECT_SOURCE_DIR}/src/editor/editor_ui.cpp)
target_link_libraries(faset_editor_ui PUBLIC faset_ui faset_editor_session faset_scene_view)
if(BUILD_TESTING)
add_executable(faset_editor_ui_tests ${PROJECT_SOURCE_DIR}/tests/editor_ui_tests.cpp)
target_link_libraries(faset_editor_ui_tests PRIVATE faset_editor_ui)
target_compile_definitions(faset_editor_ui_tests PRIVATE FASET_TEST_ENGINE="${PROJECT_SOURCE_DIR}")
if(TARGET faset_example_plugin)
add_dependencies(faset_editor_ui_tests faset_example_plugin)
target_compile_definitions(faset_editor_ui_tests PRIVATE FASET_TEST_PLUGIN_DIRECTORY="${PROJECT_BINARY_DIR}/example-plugin")
endif()
add_test(NAME editor_ui_authoring COMMAND faset_editor_ui_tests)
set_tests_properties(editor_ui_authoring PROPERTIES LABELS "gpu")
endif()
endif()
+24
View File
@@ -0,0 +1,24 @@
if(TARGET faset_gameplay)
add_executable(faset_schema_exporter ${PROJECT_SOURCE_DIR}/apps/schema_exporter_main.cpp)
target_link_libraries(faset_schema_exporter PRIVATE faset_core faset_gameplay)
endif()
if(TARGET faset_runtime AND TARGET faset_render AND TARGET faset_assets)
add_library(faset_scene_view STATIC
${PROJECT_SOURCE_DIR}/src/player/SceneView.cpp
${PROJECT_SOURCE_DIR}/src/player/scene_io.cpp)
target_include_directories(faset_scene_view PUBLIC ${PROJECT_SOURCE_DIR}/include)
target_link_libraries(faset_scene_view PUBLIC faset_render faset_core PRIVATE faset_asset_data)
if(TARGET faset_stb)
target_link_libraries(faset_scene_view PRIVATE faset_stb)
target_compile_definitions(faset_scene_view PRIVATE FASET_HAS_STB=1)
endif()
add_executable(faset_player ${PROJECT_SOURCE_DIR}/apps/player_main.cpp)
target_link_libraries(faset_player PRIVATE faset_scene_view faset_runtime faset_gameplay)
install(TARGETS faset_player RUNTIME DESTINATION .)
if(BUILD_TESTING)
add_executable(faset_player_tests ${PROJECT_SOURCE_DIR}/tests/runtime_player_tests.cpp)
target_link_libraries(faset_player_tests PRIVATE faset_scene_view faset_runtime faset_assets)
add_test(NAME player_scene_contracts COMMAND faset_player_tests)
endif()
endif()
+33
View File
@@ -0,0 +1,33 @@
# Native plugins deliberately require the exact SDK, compiler, CRT and build.
file(GLOB_RECURSE FASET_SDK_INPUTS CONFIGURE_DEPENDS
"${PROJECT_SOURCE_DIR}/include/faset/*.hpp"
"${PROJECT_SOURCE_DIR}/include/faset/*.h"
"${PROJECT_SOURCE_DIR}/src/editor/*.cpp"
"${PROJECT_SOURCE_DIR}/src/authoring/*.cpp")
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${FASET_SDK_INPUTS} "${PROJECT_SOURCE_DIR}/dependencies.lock.json")
set(FASET_SDK_SIGNATURE "${PROJECT_VERSION};${CMAKE_SYSTEM_NAME};${CMAKE_SYSTEM_PROCESSOR};${CMAKE_SIZEOF_VOID_P};${CMAKE_CXX_COMPILER_ID};${CMAKE_CXX_COMPILER_VERSION};${CMAKE_CXX_COMPILER_FRONTEND_VARIANT};${CMAKE_MSVC_RUNTIME_LIBRARY};${CMAKE_BUILD_TYPE};${CMAKE_CXX_FLAGS};${FASET_SANITIZERS}")
foreach(source IN LISTS FASET_SDK_INPUTS)
file(SHA256 "${source}" source_hash)
string(APPEND FASET_SDK_SIGNATURE ";${source_hash}")
endforeach()
file(SHA256 "${PROJECT_SOURCE_DIR}/dependencies.lock.json" dependency_hash)
string(SHA256 FASET_EDITOR_SDK_FINGERPRINT "${FASET_SDK_SIGNATURE};${dependency_hash}")
file(MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/generated/faset/editor")
file(WRITE "${PROJECT_BINARY_DIR}/generated/faset/editor/sdk_build.h"
"#pragma once\n#define FASET_EDITOR_SDK_FINGERPRINT \"${FASET_EDITOR_SDK_FINGERPRINT}\"\n")
add_library(faset_editor_sdk INTERFACE)
target_include_directories(faset_editor_sdk INTERFACE "${PROJECT_SOURCE_DIR}/include" "${PROJECT_BINARY_DIR}/generated")
add_library(faset_editor_plugins STATIC src/editor/plugins.cpp)
target_link_libraries(faset_editor_plugins PUBLIC faset_editor_commands faset_editor_sdk PRIVATE ${CMAKE_DL_LIBS})
add_library(faset_example_plugin MODULE examples/extensions/beacon/Editor.cpp)
target_link_libraries(faset_example_plugin PRIVATE faset_editor_sdk nlohmann_json::nlohmann_json)
set_target_properties(faset_example_plugin PROPERTIES PREFIX "" LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/example-plugin" RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/example-plugin")
file(GENERATE OUTPUT "${PROJECT_BINARY_DIR}/example-plugin/beacon.faset-plugin.json" CONTENT
"{\n \"format\":\"faset.editor_plugin\",\n \"version\":1,\n \"id\":\"example.beacon\",\n \"module_version\":\"1.0.0\",\n \"kind\":\"editor\",\n \"api_version\":1,\n \"build_fingerprint\":\"${FASET_EDITOR_SDK_FINGERPRINT}\",\n \"library\":\"$<TARGET_FILE_NAME:faset_example_plugin>\",\n \"dependencies\":[]\n}\n")
if(BUILD_TESTING)
add_executable(faset_plugin_tests tests/plugin_tests.cpp)
target_link_libraries(faset_plugin_tests PRIVATE faset_editor_plugins faset_runtime)
target_compile_definitions(faset_plugin_tests PRIVATE FASET_TEST_PLUGIN_DIRECTORY="${PROJECT_BINARY_DIR}/example-plugin")
add_dependencies(faset_plugin_tests faset_example_plugin)
add_test(NAME editor_plugins COMMAND faset_plugin_tests)
endif()
+14 -3
View File
@@ -6,13 +6,24 @@ target_compile_features(faset_runtime PUBLIC cxx_std_20)
target_include_directories(faset_runtime PUBLIC ${CMAKE_CURRENT_LIST_DIR}/../include)
target_link_libraries(faset_runtime PUBLIC nlohmann_json::nlohmann_json PRIVATE EnTT::EnTT box2d box3d)
add_library(faset_gameplay STATIC ${CMAKE_CURRENT_LIST_DIR}/../examples/gameplay/Gameplay.cpp)
set(FASET_GAMEPLAY_SOURCE_DIR "${PROJECT_SOURCE_DIR}/examples/gameplay" CACHE PATH "Directory containing the game's Gameplay.cpp and Gameplay.hpp")
if(NOT EXISTS "${FASET_GAMEPLAY_SOURCE_DIR}/Gameplay.cpp" OR NOT EXISTS "${FASET_GAMEPLAY_SOURCE_DIR}/Gameplay.hpp")
message(FATAL_ERROR "FASET_GAMEPLAY_SOURCE_DIR must contain Gameplay.cpp and Gameplay.hpp")
endif()
add_library(faset_gameplay STATIC "${FASET_GAMEPLAY_SOURCE_DIR}/Gameplay.cpp")
add_library(Faset::Gameplay ALIAS faset_gameplay)
target_include_directories(faset_gameplay PUBLIC ${CMAKE_CURRENT_LIST_DIR}/../examples/gameplay)
target_include_directories(faset_gameplay PUBLIC "${FASET_GAMEPLAY_SOURCE_DIR}")
target_link_libraries(faset_gameplay PUBLIC faset_runtime)
if(BUILD_TESTING)
add_executable(faset_runtime_tests ${CMAKE_CURRENT_LIST_DIR}/../tests/runtime_tests.cpp)
target_link_libraries(faset_runtime_tests PRIVATE faset_runtime faset_gameplay)
if(FASET_GAMEPLAY_SOURCE_DIR STREQUAL "${PROJECT_SOURCE_DIR}/examples/gameplay")
target_link_libraries(faset_runtime_tests PRIVATE faset_runtime faset_gameplay)
else()
add_library(faset_gameplay_test_fixture STATIC ${CMAKE_CURRENT_LIST_DIR}/../examples/gameplay/Gameplay.cpp)
target_include_directories(faset_gameplay_test_fixture PUBLIC ${CMAKE_CURRENT_LIST_DIR}/../examples/gameplay)
target_link_libraries(faset_gameplay_test_fixture PUBLIC faset_runtime)
target_link_libraries(faset_runtime_tests PRIVATE faset_runtime faset_gameplay_test_fixture)
endif()
add_test(NAME runtime_contracts COMMAND faset_runtime_tests)
endif()
+14
View File
@@ -0,0 +1,14 @@
if(BUILD_TESTING AND TARGET faset_runtime)
foreach(tutorial moving following spawning physics)
set(tutorial_dir "${PROJECT_SOURCE_DIR}/examples/tutorials/${tutorial}")
add_library(faset_tutorial_${tutorial} STATIC "${tutorial_dir}/Gameplay.cpp")
target_include_directories(faset_tutorial_${tutorial} PUBLIC "${tutorial_dir}")
target_link_libraries(faset_tutorial_${tutorial} PUBLIC faset_runtime)
add_executable(faset_tutorial_${tutorial}_tests "${PROJECT_SOURCE_DIR}/tests/runtime_tutorials.cpp")
target_link_libraries(faset_tutorial_${tutorial}_tests PRIVATE faset_tutorial_${tutorial})
target_compile_definitions(faset_tutorial_${tutorial}_tests PRIVATE
FASET_TUTORIAL_NAME="${tutorial}"
FASET_TUTORIAL_SCENE="${tutorial_dir}/scene.json")
add_test(NAME tutorial_${tutorial} COMMAND faset_tutorial_${tutorial}_tests)
endforeach()
endif()
+59
View File
@@ -0,0 +1,59 @@
# FreeType rasterization + HarfBuzz shaping. The default uses verified pinned archives.
option(FASET_USE_SYSTEM_TEXT_LIBRARIES "Use system FreeType/HarfBuzz instead of pinned SDK versions" OFF)
if(FASET_USE_SYSTEM_TEXT_LIBRARIES)
find_package(Freetype QUIET)
endif()
if(NOT TARGET Freetype::Freetype)
include(FetchContent)
set(FT_DISABLE_ZLIB ON CACHE BOOL "" FORCE)
set(FT_DISABLE_BZIP2 ON CACHE BOOL "" FORCE)
set(FT_DISABLE_PNG ON CACHE BOOL "" FORCE)
set(FT_DISABLE_BROTLI ON CACHE BOOL "" FORCE)
set(FT_DISABLE_HARFBUZZ ON CACHE BOOL "" FORCE)
faset_dependency(freetype)
if(NOT TARGET Freetype::Freetype)
add_library(Freetype::Freetype ALIAS freetype)
endif()
endif()
if(FASET_USE_SYSTEM_TEXT_LIBRARIES)
find_package(harfbuzz CONFIG QUIET)
endif()
if(TARGET harfbuzz::harfbuzz)
set(FASET_HARFBUZZ_TARGET harfbuzz::harfbuzz)
else()
find_package(PkgConfig QUIET)
if(PkgConfig_FOUND AND FASET_USE_SYSTEM_TEXT_LIBRARIES)
pkg_check_modules(FASET_HARFBUZZ QUIET IMPORTED_TARGET harfbuzz)
endif()
if(TARGET PkgConfig::FASET_HARFBUZZ)
set(FASET_HARFBUZZ_TARGET PkgConfig::FASET_HARFBUZZ)
else()
include(FetchContent)
set(HB_HAVE_FREETYPE ON CACHE BOOL "" FORCE)
set(HB_BUILD_UTILS OFF CACHE BOOL "" FORCE)
set(HB_BUILD_SUBSET OFF CACHE BOOL "" FORCE)
faset_dependency(harfbuzz)
set(FASET_HARFBUZZ_TARGET harfbuzz)
endif()
endif()
add_library(faset_ui
${PROJECT_SOURCE_DIR}/src/ui/ui.cpp
${PROJECT_SOURCE_DIR}/src/ui/text.cpp
${PROJECT_SOURCE_DIR}/src/ui/font.cpp)
target_compile_features(faset_ui PUBLIC cxx_std_20)
target_include_directories(faset_ui PUBLIC ${PROJECT_SOURCE_DIR}/include)
target_link_libraries(faset_ui PUBLIC faset_core PRIVATE Freetype::Freetype ${FASET_HARFBUZZ_TARGET})
if(BUILD_TESTING)
add_executable(faset_ui_tests ${PROJECT_SOURCE_DIR}/tests/ui_tests.cpp)
target_link_libraries(faset_ui_tests PRIVATE faset_ui)
target_compile_definitions(faset_ui_tests PRIVATE FASET_TEST_FONT="${PROJECT_SOURCE_DIR}/assets/fonts/NotoSans.ttf")
add_test(NAME ui_widgets COMMAND faset_ui_tests)
if(TARGET faset_render)
add_executable(faset_ui_render_test ${PROJECT_SOURCE_DIR}/tests/ui_render_test.cpp)
target_link_libraries(faset_ui_render_test PRIVATE faset_ui faset_render)
target_compile_definitions(faset_ui_render_test PRIVATE FASET_TEST_FONT="${PROJECT_SOURCE_DIR}/assets/fonts/NotoSans.ttf" FASET_UI_THEME="${PROJECT_SOURCE_DIR}/assets/ui/dark.json")
add_test(NAME ui_render COMMAND faset_ui_render_test ${CMAKE_BINARY_DIR}/ui-test.ppm)
set_tests_properties(ui_render PROPERTIES LABELS "gpu")
endif()
endif()
install(DIRECTORY ${PROJECT_SOURCE_DIR}/assets/fonts ${PROJECT_SOURCE_DIR}/assets/ui DESTINATION assets)