flo_ui/session/
session.rs

1use super::*;
2use super::core::*;
3use super::event::*;
4use super::update::*;
5use super::event_sink::*;
6use super::update_stream::*;
7use super::super::controller::*;
8use super::super::user_interface::*;
9
10use desync::*;
11use binding::*;
12
13use std::sync::*;
14use std::ops::Deref;
15
16///
17/// UI session provides a raw user interface implementation for a core controller
18/// 
19pub struct UiSession<CoreController: Controller> {
20    /// The core controller
21    controller: Arc<CoreController>,
22
23    /// The core of the UI session
24    core: Arc<Desync<UiSessionCore>>,
25
26    /// A releasable that tracks UI updates
27    ui_update_lifetime: Mutex<Box<Releasable>>
28}
29
30impl<CoreController: Controller+'static> UiSession<CoreController> {
31    ///
32    /// Cretes a new UI session with the specified core controller
33    /// 
34    pub fn new(controller: CoreController) -> UiSession<CoreController> {
35        let controller          = Arc::new(controller);
36        let core                = UiSessionCore::new(controller.clone());
37        let core                = Arc::new(Desync::new(core));
38
39        let ui_update_lifetime  = Self::track_ui_updates(Arc::clone(&core));
40
41        UiSession {
42            controller:         controller,
43            core:               core,
44            ui_update_lifetime: Mutex::new(ui_update_lifetime)
45        }
46    }
47
48    ///
49    /// Causes wake_for_updates to be called on a core when its UI changes
50    /// 
51    fn track_ui_updates(core: Arc<Desync<UiSessionCore>>) -> Box<Releasable> {
52        let update_core = Arc::clone(&core);
53
54        core.sync(move |core| {
55            let ui = core.ui_tree();
56
57            ui.when_changed(notify(move || update_core.async(|core| core.wake_for_updates())))
58        })
59    }
60}
61
62impl<CoreController: Controller> Drop for UiSession<CoreController> {
63    fn drop(&mut self) {
64        self.ui_update_lifetime.lock().unwrap().done();
65    }
66}
67
68impl<CoreController: Controller> Deref for UiSession<CoreController> {
69    type Target = Arc<CoreController>;
70
71    fn deref(&self) -> &Arc<CoreController> {
72        &self.controller
73    }
74}
75
76impl<CoreController: 'static+Controller> UserInterface<Vec<UiEvent>, Vec<UiUpdate>, ()> for UiSession<CoreController> {
77    /// The type of the event sink for this UI
78    type EventSink = UiEventSink;
79
80    /// The type of the update stream for this UI
81    type UpdateStream = UiUpdateStream;
82
83    /// Retrieves an input event sink for this user interface
84    fn get_input_sink(&self) -> UiEventSink {
85        UiEventSink::new(Arc::clone(&self.controller), Arc::clone(&self.core))
86    }
87
88    /// Retrieves a view onto the update stream for this user interface
89    fn get_updates(&self) -> UiUpdateStream {
90        UiUpdateStream::new(self.controller.clone(), Arc::clone(&self.core))
91    }
92}
93
94impl<CoreController: 'static+Controller> CoreUserInterface for UiSession<CoreController> {
95    fn ui_tree(&self) -> BindRef<Control> {
96        self.core.sync(|core| core.ui_tree())
97    }
98}