flo_ui/session/
session.rs1use 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
16pub struct UiSession<CoreController: Controller> {
20 controller: Arc<CoreController>,
22
23 core: Arc<Desync<UiSessionCore>>,
25
26 ui_update_lifetime: Mutex<Box<Releasable>>
28}
29
30impl<CoreController: Controller+'static> UiSession<CoreController> {
31 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 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 type EventSink = UiEventSink;
79
80 type UpdateStream = UiUpdateStream;
82
83 fn get_input_sink(&self) -> UiEventSink {
85 UiEventSink::new(Arc::clone(&self.controller), Arc::clone(&self.core))
86 }
87
88 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}