Skip to content
Draft
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
228 changes: 172 additions & 56 deletions ZEngine/ZEngine/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,68 +31,187 @@ 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
)

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})
if(APPLE)
list(APPEND ZENGINE_SOURCES_CRASH_HANDLERS
${CMAKE_CURRENT_SOURCE_DIR}/CrashHandlers/CrashHandlerMacOS.cpp
)
elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
list(APPEND ZENGINE_SOURCES_CRASH_HANDLERS
${CMAKE_CURRENT_SOURCE_DIR}/CrashHandlers/CrashHandlerWindows.cpp
)
else(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
list(APPEND ZENGINE_SOURCES_CRASH_HANDLERS
${CMAKE_CURRENT_SOURCE_DIR}/CrashHandlers/CrashHandlerLinux.cpp
)
endif()

file(GLOB_RECURSE ZENGINE_HEADERS CONFIGURE_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/*.h)
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)
add_library(zEngineLib STATIC)

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_sources(zEngineLib PRIVATE ${CPP_FILES_LIST})
# Subsystem include directories.
# Each variable owns one logical subsystem. To add platform-specific paths,
# append to the relevant variable inside the per-platform blocks below, e.g.:
# list(APPEND ZENGINE_SUBSYSTEM_WINDOWS ./Windows/Inputs/Platform/Win32)
#
set(ZENGINE_SUBSYSTEM_CORE
./Core
./Core/Maths
./Core/Memory
./Core/Containers
./Core/VFS
)

target_include_directories (zEngineLib
PUBLIC
set(ZENGINE_SUBSYSTEM_RENDERING
./Rendering
./Rendering/Buffers
./Rendering/Cameras
./Rendering/Components
./Rendering/Entities
./Rendering/Geometries
./Rendering/Lights
./Rendering/Materials
./Rendering/Meshes
./Rendering/Pools
./Rendering/Primitives
./Rendering/Renderers
./Rendering/Renderers/Contracts
./Rendering/Renderers/Pipelines
./Rendering/Renderers/RenderPasses
./Rendering/Renderers/Storages
./Rendering/Scenes
./Rendering/Shaders
./Rendering/Shaders/Compilers
./Rendering/Specifications
./Rendering/Textures
)

set(ZENGINE_SUBSYSTEM_WINDOWS
./Windows
./Windows/Events
./Windows/Inputs
./Windows/Layers
)

set(ZENGINE_SUBSYSTEM_APPLICATION
./Applications
./Layers
./Controllers
)

set(ZENGINE_SUBSYSTEM_MANAGERS
./Managers
./Serializers
./Importers
)

set(ZENGINE_SUBSYSTEM_HELPERS
./Helpers
./Logging
)

set(ZENGINE_SUBSYSTEM_EVENT
./Event
)

set(ZENGINE_SUBSYSTEM_HARDWARE
./Hardwares
)

# CrashHandlers is intentionally kept as an isolated subsystem so it can be
# replaced or disabled independently (e.g. platform that ships its own handler).
set(ZENGINE_SUBSYSTEM_CRASH_HANDLERS
./CrashHandlers
)

target_include_directories(zEngineLib
PUBLIC
${PROJECT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR}
./Applications
./Core
./Core/Maths
./Core/Memory
./Core/Containers
./Core/VFS
./Hardwares
./Helpers
./Layers
./Managers
./Importers
./Controllers
./Logging
./Rendering
./Rendering/Entities
./Rendering/Meshes
./Rendering/Buffers
./Rendering/Cameras
./Rendering/Pools
./Rendering/Primitives
./Rendering/Renderers
./Rendering/Renderers/Pipelines
./Rendering/Renderers/RenderPasses
./Rendering/Renderers/Storages
./Rendering/Scenes
./Rendering/Shaders
./Rendering/Shaders/Compilers
./Rendering/Specifications
./Rendering/Textures
./Windows
./Windows/Events
./Windows/Inputs
./Windows/Layers
./Managers
./Serializers
${ZENGINE_SUBSYSTEM_CORE}
${ZENGINE_SUBSYSTEM_RENDERING}
${ZENGINE_SUBSYSTEM_WINDOWS}
${ZENGINE_SUBSYSTEM_APPLICATION}
${ZENGINE_SUBSYSTEM_MANAGERS}
${ZENGINE_SUBSYSTEM_HELPERS}
${ZENGINE_SUBSYSTEM_EVENT}
${ZENGINE_SUBSYSTEM_HARDWARE}
${ZENGINE_SUBSYSTEM_CRASH_HANDLERS}
)

target_precompile_headers(zEngineLib PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/pch.h)

if(${CMAKE_BUILD_TYPE} STREQUAL "Debug")
target_compile_definitions (zEngineLib PUBLIC ENABLE_VULKAN_VALIDATION_LAYER)
endif()

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 @@ -102,15 +221,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")
target_compile_definitions(zEngineLib PUBLIC GLFW_EXPOSE_NATIVE_COCOA)
endif()
58 changes: 58 additions & 0 deletions ZEngine/ZEngine/CrashHandlers/CrashHandler.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#pragma once

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

// 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(cstring app_name, cstring version, cstring 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(cstring 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(cstring file, int line, cstring message);

private:
CrashHandler() = delete;

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

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

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

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

static CrashHandlerState g_state;
} // namespace
} // namespace ZEngine::CrashHandlers
Empty file.
Empty file.
Loading
Loading