Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
151 changes: 138 additions & 13 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,8 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
add_compile_options("$<$<C_COMPILER_ID:MSVC>:/utf-8>")
add_compile_options("$<$<CXX_COMPILER_ID:MSVC>:/utf-8>")

set(ENGINE_FOLDER "${PROJECT_SOURCE_DIR}/Engine")
set(SHADERS_FOLDER "${ENGINE_FOLDER}/Shaders")
set(ENGINE_TEMP_FOLDER "${ENGINE_FOLDER}/Save")
set(ASSETS_FOLDER "${PROJECT_SOURCE_DIR}/Assets")
set(WAVE_ENGINE_DIR "${PROJECT_SOURCE_DIR}/Engine")
set(WAVE_SHADER_DIR "${WAVE_ENGINE_DIR}/Shaders")

file(GLOB_RECURSE WAVE_RUNTIME_HEADER CONFIGURE_DEPENDS
"${PROJECT_SOURCE_DIR}/Engine/Source/Core/*.h"
Expand All @@ -43,9 +41,11 @@ file(GLOB_RECURSE WAVE_RUNTIME_SOURCE CONFIGURE_DEPENDS
list(APPEND WAVE_RUNTIME_SOURCE
"${PROJECT_SOURCE_DIR}/Engine/Source/Window.cpp")
list(REMOVE_ITEM WAVE_RUNTIME_HEADER
"${PROJECT_SOURCE_DIR}/Engine/Source/Core/Paths/LegacyMigration.h"
"${PROJECT_SOURCE_DIR}/Engine/Source/Renderer/EditorCompositePass.h"
"${PROJECT_SOURCE_DIR}/Engine/Source/Renderer/EditorSelectionPass.h")
list(REMOVE_ITEM WAVE_RUNTIME_SOURCE
"${PROJECT_SOURCE_DIR}/Engine/Source/Core/Paths/LegacyMigration.cpp"
"${PROJECT_SOURCE_DIR}/Engine/Source/Renderer/EditorCompositePass.cpp"
"${PROJECT_SOURCE_DIR}/Engine/Source/Renderer/EditorSelectionPass.cpp")

Expand Down Expand Up @@ -123,12 +123,12 @@ if (WIN32)
)
endif()
file(GLOB_RECURSE WAVE_RUNTIME_SHADERS CONFIGURE_DEPENDS
"${SHADERS_FOLDER}/*.hlsl"
"${SHADERS_FOLDER}/*.hlsli"
"${SHADERS_FOLDER}/*.h")
"${WAVE_SHADER_DIR}/*.hlsl"
"${WAVE_SHADER_DIR}/*.hlsli"
"${WAVE_SHADER_DIR}/*.h")
set(WAVE_EDITOR_SHADERS
"${SHADERS_FOLDER}/EditorComposite.hlsl"
"${SHADERS_FOLDER}/EditorSelection.hlsl")
"${WAVE_SHADER_DIR}/EditorComposite.hlsl"
"${WAVE_SHADER_DIR}/EditorSelection.hlsl")
list(REMOVE_ITEM WAVE_RUNTIME_SHADERS ${WAVE_EDITOR_SHADERS})

