From b101c08a7aa7d88bad2d023d933346f6ef71ed7c Mon Sep 17 00:00:00 2001
From: Ivan Gagis <igagis@gmail.com>
Date: Tue, 10 Sep 2024 14:07:20 +0300
Subject: [PATCH] resolve TODO

---
 src/bedsidemon/settings.hpp                   |  4 ++--
 src/bedsidemon/settings_menu.cpp              |  4 ++--
 src/bedsidemon/spo2/spo2_parameter_window.cpp | 20 +++++++++++--------
 3 files changed, 16 insertions(+), 12 deletions(-)

diff --git a/src/bedsidemon/settings.hpp b/src/bedsidemon/settings.hpp
index e183a3f..8769ea0 100644
--- a/src/bedsidemon/settings.hpp
+++ b/src/bedsidemon/settings.hpp
@@ -22,8 +22,8 @@ along with this program.  If not, see <https://www.gnu.org/licenses/>.
 #pragma once
 
 #include <tml/tree.hpp>
-
 #include <utki/signal.hpp>
+#include <utki/singleton.hpp>
 
 namespace bedsidemon {
 
@@ -32,7 +32,7 @@ struct settings {
 	uint32_t sweep_speed_um_per_sec = default_sweep_speed_um_per_sec;
 };
 
-class settings_storage
+class settings_storage : public utki::singleton<settings_storage>
 {
 	std::string filename;
 
diff --git a/src/bedsidemon/settings_menu.cpp b/src/bedsidemon/settings_menu.cpp
index 74d4b89..d21251d 100644
--- a/src/bedsidemon/settings_menu.cpp
+++ b/src/bedsidemon/settings_menu.cpp
@@ -196,14 +196,14 @@ settings_menu::settings_menu(utki::shared_ref<ruis::context> context) :
 			ASSERT(sb.get_selection() < sweep_speeds_um_per_sec.size())
 			auto speed = sweep_speeds_um_per_sec[sb.get_selection()];
 
-			auto& ss = bedsidemon::application::inst().settings_storage;
+			auto& ss = settings_storage::inst();
 
 			auto s = ss.get();
 			s.sweep_speed_um_per_sec = speed;
 			ss.set(s);
 		};
 
-		auto& ss = bedsidemon::application::inst().settings_storage;
+		auto& ss = settings_storage::inst();
 		const auto& s = ss.get();
 		auto i = std::find(
 			sweep_speeds_um_per_sec.begin(), //
diff --git a/src/bedsidemon/spo2/spo2_parameter_window.cpp b/src/bedsidemon/spo2/spo2_parameter_window.cpp
index 8fca506..6bbdc10 100644
--- a/src/bedsidemon/spo2/spo2_parameter_window.cpp
+++ b/src/bedsidemon/spo2/spo2_parameter_window.cpp
@@ -235,7 +235,7 @@ spo2_parameter_window::spo2_parameter_window(utki::shared_ref<ruis::context> con
 	    }
     ))
 {
-	auto& ss = bedsidemon::application::inst().settings_storage;
+	auto& ss = settings_storage::inst();
 	decltype(settings_storage::settings_changed_signal
 	)::callback_type settings_change_handler = [&pw = *this](const settings& s) {
 		pw.waveform.set_sweep_speed(ruis::real(s.sweep_speed_um_per_sec) / ruis::real(std::milli::den));
@@ -244,13 +244,17 @@ spo2_parameter_window::spo2_parameter_window(utki::shared_ref<ruis::context> con
 	this->settings_change_signal_connection = ss.settings_changed_signal.connect(std::move(settings_change_handler));
 }
 
-spo2_parameter_window::~spo2_parameter_window() = default;
-
-// {
-// TODO: disconnect settings change observer
-// auto& ss = bedsidemon::application::inst().settings_storage;
-// ss.settings_changed_signal.disconnect(this->settings_change_signal_connection);
-// }
+spo2_parameter_window::~spo2_parameter_window()
+{
+	// in case of application exit, the parameter window widgets will be destroyed by
+	// ruisapp::application::gui destructor, which is after the settings_storage,
+	// so we need to check if the settings_storage object still exists before
+	// disconnecting from its signal
+	if (settings_storage::is_created()) {
+		auto& ss = settings_storage::inst();
+		ss.settings_changed_signal.disconnect(this->settings_change_signal_connection);
+	}
+}
 
 void spo2_parameter_window::set(const spo2_measurement& meas)
 {