editor: explicit runtime path contract
This commit is contained in:
@@ -35,11 +35,48 @@ constexpr const wchar_t* kWindowTitle = L"Main Scene * - Main.xx - XCEngine Edit
|
||||
constexpr DWORD kBorderlessWindowStyle = WS_POPUP | WS_THICKFRAME;
|
||||
constexpr int kDefaultSmokeTestDurationSeconds = 12;
|
||||
|
||||
bool HasEditorRepoMarkers(const std::filesystem::path& root) {
|
||||
return std::filesystem::exists(root / "editor" / "AGENTS.md") &&
|
||||
bool HasEditorWorkspaceMarkers(const std::filesystem::path& root) {
|
||||
return std::filesystem::exists(root / "CMakeLists.txt") &&
|
||||
std::filesystem::exists(root / "editor" / "resources") &&
|
||||
std::filesystem::exists(root / "project");
|
||||
}
|
||||
|
||||
std::filesystem::path NormalizePath(const std::filesystem::path& path) {
|
||||
std::error_code errorCode = {};
|
||||
std::filesystem::path normalized =
|
||||
std::filesystem::weakly_canonical(path, errorCode);
|
||||
return errorCode
|
||||
? path.lexically_normal()
|
||||
: normalized.lexically_normal();
|
||||
}
|
||||
|
||||
App::EditorRuntimePaths BuildEditorRuntimePaths(
|
||||
const std::filesystem::path& workspaceRoot,
|
||||
const std::filesystem::path& executableDirectory) {
|
||||
App::EditorRuntimePaths paths = {};
|
||||
paths.workspaceRoot = NormalizePath(workspaceRoot);
|
||||
paths.executableRoot = NormalizePath(executableDirectory);
|
||||
|
||||
const std::filesystem::path sourceTreeResourceRoot =
|
||||
paths.workspaceRoot / "editor" / "resources";
|
||||
const std::filesystem::path packagedResourceRoot =
|
||||
paths.executableRoot / "resources";
|
||||
paths.resourceRoot = std::filesystem::exists(sourceTreeResourceRoot)
|
||||
? NormalizePath(sourceTreeResourceRoot)
|
||||
: NormalizePath(packagedResourceRoot);
|
||||
|
||||
const std::filesystem::path sourceTreeProjectRoot =
|
||||
paths.workspaceRoot / "project";
|
||||
const std::filesystem::path packagedProjectRoot =
|
||||
paths.executableRoot / "project";
|
||||
paths.projectRoot = std::filesystem::exists(sourceTreeProjectRoot)
|
||||
? NormalizePath(sourceTreeProjectRoot)
|
||||
: NormalizePath(packagedProjectRoot);
|
||||
|
||||
paths.captureRoot = NormalizePath(paths.executableRoot / "captures");
|
||||
return paths;
|
||||
}
|
||||
|
||||
void EnableDpiAwareness() {
|
||||
const HMODULE user32 = GetModuleHandleW(L"user32.dll");
|
||||
if (user32 != nullptr) {
|
||||
@@ -118,7 +155,7 @@ namespace XCEngine::UI::Editor {
|
||||
bool Application::Initialize(HINSTANCE hInstance, int nCmdShow) {
|
||||
m_hInstance = hInstance;
|
||||
m_resourceService = std::make_unique<Host::Win32EditorResourceService>(m_hInstance);
|
||||
m_repoRoot = ResolveRepoRootPath(m_resourceService->GetExecutableDirectory());
|
||||
m_runtimePaths = ResolveRuntimePaths(m_resourceService->GetExecutableDirectory());
|
||||
EnableDpiAwareness();
|
||||
|
||||
const std::filesystem::path logRoot = m_resourceService->GetExecutableDirectory() / "logs";
|
||||
@@ -126,7 +163,7 @@ bool Application::Initialize(HINSTANCE hInstance, int nCmdShow) {
|
||||
SetUnhandledExceptionFilter(&Application::HandleUnhandledException);
|
||||
AppendUIEditorRuntimeTrace("app", "initialize begin");
|
||||
|
||||
if (!m_editorContext->Initialize(m_repoRoot)) {
|
||||
if (!m_editorContext->Initialize(m_runtimePaths)) {
|
||||
AppendUIEditorRuntimeTrace(
|
||||
"app",
|
||||
"shell asset validation failed: " + m_editorContext->GetValidationMessage());
|
||||
@@ -149,8 +186,7 @@ bool Application::Initialize(HINSTANCE hInstance, int nCmdShow) {
|
||||
hostConfig.windowUserData = this;
|
||||
m_windowHostRuntime = std::make_unique<App::EditorWindowHostRuntime>(
|
||||
hostConfig,
|
||||
m_repoRoot,
|
||||
m_editorContext->GetShellAsset().captureRootPath);
|
||||
m_runtimePaths);
|
||||
m_renderRuntimeFactory =
|
||||
std::make_unique<Host::D3D12EditorWindowRenderRuntimeFactory>();
|
||||
App::EditorWorkspaceShellRuntimeFactory workspaceShellRuntimeFactory = []() {
|
||||
@@ -270,18 +306,13 @@ void Application::Shutdown() {
|
||||
ShutdownUIEditorRuntimeTrace();
|
||||
}
|
||||
|
||||
std::filesystem::path Application::ResolveRepoRootPath(
|
||||
App::EditorRuntimePaths Application::ResolveRuntimePaths(
|
||||
const std::filesystem::path& executableDirectory) {
|
||||
std::error_code errorCode = {};
|
||||
std::filesystem::path current =
|
||||
std::filesystem::weakly_canonical(executableDirectory, errorCode);
|
||||
if (errorCode) {
|
||||
current = executableDirectory.lexically_normal();
|
||||
}
|
||||
std::filesystem::path current = NormalizePath(executableDirectory);
|
||||
|
||||
while (!current.empty()) {
|
||||
if (HasEditorRepoMarkers(current)) {
|
||||
return current.lexically_normal();
|
||||
if (HasEditorWorkspaceMarkers(current)) {
|
||||
return BuildEditorRuntimePaths(current, executableDirectory);
|
||||
}
|
||||
|
||||
const std::filesystem::path parent = current.parent_path();
|
||||
@@ -291,7 +322,7 @@ std::filesystem::path Application::ResolveRepoRootPath(
|
||||
current = parent;
|
||||
}
|
||||
|
||||
return executableDirectory.lexically_normal();
|
||||
return BuildEditorRuntimePaths(executableDirectory, executableDirectory);
|
||||
}
|
||||
|
||||
LONG WINAPI Application::HandleUnhandledException(EXCEPTION_POINTERS* exceptionInfo) {
|
||||
|
||||
Reference in New Issue
Block a user