Files
XCEngine/new_editor/app/Bootstrap/ApplicationBootstrap.cpp

134 lines
4.3 KiB
C++
Raw Normal View History

#include "Bootstrap/Application.h"
#include "Bootstrap/ApplicationBootstrapInternal.h"
#include <XCEditor/Foundation/UIEditorRuntimeTrace.h>
#include <XCEngine/Core/Asset/ResourceManager.h>
#include "Ports/SystemInteractionPort.h"
#include "Composition/EditorContext.h"
#include "Platform/Win32/EditorWindow.h"
#include "Platform/Win32/EditorWindowManager.h"
#include "Platform/Win32/Win32SystemInteractionHost.h"
#include "Internal/ExecutablePath.h"
#ifndef XCUIEDITOR_REPO_ROOT
#define XCUIEDITOR_REPO_ROOT "."
#endif
namespace XCEngine::UI::Editor {
using namespace BootstrapInternal;
using App::Internal::GetExecutableDirectory;
bool Application::Initialize(HINSTANCE hInstance, int nCmdShow) {
m_hInstance = hInstance;
m_repoRoot = ResolveRepoRootPath();
EnableDpiAwareness();
const std::filesystem::path logRoot = GetExecutableDirectory() / "logs";
InitializeUIEditorRuntimeTrace(logRoot);
SetUnhandledExceptionFilter(&Application::HandleUnhandledException);
AppendUIEditorRuntimeTrace("app", "initialize begin");
if (!m_editorContext->Initialize(m_repoRoot)) {
AppendUIEditorRuntimeTrace(
"app",
"shell asset validation failed: " + m_editorContext->GetValidationMessage());
return false;
}
if (!RegisterWindowClass()) {
return false;
}
m_systemInteractionHost = std::make_unique<Host::Win32SystemInteractionHost>();
m_editorContext->SetSystemInteractionHost(m_systemInteractionHost.get());
App::EditorWindowHostConfig hostConfig = {};
hostConfig.hInstance = m_hInstance;
hostConfig.windowClassName = kWindowClassName;
hostConfig.windowStyle = kBorderlessWindowStyle;
hostConfig.primaryWindowTitle = kWindowTitle;
hostConfig.windowUserData = this;
m_windowManager = std::make_unique<App::EditorWindowManager>(
hostConfig,
m_repoRoot,
*m_editorContext);
m_editorContext->SetExitRequestHandler([this]() {
if (m_windowManager == nullptr) {
return;
}
if (App::EditorWindow* primaryWindow = m_windowManager->FindPrimaryWindow();
primaryWindow != nullptr &&
primaryWindow->GetHwnd() != nullptr) {
PostMessageW(primaryWindow->GetHwnd(), WM_CLOSE, 0, 0);
}
});
m_editorContext->SetReadyStatus();
App::EditorWindowManager::CreateParams createParams = {};
createParams.windowId = "main";
createParams.title = kWindowTitle;
createParams.showCommand = nCmdShow;
createParams.primary = true;
createParams.autoCaptureOnStartup = true;
if (m_windowManager->CreateEditorWindow(
m_editorContext->BuildWorkspaceController(),
createParams) == nullptr) {
AppendUIEditorRuntimeTrace("app", "primary window creation failed");
return false;
}
AppendUIEditorRuntimeTrace("app", "initialize end");
return true;
}
void Application::Shutdown() {
AppendUIEditorRuntimeTrace("app", "shutdown begin");
if (m_windowManager != nullptr) {
m_windowManager->Shutdown();
m_windowManager.reset();
}
if (m_editorContext != nullptr) {
m_editorContext->SetSystemInteractionHost(nullptr);
}
m_systemInteractionHost.reset();
::XCEngine::Resources::ResourceManager::Get().Shutdown();
if (m_windowClassAtom != 0 && m_hInstance != nullptr) {
UnregisterClassW(kWindowClassName, m_hInstance);
m_windowClassAtom = 0;
}
AppendUIEditorRuntimeTrace("app", "shutdown end");
ShutdownUIEditorRuntimeTrace();
}
std::filesystem::path Application::ResolveRepoRootPath() {
std::string root = XCUIEDITOR_REPO_ROOT;
if (root.size() >= 2u && root.front() == '"' && root.back() == '"') {
root = root.substr(1u, root.size() - 2u);
}
return std::filesystem::path(root).lexically_normal();
}
LONG WINAPI Application::HandleUnhandledException(EXCEPTION_POINTERS* exceptionInfo) {
if (exceptionInfo != nullptr &&
exceptionInfo->ExceptionRecord != nullptr) {
AppendUIEditorCrashTrace(
exceptionInfo->ExceptionRecord->ExceptionCode,
exceptionInfo->ExceptionRecord->ExceptionAddress);
} else {
AppendUIEditorCrashTrace(0u, nullptr);
}
return EXCEPTION_EXECUTE_HANDLER;
}
} // namespace XCEngine::UI::Editor