2024-03-15 14:49:25 +00:00
/*
Copyright 2024 , Savanni D ' Gerinel < savanni @ luminescent - dreams . com >
2024-03-22 03:48:48 +00:00
This file is part of On the Grid .
2024-03-15 14:49:25 +00:00
2024-03-22 03:48:48 +00:00
On the Grid is free software : you can redistribute it and / or modify it under the terms of the GNU
2024-03-15 14:49:25 +00:00
General Public License as published by the Free Software Foundation , either version 3 of the
License , or ( at your option ) any later version .
2024-03-22 03:48:48 +00:00
On the Grid is distributed in the hope that it will be useful , but WITHOUT ANY WARRANTY ; without
2024-03-15 14:49:25 +00:00
even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
General Public License for more details .
2024-03-22 03:48:48 +00:00
You should have received a copy of the GNU General Public License along with On the Grid . If not , see < https ://www.gnu.org/licenses/>.
2024-03-15 14:49:25 +00:00
* /
2024-03-22 02:39:28 +00:00
pub mod components ;
2024-02-27 13:34:17 +00:00
2024-03-15 14:49:25 +00:00
mod app_window ;
pub use app_window ::AppWindow ;
2024-02-27 13:34:17 +00:00
mod views ;
2024-03-21 23:20:09 +00:00
use async_std ::task ::{ spawn , yield_now } ;
2024-03-22 03:48:48 +00:00
use otg_core ::{ Core , Observable , CoreRequest , CoreResponse } ;
2024-02-28 04:21:54 +00:00
use std ::{ rc ::Rc , sync ::Arc } ;
use tokio ::runtime ::Runtime ;
2023-04-07 01:52:39 +00:00
#[ derive(Clone) ]
pub struct CoreApi {
2024-02-27 13:34:17 +00:00
pub core : Core ,
2023-04-07 01:52:39 +00:00
}
impl CoreApi {
2024-03-21 23:20:09 +00:00
pub async fn dispatch ( & self , request : CoreRequest ) -> CoreResponse {
self . core . dispatch ( request ) . await
2023-04-07 01:52:39 +00:00
}
}
2023-06-15 03:47:12 +00:00
pub fn perftrace < F , A > ( trace_name : & str , f : F ) -> A
where
F : FnOnce ( ) -> A ,
{
let start = std ::time ::Instant ::now ( ) ;
let result = f ( ) ;
let end = std ::time ::Instant ::now ( ) ;
println! ( " [Trace: {} ] {:?} " , trace_name , end - start ) ;
2023-10-05 16:19:57 +00:00
result
2023-06-15 03:47:12 +00:00
}
2024-02-28 04:21:54 +00:00
2024-02-28 04:36:27 +00:00
/// 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.
2024-02-28 04:21:54 +00:00
struct LocalObserver < T > {
join_handle : glib ::JoinHandle < ( ) > ,
handler : Rc < dyn Fn ( T ) > ,
}
impl < T : 'static > LocalObserver < T > {
2024-02-28 04:36:27 +00:00
/// Construct a new LocalObserver and start it running.
///
/// observable -- any object which emits events
/// handler -- a function which can process events
2024-02-28 04:21:54 +00:00
fn new ( observable : & dyn Observable < T > , handler : impl Fn ( T ) + 'static ) -> Self {
let listener = observable . subscribe ( ) ;
let handler = Rc ::new ( handler ) ;
let join_handle = glib ::spawn_future_local ( {
let handler = handler . clone ( ) ;
async move {
loop {
match listener . recv ( ) . await {
Ok ( msg ) = > handler ( msg ) ,
2024-02-28 04:36:27 +00:00
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 ;
2024-02-28 04:21:54 +00:00
}
}
yield_now ( ) . await ;
}
}
} ) ;
Self {
join_handle ,
handler ,
}
}
}
impl < T > Drop for LocalObserver < T > {
fn drop ( & mut self ) {
2024-02-28 04:36:27 +00:00
// Abort the task when the observer goes out of scope.
2024-02-28 04:21:54 +00:00
self . join_handle . abort ( ) ;
}
}