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
10 changes: 9 additions & 1 deletion Obelisk/EntryPoint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include <Tetragrama/Editor.h>
#include <ZEngine/Applications/GameApplication.h>
#include <ZEngine/Core/Memory/MemoryManager.h>
#include <ZEngine/CrashHandlers/CrashHandler.h>
#include <ZEngine/EngineConfiguration.h>
#include <ZEngine/Helpers/ThreadPool.h>
#include <ZEngine/Logging/Logger.h>
Expand All @@ -12,9 +13,12 @@ using namespace ZEngine;
using namespace ZEngine::Logging;
using namespace ZEngine::Core::Memory;
using namespace ZEngine::Applications;
using namespace ZEngine::CrashHandlers;

int applicationEntryPoint(int argc, char* argv[])
{
CrashHandler::Install("Obelisk", "1.0.0", "CrashDumps");

MemoryManager manager = {};
MemoryConfiguration config = {.BufferSize = ZGiga(3u)};
manager.Initialize(config);
Expand Down Expand Up @@ -43,7 +47,10 @@ int applicationEntryPoint(int argc, char* argv[])
app->EnableRenderOverlay = true;
}

app->ConfigFile = config_file.c_str();
auto config_file_str_size = config_file.size() + 1;
auto config_file_str = ZPushString(arena, config_file_str_size);
Helpers::secure_strncpy(config_file_str, config_file_str_size, config_file.c_str(), config_file.size());
app->ConfigFile = config_file_str;

app->Initialize(arena);
app->Run();
Expand All @@ -53,6 +60,7 @@ int applicationEntryPoint(int argc, char* argv[])

manager.Shutdown();

CrashHandler::Uninstall();
return 0;
}

Expand Down
2 changes: 1 addition & 1 deletion Scripts/ClangFormat.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ $ErrorActionPreference = "Stop"

. (Join-Path $PSScriptRoot Shared.ps1)

$srcFiles = Get-ChildItem -Path $SourceDirectory -Recurse -File | Where-Object { $_.Name -notlike "CMakeLists*" -and $_.Name -notlike "*.json" -and $_.Name -notlike "*.spv" -and $_.Name -notlike "*.md"}
$srcFiles = Get-ChildItem -Path $SourceDirectory -Recurse -File | Where-Object { $_.Name -notlike "CMakeLists*" -and $_.Name -notlike "*.json" -and $_.Name -notlike "*.spv" -and $_.Name -notlike "*.md" -and $_.Name -notlike "*.mm"}

