Răsfoiți Sursa

map: backtracked and removed Mutex due to async rendering error

ui() needs a mutable reference or Mutex but cannot be async due to
synchronous capture:

   terminal.draw(|f| {
       ui::ui(f, app.clone());
   })?;
lunar-mining 4 ani în urmă
părinte
comite
89371962fe
4 a modificat fișierele cu 23 adăugiri și 25 ștergeri
  1. 2 0
      bin/map/src/app.rs
  2. 1 0
      bin/map/src/info_list.rs
  3. 14 12
      bin/map/src/main.rs
  4. 6 13
      bin/map/src/ui.rs

+ 2 - 0
bin/map/src/app.rs

@@ -6,6 +6,8 @@ use crate::{id_list::IdList, info_list::InfoList, node_info::NodeInfo};
 // make a structure to be able to modify and read them
 // make a structure to be able to modify and read them
 // protect using a mutex
 // protect using a mutex
 // arc reference
 // arc reference
+
+#[derive(Clone)]
 pub struct App {
 pub struct App {
     pub id_list: IdList,
     pub id_list: IdList,
     pub info_list: InfoList,
     pub info_list: InfoList,

+ 1 - 0
bin/map/src/info_list.rs

@@ -1,5 +1,6 @@
 use crate::node_info::NodeInfo;
 use crate::node_info::NodeInfo;
 
 
+#[derive(Clone)]
 pub struct InfoList {
 pub struct InfoList {
     pub index: usize,
     pub index: usize,
     pub infos: Vec<NodeInfo>,
     pub infos: Vec<NodeInfo>,

+ 14 - 12
bin/map/src/main.rs

@@ -119,7 +119,8 @@ async fn main() -> Result<()> {
 
 
     let id_list = IdList::new(ids);
     let id_list = IdList::new(ids);
 
 
-    let app = Arc::new(Mutex::new(App::new(id_list, info_list)));
+    //let app = Arc::new(App::new(id_list, info_list));
+    let app = App::new(id_list, info_list);
 
 
     let nthreads = num_cpus::get();
     let nthreads = num_cpus::get();
     let (signal, shutdown) = async_channel::unbounded::<()>();
     let (signal, shutdown) = async_channel::unbounded::<()>();
@@ -142,7 +143,7 @@ async fn main() -> Result<()> {
     result
     result
 }
 }
 
 
-async fn listen(ex: Arc<Executor<'_>>, app: Arc<Mutex<App>>) -> Result<()> {
+async fn listen(ex: Arc<Executor<'_>>, app: App) -> Result<()> {
     let client = Map::new("tcp://127.0.0.1:8000".to_string());
     let client = Map::new("tcp://127.0.0.1:8000".to_string());
 
 
     ex.spawn(poll(client, app)).detach();
     ex.spawn(poll(client, app)).detach();
@@ -150,7 +151,7 @@ async fn listen(ex: Arc<Executor<'_>>, app: Arc<Mutex<App>>) -> Result<()> {
     Ok(())
     Ok(())
 }
 }
 
 
-async fn poll(client: Map, app: Arc<Mutex<App>>) -> Result<()> {
+async fn poll(client: Map, _app: App) -> Result<()> {
     loop {
     loop {
         let reply = client.get_info().await?;
         let reply = client.get_info().await?;
 
 
@@ -161,14 +162,14 @@ async fn poll(client: Map, app: Arc<Mutex<App>>) -> Result<()> {
             let node2 = &nodes[1];
             let node2 = &nodes[1];
             let node3 = &nodes[2];
             let node3 = &nodes[2];
 
 
-            let infos = vec![NodeInfo {
+            let _infos = vec![NodeInfo {
                 id: node1["id"].to_string(),
                 id: node1["id"].to_string(),
                 connections: node1["connections"].as_u64().unwrap() as usize,
                 connections: node1["connections"].as_u64().unwrap() as usize,
                 is_active: node2["is_active"].as_bool().unwrap(),
                 is_active: node2["is_active"].as_bool().unwrap(),
                 last_message: node3["message"].to_string(),
                 last_message: node3["message"].to_string(),
             }];
             }];
 
 
-            //app.update(infos).await;
+            //app.lock().await.update(infos).await;
         } else {
         } else {
             // TODO: error handling
             // TODO: error handling
             println!("Reply is an error");
             println!("Reply is an error");
@@ -178,19 +179,20 @@ async fn poll(client: Map, app: Arc<Mutex<App>>) -> Result<()> {
     }
     }
 }
 }
 
 
-async fn run_app<B: Backend>(terminal: &mut Terminal<B>, app: Arc<Mutex<App>>) -> io::Result<()> {
+async fn run_app<B: Backend>(terminal: &mut Terminal<B>, mut app: App) -> io::Result<()> {
     let mut asi = async_stdin();
     let mut asi = async_stdin();
 
 
     terminal.clear()?;
     terminal.clear()?;
 
 
-    app.lock().await.id_list.state.select(Some(0));
+    app.id_list.state.select(Some(0));
 
 
-    app.lock().await.info_list.index = 0;
+    app.info_list.index = 0;
 
 
     // acquire the mutex
     // acquire the mutex
     // let mut app = app.lock();
     // let mut app = app.lock();
 
 
     loop {
     loop {
+        // clone everything
         terminal.draw(|f| {
         terminal.draw(|f| {
             ui::ui(f, app.clone());
             ui::ui(f, app.clone());
         })?;
         })?;
@@ -201,12 +203,12 @@ async fn run_app<B: Backend>(terminal: &mut Terminal<B>, app: Arc<Mutex<App>>) -
                     return Ok(());
                     return Ok(());
                 }
                 }
                 Key::Char('j') => {
                 Key::Char('j') => {
-                    app.lock().await.id_list.next();
-                    app.lock().await.info_list.next();
+                    app.id_list.next();
+                    app.info_list.next().await;
                 }
                 }
                 Key::Char('k') => {
                 Key::Char('k') => {
-                    app.lock().await.id_list.previous();
-                    app.lock().await.info_list.previous();
+                    app.id_list.previous();
+                    app.info_list.previous().await;
                 }
                 }
                 _ => (),
                 _ => (),
             }
             }

+ 6 - 13
bin/map/src/ui.rs

@@ -9,7 +9,7 @@ use tui::{
     Frame,
     Frame,
 };
 };
 
 
-pub async fn ui<B: Backend>(f: &mut Frame<'_, B>, app: Arc<Mutex<App>>) {
+pub fn ui<B: Backend>(f: &mut Frame<'_, B>, mut app: App) {
     let slice = Layout::default()
     let slice = Layout::default()
         .direction(Direction::Horizontal)
         .direction(Direction::Horizontal)
         .margin(2)
         .margin(2)
@@ -17,8 +17,6 @@ pub async fn ui<B: Backend>(f: &mut Frame<'_, B>, app: Arc<Mutex<App>>) {
         .split(f.size());
         .split(f.size());
 
 
     let nodes: Vec<ListItem> = app
     let nodes: Vec<ListItem> = app
-        .lock()
-        .await
         .id_list
         .id_list
         .node_id
         .node_id
         .iter()
         .iter()
@@ -32,20 +30,15 @@ pub async fn ui<B: Backend>(f: &mut Frame<'_, B>, app: Arc<Mutex<App>>) {
         .block(Block::default().borders(Borders::ALL))
         .block(Block::default().borders(Borders::ALL))
         .highlight_style(Style::default().fg(Color::LightCyan).add_modifier(Modifier::BOLD));
         .highlight_style(Style::default().fg(Color::LightCyan).add_modifier(Modifier::BOLD));
 
 
-    f.render_stateful_widget(nodes, slice[0], &mut app.lock().await.id_list.state);
+    f.render_stateful_widget(nodes, slice[0], &mut app.id_list.state);
 
 
-    let index = app.lock().await.info_list.index;
+    let index = app.info_list.index;
 
 
-    render_info(app, f, index, slice).await;
+    render_info(app, f, index, slice);
 }
 }
 
 
-async fn render_info<B: Backend>(
-    app: Arc<Mutex<App>>,
-    f: &mut Frame<'_, B>,
-    index: usize,
-    slice: Vec<Rect>,
-) {
-    let info = &app.lock().await.info_list.infos;
+fn render_info<B: Backend>(app: App, f: &mut Frame<'_, B>, index: usize, slice: Vec<Rect>) {
+    let info = &app.info_list.infos;
     let id = &info[index].id;
     let id = &info[index].id;
     let connections = info[index].connections;
     let connections = info[index].connections;
     let is_active = info[index].is_active;
     let is_active = info[index].is_active;