use std::io::{Read, Write};
use msrt::endpoint::{ClientEndpoint, EngineConfig, PeerState};
use crate::error::Result;
use crate::event::AdapterEvent;
use crate::io::IoState;
#[derive(Debug)]
pub struct StdFrontend<T> {
io: T,
endpoint: ClientEndpoint,
state: IoState,
}
impl<T> StdFrontend<T>
where
T: Read + Write,
{
pub fn new(io: T) -> Self {
Self::with_config(io, EngineConfig::default())
}
pub fn with_config(io: T, config: EngineConfig) -> Self {
Self {
io,
endpoint: ClientEndpoint::new(config),
state: IoState::new(),
}
}
pub fn peer_state(&self) -> PeerState {
self.endpoint.peer().state()
}
pub const fn io(&self) -> &T {
&self.io
}
pub fn io_mut(&mut self) -> &mut T {
&mut self.io
}
pub fn into_inner(self) -> T {
self.io
}
pub fn connect(&mut self) -> Result<()> {
self.endpoint.connect(self.state.now_ms())?;
Ok(())
}
pub fn disconnect(&mut self) {
self.endpoint.disconnect();
}
pub fn send(&mut self, message: &[u8]) -> Result<bool> {
Ok(self.endpoint.send(message)?.is_some())
}
pub fn receive_available(&mut self) -> Result<usize> {
self.state.receive_available(&mut self.io, |now_ms, bytes| {
self.endpoint.receive(now_ms, bytes)
})
}
pub fn poll(&mut self) -> Result<AdapterEvent> {
self.state.poll(&mut self.io, |now_ms, tx_buf| {
self.endpoint.poll(now_ms, tx_buf)
})
}
pub fn tick(&mut self) -> Result<AdapterEvent> {
let _ = self.receive_available()?;
self.poll()
}
}