use super::*;
use super::core::*;
use super::event::*;
use super::update::*;
use super::event_sink::*;
use super::update_stream::*;
use super::super::controller::*;
use super::super::user_interface::*;
use desync::*;
use binding::*;
use std::sync::*;
use std::ops::Deref;
pub struct UiSession<CoreController: Controller> {
controller: Arc<CoreController>,
core: Arc<Desync<UiSessionCore>>,
ui_update_lifetime: Mutex<Box<Releasable>>
}
impl<CoreController: Controller+'static> UiSession<CoreController> {
pub fn new(controller: CoreController) -> UiSession<CoreController> {
let controller = Arc::new(controller);
let core = UiSessionCore::new(controller.clone());
let core = Arc::new(Desync::new(core));
let ui_update_lifetime = Self::track_ui_updates(Arc::clone(&core));
UiSession {
controller: controller,
core: core,
ui_update_lifetime: Mutex::new(ui_update_lifetime)
}
}
fn track_ui_updates(core: Arc<Desync<UiSessionCore>>) -> Box<Releasable> {
let update_core = Arc::clone(&core);
core.sync(move |core| {
let ui = core.ui_tree();
ui.when_changed(notify(move || update_core.async(|core| core.wake_for_updates())))
})
}
}
impl<CoreController: Controller> Drop for UiSession<CoreController> {
fn drop(&mut self) {
self.ui_update_lifetime.lock().unwrap().done();
}
}
impl<CoreController: Controller> Deref for UiSession<CoreController> {
type Target = Arc<CoreController>;
fn deref(&self) -> &Arc<CoreController> {
&self.controller
}
}
impl<CoreController: 'static+Controller> UserInterface<Vec<UiEvent>, Vec<UiUpdate>, ()> for UiSession<CoreController> {
type EventSink = UiEventSink;
type UpdateStream = UiUpdateStream;
fn get_input_sink(&self) -> UiEventSink {
UiEventSink::new(Arc::clone(&self.controller), Arc::clone(&self.core))
}
fn get_updates(&self) -> UiUpdateStream {
UiUpdateStream::new(self.controller.clone(), Arc::clone(&self.core))
}
}
impl<CoreController: 'static+Controller> CoreUserInterface for UiSession<CoreController> {
fn ui_tree(&self) -> BindRef<Control> {
self.core.sync(|core| core.ui_tree())
}
}