diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..873886d --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,282 @@ +name: CI + +on: + pull_request: + branches: [master, develop] + push: + branches: [master, develop] + workflow_dispatch: + +concurrency: + group: ci-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +env: + VULKAN_SDK_VERSION: 1.4.309.0 + VCPKG_COMMIT: 8779f47d2db0785ee034b47fdfdcdb0e88b7010e + VCPKG_ROOT: ${{ github.workspace }}/.eppo/tools/vcpkg/8779f47d2db0785ee034b47fdfdcdb0e88b7010e + VCPKG_DISABLE_METRICS: "1" + VCPKG_DOWNLOADS: ${{ github.workspace }}/build/vcpkg-downloads + VCPKG_NUGET_REPOSITORY: ${{ github.server_url }}/${{ github.repository }} + VCPKG_BINARY_SOURCES: clear;nuget,GitHubPackages,${{ (github.event_name == 'push' || github.event_name == 'workflow_dispatch') && 'readwrite' || 'read' }} + DOTNET_CLI_TELEMETRY_OPTOUT: "1" + DOTNET_SKIP_FIRST_TIME_EXPERIENCE: "1" + DOTNET_NOLOGO: "1" + +jobs: + build-test: + name: ${{ matrix.system }} / ${{ matrix.configuration }} + runs-on: ${{ matrix.runner }} + timeout-minutes: 60 + strategy: + fail-fast: false + matrix: + include: + - runner: ubuntu-24.04 + system: linux + configuration: Debug + - runner: ubuntu-24.04 + system: linux + configuration: Release + - runner: ubuntu-24.04 + system: linux + configuration: Dist + - runner: windows-2025-vs2026 + system: windows + configuration: Debug + - runner: windows-2025-vs2026 + system: windows + configuration: Release + - runner: windows-2025-vs2026 + system: windows + configuration: Dist + + steps: + - name: Check out repository + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + + - name: Restore build tools + id: build-tools + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + with: + path: .eppo/tools + key: eppo-tools-${{ runner.os }}-vulkan-1.4.309.0-premake-5.0.0-beta8-vcpkg-8779f47d${{ runner.os == 'Windows' && '-debug-libraries' || '' }} + + - name: Install Linux prerequisites + if: runner.os == 'Linux' + shell: bash + run: | + sudo apt-get update + sudo apt-get install -y --no-install-recommends \ + autoconf automake autoconf-archive bison flex libtool libltdl-dev \ + libx11-dev libxrandr-dev libxinerama-dev libxcursor-dev libxi-dev \ + libxext-dev libwayland-dev libxkbcommon-dev wayland-protocols \ + libgl1-mesa-dev libglu1-mesa-dev mono-complete pkg-config uuid-dev + + - name: Install Vulkan SDK on Linux + if: runner.os == 'Linux' && steps.build-tools.outputs.cache-hit != 'true' + shell: bash + run: | + archive="$RUNNER_TEMP/vulkansdk.tar.xz" + curl -fsSL "https://sdk.lunarg.com/sdk/download/$VULKAN_SDK_VERSION/linux/vulkansdk-linux-x86_64-$VULKAN_SDK_VERSION.tar.xz" -o "$archive" + echo "616a25a9d8b33336e83957f97ca273b8e95461649723354300d02c26ae52a1f6 $archive" | sha256sum --check + mkdir -p .eppo/tools/vulkan + tar -xf "$archive" -C .eppo/tools/vulkan + + - name: Install Vulkan SDK on Windows + if: runner.os == 'Windows' && steps.build-tools.outputs.cache-hit != 'true' + shell: pwsh + run: | + $installer = Join-Path $env:RUNNER_TEMP "VulkanSDK-Installer.exe" + $destination = Join-Path $env:GITHUB_WORKSPACE ".eppo/tools/vulkan/$env:VULKAN_SDK_VERSION" + curl.exe --fail --location "https://sdk.lunarg.com/sdk/download/$env:VULKAN_SDK_VERSION/windows/VulkanSDK-$env:VULKAN_SDK_VERSION-Installer.exe" --output $installer + if ((Get-FileHash -Algorithm SHA256 $installer).Hash -ne "48B132169B64FE65CDB0F20970195335A65354E73F1EA5373032C2A8BBAD4297") { + throw "The Vulkan SDK installer checksum does not match." + } + $process = Start-Process -FilePath $installer -ArgumentList @( + "--root", $destination, + "--accept-licenses", "--default-answer", "--confirm-command", "install", + "com.lunarg.vulkan", "com.lunarg.vulkan.debug", "copy_only=1" + ) -Wait -PassThru + if ($process.ExitCode -ne 0) { + throw "The Vulkan SDK installer failed with exit code $($process.ExitCode)." + } + + - name: Configure Vulkan SDK on Linux + if: runner.os == 'Linux' + shell: bash + run: | + vulkan_root="$GITHUB_WORKSPACE/.eppo/tools/vulkan/$VULKAN_SDK_VERSION/x86_64" + test -x "$vulkan_root/bin/dxc" + test -f "$vulkan_root/lib/libdxcompiler.so" + echo "VULKAN_SDK=$vulkan_root" >> "$GITHUB_ENV" + echo "$vulkan_root/bin" >> "$GITHUB_PATH" + echo "LD_LIBRARY_PATH=$vulkan_root/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" >> "$GITHUB_ENV" + + - name: Configure Vulkan SDK on Windows + if: runner.os == 'Windows' + shell: pwsh + run: | + $vulkanRoot = Join-Path $env:GITHUB_WORKSPACE ".eppo/tools/vulkan/$env:VULKAN_SDK_VERSION" + if (!(Test-Path (Join-Path $vulkanRoot "Bin/dxc.exe")) -or !(Test-Path (Join-Path $vulkanRoot "Bin/dxcompiler.dll"))) { + throw "The cached Vulkan SDK is incomplete." + } + "VULKAN_SDK=$vulkanRoot" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + (Join-Path $vulkanRoot "Bin") | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append + + - name: Set up .NET 10 + uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0 + with: + dotnet-version: 10.0.x + + - name: Set up MSBuild + if: runner.os == 'Windows' + uses: microsoft/setup-msbuild@30375c66a4eea26614e0d39710365f22f8b0af57 # v3 + with: + vs-version: "[18.0,19.0)" + + - name: Provision pinned vcpkg on Linux + if: runner.os == 'Linux' + shell: bash + run: | + mkdir -p "$VCPKG_DOWNLOADS" + if [[ ! -x "$VCPKG_ROOT/vcpkg" ]]; then + mkdir -p "$(dirname "$VCPKG_ROOT")" + git init "$VCPKG_ROOT" + git -C "$VCPKG_ROOT" remote add origin https://github.com/microsoft/vcpkg.git + git -C "$VCPKG_ROOT" fetch --depth 1 origin "$VCPKG_COMMIT" + git -C "$VCPKG_ROOT" checkout --detach FETCH_HEAD + "$VCPKG_ROOT/bootstrap-vcpkg.sh" -disableMetrics + fi + test "$(git -C "$VCPKG_ROOT" rev-parse HEAD)" = "$VCPKG_COMMIT" + + - name: Provision pinned vcpkg on Windows + if: runner.os == 'Windows' + shell: pwsh + run: | + if (!(Test-Path (Join-Path $env:VCPKG_ROOT "vcpkg.exe"))) { + New-Item -ItemType Directory -Force (Split-Path $env:VCPKG_ROOT) | Out-Null + git init $env:VCPKG_ROOT + git -C $env:VCPKG_ROOT remote add origin https://github.com/microsoft/vcpkg.git + git -C $env:VCPKG_ROOT fetch --depth 1 origin $env:VCPKG_COMMIT + git -C $env:VCPKG_ROOT checkout --detach FETCH_HEAD + & (Join-Path $env:VCPKG_ROOT "bootstrap-vcpkg.bat") -disableMetrics + if ($LASTEXITCODE -ne 0) { + exit $LASTEXITCODE + } + } + if ((git -C $env:VCPKG_ROOT rev-parse HEAD) -ne $env:VCPKG_COMMIT) { + throw "The cached vcpkg checkout is not the pinned commit." + } + + - name: Provision pinned build tools on Linux + if: runner.os == 'Linux' + shell: bash + run: python3 Scripts/Setup.py --action ninja --compiler clang --yes --skip-dependencies --no-generate + + - name: Provision pinned build tools on Windows + if: runner.os == 'Windows' + shell: pwsh + run: | + & .\Scripts\Setup.bat --action vs2026 --compiler msc --yes --skip-dependencies --no-generate + if ($LASTEXITCODE -ne 0) { + exit $LASTEXITCODE + } + + - name: Configure GitHub Packages for vcpkg on Linux + if: runner.os == 'Linux' + shell: bash + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + nuget=$("$VCPKG_ROOT/vcpkg" fetch nuget | tail -n 1) + mono "$nuget" sources add \ + -Source "https://nuget.pkg.github.com/$GITHUB_REPOSITORY_OWNER/index.json" \ + -StorePasswordInClearText \ + -Name GitHubPackages \ + -UserName "$GITHUB_REPOSITORY_OWNER" \ + -Password "$GITHUB_TOKEN" \ + -NonInteractive + mono "$nuget" setapikey "$GITHUB_TOKEN" \ + -Source "https://nuget.pkg.github.com/$GITHUB_REPOSITORY_OWNER/index.json" \ + -NonInteractive + + - name: Configure GitHub Packages for vcpkg on Windows + if: runner.os == 'Windows' + shell: pwsh + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + $vcpkg = Join-Path $env:VCPKG_ROOT "vcpkg.exe" + $nuget = (& $vcpkg fetch nuget | Select-Object -Last 1).Trim() + & $nuget sources add ` + -Source "https://nuget.pkg.github.com/$env:GITHUB_REPOSITORY_OWNER/index.json" ` + -StorePasswordInClearText ` + -Name GitHubPackages ` + -UserName $env:GITHUB_REPOSITORY_OWNER ` + -Password $env:GITHUB_TOKEN ` + -NonInteractive + if ($LASTEXITCODE -ne 0) { + exit $LASTEXITCODE + } + & $nuget setapikey $env:GITHUB_TOKEN ` + -Source "https://nuget.pkg.github.com/$env:GITHUB_REPOSITORY_OWNER/index.json" ` + -NonInteractive + if ($LASTEXITCODE -ne 0) { + exit $LASTEXITCODE + } + + - name: Generate build files on Linux + if: runner.os == 'Linux' + shell: bash + run: python3 Scripts/Setup.py --action ninja --compiler clang --yes + + - name: Generate build files on Windows + if: runner.os == 'Windows' + shell: pwsh + run: | + & .\Scripts\Setup.bat --action vs2026 --compiler msc --yes + if ($LASTEXITCODE -ne 0) { + exit $LASTEXITCODE + } + + - name: Build tests on Linux + if: runner.os == 'Linux' + shell: bash + run: ninja EppoEngineTesting_${{ matrix.configuration }}_x64 + + - name: Build tests on Windows + if: runner.os == 'Windows' + shell: pwsh + run: msbuild EppoEngine.slnx /restore /t:EppoEngineTesting /p:Configuration=${{ matrix.configuration }} /p:Platform=x64 /v:minimal + + - name: Run tests + run: >- + ctest + --test-dir build/bin/${{ matrix.configuration }}-${{ matrix.system }}-x86_64 + --label-exclude graphical + --output-on-failure + --output-junit build/bin/${{ matrix.configuration }}-${{ matrix.system }}-x86_64/report.xml + + - name: Upload test report + if: always() + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: test-report-${{ matrix.system }}-${{ matrix.configuration }} + path: build/bin/${{ matrix.configuration }}-${{ matrix.system }}-x86_64/report.xml + if-no-files-found: ignore + retention-days: 30 + + - name: Remove transient vcpkg files from the build-tools cache + if: always() + shell: pwsh + run: | + $vcpkgRoot = $env:VCPKG_ROOT + foreach ($directory in @("buildtrees", "downloads", "packages")) { + $path = Join-Path $vcpkgRoot $directory + if (Test-Path $path) { + Remove-Item -LiteralPath $path -Recurse -Force + } + } diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml deleted file mode 100644 index a88f1a9..0000000 --- a/.gitlab-ci.yml +++ /dev/null @@ -1,73 +0,0 @@ -stages: - - build-image - - build-test - -workflow: - rules: - - if: '$CI_PIPELINE_SOURCE == "merge_request_event"' - - if: '$CI_COMMIT_BRANCH == "master" || $CI_COMMIT_BRANCH == "develop"' - - if: '$CI_COMMIT_BRANCH =~ /^(feature|test)\//' - - when: never - -variables: - GIT_DEPTH: "1" - GIT_SUBMODULE_STRATEGY: none - VCPKG_BINARY_SOURCES: "clear;files,$CI_PROJECT_DIR/.vcpkg-cache,readwrite" - VCPKG_DISABLE_METRICS: "1" - DOCKER_IMAGE: "$CI_REGISTRY_IMAGE/ci:latest" - -build-ci-image: - stage: build-image - image: - name: gcr.io/kaniko-project/executor:debug - entrypoint: [""] - interruptible: true - rules: - - if: '$CI_PIPELINE_SOURCE == "merge_request_event"' - changes: [.gitlab/ci/Dockerfile] - - if: '$CI_COMMIT_BRANCH' - changes: [.gitlab/ci/Dockerfile] - - when: manual - allow_failure: true - script: - - mkdir -p /kaniko/.docker - - echo "{\"auths\":{\"$CI_REGISTRY\":{\"auth\":\"$(printf '%s:%s' "$CI_REGISTRY_USER" "$CI_REGISTRY_PASSWORD" | base64 | tr -d '\n')\"}}}" > /kaniko/.docker/config.json - - >- - /kaniko/executor - --context "$CI_PROJECT_DIR" - --dockerfile "$CI_PROJECT_DIR/.gitlab/ci/Dockerfile" - --destination "$DOCKER_IMAGE" - --cache=true - -build-and-test: - stage: build-test - image: "$DOCKER_IMAGE" - interruptible: true - needs: - - job: build-ci-image - optional: true - cache: - - key: - files: - - vcpkg.json - - vcpkg-configuration.json - paths: - - .vcpkg-cache/ - policy: pull-push - before_script: - - mkdir -p .vcpkg-cache - - 'test -n "$VCPKG_ROOT" || { echo "VCPKG_ROOT missing from image"; exit 1; }' - - 'test -n "$VULKAN_SDK" || { echo "VULKAN_SDK missing from image"; exit 1; }' - - 'test -n "$DOTNET_ROOT" || { echo "DOTNET_ROOT missing from image"; exit 1; }' - - premake5 --version | grep '5.0.0-beta8' - script: - - python3 Scripts/Setup.py --action ninja --compiler clang --yes - - ninja EppoEngineTesting_Debug_x64 - - ctest --test-dir build/bin/Debug-linux-x86_64 --label-exclude graphical --output-on-failure --output-junit "$CI_PROJECT_DIR/build/bin/Debug-linux-x86_64/report.xml" - artifacts: - when: always - reports: - junit: build/bin/Debug-linux-x86_64/report.xml - paths: - - build/bin/Debug-linux-x86_64/report.xml - expire_in: 1 week diff --git a/.gitlab/ci/Dockerfile b/.gitlab/ci/Dockerfile deleted file mode 100644 index 0eb53b0..0000000 --- a/.gitlab/ci/Dockerfile +++ /dev/null @@ -1,57 +0,0 @@ -FROM ubuntu:24.04 - -ENV DEBIAN_FRONTEND=noninteractive - -# Ubuntu distributes CTest in the cmake package; Eppo never invokes CMake to generate or build. -RUN apt-get update && apt-get install -y --no-install-recommends \ - ca-certificates curl git wget \ - clang lld llvm \ - cmake ninja-build make pkg-config uuid-dev \ - zip unzip tar xz-utils \ - python3 \ - autoconf automake autoconf-archive libtool libltdl-dev bison flex \ - libx11-dev libxrandr-dev libxinerama-dev libxcursor-dev libxi-dev \ - libxext-dev libwayland-dev libxkbcommon-dev wayland-protocols \ - libgl1-mesa-dev \ - && rm -rf /var/lib/apt/lists/* - -ARG PREMAKE_VERSION=5.0.0-beta8 -ARG PREMAKE_COMMIT=2ca338a25ed5f6e62d36c9cd70e5f313953c630d -RUN git clone --branch "v${PREMAKE_VERSION}" --depth 1 https://github.com/premake/premake-core.git /tmp/premake \ - && test "$(git -C /tmp/premake rev-parse HEAD)" = "${PREMAKE_COMMIT}" \ - && cd /tmp/premake \ - && CC=clang CXX=clang++ PREMAKE_OPTS=--cc=clang sh Bootstrap.sh \ - && install -m 0755 bin/release/premake5 /usr/local/bin/premake5 \ - && rm -rf /tmp/premake \ - && premake5 --version | grep "${PREMAKE_VERSION}" - -ARG VULKAN_SDK_VERSION=1.4.309.0 -RUN curl -fsSL "https://sdk.lunarg.com/sdk/download/${VULKAN_SDK_VERSION}/linux/vulkansdk-linux-x86_64-${VULKAN_SDK_VERSION}.tar.xz" \ - -o /tmp/vulkansdk.tar.xz \ - && mkdir -p /opt/vulkan \ - && tar -xf /tmp/vulkansdk.tar.xz -C /opt/vulkan \ - && rm /tmp/vulkansdk.tar.xz -ENV VULKAN_SDK=/opt/vulkan/${VULKAN_SDK_VERSION}/x86_64 -ENV PATH="${VULKAN_SDK}/bin:${PATH}" -ENV LD_LIBRARY_PATH="${VULKAN_SDK}/lib" - -ENV DOTNET_ROOT=/usr/share/dotnet -RUN curl -fsSL https://dot.net/v1/dotnet-install.sh -o /tmp/dotnet-install.sh \ - && bash /tmp/dotnet-install.sh --channel 10.0 --install-dir "${DOTNET_ROOT}" \ - && rm /tmp/dotnet-install.sh -ENV PATH="${DOTNET_ROOT}:${PATH}" -ENV DOTNET_CLI_TELEMETRY_OPTOUT=1 \ - DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1 \ - DOTNET_NOLOGO=1 - -ENV VCPKG_ROOT=/opt/vcpkg -ARG VCPKG_COMMIT=8779f47d2db0785ee034b47fdfdcdb0e88b7010e -RUN git init "${VCPKG_ROOT}" \ - && git -C "${VCPKG_ROOT}" remote add origin https://github.com/microsoft/vcpkg.git \ - && git -C "${VCPKG_ROOT}" fetch --depth 1 origin "${VCPKG_COMMIT}" \ - && git -C "${VCPKG_ROOT}" checkout --detach FETCH_HEAD \ - && "${VCPKG_ROOT}/bootstrap-vcpkg.sh" -disableMetrics -ENV PATH="${VCPKG_ROOT}:${PATH}" \ - VCPKG_DISABLE_METRICS=1 \ - CC=clang \ - CXX=clang++ diff --git a/AGENTS.md b/AGENTS.md index f829b16..7d0a912 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -148,4 +148,4 @@ Seven domain skills live in `.agents/skills/` (each `SKILL.md` + `references/arc ## CI -GitLab CI (`.gitlab-ci.yml`): runs on MRs, `master`, `develop`, `feature/*`, `test/*`. On Linux it generates Ninja with Premake beta8, builds only `EppoEngineTesting_Debug_x64`, runs `ctest --label-exclude graphical`, and publishes JUnit. The toolchain is baked into `.gitlab/ci/Dockerfile`; the vcpkg binary cache is keyed on `vcpkg.json` + `vcpkg-configuration.json`. Use `glab` CLI for MR operations. +GitHub Actions (`.github/workflows/ci.yml`) runs the `EppoEngineTesting` Debug, Release and Dist configurations on Linux and Windows for pull requests and pushes to `master` or `develop`, plus manual dispatches. Every job runs `ctest --label-exclude graphical` and retains its JUnit report for 30 days. The pinned Vulkan SDK, Premake and vcpkg tools are cached per host under `.eppo/tools`; vcpkg binary packages are restored from GitHub Packages through its NuGet provider. Pull requests read the package cache, while trusted pushes and manual runs can update it. diff --git a/EppoEngine/Source/Core/Base.h b/EppoEngine/Source/Core/Base.h index 309a705..6505f2b 100644 --- a/EppoEngine/Source/Core/Base.h +++ b/EppoEngine/Source/Core/Base.h @@ -4,6 +4,11 @@ #include +#if defined(EP_DIST) + #undef TracyFree + #define TracyFree(ptr) ((void)0) +#endif + #include #include diff --git a/EppoEngine/Source/Scripting/ScriptGlue.cpp b/EppoEngine/Source/Scripting/ScriptGlue.cpp index a87c5ef..cb2a7c5 100644 --- a/EppoEngine/Source/Scripting/ScriptGlue.cpp +++ b/EppoEngine/Source/Scripting/ScriptGlue.cpp @@ -82,12 +82,12 @@ namespace Eppo } #pragma region Core - auto Input_IsKeyPressed(const uint16_t keyCode) -> bool + auto Input_IsKeyPressed(const uint16_t keyCode) -> uint8_t { return Input::IsKeyPressed(keyCode); } - auto Input_IsMouseButtonPressed(const uint16_t button) -> bool + auto Input_IsMouseButtonPressed(const uint16_t button) -> uint8_t { return Input::IsMouseButtonPressed(button); } @@ -175,7 +175,7 @@ namespace Eppo outHit->EntityId = static_cast(hit.EntityId); } - auto Physics_OverlapsSphere(const uint64_t id, const glm::vec3* center, const float radius) -> bool + auto Physics_OverlapsSphere(const uint64_t id, const glm::vec3* center, const float radius) -> uint8_t { const auto world = ScriptEngine::Get().GetActivePhysicsWorld(); if (!world) @@ -186,7 +186,7 @@ namespace Eppo #pragma endregion #pragma region Scene - auto Entity_HasComponent(const uint64_t id, const char* typeName) -> bool + auto Entity_HasComponent(const uint64_t id, const char* typeName) -> uint8_t { const Entity entity = GetEntity(id); if (!entity) @@ -254,7 +254,7 @@ namespace Eppo entity.TryAddComponent(); } - auto Entity_RemoveComponent(const uint64_t id, const char* typeName) -> bool + auto Entity_RemoveComponent(const uint64_t id, const char* typeName) -> uint8_t { Entity entity = GetEntity(id); if (!entity) @@ -446,7 +446,7 @@ namespace Eppo entity.GetComponent().MeshHandle = handle; } - auto CameraComponent_GetPrimary(const uint64_t id) -> bool + auto CameraComponent_GetPrimary(const uint64_t id) -> uint8_t { const Entity entity = GetEntity(id); if (!entity || !entity.HasComponent()) @@ -455,13 +455,13 @@ namespace Eppo return entity.GetComponent().Primary; } - auto CameraComponent_SetPrimary(const uint64_t id, const bool primary) -> void + auto CameraComponent_SetPrimary(const uint64_t id, const uint8_t primary) -> void { const Entity entity = GetEntity(id); if (!entity || !entity.HasComponent()) return; - entity.GetComponent().Primary = primary; + entity.GetComponent().Primary = primary != 0; } auto CameraComponent_GetVerticalFov(const uint64_t id) -> float @@ -706,7 +706,7 @@ namespace Eppo entity.GetComponent().AngularDamping = angularDamping; } - auto RigidBodyComponent_GetLockLinearX(const uint64_t id) -> bool + auto RigidBodyComponent_GetLockLinearX(const uint64_t id) -> uint8_t { const Entity entity = GetEntity(id); if (!entity || !entity.HasComponent()) @@ -715,16 +715,16 @@ namespace Eppo return entity.GetComponent().LockLinearX; } - auto RigidBodyComponent_SetLockLinearX(const uint64_t id, const bool locked) -> void + auto RigidBodyComponent_SetLockLinearX(const uint64_t id, const uint8_t locked) -> void { const Entity entity = GetEntity(id); if (!entity || !entity.HasComponent()) return; - entity.GetComponent().LockLinearX = locked; + entity.GetComponent().LockLinearX = locked != 0; } - auto RigidBodyComponent_GetLockLinearY(const uint64_t id) -> bool + auto RigidBodyComponent_GetLockLinearY(const uint64_t id) -> uint8_t { const Entity entity = GetEntity(id); if (!entity || !entity.HasComponent()) @@ -733,16 +733,16 @@ namespace Eppo return entity.GetComponent().LockLinearY; } - auto RigidBodyComponent_SetLockLinearY(const uint64_t id, const bool locked) -> void + auto RigidBodyComponent_SetLockLinearY(const uint64_t id, const uint8_t locked) -> void { const Entity entity = GetEntity(id); if (!entity || !entity.HasComponent()) return; - entity.GetComponent().LockLinearY = locked; + entity.GetComponent().LockLinearY = locked != 0; } - auto RigidBodyComponent_GetLockLinearZ(const uint64_t id) -> bool + auto RigidBodyComponent_GetLockLinearZ(const uint64_t id) -> uint8_t { const Entity entity = GetEntity(id); if (!entity || !entity.HasComponent()) @@ -751,16 +751,16 @@ namespace Eppo return entity.GetComponent().LockLinearZ; } - auto RigidBodyComponent_SetLockLinearZ(const uint64_t id, const bool locked) -> void + auto RigidBodyComponent_SetLockLinearZ(const uint64_t id, const uint8_t locked) -> void { const Entity entity = GetEntity(id); if (!entity || !entity.HasComponent()) return; - entity.GetComponent().LockLinearZ = locked; + entity.GetComponent().LockLinearZ = locked != 0; } - auto RigidBodyComponent_GetLockAngularX(const uint64_t id) -> bool + auto RigidBodyComponent_GetLockAngularX(const uint64_t id) -> uint8_t { const Entity entity = GetEntity(id); if (!entity || !entity.HasComponent()) @@ -769,16 +769,16 @@ namespace Eppo return entity.GetComponent().LockAngularX; } - auto RigidBodyComponent_SetLockAngularX(const uint64_t id, const bool locked) -> void + auto RigidBodyComponent_SetLockAngularX(const uint64_t id, const uint8_t locked) -> void { const Entity entity = GetEntity(id); if (!entity || !entity.HasComponent()) return; - entity.GetComponent().LockAngularX = locked; + entity.GetComponent().LockAngularX = locked != 0; } - auto RigidBodyComponent_GetLockAngularY(const uint64_t id) -> bool + auto RigidBodyComponent_GetLockAngularY(const uint64_t id) -> uint8_t { const Entity entity = GetEntity(id); if (!entity || !entity.HasComponent()) @@ -787,16 +787,16 @@ namespace Eppo return entity.GetComponent().LockAngularY; } - auto RigidBodyComponent_SetLockAngularY(const uint64_t id, const bool locked) -> void + auto RigidBodyComponent_SetLockAngularY(const uint64_t id, const uint8_t locked) -> void { const Entity entity = GetEntity(id); if (!entity || !entity.HasComponent()) return; - entity.GetComponent().LockAngularY = locked; + entity.GetComponent().LockAngularY = locked != 0; } - auto RigidBodyComponent_GetLockAngularZ(const uint64_t id) -> bool + auto RigidBodyComponent_GetLockAngularZ(const uint64_t id) -> uint8_t { const Entity entity = GetEntity(id); if (!entity || !entity.HasComponent()) @@ -805,13 +805,13 @@ namespace Eppo return entity.GetComponent().LockAngularZ; } - auto RigidBodyComponent_SetLockAngularZ(const uint64_t id, const bool locked) -> void + auto RigidBodyComponent_SetLockAngularZ(const uint64_t id, const uint8_t locked) -> void { const Entity entity = GetEntity(id); if (!entity || !entity.HasComponent()) return; - entity.GetComponent().LockAngularZ = locked; + entity.GetComponent().LockAngularZ = locked != 0; } auto BoxColliderComponent_GetHalfSize(const uint64_t id, glm::vec3* outHalfSize) -> void diff --git a/EppoEngineTesting/Source/Core/Timer.cpp b/EppoEngineTesting/Source/Core/Timer.cpp index 5ec218c..8929262 100644 --- a/EppoEngineTesting/Source/Core/Timer.cpp +++ b/EppoEngineTesting/Source/Core/Timer.cpp @@ -8,6 +8,7 @@ TEST(Core, Timer_StartsOnConstruction) using namespace std::chrono; Timer timer; + std::this_thread::sleep_for(2ms); EXPECT_LT(0, timer.GetElapsedMilliseconds()); auto elapsed = timer.GetElapsedMilliseconds(); diff --git a/EppoEngineTesting/Source/Scripting/Scripting.cpp b/EppoEngineTesting/Source/Scripting/Scripting.cpp index 13f1182..f2b538e 100644 --- a/EppoEngineTesting/Source/Scripting/Scripting.cpp +++ b/EppoEngineTesting/Source/Scripting/Scripting.cpp @@ -1831,6 +1831,34 @@ TEST(Scripting, RigidBodyComponent_AngularDamping_RoundTripsSceneValue) engine.OnDestroyEntity(entity); } +TEST(Scripting, RigidBodyComponent_MotionLockGetters_FalseValuesMarshalAcrossNativeBoundary) +{ + EP_REQUIRE(EnsureRuntime()); + + const Ref scene = CreateRef(); + auto& engine = ScriptEngine::Get(); + Entity entity = MakeContextEntity(scene); + entity.AddComponent(); + + const ScriptClass* c = FindClass(kUserClass); + EP_REQUIRE(c != nullptr); + + const char* getters[] = { + "RigidBodyComponent_GetLockLinearX", "RigidBodyComponent_GetLockLinearY", "RigidBodyComponent_GetLockLinearZ", + "RigidBodyComponent_GetLockAngularX", "RigidBodyComponent_GetLockAngularY", "RigidBodyComponent_GetLockAngularZ", + }; + for (const char* name : getters) + { + const ScriptMethod* getter = c->GetMethod(name); + EP_REQUIRE(getter != nullptr); + bool got = true; + c->InvokeMethod(entity, *getter, nullptr, &got); + EXPECT_FALSE(got); + } + + engine.OnDestroyEntity(entity); +} + TEST(Scripting, RigidBodyComponent_MotionLocks_RoundTripSceneValues) { EP_REQUIRE(EnsureRuntime()); diff --git a/EppoScriptCore/Source/Core/InternalCalls.cs b/EppoScriptCore/Source/Core/InternalCalls.cs index 1520e8f..f46eb37 100644 --- a/EppoScriptCore/Source/Core/InternalCalls.cs +++ b/EppoScriptCore/Source/Core/InternalCalls.cs @@ -245,12 +245,12 @@ internal static void MeshComponent_SetMeshHandle(ulong id, ulong meshHandle) internal static bool CameraComponent_GetPrimary(ulong id) { - return ((delegate* unmanaged[Cdecl])Get("CameraComponent_GetPrimary"))(id); + return ((delegate* unmanaged[Cdecl])Get("CameraComponent_GetPrimary"))(id) != 0; } internal static void CameraComponent_SetPrimary(ulong id, bool primary) { - ((delegate* unmanaged[Cdecl])Get("CameraComponent_SetPrimary"))(id, primary); + ((delegate* unmanaged[Cdecl])Get("CameraComponent_SetPrimary"))(id, primary ? (byte)1 : (byte)0); } internal static float CameraComponent_GetVerticalFov(ulong id) @@ -390,62 +390,62 @@ internal static void RigidBodyComponent_SetAngularDamping(ulong id, float angula internal static bool RigidBodyComponent_GetLockLinearX(ulong id) { - return ((delegate* unmanaged[Cdecl])Get("RigidBodyComponent_GetLockLinearX"))(id); + return ((delegate* unmanaged[Cdecl])Get("RigidBodyComponent_GetLockLinearX"))(id) != 0; } internal static void RigidBodyComponent_SetLockLinearX(ulong id, bool locked) { - ((delegate* unmanaged[Cdecl])Get("RigidBodyComponent_SetLockLinearX"))(id, locked); + ((delegate* unmanaged[Cdecl])Get("RigidBodyComponent_SetLockLinearX"))(id, locked ? (byte)1 : (byte)0); } internal static bool RigidBodyComponent_GetLockLinearY(ulong id) { - return ((delegate* unmanaged[Cdecl])Get("RigidBodyComponent_GetLockLinearY"))(id); + return ((delegate* unmanaged[Cdecl])Get("RigidBodyComponent_GetLockLinearY"))(id) != 0; } internal static void RigidBodyComponent_SetLockLinearY(ulong id, bool locked) { - ((delegate* unmanaged[Cdecl])Get("RigidBodyComponent_SetLockLinearY"))(id, locked); + ((delegate* unmanaged[Cdecl])Get("RigidBodyComponent_SetLockLinearY"))(id, locked ? (byte)1 : (byte)0); } internal static bool RigidBodyComponent_GetLockLinearZ(ulong id) { - return ((delegate* unmanaged[Cdecl])Get("RigidBodyComponent_GetLockLinearZ"))(id); + return ((delegate* unmanaged[Cdecl])Get("RigidBodyComponent_GetLockLinearZ"))(id) != 0; } internal static void RigidBodyComponent_SetLockLinearZ(ulong id, bool locked) { - ((delegate* unmanaged[Cdecl])Get("RigidBodyComponent_SetLockLinearZ"))(id, locked); + ((delegate* unmanaged[Cdecl])Get("RigidBodyComponent_SetLockLinearZ"))(id, locked ? (byte)1 : (byte)0); } internal static bool RigidBodyComponent_GetLockAngularX(ulong id) { - return ((delegate* unmanaged[Cdecl])Get("RigidBodyComponent_GetLockAngularX"))(id); + return ((delegate* unmanaged[Cdecl])Get("RigidBodyComponent_GetLockAngularX"))(id) != 0; } internal static void RigidBodyComponent_SetLockAngularX(ulong id, bool locked) { - ((delegate* unmanaged[Cdecl])Get("RigidBodyComponent_SetLockAngularX"))(id, locked); + ((delegate* unmanaged[Cdecl])Get("RigidBodyComponent_SetLockAngularX"))(id, locked ? (byte)1 : (byte)0); } internal static bool RigidBodyComponent_GetLockAngularY(ulong id) { - return ((delegate* unmanaged[Cdecl])Get("RigidBodyComponent_GetLockAngularY"))(id); + return ((delegate* unmanaged[Cdecl])Get("RigidBodyComponent_GetLockAngularY"))(id) != 0; } internal static void RigidBodyComponent_SetLockAngularY(ulong id, bool locked) { - ((delegate* unmanaged[Cdecl])Get("RigidBodyComponent_SetLockAngularY"))(id, locked); + ((delegate* unmanaged[Cdecl])Get("RigidBodyComponent_SetLockAngularY"))(id, locked ? (byte)1 : (byte)0); } internal static bool RigidBodyComponent_GetLockAngularZ(ulong id) { - return ((delegate* unmanaged[Cdecl])Get("RigidBodyComponent_GetLockAngularZ"))(id); + return ((delegate* unmanaged[Cdecl])Get("RigidBodyComponent_GetLockAngularZ"))(id) != 0; } internal static void RigidBodyComponent_SetLockAngularZ(ulong id, bool locked) { - ((delegate* unmanaged[Cdecl])Get("RigidBodyComponent_SetLockAngularZ"))(id, locked); + ((delegate* unmanaged[Cdecl])Get("RigidBodyComponent_SetLockAngularZ"))(id, locked ? (byte)1 : (byte)0); } internal static Vector3 BoxColliderComponent_GetHalfSize(ulong id)