set(ENGINE_HEADER ${WAVE_RUNTIME_HEADER} ${WAVE_EDITOR_SUPPORT_HEADER})
Expand Down Expand Up @@ -162,12 +162,30 @@ set_property(TARGET WaveEditor PROPERTY COMPILE_WARNING_AS_ERROR ON)
# or third-party source dependencies.
set(WAVE_CORE_CONTRACT_SOURCES
${CORE_RUNTIME_CONTRACT_SUITE}
"${PROJECT_SOURCE_DIR}/Tests/ApplicationContracts.h"
"${PROJECT_SOURCE_DIR}/Tests/ApplicationContracts.cpp"
"${PROJECT_SOURCE_DIR}/Tests/ContractCoreContracts.h"
"${PROJECT_SOURCE_DIR}/Tests/ContractCoreContracts.cpp"
"${PROJECT_SOURCE_DIR}/Tests/PathContracts.h"
"${PROJECT_SOURCE_DIR}/Tests/PathContracts.cpp"
"${PROJECT_SOURCE_DIR}/Tests/CoreRuntimeContractsMain.cpp"
"${PROJECT_SOURCE_DIR}/Engine/Source/Contract/CapabilityRegistry.h"
"${PROJECT_SOURCE_DIR}/Engine/Source/Contract/ContractCore.h"
"${PROJECT_SOURCE_DIR}/Engine/Source/Contract/ContractCore.cpp"
"${PROJECT_SOURCE_DIR}/Engine/Source/Core/Application/ApplicationClock.h"
"${PROJECT_SOURCE_DIR}/Engine/Source/Core/Application/ApplicationClock.cpp"
"${PROJECT_SOURCE_DIR}/Engine/Source/Core/Application/ApplicationConfig.h"
"${PROJECT_SOURCE_DIR}/Engine/Source/Core/Application/ApplicationConfig.cpp"
"${PROJECT_SOURCE_DIR}/Engine/Source/Core/Application/ApplicationLifecycle.h"
"${PROJECT_SOURCE_DIR}/Engine/Source/Core/Application/ApplicationLifecycle.cpp"
"${PROJECT_SOURCE_DIR}/Engine/Source/Core/Application/ApplicationRunner.h"
"${PROJECT_SOURCE_DIR}/Engine/Source/Core/Application/ApplicationRunner.cpp"
"${PROJECT_SOURCE_DIR}/Engine/Source/Core/Paths/PathService.h"
"${PROJECT_SOURCE_DIR}/Engine/Source/Core/Paths/PathService.cpp"
"${PROJECT_SOURCE_DIR}/Engine/Source/Core/Paths/AtomicFileStore.h"
"${PROJECT_SOURCE_DIR}/Engine/Source/Core/Paths/AtomicFileStore.cpp"
"${PROJECT_SOURCE_DIR}/Engine/Source/Core/Paths/LegacyMigration.h"
"${PROJECT_SOURCE_DIR}/Engine/Source/Core/Paths/LegacyMigration.cpp"
"${PROJECT_SOURCE_DIR}/Engine/Source/Core/Engine.cpp"
"${PROJECT_SOURCE_DIR}/Engine/Source/Core/Profiler.cpp"
"${PROJECT_SOURCE_DIR}/Engine/Source/Misc/Log.cpp"
Expand All @@ -189,11 +207,34 @@ if(MSVC)
target_compile_options(WaveCoreContracts PRIVATE /bigobj /Zc:preprocessor)
endif()

# ---------------- WaveEditorDomainContracts ----------------
# Explicit CPU-only sibling closure for G0-04 pure Editor-domain contracts.
# It compiles no Runtime Scene/Renderer, UI, MCP, RHI, PCH, or third-party source.
set(WAVE_EDITOR_DOMAIN_CONTRACT_SOURCES
"${PROJECT_SOURCE_DIR}/Tests/EditorDomainContractTests.h"
"${PROJECT_SOURCE_DIR}/Tests/EditorDomainContractTests.cpp"
"${PROJECT_SOURCE_DIR}/Tests/EditorDomainContractsMain.cpp"
"${PROJECT_SOURCE_DIR}/Engine/Source/Contract/ContractCore.h"
"${PROJECT_SOURCE_DIR}/Engine/Source/Contract/ContractCore.cpp"
"${PROJECT_SOURCE_DIR}/Engine/Source/Developer/Document/EditorDocumentLedger.h"
"${PROJECT_SOURCE_DIR}/Engine/Source/Developer/Document/EditorDocumentLedger.cpp"
"${PROJECT_SOURCE_DIR}/Engine/Source/Developer/Scene/EditorDomainContracts.h"
"${PROJECT_SOURCE_DIR}/Engine/Source/Developer/Scene/EditorDomainContracts.cpp")
add_executable(WaveEditorDomainContracts ${WAVE_EDITOR_DOMAIN_CONTRACT_SOURCES})
set_property(TARGET WaveEditorDomainContracts PROPERTY COMPILE_WARNING_AS_ERROR ON)
target_include_directories(WaveEditorDomainContracts PRIVATE
"${PROJECT_SOURCE_DIR}/Engine/Source"
"${PROJECT_SOURCE_DIR}/Tests")
if(MSVC)
target_compile_options(WaveEditorDomainContracts PRIVATE /bigobj /Zc:preprocessor)
endif()

# ---------------- WaveTraceViewer ----------------
file(GLOB TRACE_VIEWER_SOURCES CONFIGURE_DEPENDS
"${PROJECT_SOURCE_DIR}/Tools/TraceViewer/*.h"
"${PROJECT_SOURCE_DIR}/Tools/TraceViewer/*.cpp")
set(TRACE_VIEWER_SHARED
"${PROJECT_SOURCE_DIR}/Engine/Source/Core/Paths/PathService.cpp"
"${PROJECT_SOURCE_DIR}/Engine/Source/Trace/TraceCodec.cpp"
"${PROJECT_SOURCE_DIR}/Engine/Source/Trace/TraceAnalysis.cpp"
"${PROJECT_SOURCE_DIR}/Engine/Source/UI/EditorStyle.cpp"
Expand Down Expand Up @@ -288,10 +329,6 @@ if (WIN32)
endif()

add_definitions(-DNOMINMAX)
add_definitions(-DENGINE_FOLDER="${ENGINE_FOLDER}/")
add_definitions(-DSHADERS_FOLDER="${SHADERS_FOLDER}/")
add_definitions(-DASSETS_FOLDER="${ASSETS_FOLDER}/")
add_definitions(-DENGINE_TEMP_FOLDER="${ENGINE_TEMP_FOLDER}/")

source_group(TREE "${PROJECT_SOURCE_DIR}/Engine/Source" PREFIX "Runtime Source"
FILES ${WAVE_RUNTIME_HEADER} ${WAVE_RUNTIME_SOURCE})
Expand Down Expand Up @@ -397,6 +434,34 @@ if(BUILD_TESTING)
LABELS "contract;core;cpu"
)

add_test(
NAME WaveEngine.PathTargetContracts
COMMAND "${Python3_EXECUTABLE}"
"${PROJECT_SOURCE_DIR}/Tests/path_target_contracts.py"
"${PROJECT_SOURCE_DIR}"
)
set_tests_properties(
WaveEngine.PathTargetContracts
PROPERTIES
WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}"
TIMEOUT 10
LABELS "contract;path;cpu"
)