if ($srcFiles.Count -eq 0) {
Write-Host "No source files found in the specified directory."
Expand Down
108 changes: 88 additions & 20 deletions ZEngine/ZEngine/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,26 +31,97 @@ configure_file(
@ONLY
)

file (GLOB_RECURSE HEADER_FILES_LIST CONFIGURE_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/*.h)
file (GLOB_RECURSE CPP_FILES_LIST CONFIGURE_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
file (GLOB_RECURSE RESOURCE_FILES_LIST CONFIGURE_DEPENDS ${PROJECT_SOURCE_DIR}/../Resources/Shaders/*.*)
# Per-subsystem source globs — add platform-specific .cpp files by appending to
# the relevant variable inside the per-platform blocks further below, e.g.:
# list(APPEND ZENGINE_SOURCES_WINDOWS
# ${CMAKE_CURRENT_SOURCE_DIR}/Windows/Inputs/Platform/Win32/Win32Input.cpp)
#
file(GLOB_RECURSE ZENGINE_SOURCES_CORE CONFIGURE_DEPENDS
${CMAKE_CURRENT_SOURCE_DIR}/Core/*.cpp
)
file(GLOB_RECURSE ZENGINE_SOURCES_RENDERING CONFIGURE_DEPENDS
${CMAKE_CURRENT_SOURCE_DIR}/Rendering/*.cpp
)
file(GLOB_RECURSE ZENGINE_SOURCES_WINDOWS CONFIGURE_DEPENDS
${CMAKE_CURRENT_SOURCE_DIR}/Windows/*.cpp
)
file(GLOB_RECURSE ZENGINE_SOURCES_APPLICATION CONFIGURE_DEPENDS
${CMAKE_CURRENT_SOURCE_DIR}/Applications/*.cpp
${CMAKE_CURRENT_SOURCE_DIR}/Layers/*.cpp
${CMAKE_CURRENT_SOURCE_DIR}/Controllers/*.cpp
)
file(GLOB_RECURSE ZENGINE_SOURCES_MANAGERS CONFIGURE_DEPENDS
${CMAKE_CURRENT_SOURCE_DIR}/Managers/*.cpp
${CMAKE_CURRENT_SOURCE_DIR}/Serializers/*.cpp
${CMAKE_CURRENT_SOURCE_DIR}/Importers/*.cpp
)
file(GLOB_RECURSE ZENGINE_SOURCES_HELPERS CONFIGURE_DEPENDS
${CMAKE_CURRENT_SOURCE_DIR}/Helpers/*.cpp
${CMAKE_CURRENT_SOURCE_DIR}/Logging/*.cpp
)
file(GLOB_RECURSE ZENGINE_SOURCES_EVENT CONFIGURE_DEPENDS
${CMAKE_CURRENT_SOURCE_DIR}/Event/*.cpp
)
file(GLOB_RECURSE ZENGINE_SOURCES_HARDWARE CONFIGURE_DEPENDS
${CMAKE_CURRENT_SOURCE_DIR}/Hardwares/*.cpp
)

if(APPLE)
list(APPEND ZENGINE_SOURCES_CRASH_HANDLERS
${CMAKE_CURRENT_SOURCE_DIR}/CrashHandlers/CrashHandlerMacOS.mm
)
elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
list(APPEND ZENGINE_SOURCES_CRASH_HANDLERS
${CMAKE_CURRENT_SOURCE_DIR}/CrashHandlers/CrashHandlerWindows.cpp
)
elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
list(APPEND ZENGINE_SOURCES_CRASH_HANDLERS
${CMAKE_CURRENT_SOURCE_DIR}/CrashHandlers/CrashHandlerLinux.cpp
)
else()
message(WARNING "CrashHandler: unsupported platform '${CMAKE_SYSTEM_NAME}' — crash reporting disabled")
endif()

source_group (TREE ${PROJECT_SOURCE_DIR}/ZEngine PREFIX "Source Files" FILES ${HEADER_FILES_LIST} ${CPP_FILES_LIST})
source_group (TREE ${PROJECT_SOURCE_DIR}/../Resources PREFIX "Resources Files" FILES ${RESOURCE_FILES_LIST})
file(GLOB_RECURSE ZENGINE_RESOURCES CONFIGURE_DEPENDS ${PROJECT_SOURCE_DIR}/../Resources/Shaders/*.*)

source_group(TREE ${PROJECT_SOURCE_DIR}/ZEngine PREFIX "Source Files" FILES
${ZENGINE_HEADERS}
${ZENGINE_SOURCES_CORE}
${ZENGINE_SOURCES_RENDERING}
${ZENGINE_SOURCES_WINDOWS}
${ZENGINE_SOURCES_APPLICATION}
${ZENGINE_SOURCES_MANAGERS}
${ZENGINE_SOURCES_HELPERS}
${ZENGINE_SOURCES_EVENT}
${ZENGINE_SOURCES_HARDWARE}
${ZENGINE_SOURCES_CRASH_HANDLERS}
)
source_group(TREE ${PROJECT_SOURCE_DIR}/../Resources PREFIX "Resources Files" FILES ${ZENGINE_RESOURCES})

# ZEngine source files
#
add_library (zEngineLib STATIC)

target_sources(zEngineLib PRIVATE ${CPP_FILES_LIST}
PUBLIC FILE_SET HEADERS BASE_DIRS ${PROJECT_SOURCE_DIR})
add_library(zEngineLib STATIC)

target_sources(zEngineLib PUBLIC FILE_SET HEADERS BASE_DIRS ${PROJECT_SOURCE_DIR})

if(${CMAKE_BUILD_TYPE} STREQUAL "Debug")
target_compile_definitions (zEngineLib PUBLIC ENABLE_VULKAN_VALIDATION_LAYER)
endif()
target_sources(zEngineLib PRIVATE
${ZENGINE_SOURCES_CORE}
${ZENGINE_SOURCES_RENDERING}
${ZENGINE_SOURCES_WINDOWS}
${ZENGINE_SOURCES_APPLICATION}
${ZENGINE_SOURCES_MANAGERS}
${ZENGINE_SOURCES_HELPERS}
${ZENGINE_SOURCES_EVENT}
${ZENGINE_SOURCES_HARDWARE}
${ZENGINE_SOURCES_CRASH_HANDLERS}
${CMAKE_CURRENT_SOURCE_DIR}/Engine.cpp
)

target_compile_definitions (zEngineLib
PRIVATE
$<$<OR:$<CONFIG:Release>,$<CONFIG:RelWithDebInfo>>:ZENGINE_CRASH_HANDLER_ENABLED=1>
$<$<CONFIG:Release>:ZENGINE_RELEASE=1>
$<$<CONFIG:RelWithDebInfo>:ZENGINE_RELWITHDEBINFO=1>
PUBLIC
ZENGINE_PLATFORM
ENABLE_VULKAN_SYNCHRONIZATION_LAYER
Expand All @@ -60,15 +131,12 @@ target_compile_definitions (zEngineLib
target_link_libraries (zEngineLib PUBLIC imported::ZEngine_External_Dependencies)

if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
target_link_libraries (zEngineLib PUBLIC imported::cppwinrt_headers WindowsApp.lib)
target_link_libraries (zEngineLib PUBLIC imported::cppwinrt_headers WindowsApp.lib DbgHelp.lib User32.lib)
target_compile_definitions(zEngineLib PUBLIC NOMINMAX GLFW_EXPOSE_NATIVE_WIN32)
endif()

if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
target_link_libraries(zEngineLib PUBLIC stdc++fs)
elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
target_link_libraries(zEngineLib PUBLIC stdc++fs dl)
target_compile_definitions(zEngineLib PUBLIC GLFW_EXPOSE_NATIVE_WAYLAND)
endif ()

if (CMAKE_SYSTEM_NAME STREQUAL "Darwin")
elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin")
target_link_libraries(zEngineLib PRIVATE "-lobjc" "-framework AppKit" "-framework CoreGraphics")
target_compile_definitions(zEngineLib PUBLIC GLFW_EXPOSE_NATIVE_COCOA)
endif()
57 changes: 57 additions & 0 deletions ZEngine/ZEngine/CrashHandlers/CrashHandler.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#pragma once

namespace ZEngine::CrashHandlers
{
struct CrashHandler
{
using PreCrashFn = void (*)(void* ctx);

// Install the platform crash handler.
// app_name — e.g. "GameName"
// version — e.g. "1.0.0"
// crash_log_dir — directory where crash logs and .dmp files are written.
// Created if it does not exist.
//
// Call once, before any engine subsystem is initialized.
// No-op if already installed.
static void Install(const char* app_name, const char* version, const char* crash_log_dir);

// Remove the platform crash handler and restore default OS behavior.
// Call at engine shutdown. Safe to call if Install() was never called.
static void Uninstall();

// Set a callback to be called just before the crash dump is written.
// This is useful for flushing logs, saving game state, etc.
//
// The callback must complete within a defined timeout (default 2 seconds) or the crash handler will proceed to write the dump anyway.
// On Windows, a helper thread's timeout fires
// On Linux, macOS SIGALRM is raised on the callback thread
//
// Only one callback can be set at a time. Setting a new callback replaces the previous one.
// It must not allocate memory on the ZEngine heap, or call ZENGINE_VALIDATE_ASSERT.
static void SetPreCrashCallback(PreCrashFn fn, void* ctx = nullptr);

// Called by the platform handler (SEH filter on Windows, signal handler
// on POSIX) to perform the cross-platform crash response.
// signal_or_exception — human-readable description, e.g.
// "Access Violation at 0x0000000000000000"
// context — platform-specific context:
// Windows: EXCEPTION_POINTERS*
// POSIX: ucontext_t*
//
// This function does not return under normal conditions.
[[noreturn]] static void OnCrash(const char* signal_or_exception, void* ctx = nullptr);

// Called by ZENGINE_VALIDATE_ASSERT to produce a crash report for
// assertion failures in Release/RelWithDebInfo builds.
// file — __FILE__
// line — __LINE__
// message — the assertion condition and user message string
[[noreturn]] static void OnAssertionFailure(const char* file, int line, const char* message);

private:
CrashHandler() = delete;

static void StoreMetadata(const char* app_name, const char* version, const char* crash_log_dir);
};
} // namespace ZEngine::CrashHandlers
29 changes: 29 additions & 0 deletions ZEngine/ZEngine/CrashHandlers/CrashHandlerInternal.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#pragma once
#include <ZEngine/CrashHandlers/CrashHandler.h>
#include <cstddef>

namespace ZEngine::CrashHandlers
{
namespace
{
constexpr size_t kMaxPathLen = 512;
constexpr size_t kMaxNameLen = 128;
constexpr size_t kMaxCommentLen = 1024;
constexpr int kCallbackTimeoutSec = 2;

struct CrashHandlerState
{
bool Installed = false;
bool UserConsentUpload = false;
char AppName[kMaxNameLen] = {};
char Version[kMaxNameLen] = {};
char CrashLogDir[kMaxPathLen] = {};
char UserComment[kMaxCommentLen] = {};

void* PreCrashCtx = nullptr;
CrashHandler::PreCrashFn PreCrashFn = nullptr;
};

CrashHandlerState g_state = {};
} // namespace
} // namespace ZEngine::CrashHandlers
Loading
Loading