makepad_hub/
hubui.rs

1use std::sync::{mpsc, Arc, Mutex};
2use crate::hubmsg::*;
3use crate::hubrouter::*;
4use crate::hubclient::*;
5
6pub struct HubUI {
7    pub hub_log:HubLog,
8    pub thread: Option<std::thread::JoinHandle<()>>,
9    pub route_send: HubRouteSend,
10    pub htc_msgs_arc: Arc<Mutex<Vec<FromHubMsg>>>,
11}
12
13impl HubUI {
14    
15    pub fn start_hub_ui_direct<F>(hub_router:&mut HubRouter,event_handler: F)->HubUI
16    where F: Fn() + Clone + Send + 'static{
17        // lets create a tx pair, and add a route
18        let (tx_write, rx_write) = mpsc::channel::<FromHubMsg>();
19        
20        let htc_msgs_arc = Arc::new(Mutex::new(Vec::new()));
21        let route_send = hub_router.connect_direct(HubRouteType::UI, tx_write);
22        
23        let thread = {
24            let htc_msgs_arc = Arc::clone(&htc_msgs_arc);
25            let route_send = route_send.clone();
26            let event_handler = event_handler.clone();
27            std::thread::spawn(move || {
28                // lets transmit a BuildServer ack
29                route_send.send(ToHubMsg {
30                    to: HubMsgTo::All,
31                    msg: HubMsg::ConnectUI
32                });
33                
34                // this is the main messageloop, on rx
35                while let Ok(htc) = rx_write.recv() {
36                    let mut do_signal = false;
37                    if let Ok(mut htc_msgs) = htc_msgs_arc.lock(){
38                        if htc_msgs.len() == 0{
39                            do_signal = true;
40                        }
41                        htc_msgs.push(htc);
42                    } 
43                    if do_signal{
44                        event_handler();
45                    }
46                }
47            })
48        };
49
50        HubUI{
51            thread: Some(thread),
52            htc_msgs_arc: htc_msgs_arc,
53            hub_log: HubLog::None,
54            route_send: route_send
55        }
56    }
57
58    pub fn start_hub_ui_networked<F>(digest: Digest, hub_log:HubLog,event_handler: &'static F)->HubUI
59    where F: Fn() + Clone + Send {
60
61        let route_send = HubRouteSend::Networked{
62            uid_alloc: Arc::new(Mutex::new(0)),
63            tx_write_arc:  Arc::new(Mutex::new(None)),
64            own_addr_arc:  Arc::new(Mutex::new(None))
65        };
66
67        let htc_msgs_arc = Arc::new(Mutex::new(Vec::new()));
68        
69        // lets start a thread that stays connected
70        let thread = {
71            let htc_msgs_arc = Arc::clone(&htc_msgs_arc);
72            let hub_log = hub_log.clone();
73            let event_handler = event_handler.clone();
74            std::thread::spawn(move || {
75                loop {
76                    
77                    hub_log.log("HubUI waiting for hub announcement..");
78                    
79                    // lets wait for a server announce
80                    let address = HubClient::wait_for_announce(digest.clone()).expect("cannot wait for announce");
81                    
82                    hub_log.msg("HubUI got announce, connecting to ", &address);
83                    
84                    // ok now connect to that address
85                    let hub_client = HubClient::connect_to_server(digest.clone(), address, hub_log.clone()).expect("cannot connect to hub");
86                    
87                    hub_log.msg("HubUI connected to ", &hub_client.server_addr);
88                    
89                    let route_send = hub_client.get_route_send();
90                    
91                    // lets transmit a BuildServer ack
92                    route_send.send(ToHubMsg {
93                        to: HubMsgTo::All,
94                        msg: HubMsg::ConnectUI
95                    });
96                    
97                    // this is the main messageloop, on rx
98                    while let Ok(htc) = hub_client.rx_read.as_ref().unwrap().recv() {
99                        let restart_connection = if let HubMsg::ConnectionError(_e) = &htc.msg{
100                            true
101                        }
102                        else{
103                            false
104                        };
105                        let mut do_signal = false;
106                        if let Ok(mut htc_msgs) = htc_msgs_arc.lock(){
107                            if htc_msgs.len() == 0{
108                                do_signal = true;
109                            }
110                            htc_msgs.push(htc);
111                        } 
112                        if do_signal{
113                            event_handler();
114                        }
115                        if restart_connection {
116                            break
117                        }
118                    }
119                }
120            })
121        };
122
123        HubUI{
124            hub_log:hub_log.clone(),
125            thread: Some(thread),
126            htc_msgs_arc: htc_msgs_arc,
127            route_send: route_send
128        }
129    }
130    
131    pub fn get_messages(&mut self)->Option<Vec<FromHubMsg>>{
132        if let Ok(mut htc_msgs) = self.htc_msgs_arc.lock() {
133            let mut msgs = Vec::new();
134            std::mem::swap(&mut msgs, &mut htc_msgs);
135            return Some(msgs);
136        }
137        None
138    }
139}