From a0478f8b62cc9ff7d451e919914eae52a4e166ac Mon Sep 17 00:00:00 2001 From: Savanni D'Gerinel Date: Tue, 27 Feb 2024 23:36:27 -0500 Subject: [PATCH] Write some documentation for the LocalObserver --- kifu/gtk/src/lib.rs | 13 +++++++++++-- kifu/gtk/src/view_models/home_view_model.rs | 2 +- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/kifu/gtk/src/lib.rs b/kifu/gtk/src/lib.rs index 45106ab..ef7508c 100644 --- a/kifu/gtk/src/lib.rs +++ b/kifu/gtk/src/lib.rs @@ -39,12 +39,19 @@ where result } +/// LocalObserver creates a task on the current thread which watches the specified observer for notifications and calls the handler function with each one. +/// +/// The LocalObserver starts a task which listens for notifications during the constructor. When the observer goes out of scope, it will make a point of aborting the task. This combination means that anything which uses the observer can create it, hold on to a reference of it, and then drop it when done, and not have to do anything else with the observer object. struct LocalObserver { join_handle: glib::JoinHandle<()>, handler: Rc, } impl LocalObserver { + /// Construct a new LocalObserver and start it running. + /// + /// observable -- any object which emits events + /// handler -- a function which can process events fn new(observable: &dyn Observable, handler: impl Fn(T) + 'static) -> Self { let listener = observable.subscribe(); let handler = Rc::new(handler); @@ -54,8 +61,9 @@ impl LocalObserver { loop { match listener.recv().await { Ok(msg) => handler(msg), - Err(err) => { - unimplemented!("Should display an error message in the UI: {}", err) + Err(_) => { + // recv only fails if the channel has been closed and no other notifications are pending. This will break out of the loop and terminate the observer. + return; } } yield_now().await; @@ -71,6 +79,7 @@ impl LocalObserver { impl Drop for LocalObserver { fn drop(&mut self) { + // Abort the task when the observer goes out of scope. self.join_handle.abort(); } } diff --git a/kifu/gtk/src/view_models/home_view_model.rs b/kifu/gtk/src/view_models/home_view_model.rs index 78db7bc..effe97a 100644 --- a/kifu/gtk/src/view_models/home_view_model.rs +++ b/kifu/gtk/src/view_models/home_view_model.rs @@ -17,7 +17,7 @@ You should have received a copy of the GNU General Public License along with Kif use crate::LocalObserver; use kifu_core::{Core, CoreNotification}; -/// DatabaseViewModel controls the view that the user sees when starting the application if the application has been configured and if there are no games in progress. It provides a window into the database, showing a list of recently recorded games (whether from this app or from a main database). It also provides the UI for starting a new game. This will render an empty database view if the user hasn't configured a database yet. +/// Home controls the view that the user sees when starting the application if there are no games in progress. It provides a window into the database, showing a list of recently recorded games. It also provides the UI for starting a new game. This will render an empty database view if the user hasn't configured a database yet. pub struct HomeViewModel { core: Core, notification_observer: LocalObserver,