playdate_device/device/
methods.rs1use crate::retry::{IterTime, Retries};
2use crate::usb::mode::Mode;
3use crate::error::Error;
4
5use super::Device;
6
7
8type Result<T = (), E = Error> = std::result::Result<T, E>;
9
10
11pub async fn wait_mode_storage<T>(dev: Device, retry: Retries<T>) -> Result<Device>
12 where T: IterTime {
13 wait_mode_change(dev, Mode::Storage, retry).await
14}
15
16pub async fn wait_mode_data<T>(dev: Device, retry: Retries<T>) -> Result<Device>
17 where T: IterTime {
18 wait_mode_change(dev, Mode::Data, retry).await
19}
20
21
22#[cfg_attr(feature = "tracing", tracing::instrument(skip(dev, retry), fields(dev = dev.info().serial_number())))]
23pub async fn wait_mode_change(mut dev: Device, to: Mode, retry: Retries<impl IterTime>) -> Result<Device> {
24 let total = &retry.total;
25 let iter_ms = retry.iters.interval(total);
26 let retries_num = total.as_millis() / iter_ms.as_millis();
27 debug!("retries: {retries_num} * {iter_ms:?} ≈ {total:?}.");
28
29 let mut counter = retries_num;
30 #[cfg(all(feature = "tokio", not(feature = "async-std")))]
31 let mut interval = tokio::time::interval(iter_ms);
32
33 while {
34 counter -= 1;
35 counter
36 } != 0
37 {
38 #[cfg(all(not(feature = "async-std"), feature = "tokio"))]
39 interval.tick().await;
40 #[cfg(feature = "async-std")]
41 async_std::task::sleep(iter_ms).await;
42 #[cfg(all(not(feature = "tokio"), not(feature = "async-std")))]
43 std::thread::sleep(iter_ms);
44
45 let mode = dev.mode_cached();
46 trace!(
47 "{dev}: waiting mode {to}, current: {mode}, try: {}/{retries_num}",
48 retries_num - counter
49 );
50
51 if mode == to {
52 trace!("{dev} is in {to} mode.");
53 return Ok(dev);
54 }
55
56 if dev.refresh()? {
57 if dev.mode_cached() == to {
58 return Ok(dev);
59 } else {
60 trace!("refreshed to {mode} mode, waiting...")
61 }
62 }
63 }
64
65 Err(Error::usb_timeout(dev))
66}