From 5381475a29eabb6737a30adceb1d7c2dbd270d2c Mon Sep 17 00:00:00 2001 From: Michael Gerhold Date: Sat, 21 Sep 2024 15:06:50 +0200 Subject: [PATCH] fix: wrap all c-facing functions with `try`-`catch` --- src/obpf/lobby.cpp | 286 +++++++++++++++++++++++++++++++++++------ src/obpf/simulator.cpp | 148 ++++++++++++++++++--- 2 files changed, 379 insertions(+), 55 deletions(-) diff --git a/src/obpf/lobby.cpp b/src/obpf/lobby.cpp index 090e117..edcc9c5 100644 --- a/src/obpf/lobby.cpp +++ b/src/obpf/lobby.cpp @@ -1,16 +1,26 @@ #include +#include #include #include -ObpfLobbyServerConnection* obpf_create_lobby_server_connection( - char const* const host, - uint16_t const port -) { +ObpfLobbyServerConnection* obpf_create_lobby_server_connection(char const* const host, uint16_t const port) try { return reinterpret_cast(new LobbyServerConnection{ host, port }); +} catch (std::exception const& e) { + + spdlog::error("Failed to create lobby server connection: {}", e.what()); + return nullptr; +} catch (...) { + spdlog::error("Failed to create lobby server connection: unknown error"); + return nullptr; } -void obpf_destroy_lobby_server_connection(ObpfLobbyServerConnection const* lobby_server_connection) { +void obpf_destroy_lobby_server_connection(ObpfLobbyServerConnection const* lobby_server_connection) try { delete reinterpret_cast(lobby_server_connection); +} catch (std::exception const& e) { + + spdlog::error("Failed to destroy lobby server connection: {}", e.what()); +} catch (...) { + spdlog::error("Failed to destroy lobby server connection: unknown error"); } // clang-format off @@ -18,39 +28,63 @@ ObpfLobbyUser* obpf_lobby_connection_register_user( ObpfLobbyServerConnection* const lobby_server_connection, char const* const username, char const* const password -) { // clang-format on +) try { // clang-format on auto& connection = *reinterpret_cast(lobby_server_connection); if (auto const user = connection.register_user(username, password)) { return reinterpret_cast(new User{ user.value() }); } return nullptr; +} catch (std::exception const& e) { + + spdlog::error("Failed to register user: {}", e.what()); + return nullptr; +} catch (...) { + spdlog::error("Failed to register user: unknown error"); + return nullptr; } ObpfLobbyUser* obpf_lobby_connection_authenticate_user( ObpfLobbyServerConnection* const lobby_server_connection, char const* const username, char const* const password -) { +) try { auto& connection = *reinterpret_cast(lobby_server_connection); if (auto const user = connection.authenticate(username, password)) { return reinterpret_cast(new User{ user.value() }); } return nullptr; +} catch (std::exception const& e) { + + spdlog::error("Failed to authenticate user: {}", e.what()); + return nullptr; +} catch (...) { + spdlog::error("Failed to authenticate user: unknown error"); + return nullptr; } -void obpf_user_destroy(ObpfLobbyUser const* const user) { +void obpf_user_destroy(ObpfLobbyUser const* const user) try { delete reinterpret_cast(user); +} catch (std::exception const& e) { + + spdlog::error("Failed to destroy user: {}", e.what()); +} catch (...) { + spdlog::error("Failed to destroy user: unknown error"); } // clang-format off void obpf_lobby_unregister_user( ObpfLobbyServerConnection* const lobby_server_connection, ObpfLobbyUser** const user_pointer -) { // clang-format on +) try { // clang-format on auto& connection = *reinterpret_cast(lobby_server_connection); connection.unregister(*reinterpret_cast(*user_pointer)); obpf_user_destroy(*user_pointer); *user_pointer = nullptr; +} catch (std::exception const& e) { + + spdlog::error("Failed to unregister user: {}", e.what()); +} catch (...) { + spdlog::error("Failed to unregister user: unknown error"); } ObpfLobby* obpf_lobby_connection_create_lobby( @@ -58,20 +92,27 @@ ObpfLobby* obpf_lobby_connection_create_lobby( ObpfLobbyUser const* const user, char const* const lobby_name, uint16_t const lobby_size -) { +) try { auto& connection = *reinterpret_cast(lobby_server_connection); auto const settings = LobbySettings{ lobby_name, lobby_size }; if (auto const lobby = connection.create_lobby(*reinterpret_cast(user), settings)) { return reinterpret_cast(new Lobby{ lobby.value() }); } return nullptr; +} catch (std::exception const& e) { + + spdlog::error("Failed to create lobby: {}", e.what()); + return nullptr; +} catch (...) { + spdlog::error("Failed to create lobby: unknown error"); + return nullptr; } bool obpf_lobby_connection_destroy_lobby( ObpfLobbyServerConnection* const lobby_server_connection, ObpfLobbyUser const* const lobby_user, ObpfLobby** const obpf_lobby -) { +) try { auto& connection = *reinterpret_cast(lobby_server_connection); auto const& user = *reinterpret_cast(lobby_user); auto lobby = *reinterpret_cast(*obpf_lobby); @@ -79,6 +120,13 @@ bool obpf_lobby_connection_destroy_lobby( delete reinterpret_cast(*obpf_lobby); *obpf_lobby = nullptr; return result; +} catch (std::exception const& e) { + + spdlog::error("Failed to destroy lobby: {}", e.what()); + return false; +} catch (...) { + spdlog::error("Failed to destroy lobby: unknown error"); + return false; } bool obpf_lobby_connection_start_lobby( @@ -86,7 +134,7 @@ bool obpf_lobby_connection_start_lobby( ObpfLobbyUser const* const lobby_user, ObpfLobby const* const obpf_lobby, uint16_t* const out_server_port -) { +) try { auto& connection = *reinterpret_cast(lobby_server_connection); auto const& user = *reinterpret_cast(lobby_user); auto const& lobby = *reinterpret_cast(obpf_lobby); @@ -96,53 +144,126 @@ bool obpf_lobby_connection_start_lobby( return true; } return false; +} catch (std::exception const& e) { + + spdlog::error("Failed to start lobby: {}", e.what()); + return false; +} catch (...) { + spdlog::error("Failed to start lobby: unknown error"); + return false; } -ObpfLobbyList const* obpf_get_lobby_list(ObpfLobbyServerConnection* lobby_server_connection) { +ObpfLobbyList const* obpf_get_lobby_list(ObpfLobbyServerConnection* lobby_server_connection) try { auto& connection = *reinterpret_cast(lobby_server_connection); auto const lobbies = new LobbyList{ connection.lobbies() }; return reinterpret_cast(lobbies); +} catch (std::exception const& e) { + + spdlog::error("Failed to get lobby list: {}", e.what()); + return nullptr; +} catch (...) { + spdlog::error("Failed to get lobby list: unknown error"); + return nullptr; } -void obpf_free_lobby_list(ObpfLobbyList const* lobby_list) { +void obpf_free_lobby_list(ObpfLobbyList const* lobby_list) try { delete reinterpret_cast(lobby_list); +} catch (std::exception const& e) { + + spdlog::error("Failed to free lobby list: {}", e.what()); +} catch (...) { + spdlog::error("Failed to free lobby list: unknown error"); } -size_t obpf_lobby_list_length(ObpfLobbyList const* lobby_list) { +size_t obpf_lobby_list_length(ObpfLobbyList const* lobby_list) try { return reinterpret_cast(lobby_list)->lobbies.size(); +} catch (std::exception const& e) { + + spdlog::error("Failed to get lobby list length: {}", e.what()); + return 0; +} catch (...) { + spdlog::error("Failed to get lobby list length: unknown error"); + return 0; } -ObpfLobbyInfo const* obpf_lobby_list_at(ObpfLobbyList const* lobby_list, size_t index) { +ObpfLobbyInfo const* obpf_lobby_list_at(ObpfLobbyList const* lobby_list, size_t index) try { if (index >= obpf_lobby_list_length(lobby_list)) { return nullptr; } - return reinterpret_cast( - &reinterpret_cast(lobby_list)->lobbies.at(index) - ); + return reinterpret_cast(&reinterpret_cast(lobby_list)->lobbies.at(index)); +} catch (std::exception const& e) { + + spdlog::error("Failed to get lobby info at index: {}", e.what()); + return nullptr; +} catch (...) { + spdlog::error("Failed to get lobby info at index: unknown error"); + return nullptr; } -char const* obpf_lobby_info_id(ObpfLobbyInfo const* lobby_info) { +char const* obpf_lobby_info_id(ObpfLobbyInfo const* lobby_info) try { return reinterpret_cast(lobby_info)->id.c_str(); +} catch (std::exception const& e) { + + spdlog::error("Failed to get lobby info id: {}", e.what()); + return nullptr; +} catch (...) { + spdlog::error("Failed to get lobby info id: unknown error"); + return nullptr; } -char const* obpf_lobby_info_name(ObpfLobbyInfo const* lobby_info) { +char const* obpf_lobby_info_name(ObpfLobbyInfo const* lobby_info) try { return reinterpret_cast(lobby_info)->name.c_str(); +} catch (std::exception const& e) { + + spdlog::error("Failed to get lobby info name: {}", e.what()); + return nullptr; +} catch (...) { + spdlog::error("Failed to get lobby info name: unknown error"); + return nullptr; } -uint16_t obpf_lobby_info_size(ObpfLobbyInfo const* lobby_info) { +uint16_t obpf_lobby_info_size(ObpfLobbyInfo const* lobby_info) try { return reinterpret_cast(lobby_info)->size; +} catch (std::exception const& e) { + + spdlog::error("Failed to get lobby info size: {}", e.what()); + return 0; +} catch (...) { + spdlog::error("Failed to get lobby info size: unknown error"); + return 0; } -uint16_t obpf_lobby_info_num_players_in_lobby(ObpfLobbyInfo const* lobby_info) { +uint16_t obpf_lobby_info_num_players_in_lobby(ObpfLobbyInfo const* lobby_info) try { return reinterpret_cast(lobby_info)->num_players_in_lobby; +} catch (std::exception const& e) { + + spdlog::error("Failed to get lobby info num players in lobby: {}", e.what()); + return 0; +} catch (...) { + spdlog::error("Failed to get lobby info num players in lobby: unknown error"); + return 0; } -char const* obpf_lobby_info_host_id(ObpfLobbyInfo const* lobby_info) { +char const* obpf_lobby_info_host_id(ObpfLobbyInfo const* lobby_info) try { return reinterpret_cast(lobby_info)->host_info.id.c_str(); +} catch (std::exception const& e) { + + spdlog::error("Failed to get lobby info host id: {}", e.what()); + return nullptr; +} catch (...) { + spdlog::error("Failed to get lobby info host id: unknown error"); + return nullptr; } -char const* obpf_lobby_info_host_name(ObpfLobbyInfo const* lobby_info) { +char const* obpf_lobby_info_host_name(ObpfLobbyInfo const* lobby_info) try { return reinterpret_cast(lobby_info)->host_info.name.c_str(); +} catch (std::exception const& e) { + + spdlog::error("Failed to get lobby info host name: {}", e.what()); + return nullptr; +} catch (...) { + spdlog::error("Failed to get lobby info host name: unknown error"); + return nullptr; } // clang-format off @@ -150,7 +271,7 @@ ObpfLobby* obpf_lobby_connection_join( ObpfLobbyServerConnection* lobby_server_connection, ObpfLobbyInfo const* lobby_info, ObpfLobbyUser const* lobby_user -) { // clang-format on +) try { // clang-format on auto& connection = *reinterpret_cast(lobby_server_connection); auto const& user = *reinterpret_cast(lobby_user); auto const& info = *reinterpret_cast(lobby_info); @@ -161,6 +282,13 @@ ObpfLobby* obpf_lobby_connection_join( return nullptr; } return reinterpret_cast(new Lobby{ std::move(result).value() }); +} catch (std::exception const& e) { + + spdlog::error("Failed to join lobby: {}", e.what()); + return nullptr; +} catch (...) { + spdlog::error("Failed to join lobby: unknown error"); + return nullptr; } // clang-format off @@ -168,20 +296,27 @@ uint16_t obpf_lobby_set_ready( ObpfLobbyServerConnection* lobby_server_connection, ObpfLobbyUser const* lobby_user, ObpfLobby* obpf_lobby -) { // clang-format on +) try { // clang-format on auto& connection = *reinterpret_cast(lobby_server_connection); auto const& user = *reinterpret_cast(lobby_user); auto const& lobby = *reinterpret_cast(obpf_lobby); auto const result = connection.set_ready(user, lobby); assert(result.has_value()); return std::to_underlying(result.value()); +} catch (std::exception const& e) { + + spdlog::error("Failed to set ready: {}", e.what()); + return 0; +} catch (...) { + spdlog::error("Failed to set ready: unknown error"); + return 0; } ObpfLobbyDetails const* obpf_lobby_connection_get_lobby_details( ObpfLobbyServerConnection* lobby_server_connection, ObpfLobbyInfo const* lobby_info, ObpfLobbyUser const* lobby_user -) { +) try { std::cerr << "function called\n"; auto& connection = *reinterpret_cast(lobby_server_connection); std::cerr << "connection\n"; @@ -196,53 +331,128 @@ ObpfLobbyDetails const* obpf_lobby_connection_get_lobby_details( return nullptr; } return reinterpret_cast(new LobbyDetails{ std::move(result).value() }); +} catch (std::exception const& e) { + + spdlog::error("Failed to get lobby details: {}", e.what()); + return nullptr; +} catch (...) { + spdlog::error("Failed to get lobby details: unknown error"); + return nullptr; } -void obpf_free_lobby_details(ObpfLobbyDetails const* lobby_details) { +void obpf_free_lobby_details(ObpfLobbyDetails const* lobby_details) try { delete reinterpret_cast(lobby_details); +} catch (std::exception const& e) { + + spdlog::error("Failed to free lobby details: {}", e.what()); +} catch (...) { + spdlog::error("Failed to free lobby details: unknown error"); } -char const* obpf_lobby_details_id(ObpfLobbyDetails const* lobby_details) { +char const* obpf_lobby_details_id(ObpfLobbyDetails const* lobby_details) try { return reinterpret_cast(lobby_details)->id.c_str(); +} catch (std::exception const& e) { + + spdlog::error("Failed to get lobby details id: {}", e.what()); + return nullptr; +} catch (...) { + spdlog::error("Failed to get lobby details id: unknown error"); + return nullptr; } -char const* obpf_lobby_details_name(ObpfLobbyDetails const* lobby_details) { +char const* obpf_lobby_details_name(ObpfLobbyDetails const* lobby_details) try { return reinterpret_cast(lobby_details)->name.c_str(); +} catch (std::exception const& e) { + + spdlog::error("Failed to get lobby details name: {}", e.what()); + return nullptr; +} catch (...) { + spdlog::error("Failed to get lobby details name: unknown error"); + return nullptr; } -uint16_t obpf_lobby_details_size(ObpfLobbyDetails const* lobby_details) { +uint16_t obpf_lobby_details_size(ObpfLobbyDetails const* lobby_details) try { return reinterpret_cast(lobby_details)->size; +} catch (std::exception const& e) { + + spdlog::error("Failed to get lobby details size: {}", e.what()); + return 0; +} catch (...) { + spdlog::error("Failed to get lobby details size: unknown error"); + return 0; } -size_t obpf_lobby_details_num_clients(ObpfLobbyDetails const* lobby_details) { +size_t obpf_lobby_details_num_clients(ObpfLobbyDetails const* lobby_details) try { return reinterpret_cast(lobby_details)->client_infos.size(); +} catch (std::exception const& e) { + + spdlog::error("Failed to get lobby details num clients: {}", e.what()); + return 0; +} catch (...) { + spdlog::error("Failed to get lobby details num clients: unknown error"); + return 0; } -char const* obpf_lobby_details_client_id(ObpfLobbyDetails const* lobby_details, size_t index) { +char const* obpf_lobby_details_client_id(ObpfLobbyDetails const* lobby_details, size_t index) try { if (index >= obpf_lobby_details_num_clients(lobby_details)) { return nullptr; } return reinterpret_cast(lobby_details)->client_infos.at(index).id.c_str(); +} catch (std::exception const& e) { + + spdlog::error("Failed to get lobby details client id: {}", e.what()); + return nullptr; +} catch (...) { + spdlog::error("Failed to get lobby details client id: unknown error"); + return nullptr; } -char const* obpf_lobby_details_client_name(ObpfLobbyDetails const* lobby_details, size_t index) { +char const* obpf_lobby_details_client_name(ObpfLobbyDetails const* lobby_details, size_t index) try { if (index >= obpf_lobby_details_num_clients(lobby_details)) { return nullptr; } return reinterpret_cast(lobby_details)->client_infos.at(index).name.c_str(); +} catch (std::exception const& e) { + + spdlog::error("Failed to get lobby details client name: {}", e.what()); + return nullptr; +} catch (...) { + spdlog::error("Failed to get lobby details client name: unknown error"); + return nullptr; } -bool obpf_lobby_details_client_is_ready(ObpfLobbyDetails const* lobby_details, size_t index) { +bool obpf_lobby_details_client_is_ready(ObpfLobbyDetails const* lobby_details, size_t index) try { if (index >= obpf_lobby_details_num_clients(lobby_details)) { return false; } return reinterpret_cast(lobby_details)->client_infos.at(index).is_ready; +} catch (std::exception const& e) { + + spdlog::error("Failed to get lobby details client is ready: {}", e.what()); + return false; +} catch (...) { + spdlog::error("Failed to get lobby details client is ready: unknown error"); + return false; } -char const* obpf_lobby_details_host_id(ObpfLobbyDetails const* lobby_details) { +char const* obpf_lobby_details_host_id(ObpfLobbyDetails const* lobby_details) try { return reinterpret_cast(lobby_details)->host_info.id.c_str(); +} catch (std::exception const& e) { + + spdlog::error("Failed to get lobby details host id: {}", e.what()); + return nullptr; +} catch (...) { + spdlog::error("Failed to get lobby details host id: unknown error"); + return nullptr; } -char const* obpf_lobby_details_host_name(ObpfLobbyDetails const* lobby_details) { +char const* obpf_lobby_details_host_name(ObpfLobbyDetails const* lobby_details) try { return reinterpret_cast(lobby_details)->host_info.name.c_str(); +} catch (std::exception const& e) { + + spdlog::error("Failed to get lobby details host name: {}", e.what()); + return nullptr; +} catch (...) { + spdlog::error("Failed to get lobby details host name: unknown error"); + return nullptr; } diff --git a/src/obpf/simulator.cpp b/src/obpf/simulator.cpp index 9f7b0e9..d9d03b0 100644 --- a/src/obpf/simulator.cpp +++ b/src/obpf/simulator.cpp @@ -36,17 +36,31 @@ enum class TetrominoSelection { return true; } -ObpfTetrion* obpf_create_tetrion(uint64_t const seed) { +ObpfTetrion* obpf_create_tetrion(uint64_t const seed) try { return new ObpfTetrion{ seed }; +} catch (std::exception const& e) { + + spdlog::error("Failed to create tetrion: {}", e.what()); + return nullptr; +} catch (...) { + spdlog::error("Failed to create tetrion: Unknown error"); + return nullptr; } -ObpfTetrion* obpf_clone_tetrion(ObpfTetrion const* const tetrion) { +ObpfTetrion* obpf_clone_tetrion(ObpfTetrion const* const tetrion) try { auto result = new ObpfTetrion{ *tetrion }; result->set_action_handler(nullptr, nullptr); return result; +} catch (std::exception const& e) { + + spdlog::error("Failed to clone tetrion: {}", e.what()); + return nullptr; +} catch (...) { + spdlog::error("Failed to clone tetrion: Unknown error"); + return nullptr; } -ObpfLineClearDelayState obpf_tetrion_get_line_clear_delay_state(ObpfTetrion const* tetrion) { +ObpfLineClearDelayState obpf_tetrion_get_line_clear_delay_state(ObpfTetrion const* tetrion) try { auto [lines, countdown] = tetrion->line_clear_delay_state(); auto const original_size = lines.size(); while (lines.size() < decltype(lines)::capacity()) { @@ -63,10 +77,34 @@ ObpfLineClearDelayState obpf_tetrion_get_line_clear_delay_state(ObpfTetrion cons .countdown = countdown, .delay = LineClearDelay::delay, }; +} catch (std::exception const& e) { + + spdlog::error("Failed to get line clear delay state: {}", e.what()); + return ObpfLineClearDelayState{ + .count = 0, + .lines{ 0, 0, 0, 0 }, + .countdown = 0, + .delay = LineClearDelay::delay, + }; +} catch (...) { + spdlog::error("Failed to get line clear delay state: Unknown error"); + return ObpfLineClearDelayState{ + .count = 0, + .lines{ 0, 0, 0, 0 }, + .countdown = 0, + .delay = LineClearDelay::delay, + }; } -bool obpf_tetrion_try_get_active_tetromino(ObpfTetrion const* const tetrion, ObpfTetromino* const out_tetromino) { +bool obpf_tetrion_try_get_active_tetromino(ObpfTetrion const* const tetrion, ObpfTetromino* const out_tetromino) try { return try_get_tetromino(tetrion, out_tetromino, TetrominoSelection::ActiveTetromino); +} catch (std::exception const& e) { + + spdlog::error("Failed to get active tetromino: {}", e.what()); + return false; +} catch (...) { + spdlog::error("Failed to get active tetromino: Unknown error"); + return false; } bool obpf_tetrion_try_get_active_tetromino_transform( @@ -74,7 +112,7 @@ bool obpf_tetrion_try_get_active_tetromino_transform( ObpfTetrominoType* const out_type, ObpfRotation* const out_rotation, ObpfVec2i* const out_position -) { +) try { auto const tetromino = tetrion->active_tetromino(); if (not tetromino.has_value()) { return false; @@ -92,22 +130,51 @@ bool obpf_tetrion_try_get_active_tetromino_transform( }; } return true; +} catch (std::exception const& e) { + + spdlog::error("Failed to get active tetromino transform: {}", e.what()); + return false; +} catch (...) { + spdlog::error("Failed to get active tetromino transform: Unknown error"); + return false; } -bool obpf_tetrion_try_get_ghost_tetromino(ObpfTetrion const* tetrion, ObpfTetromino* out_tetromino) { +bool obpf_tetrion_try_get_ghost_tetromino(ObpfTetrion const* tetrion, ObpfTetromino* out_tetromino) try { return try_get_tetromino(tetrion, out_tetromino, TetrominoSelection::GhostTetromino); +} catch (std::exception const& e) { + + spdlog::error("Failed to get ghost tetromino: {}", e.what()); + return false; +} catch (...) { + spdlog::error("Failed to get ghost tetromino: Unknown error"); + return false; } -uint64_t obpf_tetrion_get_next_frame(ObpfTetrion const* const tetrion) { +uint64_t obpf_tetrion_get_next_frame(ObpfTetrion const* const tetrion) try { return tetrion->next_frame(); +} catch (std::exception const& e) { + + spdlog::error("Failed to get next frame: {}", e.what()); + return 0; +} catch (...) { + spdlog::error("Failed to get next frame: Unknown error"); + return 0; } -void obpf_tetrion_simulate_next_frame(ObpfTetrion* const tetrion, ObpfKeyState const key_state) { +void obpf_tetrion_simulate_next_frame(ObpfTetrion* const tetrion, ObpfKeyState const key_state) try { tetrion->simulate_next_frame(KeyState::from_bitmask(key_state.bitmask).value()); +} catch (std::exception const& e) { + + spdlog::error("Failed to simulate next frame: {}", e.what()); +} catch (...) { + spdlog::error("Failed to simulate next frame: Unknown error"); } -void obpf_destroy_tetrion(ObpfTetrion const* const tetrion) { - delete tetrion; +void obpf_destroy_tetrion(ObpfTetrion const* const tetrion) try { delete tetrion; } catch (std::exception const& e) { + + spdlog::error("Failed to destroy tetrion: {}", e.what()); +} catch (...) { + spdlog::error("Failed to destroy tetrion: Unknown error"); } uint8_t obpf_tetrion_width() { @@ -122,21 +189,35 @@ uint8_t obpf_tetrion_num_invisible_lines() { return uint8_t{ Matrix::num_invisible_lines }; } -ObpfTetrominoType obpf_tetrion_matrix_get(ObpfTetrion const* const tetrion, ObpfVec2 const position) { +ObpfTetrominoType obpf_tetrion_matrix_get(ObpfTetrion const* const tetrion, ObpfVec2 const position) try { auto const pos = Vec2{ position.x, position.y }; return static_cast(tetrion->matrix()[pos]); +} catch (std::exception const& e) { + + spdlog::error("Failed to get matrix value: {}", e.what()); + return OBPF_TETROMINO_TYPE_EMPTY; +} catch (...) { + spdlog::error("Failed to get matrix value: Unknown error"); + return OBPF_TETROMINO_TYPE_EMPTY; } -ObpfPreviewPieces obpf_tetrion_get_preview_pieces(ObpfTetrion const* tetrion) { +ObpfPreviewPieces obpf_tetrion_get_preview_pieces(ObpfTetrion const* tetrion) try { auto const preview_tetrominos = tetrion->get_preview_tetrominos(); ObpfPreviewPieces result{}; for (usize i = 0; i < preview_tetrominos.size(); ++i) { result.types[i] = static_cast(preview_tetrominos.at(i)); } return result; +} catch (std::exception const& e) { + + spdlog::error("Failed to get preview pieces: {}", e.what()); + return ObpfPreviewPieces{}; +} catch (...) { + spdlog::error("Failed to get preview pieces: Unknown error"); + return ObpfPreviewPieces{}; } -ObpfMinoPositions obpf_tetromino_get_mino_positions(ObpfTetrominoType const type, ObpfRotation const rotation) { +ObpfMinoPositions obpf_tetromino_get_mino_positions(ObpfTetrominoType const type, ObpfRotation const rotation) try { auto const tetromino = Tetromino{ Vec2{ 0, 0 }, static_cast(rotation), @@ -151,13 +232,27 @@ ObpfMinoPositions obpf_tetromino_get_mino_positions(ObpfTetrominoType const type }; } return result; +} catch (std::exception const& e) { + + spdlog::error("Failed to get mino positions: {}", e.what()); + return ObpfMinoPositions{}; +} catch (...) { + spdlog::error("Failed to get mino positions: Unknown error"); + return ObpfMinoPositions{}; } -ObpfTetrominoType obpf_tetrion_get_hold_piece(ObpfTetrion const* const tetrion) { +ObpfTetrominoType obpf_tetrion_get_hold_piece(ObpfTetrion const* const tetrion) try { if (auto const hold_piece = tetrion->hold_piece(); hold_piece.has_value()) { return static_cast(hold_piece.value()); } return OBPF_TETROMINO_TYPE_EMPTY; +} catch (std::exception const& e) { + + spdlog::error("Failed to get hold piece: {}", e.what()); + return OBPF_TETROMINO_TYPE_EMPTY; +} catch (...) { + spdlog::error("Failed to get hold piece: Unknown error"); + return OBPF_TETROMINO_TYPE_EMPTY; } ObpfKeyState obpf_key_state_create( @@ -175,18 +270,37 @@ ObpfKeyState obpf_key_state_create( }; } -ObpfStats obpf_tetrion_get_stats(ObpfTetrion const* tetrion) { +ObpfStats obpf_tetrion_get_stats(ObpfTetrion const* tetrion) try { return ObpfStats{ .score = tetrion->score(), .lines_cleared = tetrion->num_lines_cleared(), .level = tetrion->level(), }; +} catch (std::exception const& e) { + + spdlog::error("Failed to get stats: {}", e.what()); + return ObpfStats{}; +} catch (...) { + spdlog::error("Failed to get stats: Unknown error"); + return ObpfStats{}; } -bool obpf_tetrion_is_game_over(ObpfTetrion const* const tetrion) { +bool obpf_tetrion_is_game_over(ObpfTetrion const* const tetrion) try { return tetrion->is_game_over(); +} catch (std::exception const& e) { + + spdlog::error("Failed to check if game is over: {}", e.what()); + return false; +} catch (...) { + spdlog::error("Failed to check if game is over: Unknown error"); + return false; } -void obpf_tetrion_set_action_handler(ObpfTetrion* const tetrion, ObpfActionHandler const handler, void* const user_data) { +void obpf_tetrion_set_action_handler(ObpfTetrion* const tetrion, ObpfActionHandler const handler, void* const user_data) try { tetrion->set_action_handler(handler, user_data); +} catch (std::exception const& e) { + + spdlog::error("Failed to set action handler: {}", e.what()); +} catch (...) { + spdlog::error("Failed to set action handler: Unknown error"); }