Calls and input
Every Device method is one of three kinds, tagged with a badge on the API pages.
| Badge | Meaning |
|---|---|
| Fire-and-forget | Writes one frame, returns once the bytes are out, no reply. |
| Blocks | Sends a QUERY and waits for the correlated RESP. |
| No round-trip | Reads state the library already holds; can't fail on the link. |
device.move_rel(100, -50)?; // fire-and-forget: one frame out, no reply
let v = device.query_version()?; // blocks: waits for the box to reply
let c = device.counters(); // no round-trip: local snapshot, nothing on the wireAsync queries Queries await a reply, everything else fires and forgets
With the async feature, the QUERY methods are async fns that await their RESP (listed on Requests). Every other method is fire-and-forget and stays synchronous.
Futures without a runtime futures::executor::block_on
block_on runs one future to completion on the current thread, with no async runtime.
use futures::executor::block_on;
let device = Device::find()?.into_async();
let v = block_on(device.query_version())?;
println!("{v}");Query timeout Default timeout and QueryTimeout
A query, sync or async, waits DEFAULT_QUERY_TIMEOUT (1 s), then returns Err(Error::QueryTimeout).
match device.query_health() {
Ok(h) => println!("{h:?}"),
Err(medius::Error::QueryTimeout) => eprintln!("no reply in time"),
Err(e) => return Err(e),
}QueryTimeout is a query past its deadline; NoReply is a silent handshake. Both are on Errors.
Smooth motion Subdivide the delta, pace the steps
move_rel applies its delta at once. To spread it over time, send smaller steps ~1 ms apart.
use std::thread::sleep;
use std::time::Duration;
// ~400 counts right over 200 steps (~200 ms at 1 kHz).
for _ in 0..200 {
device.move_rel(2, 0)?;
sleep(Duration::from_millis(1));
}The library applies no rate limit: a loop with no sleep queues frames faster than 6 Mbaud drains.
ClicksPress, wait, release
A click is press, a wait, then release, which clears only the box's override.
use std::{thread, time::Duration};
use medius::Button;
device.press(Button::LEFT)?;
thread::sleep(Duration::from_millis(20));
device.release(Button::LEFT)?;reset drops every override at once. reapply re-asserts a held press on reconnect.