add_test(
NAME WaveEngine.EditorDomainTargetBoundary
COMMAND "${Python3_EXECUTABLE}"
"${PROJECT_SOURCE_DIR}/Tests/editor_domain_target_contracts.py"
"${PROJECT_SOURCE_DIR}"
)
set_tests_properties(
WaveEngine.EditorDomainTargetBoundary
PROPERTIES
WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}"
TIMEOUT 10
LABELS "contract;editor-domain;cpu"
)

add_test(
NAME WaveEngine.McpCapabilityRegistrationContracts
COMMAND "${Python3_EXECUTABLE}"
Expand Down Expand Up @@ -471,6 +536,54 @@ if(BUILD_TESTING)
RUN_SERIAL TRUE
)

add_test(
NAME WaveEngine.EditorSceneAuthoringContracts
COMMAND "${Python3_EXECUTABLE}"
"${PROJECT_SOURCE_DIR}/Tests/editor_scene_authoring_contracts.py"
"$<TARGET_FILE:WaveEditor>"
)
set_tests_properties(
WaveEngine.EditorSceneAuthoringContracts
PROPERTIES
WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}"
TIMEOUT 120
LABELS "contract;editor-domain;mcp;gpu"
ENVIRONMENT "WAVE_RG_STRICT=1"
RUN_SERIAL TRUE
)

add_test(
NAME WaveEngine.EditorCameraAuthoringContracts
COMMAND "${Python3_EXECUTABLE}"
"${PROJECT_SOURCE_DIR}/Tests/editor_camera_authoring_contracts.py"
"$<TARGET_FILE:WaveEditor>"
)
set_tests_properties(
WaveEngine.EditorCameraAuthoringContracts
PROPERTIES
WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}"
TIMEOUT 120
LABELS "contract;editor-domain;mcp;gpu;camera"
ENVIRONMENT "WAVE_RG_STRICT=1"
RUN_SERIAL TRUE
)

add_test(
NAME WaveEngine.EditorRenderAuthoringContracts
COMMAND "${Python3_EXECUTABLE}"
"${PROJECT_SOURCE_DIR}/Tests/editor_render_authoring_contracts.py"
"$<TARGET_FILE:WaveEditor>"
)
set_tests_properties(
WaveEngine.EditorRenderAuthoringContracts
PROPERTIES
WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}"
TIMEOUT 120
LABELS "contract;editor-domain;mcp;gpu;render"
ENVIRONMENT "WAVE_RG_STRICT=1"
RUN_SERIAL TRUE
)

add_test(
NAME WaveEngine.WEMeshCacheContracts
COMMAND "${Python3_EXECUTABLE}"
Expand Down Expand Up @@ -501,4 +614,16 @@ if(BUILD_TESTING)
TIMEOUT 10
LABELS "contract;core;cpu"
)

