use std::time::Duration;
use leaprs::*;
use throbber::Throbber;
fn main() {
let mut connection =
Connection::create(ConnectionConfig::default()).expect("Failed to create connection");
connection.open().expect("Failed to open the connection");
connection.wait_for("Connecting to the service...".to_string(), |e| match e {
EventRef::Connection(e) => {
let flags = e.flags();
Msg::Success(format!("Connected. Service state: {:?}", flags))
}
_ => Msg::None,
});
connection.wait_for("Waiting for a device...".to_string(), |e| match e {
EventRef::Device(e) => {
let device_info = e
.device()
.open()
.expect("Failed to open the device")
.get_info()
.expect("Failed to get device info");
let serial = device_info
.serial()
.expect("Failed to get the device serial");
let pid = device_info.pid();
Msg::Success(format!("Got the device {} ({})", serial, pid))
}
_ => Msg::None,
});
#[cfg(feature = "gemini")]
{
connection
.get_tracking_mode()
.expect("Failed to request for tracking mode");
connection.wait_for(
"Waiting for the tracking mode message...".to_string(),
|e| match e {
EventRef::TrackingMode(e) => {
Msg::Success(format!("Tracking mode: {:#?}", e.current_tracking_mode()))
}
_ => Msg::None,
},
);
}
connection.wait_for("Waiting for a hand...".to_string(), |e| match e {
EventRef::Tracking(e) => {
if !e.hands().is_empty() {
Msg::Success("Got a hand".to_string())
} else {
Msg::None
}
}
_ => Msg::None,
});
connection.wait_for("Close the hand".to_string(), |e| match e {
EventRef::Tracking(e) => {
if let Some(hand) = e.hands().first() {
let grab_strength = hand.grab_strength;
if grab_strength >= 1.0 {
Msg::Success("The hand is closed".to_string())
} else {
Msg::Progress(format!("Close the hand {:.0}%", grab_strength * 100.0))
}
} else {
Msg::Progress("Close the hand".to_string())
}
}
_ => Msg::None,
});
connection.wait_for("Open the hand".to_string(), |e| match e {
EventRef::Tracking(e) => {
if let Some(hand) = e.hands().first() {
let ungrab_strength = 1.0 - hand.grab_strength;
if ungrab_strength >= 0.999 {
Msg::Success("The hand is opened".to_string())
} else {
Msg::Progress(format!("Open the hand {:.0}%", ungrab_strength * 100.0))
}
} else {
Msg::Progress("Open the hand".to_string())
}
}
_ => Msg::None,
});
connection
.set_policy_flags(PolicyFlags::IMAGES, PolicyFlags::empty())
.expect("Failed to set policy flags");
connection.wait_for("Reading image".to_string(), |e| match e {
EventRef::Image(e) => {
let w = e.images()[0].properties().width;
let h = e.images()[0].properties().height;
let images = e.images();
let image_data = images[0].data();
image::save_buffer("image.png", image_data, w, h, image::ColorType::L8)
.expect("failed to save buffer");
Msg::Success("Saved image.png".to_string())
}
_ => Msg::None,
});
connection
.set_policy_flags(PolicyFlags::empty(), PolicyFlags::IMAGES)
.expect("Failed to set policy flags");
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Msg {
None,
Success(String),
Progress(String),
Failure(String),
}
trait WaitFor {
fn wait_for<F>(&mut self, message: String, condition: F)
where
F: Fn(&EventRef) -> Msg;
}
impl WaitFor for Connection {
fn wait_for<F>(&mut self, message: String, condition: F)
where
F: Fn(&EventRef) -> Msg,
{
let mut throbber = Throbber::new().interval(Duration::from_millis(100));
throbber.start_with_msg(message);
loop {
if let Ok(message) = self.poll(100) {
match condition(&message.event()) {
Msg::None => {}
Msg::Success(message) => {
throbber.success(message);
break;
}
Msg::Progress(message) => {
throbber.change_message(message);
}
Msg::Failure(message) => {
throbber.fail(message);
break;
}
}
}
}
throbber.end();
}
}