Update the build environment and some architectural elements of the Kifu app #210
|
@ -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<T> {
|
||||
join_handle: glib::JoinHandle<()>,
|
||||
handler: Rc<dyn Fn(T)>,
|
||||
}
|
||||
|
||||
impl<T: 'static> LocalObserver<T> {
|
||||
/// 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<T>, handler: impl Fn(T) + 'static) -> Self {
|
||||
let listener = observable.subscribe();
|
||||
let handler = Rc::new(handler);
|
||||
|
@ -54,8 +61,9 @@ impl<T: 'static> LocalObserver<T> {
|
|||
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<T: 'static> LocalObserver<T> {
|
|||
|
||||
impl<T> Drop for LocalObserver<T> {
|
||||
fn drop(&mut self) {
|
||||
// Abort the task when the observer goes out of scope.
|
||||
self.join_handle.abort();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<CoreNotification>,
|
||||
|
|
Loading…
Reference in New Issue