use std::sync::{Arc, Weak};
use hidpp::channel::HidppChannel;
use tokio::sync::Mutex;
use crate::route::{DeviceRoute, open_route_channel};
#[derive(Clone, Default)]
pub struct ChannelPool {
entries: Arc<Mutex<Vec<PoolEntry>>>,
}
struct PoolEntry {
route: DeviceRoute,
channel: Weak<HidppChannel>,
}
impl ChannelPool {
pub async fn open(
&self,
route: &DeviceRoute,
) -> Result<Option<Arc<HidppChannel>>, async_hid::HidError> {
let mut entries = self.entries.lock().await;
entries.retain(|entry| entry.channel.strong_count() > 0);
if let Some(channel) = entries.iter().find_map(|entry| {
entry
.route
.shares_transport(route)
.then(|| entry.channel.upgrade())
.flatten()
}) {
return Ok(Some(channel));
}
let Some(channel) = open_route_channel(route).await? else {
return Ok(None);
};
entries.push(PoolEntry {
route: route.clone(),
channel: Arc::downgrade(&channel),
});
Ok(Some(channel))
}
}