#include "MetaCoreEditor/MetaCoreEditorApp.h" #include #include #include #include #include #include #include #include #include #include #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #endif #include namespace { std::filesystem::path MetaCoreGetExecutableDirectory() { std::vector buffer(MAX_PATH, L'\0'); while (true) { const DWORD copied = GetModuleFileNameW(nullptr, buffer.data(), static_cast(buffer.size())); if (copied == 0) { return {}; } if (copied < buffer.size() - 1) { return std::filesystem::path(std::wstring(buffer.data(), copied)).parent_path(); } buffer.resize(buffer.size() * 2, L'\0'); } } std::filesystem::path MetaCoreGetCrashLogPath() { const std::filesystem::path executableDirectory = MetaCoreGetExecutableDirectory(); if (!executableDirectory.empty()) { return executableDirectory / "editor.crash.log"; } return "editor.crash.log"; } void MetaCoreResetCrashLog() { std::ofstream stream(MetaCoreGetCrashLogPath(), std::ios::trunc); } void MetaCoreWriteCrashLog(const std::string& message) { std::ofstream stream(MetaCoreGetCrashLogPath(), std::ios::app); if (!stream.is_open()) { return; } stream << message << '\n'; } void MetaCoreWriteCrashLogRaw(const char* message) { if (message == nullptr) { return; } FILE* file = nullptr; const std::filesystem::path crashLogPath = MetaCoreGetCrashLogPath(); if (fopen_s(&file, crashLogPath.string().c_str(), "a") == 0 && file != nullptr) { std::fputs(message, file); std::fputs("\n", file); std::fclose(file); } } void MetaCoreInvalidParameterHandler( const wchar_t* expression, const wchar_t* functionName, const wchar_t* fileName, unsigned int line, uintptr_t reserved ) { (void)reserved; MetaCoreWriteCrashLog("metacore.app: invalid parameter triggered"); if (expression != nullptr) { MetaCoreWriteCrashLog("metacore.app: invalid parameter expression="); } if (functionName != nullptr) { MetaCoreWriteCrashLog("metacore.app: invalid parameter function="); } if (fileName != nullptr) { MetaCoreWriteCrashLog("metacore.app: invalid parameter file="); } MetaCoreWriteCrashLog("metacore.app: invalid parameter line=" + std::to_string(line)); } void MetaCorePureCallHandler() { MetaCoreWriteCrashLog("metacore.app: purecall handler triggered"); } void MetaCoreSignalHandler(int signalValue) { MetaCoreWriteCrashLog("metacore.app: signal=" + std::to_string(signalValue)); } void MetaCoreTerminateHandler() { MetaCoreWriteCrashLog("metacore.app: std::terminate triggered"); if (std::exception_ptr exceptionPtr = std::current_exception(); exceptionPtr != nullptr) { try { std::rethrow_exception(exceptionPtr); } catch (const std::exception& exceptionObject) { MetaCoreWriteCrashLog(std::string("metacore.app: exception=") + exceptionObject.what()); } catch (...) { MetaCoreWriteCrashLog("metacore.app: exception="); } } else { MetaCoreWriteCrashLog("metacore.app: exception="); } std::_Exit(3); } void MetaCoreInstallDebugCrashHooks() { #if defined(_DEBUG) _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT); _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE); _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE); _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR); _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR); _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR); _set_invalid_parameter_handler(&MetaCoreInvalidParameterHandler); _set_purecall_handler(&MetaCorePureCallHandler); std::set_terminate(&MetaCoreTerminateHandler); std::signal(SIGABRT, &MetaCoreSignalHandler); MetaCoreWriteCrashLog("metacore.app: debug crash hooks installed"); #endif } } // namespace int main(int argc, char* argv[]) { if (argc > 0) { const std::filesystem::path executableDirectory = MetaCoreGetExecutableDirectory(); if (!executableDirectory.empty()) { std::filesystem::current_path(executableDirectory); } } MetaCoreResetCrashLog(); MetaCoreInstallDebugCrashHooks(); MetaCoreWriteCrashLogRaw("metacore.app: hooks installed"); MetaCoreWriteCrashLogRaw("metacore.app: set current_path done"); MetaCoreWriteCrashLogRaw("metacore.app: construct app begin"); MetaCore::MetaCoreEditorApp editorApp; MetaCoreWriteCrashLogRaw("metacore.app: construct app done"); MetaCoreWriteCrashLogRaw("metacore.app: initialize begin"); if (!editorApp.Initialize(argc, argv)) { MetaCoreWriteCrashLogRaw("metacore.app: initialize failed"); std::cerr << "MetaCoreEditorApp initialize failed\n"; return 1; } MetaCoreWriteCrashLogRaw("metacore.app: initialize done"); MetaCoreWriteCrashLogRaw("metacore.app: run begin"); const int exitCode = editorApp.Run(); MetaCoreWriteCrashLogRaw("metacore.app: run done"); editorApp.Shutdown(); MetaCoreWriteCrashLogRaw("metacore.app: shutdown done"); return exitCode; }