add_test(
NAME WaveEngine.EditorDomainContracts
COMMAND "$<TARGET_FILE:WaveEditorDomainContracts>"
)
set_tests_properties(
WaveEngine.EditorDomainContracts
PROPERTIES
WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}"
TIMEOUT 10
LABELS "contract;editor-domain;cpu"
)
endif()
6 changes: 4 additions & 2 deletions CMakePresets.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@
"configurePreset": "vs2022-x64",
"configuration": "Debug",
"targets": [
"WaveCoreContracts"
"WaveCoreContracts",
"WaveEditorDomainContracts"
]
},
{
Expand All @@ -37,7 +38,8 @@
"configurePreset": "vs2022-x64",
"configuration": "Release",
"targets": [
"WaveCoreContracts"
"WaveCoreContracts",
"WaveEditorDomainContracts"
]
}
],
Expand Down
89 changes: 89 additions & 0 deletions Engine/Source/Core/Application/ApplicationClock.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
#include "ApplicationClock.h"

#include <algorithm>
#include <cmath>
#include <stdexcept>

namespace WaveApplication
{
FApplicationClock::FApplicationClock(FApplicationTimingConfig InConfig)
: Config(std::move(InConfig))
{
if (!std::isfinite(Config.MaxDeltaSeconds)
|| Config.MaxDeltaSeconds <= 0.0
|| Config.MaxDeltaSeconds > 0.25)
{
throw std::invalid_argument("Application clock maximum delta must be in (0, 0.25].");
}
if (Config.FixedDeltaSeconds
&& (!std::isfinite(*Config.FixedDeltaSeconds)
|| *Config.FixedDeltaSeconds <= 0.0
|| *Config.FixedDeltaSeconds > 0.25))
{
throw std::invalid_argument("Application clock fixed delta must be in (0, 0.25].");
}
}

FApplicationClockResult FApplicationClock::Tick(double MonotonicSeconds)
{
FApplicationClockResult Result;
if (!std::isfinite(MonotonicSeconds))
{
Result.Diagnostics.push_back({
"application.clock.non_finite",
"clock.monotonic_seconds",
"Monotonic clock sample must be finite.",
EApplicationDiagnosticSeverity::Fatal,
false,
});
return Result;
}
if (PreviousSeconds && MonotonicSeconds < *PreviousSeconds)
{
Result.Diagnostics.push_back({
"application.clock.regressed",
"clock.monotonic_seconds",
"Monotonic clock sample moved backwards.",
EApplicationDiagnosticSeverity::Fatal,
false,
});
return Result;
}

FApplicationClockSample Sample;
Sample.TickSequence = TickSequence;
Sample.RealTimeSeconds = MonotonicSeconds;
Sample.bFirstTick = !PreviousSeconds.has_value();
Sample.RealDeltaSeconds = PreviousSeconds
? MonotonicSeconds - *PreviousSeconds
: 1.0 / 60.0;
Sample.GameDeltaSeconds = std::min(Sample.RealDeltaSeconds, Config.MaxDeltaSeconds);
Sample.bClamped = Sample.RealDeltaSeconds > Config.MaxDeltaSeconds;
if (Config.FixedDeltaSeconds)
{
Sample.GameDeltaSeconds = *Config.FixedDeltaSeconds;
Sample.bFixed = true;
}

PreviousSeconds = MonotonicSeconds;
++TickSequence;
Result.Sample = Sample;
if (Sample.bClamped)
{
Result.Diagnostics.push_back({
"application.clock.delta_clamped",
"clock.game_delta_seconds",
"Variable game delta was clamped to the configured maximum.",
EApplicationDiagnosticSeverity::Warning,
false,
});
}
return Result;
}

void FApplicationClock::Reset()
{
PreviousSeconds.reset();
TickSequence = 0;
}
}
40 changes: 40 additions & 0 deletions Engine/Source/Core/Application/ApplicationClock.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#pragma once

#include "ApplicationConfig.h"

#include <optional>
#include <vector>

namespace WaveApplication
{
struct FApplicationClockSample
{
uint64 TickSequence = 0;
double RealTimeSeconds = 0.0;
double RealDeltaSeconds = 0.0;
double GameDeltaSeconds = 0.0;
bool bFirstTick = false;
bool bClamped = false;
bool bFixed = false;
};

struct FApplicationClockResult
{
std::optional<FApplicationClockSample> Sample;
std::vector<FApplicationDiagnostic> Diagnostics;
};

class FApplicationClock
{
public:
explicit FApplicationClock(FApplicationTimingConfig InConfig);

[[nodiscard]] FApplicationClockResult Tick(double MonotonicSeconds);
void Reset();

private:
FApplicationTimingConfig Config;
std::optional<double> PreviousSeconds;
uint64 TickSequence = 0;
};
}
Loading