rstango 0.3.0

Implementation of the Tango distributed control system
Documentation
//! Requests made concurrently, against devices of the `server` example: every
//! blocking method of a proxy has an asynchronous form, which runs on any executor, so that
//! a single thread waits on all the devices at once.
//!
//! ```sh
//! cargo run --example concurrent -- test/motor/1 test/motor/2
//! ```

use std::env;

use futures::executor::block_on;
use futures::future::{join_all, try_join};

use tango::dev::{DevProxy, DevState};
use tango::error::Result;


/// Send a motor somewhere, then ask where it is and what it says of itself, the last two
/// being asked at once.
async fn move_motor(motor: &DevProxy, target: f64) -> Result<(f64, DevState)> {
    motor.command_async::<_, f64>("MoveTo", target).await?;
    let (position, state) = try_join(motor.read_attr_async::<f64, _>("position"), motor.state_async()).await?;
    Ok((position.value.unwrap_or(f64::NAN), state))
}


fn main() {

    let mut names = env::args().skip(1).collect::<Vec<_>>();
    if names.is_empty() {
        names.push("test/motor/1".to_string());
    }

    let motors = names.iter()
        .map(|name| DevProxy::new(name.as_str()))
        .collect::<Vec<_>>();

    // Every motor is moved at once, each to a target of its own, and one failing does not
    // stop the others.
    let moves = motors.iter()
        .enumerate()
        .map(|(index, motor)| move_motor(motor, 5.0 * (index + 1) as f64));
    let results = block_on(join_all(moves));

    for (name, res) in names.iter().zip(results) {
        match res {
            Ok((position, state)) => println!("{name}: {position} deg, {state:?}"),
            Err(err) => println!("{name}: {err}"),
        }
    }

}