|
- use futures::Future;
- use qmetaobject::*;
-
- #[derive(QObject, Default)]
- pub struct PairingManager {
- base: qt_base_class!(trait QObject),
- discovered_bridges: qt_signal!(count: usize),
- errored: qt_signal!(err: String),
- authenticated: qt_signal!(address: String, username: String),
- start_searching: qt_method!(fn(&self)),
- }
-
- impl PairingManager {
- fn start_searching(&self) {
- let callback_discovered = {
- let ptr = QPointer::from(&*self);
- queued_callback(move |count| {
- ptr.as_ref().map(|x| x.discovered_bridges(count));
- })
- };
- let callback_errored_1 = {
- let ptr = QPointer::from(&*self);
- queued_callback(move |err| {
- ptr.as_ref().map(|x| x.errored(err));
- })
- };
- let callback_errored_2 = callback_errored_1.clone();
- let callback_authenticated = {
- let ptr = QPointer::from(&*self);
- queued_callback(move |(address, username)| {
- ptr.as_ref().map(|x| x.authenticated(address, username));
- })
- };
- tokio::spawn(huey::bridge_discovery::discover()
- .then(move |result| {
- println!("{:?}", result);
- match result {
- Ok(bridges) => {
- if bridges.len() == 0 {
- callback_errored_1("Couldn't find a bridge.".to_owned());
- Err(())
- }
- else {
- callback_discovered(bridges.len());
- Ok(bridges)
- }
- },
- Err(err) => {
- eprintln!("{:?}", err);
- callback_errored_1(format!("{}", err));
- Err(())
- }
- }
- })
- .and_then(move |bridges| {
- fn run(bridges: Vec<huey::bridge_discovery::DiscoveredBridge>, i: usize) -> Box<Future<Item=(huey::bridge_discovery::DiscoveredBridge, String), Error=(Vec<huey::bridge_discovery::DiscoveredBridge>, usize, huey::HueError)> + Send> {
- let bridge: &huey::bridge_discovery::DiscoveredBridge = &bridges[i];
- Box::new(huey::registration::register(&bridge.internalipaddress, "radiate")
- .then(move |res| {
- match res {
- Ok(username) => Ok((bridges.into_iter().nth(i).unwrap(), username)),
- Err(err) => Err((bridges, i, err)),
- }
- })
- .or_else(|(bridges, i, err)| {
- match err {
- huey::HueError::LinkButtonNotPressed => {
- if i + 1 < bridges.len() {
- run(bridges, i + 1)
- } else {
- Box::new(tokio::timer::Delay::new(std::time::Instant::now() + std::time::Duration::from_millis(400))
- .or_else(|err| {
- eprintln!("Timer failed: {:?}", err);
- Ok(())
- })
- .and_then(|_| run(bridges, 0)))
- }
- },
- other_err => {
- Box::new(futures::future::err((bridges, i, other_err)))
- }
- }
- }))
- }
-
- run(bridges, 0)
- .then(move |res| {
- match res {
- Ok((bridge, username)) => {
- callback_authenticated((bridge.internalipaddress, username));
- },
- Err((_, _, err)) => {
- eprintln!("{:?}", err);
- callback_errored_2(format!("{}", err));
- },
- }
- Ok(())
- })
- }));
- }
- }
|