1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
use std::sync::{mpsc, Arc, Mutex};
use crate::hubmsg::*;
use crate::hubrouter::*;
use crate::hubclient::*;

pub struct HubUI {
    pub hub_log:HubLog,
    pub thread: Option<std::thread::JoinHandle<()>>,
    pub route_send: HubRouteSend,
    pub htc_msgs_arc: Arc<Mutex<Vec<FromHubMsg>>>,
}

impl HubUI {
    
    pub fn start_hub_ui_direct<F>(hub_router:&mut HubRouter,event_handler: F)->HubUI
    where F: Fn() + Clone + Send + 'static{
        // lets create a tx pair, and add a route
        let (tx_write, rx_write) = mpsc::channel::<FromHubMsg>();
        
        let htc_msgs_arc = Arc::new(Mutex::new(Vec::new()));
        let route_send = hub_router.connect_direct(HubRouteType::UI, tx_write);
        
        let thread = {
            let htc_msgs_arc = Arc::clone(&htc_msgs_arc);
            let route_send = route_send.clone();
            let event_handler = event_handler.clone();
            std::thread::spawn(move || {
                // lets transmit a BuildServer ack
                route_send.send(ToHubMsg {
                    to: HubMsgTo::All,
                    msg: HubMsg::ConnectUI
                });
                
                // this is the main messageloop, on rx
                while let Ok(htc) = rx_write.recv() {
                    let mut do_signal = false;
                    if let Ok(mut htc_msgs) = htc_msgs_arc.lock(){
                        if htc_msgs.len() == 0{
                            do_signal = true;
                        }
                        htc_msgs.push(htc);
                    } 
                    if do_signal{
                        event_handler();
                    }
                }
            })
        };

        HubUI{
            thread: Some(thread),
            htc_msgs_arc: htc_msgs_arc,
            hub_log: HubLog::None,
            route_send: route_send
        }
    }

    pub fn start_hub_ui_networked<F>(digest: Digest, hub_log:HubLog,event_handler: &'static F)->HubUI
    where F: Fn() + Clone + Send {

        let route_send = HubRouteSend::Networked{
            uid_alloc: Arc::new(Mutex::new(0)),
            tx_write_arc:  Arc::new(Mutex::new(None)),
            own_addr_arc:  Arc::new(Mutex::new(None))
        };

        let htc_msgs_arc = Arc::new(Mutex::new(Vec::new()));
        
        // lets start a thread that stays connected
        let thread = {
            let htc_msgs_arc = Arc::clone(&htc_msgs_arc);
            let hub_log = hub_log.clone();
            let event_handler = event_handler.clone();
            std::thread::spawn(move || {
                loop {
                    
                    hub_log.log("HubUI waiting for hub announcement..");
                    
                    // lets wait for a server announce
                    let address = HubClient::wait_for_announce(digest.clone()).expect("cannot wait for announce");
                    
                    hub_log.msg("HubUI got announce, connecting to ", &address);
                    
                    // ok now connect to that address
                    let hub_client = HubClient::connect_to_server(digest.clone(), address, hub_log.clone()).expect("cannot connect to hub");
                    
                    hub_log.msg("HubUI connected to ", &hub_client.server_addr);
                    
                    let route_send = hub_client.get_route_send();
                    
                    // lets transmit a BuildServer ack
                    route_send.send(ToHubMsg {
                        to: HubMsgTo::All,
                        msg: HubMsg::ConnectUI
                    });
                    
                    // this is the main messageloop, on rx
                    while let Ok(htc) = hub_client.rx_read.as_ref().unwrap().recv() {
                        let restart_connection = if let HubMsg::ConnectionError(_e) = &htc.msg{
                            true
                        }
                        else{
                            false
                        };
                        let mut do_signal = false;
                        if let Ok(mut htc_msgs) = htc_msgs_arc.lock(){
                            if htc_msgs.len() == 0{
                                do_signal = true;
                            }
                            htc_msgs.push(htc);
                        } 
                        if do_signal{
                            event_handler();
                        }
                        if restart_connection {
                            break
                        }
                    }
                }
            })
        };

        HubUI{
            hub_log:hub_log.clone(),
            thread: Some(thread),
            htc_msgs_arc: htc_msgs_arc,
            route_send: route_send
        }
    }
    
    pub fn get_messages(&mut self)->Option<Vec<FromHubMsg>>{
        if let Ok(mut htc_msgs) = self.htc_msgs_arc.lock() {
            let mut msgs = Vec::new();
            std::mem::swap(&mut msgs, &mut htc_msgs);
            return Some(msgs);
        }
        None
    }
}