chore(refactor): use new logger api
This commit is contained in:
parent
fef4a92378
commit
93d62c5b1a
@ -12,7 +12,7 @@ if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
|||||||
set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Choose the type of build." FORCE)
|
set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Choose the type of build." FORCE)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 17)
|
set(CMAKE_CXX_STANDARD 20)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
set(CMAKE_XCODE_GENERATE_SCHEME ON)
|
set(CMAKE_XCODE_GENERATE_SCHEME ON)
|
||||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||||
@ -114,6 +114,11 @@ set(ENGINE_SOURCES
|
|||||||
src/scene_manager.cpp
|
src/scene_manager.cpp
|
||||||
src/filepacker.cpp
|
src/filepacker.cpp
|
||||||
)
|
)
|
||||||
|
if (WIN32)
|
||||||
|
list(APPEND ENGINE_SOURCES src/platform/windows/FatalHandlerWindows.cpp)
|
||||||
|
elseif(UNIX)
|
||||||
|
list(APPEND ENGINE_SOURCES src/platform/posix/FatalHandlerPosix.cpp)
|
||||||
|
endif()
|
||||||
|
|
||||||
add_library(IsoEngine ${ENGINE_SOURCES})
|
add_library(IsoEngine ${ENGINE_SOURCES})
|
||||||
|
|
||||||
@ -147,7 +152,7 @@ target_link_libraries(rlImGui PRIVATE raylib ImGui)
|
|||||||
target_link_libraries(IsoEngine PRIVATE ImGui rlImGui)
|
target_link_libraries(IsoEngine PRIVATE ImGui rlImGui)
|
||||||
|
|
||||||
# Example executables (client/server)
|
# Example executables (client/server)
|
||||||
if(BUILD_CLIENT OR BUILD_SANDBOX)
|
if(BUILD_CLIENT)
|
||||||
# Client executable
|
# Client executable
|
||||||
set(CLIENT_SOURCE "${CMAKE_CURRENT_LIST_DIR}/sandbox/client.cpp")
|
set(CLIENT_SOURCE "${CMAKE_CURRENT_LIST_DIR}/sandbox/client.cpp")
|
||||||
add_executable(client ${CLIENT_SOURCE})
|
add_executable(client ${CLIENT_SOURCE})
|
||||||
@ -186,6 +191,7 @@ endif()
|
|||||||
# Build Configuration Optimizations
|
# Build Configuration Optimizations
|
||||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||||
message(STATUS "Configuring Debug build: No optimizations applied.")
|
message(STATUS "Configuring Debug build: No optimizations applied.")
|
||||||
|
target_compile_definitions(IsoEngine PRIVATE ENABLE_LOGGING)
|
||||||
elseif(CMAKE_BUILD_TYPE STREQUAL "Release")
|
elseif(CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||||
message(STATUS "Configuring Release build: Applying moderate optimizations.")
|
message(STATUS "Configuring Release build: Applying moderate optimizations.")
|
||||||
target_compile_options(IsoEngine PRIVATE -O2)
|
target_compile_options(IsoEngine PRIVATE -O2)
|
||||||
|
@ -1,45 +1,99 @@
|
|||||||
#include "IsoEngine.h"
|
#include "IsoEngine.h"
|
||||||
#include "components/transform_component.h"
|
#include "components.h"
|
||||||
#include "components/input_component.h"
|
|
||||||
#include <raylib.h>
|
#include <iostream>
|
||||||
|
|
||||||
|
#define ENABLE_LOGGING
|
||||||
|
|
||||||
|
enum class MenuState {
|
||||||
|
MAIN_MENU,
|
||||||
|
OPTIONS,
|
||||||
|
QUIT
|
||||||
|
};
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
IsoEngine engine(800, 600, nullptr);
|
int screenWidth = 800;
|
||||||
|
int screenHeight = 600;
|
||||||
|
IsoEngine engine(screenWidth, screenHeight, nullptr);
|
||||||
engine.Initialize();
|
engine.Initialize();
|
||||||
|
|
||||||
SceneManager& sceneManager = engine.GetSceneManager();
|
SceneManager& sceneManager = engine.GetSceneManager();
|
||||||
entt::entity gameScene = sceneManager.CreateScene();
|
entt::entity mainMenuScene = sceneManager.CreateScene();
|
||||||
sceneManager.SetActiveScene(gameScene);
|
|
||||||
|
|
||||||
entt::entity player = engine.GetRegistry().create();
|
auto& registry = engine.GetRegistry();
|
||||||
engine.GetRegistry().emplace<TransformComponent>(player, 400.0f, 300.0f, 1.0f, 1.0f, 0.0f);
|
|
||||||
|
|
||||||
auto& inputComponent = engine.GetRegistry().emplace<InputComponent>(player);
|
// Button dimensions
|
||||||
|
float buttonWidth = 200.0f;
|
||||||
|
float buttonHeight = 50.0f;
|
||||||
|
float spacing = 20.0f; // Vertical spacing between buttons
|
||||||
|
|
||||||
inputComponent.BindKey(InputAction::MOVE_UP, KEY_W);
|
// Center X position
|
||||||
inputComponent.BindKey(InputAction::MOVE_DOWN, KEY_S);
|
float centerX = screenWidth / 2 - buttonWidth / 2;
|
||||||
inputComponent.BindKey(InputAction::MOVE_LEFT, KEY_A);
|
|
||||||
inputComponent.BindKey(InputAction::MOVE_RIGHT, KEY_D);
|
|
||||||
|
|
||||||
inputComponent.SetActionCallback(InputAction::MOVE_UP, [&]() {
|
// Y positions for each button
|
||||||
auto& transform = engine.GetRegistry().get<TransformComponent>(player);
|
float singlePlayerY = screenHeight / 2 - (buttonHeight + spacing);
|
||||||
transform.y -= 5.0f;
|
float quitButtonY = screenHeight / 2 + (buttonHeight + spacing);
|
||||||
});
|
|
||||||
inputComponent.SetActionCallback(InputAction::MOVE_DOWN, [&]() {
|
// Create a UI button for "Single Player"
|
||||||
auto& transform = engine.GetRegistry().get<TransformComponent>(player);
|
entt::entity singlePlayerButton = registry.create();
|
||||||
transform.y += 5.0f;
|
registry.emplace<TransformComponent>(singlePlayerButton, centerX, singlePlayerY, 1.0f, 1.0f, 0.0f); // Centered horizontally
|
||||||
});
|
registry.emplace<UIComponent>(singlePlayerButton, "Single Player", buttonWidth, buttonHeight, [&]() {
|
||||||
inputComponent.SetActionCallback(InputAction::MOVE_LEFT, [&]() {
|
std::cout << "Single Player button clicked!" << std::endl;
|
||||||
auto& transform = engine.GetRegistry().get<TransformComponent>(player);
|
|
||||||
transform.x -= 5.0f;
|
|
||||||
});
|
|
||||||
inputComponent.SetActionCallback(InputAction::MOVE_RIGHT, [&]() {
|
|
||||||
auto& transform = engine.GetRegistry().get<TransformComponent>(player);
|
|
||||||
transform.x += 5.0f;
|
|
||||||
});
|
});
|
||||||
|
registry.emplace<LayerComponent>(singlePlayerButton, 1); // Main menu on layer 1
|
||||||
|
|
||||||
|
// Create a "Quit" button
|
||||||
|
entt::entity quitButton = registry.create();
|
||||||
|
registry.emplace<TransformComponent>(quitButton, centerX, quitButtonY, 1.0f, 1.0f, 0.0f); // Centered horizontally
|
||||||
|
registry.emplace<UIComponent>(quitButton, "Quit", buttonWidth, buttonHeight, [&]() {
|
||||||
|
engine.Shutdown();
|
||||||
|
});
|
||||||
|
registry.emplace<LayerComponent>(quitButton, 1); // Also on layer 1
|
||||||
|
|
||||||
|
// Create an "F3" debug overlay on a higher layer
|
||||||
|
entt::entity debugOverlay = registry.create();
|
||||||
|
registry.emplace<TransformComponent>(debugOverlay, 10.0f, 10.0f, 1.0f, 1.0f, 0.0f); // Placed at top-left corner
|
||||||
|
registry.emplace<UIComponent>(debugOverlay, "FPS: 60\nPosition: (100, 200)", 300.0f, 100.0f, nullptr);
|
||||||
|
registry.emplace<LayerComponent>(debugOverlay, 2); // Debug overlay on layer 2
|
||||||
|
|
||||||
|
// Set active scene to the main menu
|
||||||
|
sceneManager.SetActiveScene(mainMenuScene);
|
||||||
|
|
||||||
|
// Run the engine loop
|
||||||
engine.Run();
|
engine.Run();
|
||||||
|
|
||||||
engine.Shutdown();
|
engine.Shutdown();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// entt::entity gameScene = sceneManager.CreateScene();
|
||||||
|
// sceneManager.SetActiveScene(gameScene);
|
||||||
|
//
|
||||||
|
// entt::entity player = engine.GetRegistry().create();
|
||||||
|
// engine.GetRegistry().emplace<TransformComponent>(player, 400.0f, 300.0f, 1.0f, 1.0f, 0.0f);
|
||||||
|
//
|
||||||
|
// auto& inputComponent = engine.GetRegistry().emplace<InputComponent>(player);
|
||||||
|
//
|
||||||
|
// inputComponent.BindKey(InputAction::MOVE_UP, KEY_W);
|
||||||
|
// inputComponent.BindKey(InputAction::MOVE_DOWN, KEY_S);
|
||||||
|
// inputComponent.BindKey(InputAction::MOVE_LEFT, KEY_A);
|
||||||
|
// inputComponent.BindKey(InputAction::MOVE_RIGHT, KEY_D);
|
||||||
|
//
|
||||||
|
// inputComponent.SetActionCallback(InputAction::MOVE_UP, [&]() {
|
||||||
|
// auto& transform = engine.GetRegistry().get<TransformComponent>(player);
|
||||||
|
// transform.y -= 5.0f;
|
||||||
|
// });
|
||||||
|
// inputComponent.SetActionCallback(InputAction::MOVE_DOWN, [&]() {
|
||||||
|
// auto& transform = engine.GetRegistry().get<TransformComponent>(player);
|
||||||
|
// transform.y += 5.0f;
|
||||||
|
// });
|
||||||
|
// inputComponent.SetActionCallback(InputAction::MOVE_LEFT, [&]() {
|
||||||
|
// auto& transform = engine.GetRegistry().get<TransformComponent>(player);
|
||||||
|
// transform.x -= 5.0f;
|
||||||
|
// });
|
||||||
|
// inputComponent.SetActionCallback(InputAction::MOVE_RIGHT, [&]() {
|
||||||
|
// auto& transform = engine.GetRegistry().get<TransformComponent>(player);
|
||||||
|
// transform.x += 5.0f;
|
||||||
|
// });
|
||||||
|
@ -5,4 +5,15 @@
|
|||||||
#ifndef FATALHANDLER_H
|
#ifndef FATALHANDLER_H
|
||||||
#define FATALHANDLER_H
|
#define FATALHANDLER_H
|
||||||
|
|
||||||
|
#include <IsoEnginePCH.h>
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: Implement warning popup/crash handler (platform specific)
|
||||||
|
// TODO: Separate fatal handlers for core (the engine) and app (the user's app)
|
||||||
|
// maybe let the user handle their own fatal errors if they so choose, or they can use the default? similar
|
||||||
|
// to how the user has to specify an engine application
|
||||||
|
namespace IsoEngine {
|
||||||
|
void FatalHandler(const std::string& message);
|
||||||
|
};
|
||||||
|
|
||||||
#endif //FATALHANDLER_H
|
#endif //FATALHANDLER_H
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
#include "IsoEngine.h"
|
#include "IsoEngine.h"
|
||||||
|
|
||||||
|
#include <Logger.h>
|
||||||
|
|
||||||
#include "components.h"
|
#include "components.h"
|
||||||
#include <raylib.h>
|
#include <raylib.h>
|
||||||
|
|
||||||
@ -16,8 +19,9 @@ void IsoEngine::Initialize() {
|
|||||||
if (network) {
|
if (network) {
|
||||||
network->Initialize();
|
network->Initialize();
|
||||||
}
|
}
|
||||||
|
Logger::GetCoreLogger().AddOutputStream(&std::cout);
|
||||||
std::cout << "Engine initialized." << std::endl;
|
Logger::GetAppLogger().AddOutputStream(&std::cout);
|
||||||
|
CORE_LOG_INFO("Engine initialized!");
|
||||||
}
|
}
|
||||||
|
|
||||||
void IsoEngine::Run() {
|
void IsoEngine::Run() {
|
||||||
@ -39,7 +43,7 @@ void IsoEngine::Shutdown() {
|
|||||||
network->Shutdown();
|
network->Shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "Engine shut down." << std::endl;
|
CORE_LOG_INFO("Engine shut down");
|
||||||
}
|
}
|
||||||
|
|
||||||
void IsoEngine::Update() {
|
void IsoEngine::Update() {
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
#include <format>
|
||||||
|
|
||||||
|
|
||||||
#endif //ISOENGINEPCH_H
|
#endif //ISOENGINEPCH_H
|
||||||
|
@ -7,17 +7,15 @@ public:
|
|||||||
ENetClient() : client(nullptr), peer(nullptr) {}
|
ENetClient() : client(nullptr), peer(nullptr) {}
|
||||||
|
|
||||||
void Initialize() override {
|
void Initialize() override {
|
||||||
Logger& logger = Logger::GetInstance();
|
|
||||||
|
|
||||||
if (enet_initialize() != 0) {
|
if (enet_initialize() != 0) {
|
||||||
logger.LogError("An error occurred while initializing ENet.", "ENetClient");
|
CORE_LOG_FATAL("An error occurred while initializing ENet");
|
||||||
exit(EXIT_FAILURE);
|
throw std::runtime_error("An error occurred while initializing ENet");
|
||||||
}
|
}
|
||||||
|
|
||||||
client = enet_host_create(nullptr, 1, 2, 0, 0);
|
client = enet_host_create(nullptr, 1, 2, 0, 0);
|
||||||
if (!client) {
|
if (!client) {
|
||||||
logger.LogError("An error occurred while creating the ENet client.", "ENetClient");
|
CORE_LOG_FATAL("An error occurred while creating the ENet client");
|
||||||
exit(EXIT_FAILURE);
|
throw std::runtime_error("An error occurred while initializing ENet Client");
|
||||||
}
|
}
|
||||||
|
|
||||||
ENetAddress address;
|
ENetAddress address;
|
||||||
@ -26,42 +24,35 @@ public:
|
|||||||
|
|
||||||
peer = enet_host_connect(client, &address, 2, 0);
|
peer = enet_host_connect(client, &address, 2, 0);
|
||||||
if (!peer) {
|
if (!peer) {
|
||||||
logger.LogError("No available peers for initiating connection.", "ENetClient");
|
CORE_LOG_ERROR("No available peers for initiating connection");
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.LogInfo("ENet client initialized and connected to server.", "ENetClient");
|
CORE_LOG_TRACE("ENet client initialized and connected to server");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Shutdown() override {
|
void Shutdown() override {
|
||||||
Logger& logger = Logger::GetInstance();
|
|
||||||
|
|
||||||
if (peer) {
|
if (peer) {
|
||||||
enet_peer_disconnect(peer, 0);
|
enet_peer_disconnect(peer, 0);
|
||||||
logger.LogInfo("Disconnected from peer.", "ENetClient");
|
CORE_LOG_TRACE("Disconnected from peer");
|
||||||
}
|
}
|
||||||
enet_host_destroy(client);
|
enet_host_destroy(client);
|
||||||
enet_deinitialize();
|
enet_deinitialize();
|
||||||
logger.LogInfo("ENet client shut down.", "ENetClient");
|
CORE_LOG_TRACE("ENet client shut down");
|
||||||
}
|
}
|
||||||
|
|
||||||
void SendData(const void* data, size_t size) override {
|
void SendData(const void* data, size_t size) override {
|
||||||
Logger& logger = Logger::GetInstance();
|
|
||||||
|
|
||||||
if (peer) {
|
if (peer) {
|
||||||
ENetPacket* packet = enet_packet_create(data, size, ENET_PACKET_FLAG_RELIABLE);
|
ENetPacket* packet = enet_packet_create(data, size, ENET_PACKET_FLAG_RELIABLE);
|
||||||
enet_peer_send(peer, 0, packet);
|
enet_peer_send(peer, 0, packet);
|
||||||
logger.LogDebug("Data sent to server.", "ENetClient");
|
CORE_LOG_TRACE("Data sent to server");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReceiveData() override {
|
void ReceiveData() override {
|
||||||
Logger& logger = Logger::GetInstance();
|
|
||||||
|
|
||||||
ENetEvent event;
|
ENetEvent event;
|
||||||
while (enet_host_service(client, &event, 0) > 0) {
|
while (enet_host_service(client, &event, 0) > 0) {
|
||||||
if (event.type == ENET_EVENT_TYPE_RECEIVE) {
|
if (event.type == ENET_EVENT_TYPE_RECEIVE) {
|
||||||
logger.LogInfo("Received packet: " + std::string(reinterpret_cast<const char*>(event.packet->data)), "ENetClient");
|
CORE_LOG_TRACE("Received packet: {}", std::string(reinterpret_cast<const char*>(event.packet->data)));
|
||||||
enet_packet_destroy(event.packet);
|
enet_packet_destroy(event.packet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ bool FilePacker::Pack(const std::string &directoryPath, const std::string &outpu
|
|||||||
std::ofstream outputFile(outputBapFile, std::ios::binary);
|
std::ofstream outputFile(outputBapFile, std::ios::binary);
|
||||||
|
|
||||||
if (!outputFile) {
|
if (!outputFile) {
|
||||||
Logger::GetInstance().LogError("FilePacker::Pack(): Failed to open output file.");
|
CORE_LOG_ERROR("Failed to open output file");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,7 +33,7 @@ bool FilePacker::Pack(const std::string &directoryPath, const std::string &outpu
|
|||||||
|
|
||||||
std::ifstream inputFile(entry.path(), std::ios::binary | std::ios::ate);
|
std::ifstream inputFile(entry.path(), std::ios::binary | std::ios::ate);
|
||||||
if (!inputFile) {
|
if (!inputFile) {
|
||||||
Logger::GetInstance().LogError("FilePacker::Pack(): Failed to open file for packing: " + entry.path().string());
|
CORE_LOG_ERROR("FilePacker::Pack(): Failed to open file for packing: {}", entry.path().string());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
fileEntry.dataSize = inputFile.tellg();
|
fileEntry.dataSize = inputFile.tellg();
|
||||||
@ -75,7 +75,7 @@ bool FilePacker::Pack(const std::string &directoryPath, const std::string &outpu
|
|||||||
std::vector<FileEntry> FilePacker::listFiles(const std::string& bapFile) {
|
std::vector<FileEntry> FilePacker::listFiles(const std::string& bapFile) {
|
||||||
std::ifstream inputFile(bapFile, std::ios::binary);
|
std::ifstream inputFile(bapFile, std::ios::binary);
|
||||||
if (!inputFile) {
|
if (!inputFile) {
|
||||||
Logger::GetInstance().LogCritical("Failed to open .bap file for listing: " + bapFile);
|
CORE_LOG_FATAL("Failed to open .bap file for listing: {}", bapFile);
|
||||||
throw std::runtime_error("File could not be opened");
|
throw std::runtime_error("File could not be opened");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,7 +87,7 @@ std::vector<FileEntry> FilePacker::listFiles(const std::string& bapFile) {
|
|||||||
bool FilePacker::ExtractFile(const std::string& bapFile, const std::string& fileName, const std::string& outputPath) {
|
bool FilePacker::ExtractFile(const std::string& bapFile, const std::string& fileName, const std::string& outputPath) {
|
||||||
std::ifstream inputFile(bapFile, std::ios::binary);
|
std::ifstream inputFile(bapFile, std::ios::binary);
|
||||||
if (!inputFile) {
|
if (!inputFile) {
|
||||||
Logger::GetInstance().LogError("Failed to open .bap file for extraction: " + bapFile);
|
CORE_LOG_ERROR("Failed to open .bap file for extraction: {}", bapFile);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,7 +96,7 @@ bool FilePacker::ExtractFile(const std::string& bapFile, const std::string& file
|
|||||||
if (fileEntry.filePath == fileName) {
|
if (fileEntry.filePath == fileName) {
|
||||||
std::ofstream outFile(outputPath, std::ios::binary);
|
std::ofstream outFile(outputPath, std::ios::binary);
|
||||||
if (!outFile) {
|
if (!outFile) {
|
||||||
Logger::GetInstance().LogError("Failed to create output file: " + outputPath);
|
CORE_LOG_ERROR("Failed to create output file: {}", outputPath);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,7 +110,7 @@ bool FilePacker::ExtractFile(const std::string& bapFile, const std::string& file
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger::GetInstance().LogError("File not found in .bap archive: " + fileName);
|
CORE_LOG_ERROR("File not found in .bap archive: {}", fileName);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,7 +143,7 @@ BapHeader FilePacker::ReadHeader(std::ifstream& inFile) {
|
|||||||
inFile.read(reinterpret_cast<char*>(&header.fileCount), sizeof(header.fileCount));
|
inFile.read(reinterpret_cast<char*>(&header.fileCount), sizeof(header.fileCount));
|
||||||
|
|
||||||
if (header.version != PACKER_VERSION) {
|
if (header.version != PACKER_VERSION) {
|
||||||
Logger::GetInstance().LogCritical("FilePacker::ReadHeader(): Wrong .bap file version.");
|
CORE_LOG_FATAL("FilePacker::ReadHeader(): Wrong .bap file version.");
|
||||||
throw std::runtime_error("Invalid bap file version");
|
throw std::runtime_error("Invalid bap file version");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,22 +8,31 @@
|
|||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <format>
|
||||||
|
|
||||||
void FatalHandler(const std::string& message) {
|
namespace IsoEngine {
|
||||||
std::ofstream crashFile("crash.log", std::ios::app);
|
|
||||||
crashFile << "FATAL ERROR: " << message << std::endl;
|
|
||||||
|
|
||||||
void* callstack[128];
|
template<typename... Args>
|
||||||
int frames = backtrace(callstack, 128);
|
void FatalHandler(const std::string& format, Args... args) {
|
||||||
char** symbols = backtrace_symbols(callstack, frames);
|
std::ostringstream stream;
|
||||||
|
stream << std::format(format, args...);
|
||||||
|
|
||||||
crashFile << "Stack trace:\n";
|
// TODO: change the name of the file to reflect the time the crash happened
|
||||||
for (int i = 0; i < frames; ++i) {
|
std::ofstream crashFile("crash.log", std::ios::app);
|
||||||
crashFile << symbols[i] << std::endl;
|
crashFile << "FATAL ERROR: " << stream.str() << std::endl;
|
||||||
|
|
||||||
|
void* callstack[128];
|
||||||
|
int frames = backtrace(callstack, 128);
|
||||||
|
char** symbols = backtrace_symbols(callstack, frames);
|
||||||
|
|
||||||
|
crashFile << "Stack trace:\n";
|
||||||
|
for (int i = 0; i < frames; ++i) {
|
||||||
|
crashFile << symbols[i] << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(symbols);
|
||||||
|
crashFile.close();
|
||||||
|
|
||||||
|
std::abort();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
free(symbols);
|
|
||||||
crashFile.close();
|
|
||||||
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
@ -7,50 +7,58 @@
|
|||||||
#include <dbghelp.h>
|
#include <dbghelp.h>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <format>
|
||||||
|
|
||||||
#pragma comment(lib, "dbghelp.lib")
|
#pragma comment(lib, "dbghelp.lib")
|
||||||
|
|
||||||
void FatalHandler(const std::string& message) {
|
namespace IsoEngine {
|
||||||
std::ofstream crashFile("crash.log", std::ios::app);
|
template<typename... Args>
|
||||||
crashFile << "FATAL ERROR: " << message << std::endl;
|
void FatalHandler(const std::string &format, Args... args) {
|
||||||
|
std::ostringstream stream;
|
||||||
|
stream << std::format(format, args...);
|
||||||
|
|
||||||
HANDLE process = GetCurrentProcess();
|
// TODO: change the name of the file to reflect the time the crash happened
|
||||||
SymInitialize(process, NULL, TRUE);
|
std::ofstream crashFile("crash.log", std::ios::app);
|
||||||
|
crashFile << "FATAL ERROR: " << stream.str() << std::endl;
|
||||||
|
|
||||||
CONTEXT context;
|
HANDLE process = GetCurrentProcess();
|
||||||
RtlCaptureContext(&context);
|
SymInitialize(process, NULL, TRUE);
|
||||||
|
|
||||||
STACKFRAME64 stackFrame = {};
|
CONTEXT context;
|
||||||
stackFrame.AddrPC.Offset = context.Rip;
|
RtlCaptureContext(&context);
|
||||||
stackFrame.AddrPC.Mode = AddrModeFlat;
|
|
||||||
stackFrame.AddrFrame.Offset = context.Rbp;
|
|
||||||
stackFrame.AddrFrame.Mode = AddrModeFlat;
|
|
||||||
stackFrame.AddrStack.Offset = context.Rsp;
|
|
||||||
stackFrame.AddrStack.Mode = AddrModeFlat;
|
|
||||||
|
|
||||||
crashFile << "Stack trace:\n";
|
STACKFRAME64 stackFrame = {};
|
||||||
|
stackFrame.AddrPC.Offset = context.Rip;
|
||||||
|
stackFrame.AddrPC.Mode = AddrModeFlat;
|
||||||
|
stackFrame.AddrFrame.Offset = context.Rbp;
|
||||||
|
stackFrame.AddrFrame.Mode = AddrModeFlat;
|
||||||
|
stackFrame.AddrStack.Offset = context.Rsp;
|
||||||
|
stackFrame.AddrStack.Mode = AddrModeFlat;
|
||||||
|
|
||||||
while (StackWalk64(IMAGE_FILE_MACHINE_AMD64, process, GetCurrentThread(), &stackFrame, &context, NULL, SymFunctionTableAccess64, SymGetModuleBase64, NULL)) {
|
crashFile << "Stack trace:\n";
|
||||||
DWORD64 address = stackFrame.AddrPC.Offset;
|
while (StackWalk64(IMAGE_FILE_MACHINE_AMD64, process, GetCurrentThread(), &stackFrame, &context, NULL,
|
||||||
if (address == 0) {
|
SymFunctionTableAccess64, SymGetModuleBase64, NULL)) {
|
||||||
break;
|
DWORD64 address = stackFrame.AddrPC.Offset;
|
||||||
|
if (address == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR)];
|
||||||
|
PSYMBOL_INFO symbol = (PSYMBOL_INFO) buffer;
|
||||||
|
symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
|
||||||
|
symbol->MaxNameLen = MAX_SYM_NAME;
|
||||||
|
|
||||||
|
DWORD64 displacement = 0;
|
||||||
|
if (SymFromAddr(process, address, &displacement, symbol)) {
|
||||||
|
crashFile << symbol->Name << " - 0x" << std::hex << symbol->Address << std::dec << "\n";
|
||||||
|
} else {
|
||||||
|
crashFile << "Unresolved symbol at address: 0x" << std::hex << address << std::dec << "\n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR)];
|
SymCleanup(process);
|
||||||
PSYMBOL_INFO symbol = (PSYMBOL_INFO)buffer;
|
crashFile.close();
|
||||||
symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
|
|
||||||
symbol->MaxNameLen = MAX_SYM_NAME;
|
|
||||||
|
|
||||||
DWORD64 displacement = 0;
|
std::abort();
|
||||||
if (SymFromAddr(process, address, &displacement, symbol)) {
|
|
||||||
crashFile << symbol->Name << " - 0x" << std::hex << symbol->Address << std::dec << "\n";
|
|
||||||
} else {
|
|
||||||
crashFile << "Unresolved symbol at address: 0x" << std::hex << address << std::dec << "\n";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
SymCleanup(process);
|
|
||||||
crashFile.close();
|
|
||||||
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user