From e02225262cf1b171d7b6cef3399b005f659e0035 Mon Sep 17 00:00:00 2001 From: Michael Fabian 'Xaymar' Dirks Date: Sat, 7 Sep 2019 21:35:32 +0200 Subject: [PATCH] obs-source: Add noexcept try-catch to C facing callbacks --- source/obs/obs-source.cpp | 198 +++++++++++++++++++++++++++----------- source/obs/obs-source.hpp | 54 +++++------ 2 files changed, 167 insertions(+), 85 deletions(-) diff --git a/source/obs/obs-source.cpp b/source/obs/obs-source.cpp index 7b3b6262..4b18142a 100644 --- a/source/obs/obs-source.cpp +++ b/source/obs/obs-source.cpp @@ -19,9 +19,9 @@ #include "obs-source.hpp" #include +#include "plugin.hpp" -void obs::source::handle_destroy(void* p, calldata_t* calldata) -{ +void obs::source::handle_destroy(void* p, calldata_t* calldata) noexcept try { obs::source* self = reinterpret_cast(p); obs_source_t* source; @@ -37,73 +37,97 @@ void obs::source::handle_destroy(void* p, calldata_t* calldata) return; } self->events.destroy(self); +} catch (std::exception& ex) { + P_LOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what()); +} catch (...) { + P_LOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__); } -void obs::source::handle_remove(void* p, calldata_t*) -{ +void obs::source::handle_remove(void* p, calldata_t*) noexcept try { obs::source* self = reinterpret_cast(p); if (!self->events.remove) { return; } self->events.remove(self); +} catch (std::exception& ex) { + P_LOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what()); +} catch (...) { + P_LOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__); } -void obs::source::handle_save(void* p, calldata_t*) -{ +void obs::source::handle_save(void* p, calldata_t*) noexcept try { obs::source* self = reinterpret_cast(p); if (!self->events.save) { return; } self->events.save(self); +} catch (std::exception& ex) { + P_LOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what()); +} catch (...) { + P_LOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__); } -void obs::source::handle_load(void* p, calldata_t*) -{ +void obs::source::handle_load(void* p, calldata_t*) noexcept try { obs::source* self = reinterpret_cast(p); if (!self->events.load) { return; } self->events.load(self); +} catch (std::exception& ex) { + P_LOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what()); +} catch (...) { + P_LOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__); } -void obs::source::handle_activate(void* p, calldata_t*) -{ +void obs::source::handle_activate(void* p, calldata_t*) noexcept try { obs::source* self = reinterpret_cast(p); if (!self->events.activate) { return; } self->events.activate(self); +} catch (std::exception& ex) { + P_LOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what()); +} catch (...) { + P_LOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__); } -void obs::source::handle_deactivate(void* p, calldata_t*) -{ +void obs::source::handle_deactivate(void* p, calldata_t*) noexcept try { obs::source* self = reinterpret_cast(p); if (!self->events.deactivate) { return; } self->events.deactivate(self); +} catch (std::exception& ex) { + P_LOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what()); +} catch (...) { + P_LOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__); } -void obs::source::handle_show(void* p, calldata_t*) -{ +void obs::source::handle_show(void* p, calldata_t*) noexcept try { obs::source* self = reinterpret_cast(p); if (!self->events.show) { return; } self->events.show(self); +} catch (std::exception& ex) { + P_LOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what()); +} catch (...) { + P_LOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__); } -void obs::source::handle_hide(void* p, calldata_t*) -{ +void obs::source::handle_hide(void* p, calldata_t*) noexcept try { obs::source* self = reinterpret_cast(p); if (!self->events.hide) { return; } self->events.hide(self); +} catch (std::exception& ex) { + P_LOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what()); +} catch (...) { + P_LOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__); } -void obs::source::handle_enable(void* p, calldata_t* calldata) -{ +void obs::source::handle_enable(void* p, calldata_t* calldata) noexcept try { obs::source* self = reinterpret_cast(p); if (!self->events.enable) { return; @@ -115,10 +139,13 @@ void obs::source::handle_enable(void* p, calldata_t* calldata) } self->events.enable(self, enabled); +} catch (std::exception& ex) { + P_LOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what()); +} catch (...) { + P_LOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__); } -void obs::source::handle_push_to_mute_changed(void* p, calldata_t* calldata) -{ +void obs::source::handle_push_to_mute_changed(void* p, calldata_t* calldata) noexcept try { obs::source* self = reinterpret_cast(p); if (!self->events.push_to_mute_changed) { return; @@ -130,10 +157,13 @@ void obs::source::handle_push_to_mute_changed(void* p, calldata_t* calldata) } self->events.push_to_mute_changed(self, enabled); +} catch (std::exception& ex) { + P_LOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what()); +} catch (...) { + P_LOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__); } -void obs::source::handle_push_to_mute_delay(void* p, calldata_t* calldata) -{ +void obs::source::handle_push_to_mute_delay(void* p, calldata_t* calldata) noexcept try { obs::source* self = reinterpret_cast(p); if (!self->events.push_to_mute_delay) { return; @@ -145,10 +175,13 @@ void obs::source::handle_push_to_mute_delay(void* p, calldata_t* calldata) } self->events.push_to_mute_delay(self, delay); +} catch (std::exception& ex) { + P_LOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what()); +} catch (...) { + P_LOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__); } -void obs::source::handle_push_to_talk_changed(void* p, calldata_t* calldata) -{ +void obs::source::handle_push_to_talk_changed(void* p, calldata_t* calldata) noexcept try { obs::source* self = reinterpret_cast(p); if (!self->events.push_to_talk_changed) { return; @@ -160,10 +193,13 @@ void obs::source::handle_push_to_talk_changed(void* p, calldata_t* calldata) } self->events.push_to_talk_changed(self, enabled); +} catch (std::exception& ex) { + P_LOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what()); +} catch (...) { + P_LOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__); } -void obs::source::handle_push_to_talk_delay(void* p, calldata_t* calldata) -{ +void obs::source::handle_push_to_talk_delay(void* p, calldata_t* calldata) noexcept try { obs::source* self = reinterpret_cast(p); if (!self->events.push_to_talk_delay) { return; @@ -175,10 +211,13 @@ void obs::source::handle_push_to_talk_delay(void* p, calldata_t* calldata) } self->events.push_to_talk_delay(self, delay); +} catch (std::exception& ex) { + P_LOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what()); +} catch (...) { + P_LOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__); } -void obs::source::handle_rename(void* p, calldata_t* calldata) -{ +void obs::source::handle_rename(void* p, calldata_t* calldata) noexcept try { obs::source* self = reinterpret_cast(p); if (!self->events.enable) { return; @@ -195,19 +234,25 @@ void obs::source::handle_rename(void* p, calldata_t* calldata) } self->events.rename(self, std::string(new_name ? new_name : ""), std::string(prev_name ? prev_name : "")); +} catch (std::exception& ex) { + P_LOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what()); +} catch (...) { + P_LOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__); } -void obs::source::handle_update_properties(void* p, calldata_t*) -{ +void obs::source::handle_update_properties(void* p, calldata_t*) noexcept try { obs::source* self = reinterpret_cast(p); if (!self->events.update_properties) { return; } self->events.update_properties(self); +} catch (std::exception& ex) { + P_LOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what()); +} catch (...) { + P_LOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__); } -void obs::source::handle_update_flags(void* p, calldata_t* calldata) -{ +void obs::source::handle_update_flags(void* p, calldata_t* calldata) noexcept try { obs::source* self = reinterpret_cast(p); if (!self->events.update_flags) { return; @@ -219,10 +264,13 @@ void obs::source::handle_update_flags(void* p, calldata_t* calldata) } self->events.update_flags(self, flags); +} catch (std::exception& ex) { + P_LOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what()); +} catch (...) { + P_LOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__); } -void obs::source::handle_mute(void* p, calldata_t* calldata) -{ +void obs::source::handle_mute(void* p, calldata_t* calldata) noexcept try { obs::source* self = reinterpret_cast(p); if (!self->events.mute) { return; @@ -234,10 +282,13 @@ void obs::source::handle_mute(void* p, calldata_t* calldata) } self->events.mute(self, muted); +} catch (std::exception& ex) { + P_LOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what()); +} catch (...) { + P_LOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__); } -void obs::source::handle_volume(void* p, calldata_t* calldata) -{ +void obs::source::handle_volume(void* p, calldata_t* calldata) noexcept try { obs::source* self = reinterpret_cast(p); if (!self->events.volume) { return; @@ -251,10 +302,13 @@ void obs::source::handle_volume(void* p, calldata_t* calldata) self->events.volume(self, volume); calldata_set_float(calldata, "volume", volume); +} catch (std::exception& ex) { + P_LOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what()); +} catch (...) { + P_LOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__); } -void obs::source::handle_audio_sync(void* p, calldata_t* calldata) -{ +void obs::source::handle_audio_sync(void* p, calldata_t* calldata) noexcept try { obs::source* self = reinterpret_cast(p); if (!self->events.audio_sync) { return; @@ -268,10 +322,13 @@ void obs::source::handle_audio_sync(void* p, calldata_t* calldata) self->events.audio_sync(self, mixers); calldata_set_int(calldata, "offset", mixers); +} catch (std::exception& ex) { + P_LOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what()); +} catch (...) { + P_LOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__); } -void obs::source::handle_audio_mixers(void* p, calldata_t* calldata) -{ +void obs::source::handle_audio_mixers(void* p, calldata_t* calldata) noexcept try { obs::source* self = reinterpret_cast(p); if (!self->events.audio_mixers) { return; @@ -285,20 +342,26 @@ void obs::source::handle_audio_mixers(void* p, calldata_t* calldata) self->events.audio_mixers(self, mixers); calldata_set_int(calldata, "mixers", mixers); +} catch (std::exception& ex) { + P_LOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what()); +} catch (...) { + P_LOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__); } -void obs::source::handle_audio_data(void* p, obs_source_t*, const audio_data* audio, bool muted) -{ +void obs::source::handle_audio_data(void* p, obs_source_t*, const audio_data* audio, bool muted) noexcept try { obs::source* self = reinterpret_cast(p); if (!self->events.audio_data) { return; } self->events.audio_data(self, audio, muted); +} catch (std::exception& ex) { + P_LOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what()); +} catch (...) { + P_LOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__); } -void obs::source::handle_filter_add(void* p, calldata_t* calldata) -{ +void obs::source::handle_filter_add(void* p, calldata_t* calldata) noexcept try { obs::source* self = reinterpret_cast(p); if (!self->events.filter_add) { return; @@ -310,10 +373,13 @@ void obs::source::handle_filter_add(void* p, calldata_t* calldata) } self->events.filter_add(self, filter); +} catch (std::exception& ex) { + P_LOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what()); +} catch (...) { + P_LOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__); } -void obs::source::handle_filter_remove(void* p, calldata_t* calldata) -{ +void obs::source::handle_filter_remove(void* p, calldata_t* calldata) noexcept try { obs::source* self = reinterpret_cast(p); if (!self->events.filter_remove) { return; @@ -325,42 +391,58 @@ void obs::source::handle_filter_remove(void* p, calldata_t* calldata) } self->events.filter_remove(self, filter); +} catch (std::exception& ex) { + P_LOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what()); +} catch (...) { + P_LOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__); } -void obs::source::handle_reorder_filters(void* p, calldata_t*) -{ +void obs::source::handle_reorder_filters(void* p, calldata_t*) noexcept try { obs::source* self = reinterpret_cast(p); if (!self->events.reorder_filters) { return; } self->events.reorder_filters(self); +} catch (std::exception& ex) { + P_LOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what()); +} catch (...) { + P_LOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__); } -void obs::source::handle_transition_start(void* p, calldata_t*) -{ +void obs::source::handle_transition_start(void* p, calldata_t*) noexcept try { obs::source* self = reinterpret_cast(p); if (!self->events.transition_start) { return; } self->events.transition_start(self); +} catch (std::exception& ex) { + P_LOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what()); +} catch (...) { + P_LOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__); } -void obs::source::handle_transition_video_stop(void* p, calldata_t*) -{ +void obs::source::handle_transition_video_stop(void* p, calldata_t*) noexcept try { obs::source* self = reinterpret_cast(p); if (!self->events.transition_video_stop) { return; } self->events.transition_video_stop(self); +} catch (std::exception& ex) { + P_LOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what()); +} catch (...) { + P_LOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__); } -void obs::source::handle_transition_stop(void* p, calldata_t*) -{ +void obs::source::handle_transition_stop(void* p, calldata_t*) noexcept try { obs::source* self = reinterpret_cast(p); if (!self->events.transition_stop) { return; } self->events.transition_stop(self); +} catch (std::exception& ex) { + P_LOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what()); +} catch (...) { + P_LOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__); } obs::source::~source() @@ -411,7 +493,7 @@ obs::source::source() #endif #define auto_signal_c(SIGNAL) \ { \ - this->events.SIGNAL.set_listen_callback([this] { \ + this->events.SIGNAL.set_listen_callback([this]() noexcept { \ if (!this->_self) \ return; \ auto sh = obs_source_get_signal_handler(this->_self); \ @@ -419,7 +501,7 @@ obs::source::source() signal_handler_connect(sh, "" #SIGNAL, obs::source::handle_##SIGNAL, this); \ } \ }); \ - this->events.SIGNAL.set_silence_callback([this] { \ + this->events.SIGNAL.set_silence_callback([this]() noexcept { \ if (!this->_self) \ return; \ auto sh = obs_source_get_signal_handler(this->_self); \ @@ -441,12 +523,12 @@ obs::source::source() // libOBS unfortunately does not use the event system for audio data callbacks, which is kind of odd as most other // things do. So instead we'll have to manually deal with it for now. { - this->events.audio_data.set_listen_callback([this] { + this->events.audio_data.set_listen_callback([this]() noexcept { if (!this->_self) return; obs_source_add_audio_capture_callback(this->_self, obs::source::handle_audio_data, this); }); - this->events.audio_data.set_silence_callback([this] { + this->events.audio_data.set_silence_callback([this]() noexcept { if (!this->_self) return; obs_source_remove_audio_capture_callback(this->_self, obs::source::handle_audio_data, this); diff --git a/source/obs/obs-source.hpp b/source/obs/obs-source.hpp index 755b26ef..678eff9b 100644 --- a/source/obs/obs-source.hpp +++ b/source/obs/obs-source.hpp @@ -40,33 +40,33 @@ namespace obs { obs_source_t* _self; bool _track_ownership = false; - static void handle_destroy(void* p, calldata_t* calldata); - static void handle_remove(void* p, calldata_t* calldata); - static void handle_save(void* p, calldata_t* calldata); - static void handle_load(void* p, calldata_t* calldata); - static void handle_activate(void* p, calldata_t* calldata); - static void handle_deactivate(void* p, calldata_t* calldata); - static void handle_show(void* p, calldata_t* calldata); - static void handle_hide(void* p, calldata_t* calldata); - static void handle_enable(void* p, calldata_t* calldata); - static void handle_push_to_mute_changed(void* p, calldata_t* calldata); - static void handle_push_to_mute_delay(void* p, calldata_t* calldata); - static void handle_push_to_talk_changed(void* p, calldata_t* calldata); - static void handle_push_to_talk_delay(void* p, calldata_t* calldata); - static void handle_rename(void* p, calldata_t* calldata); - static void handle_update_properties(void* p, calldata_t* calldata); - static void handle_update_flags(void* p, calldata_t* calldata); - static void handle_mute(void* p, calldata_t* calldata); - static void handle_volume(void* p, calldata_t* calldata); - static void handle_audio_sync(void* p, calldata_t* calldata); - static void handle_audio_mixers(void* p, calldata_t* calldata); - static void handle_audio_data(void* p, obs_source_t* source, const audio_data* audio, bool muted); - static void handle_filter_add(void* p, calldata_t* calldata); - static void handle_filter_remove(void* p, calldata_t* calldata); - static void handle_reorder_filters(void* p, calldata_t* calldata); - static void handle_transition_start(void* p, calldata_t* calldata); - static void handle_transition_video_stop(void* p, calldata_t* calldata); - static void handle_transition_stop(void* p, calldata_t* calldata); + static void handle_destroy(void* p, calldata_t* calldata) noexcept; + static void handle_remove(void* p, calldata_t* calldata) noexcept; + static void handle_save(void* p, calldata_t* calldata) noexcept; + static void handle_load(void* p, calldata_t* calldata) noexcept; + static void handle_activate(void* p, calldata_t* calldata) noexcept; + static void handle_deactivate(void* p, calldata_t* calldata) noexcept; + static void handle_show(void* p, calldata_t* calldata) noexcept; + static void handle_hide(void* p, calldata_t* calldata) noexcept; + static void handle_enable(void* p, calldata_t* calldata) noexcept; + static void handle_push_to_mute_changed(void* p, calldata_t* calldata) noexcept; + static void handle_push_to_mute_delay(void* p, calldata_t* calldata) noexcept; + static void handle_push_to_talk_changed(void* p, calldata_t* calldata) noexcept; + static void handle_push_to_talk_delay(void* p, calldata_t* calldata) noexcept; + static void handle_rename(void* p, calldata_t* calldata) noexcept; + static void handle_update_properties(void* p, calldata_t* calldata) noexcept; + static void handle_update_flags(void* p, calldata_t* calldata) noexcept; + static void handle_mute(void* p, calldata_t* calldata) noexcept; + static void handle_volume(void* p, calldata_t* calldata) noexcept; + static void handle_audio_sync(void* p, calldata_t* calldata) noexcept; + static void handle_audio_mixers(void* p, calldata_t* calldata) noexcept; + static void handle_audio_data(void* p, obs_source_t* source, const audio_data* audio, bool muted) noexcept; + static void handle_filter_add(void* p, calldata_t* calldata) noexcept; + static void handle_filter_remove(void* p, calldata_t* calldata) noexcept; + static void handle_reorder_filters(void* p, calldata_t* calldata) noexcept; + static void handle_transition_start(void* p, calldata_t* calldata) noexcept; + static void handle_transition_video_stop(void* p, calldata_t* calldata) noexcept; + static void handle_transition_stop(void* p, calldata_t* calldata) noexcept; public: virtual ~source();