use crate::connection::Connection;
use crate::connection::ConnectionTrait;
use crate::crazyflie_usb_connection::CrazyflieUSBConnection;
use crate::crazyradio::{SharedCrazyradio, WeakSharedCrazyradio};
use crate::crazyradio_connection::CrazyradioConnection;
use crate::error::{Error, Result};
use futures_util::lock::Mutex;
use std::collections::BTreeMap;
pub struct LinkContext {
radios: Mutex<BTreeMap<usize, WeakSharedCrazyradio>>,
}
impl LinkContext {
pub fn new() -> Self {
Self {
radios: Mutex::new(BTreeMap::new()),
}
}
pub async fn get_radio(&self, radio_nth: usize) -> Result<SharedCrazyradio> {
let mut radios = self.radios.lock().await;
radios.entry(radio_nth).or_insert_with(WeakSharedCrazyradio::default);
let radio = match radios[&radio_nth].upgrade() {
Some(radio) => radio,
None => {
let new_radio = crate::crazyradio::Crazyradio::open_nth_async(radio_nth).await?;
let new_radio = SharedCrazyradio::new(new_radio);
radios.insert(radio_nth, new_radio.downgrade());
new_radio
}
};
Ok(radio)
}
pub async fn scan(&self, address: [u8; 5]) -> Result<Vec<String>> {
let mut found = Vec::new();
found.extend(CrazyradioConnection::scan(self, address).await?);
found.extend(CrazyflieUSBConnection::scan().await?);
Ok(found)
}
pub async fn scan_selected(&self, uris: Vec<&str>) -> Result<Vec<String>> {
let mut found = Vec::new();
found.extend(CrazyradioConnection::scan_selected(self, uris.clone()).await?);
found.extend(CrazyflieUSBConnection::scan_selected(uris).await?);
Ok(found)
}
pub async fn open_link(&self, uri: &str) -> Result<Connection> {
let connection: Option<Box<dyn ConnectionTrait + Send + Sync>> =
if let Some(connection) = CrazyradioConnection::open(self, uri).await? {
Some(Box::new(connection))
} else if let Some(connection) = CrazyflieUSBConnection::open(self, uri).await? {
Some(Box::new(connection))
} else {
None
};
let internal_connection = connection.ok_or(Error::InvalidUri)?;
Ok(Connection::new(internal_connection))
}
}