diff --git a/src/client.rs b/src/client.rs index 9d3aef9..b35ee20 100644 --- a/src/client.rs +++ b/src/client.rs @@ -35,6 +35,10 @@ impl App { }) } + pub(crate) fn handle_stdin(&mut self, line: String) -> Result<()> { + self.client.handle_stdin(line) + } + pub(crate) fn poll_run(&mut self, cx: &mut Context<'_>) -> Poll> { match self.step(cx) { Ok(()) => Poll::Pending, @@ -126,14 +130,22 @@ impl Client { self.enqueue(&ToServer::SetName { name }) } + pub(crate) fn handle_stdin(&mut self, line: String) -> Result<()> { + let msg = ToServer::ChatLine { + line, + sequence: self.sequence, + }; + self.sequence += 1; + self.enqueue(&msg) + } + fn handle_timeout(&mut self) -> Result<()> { let msg = ToServer::ChatLine { line: "There was a time, in the era of great chaos, when the Earth and the Moon were at war with each other. A daredevil from the Moon piloted a bizarre aircraft. It was feared, and because of its shape, called EINHANDER.".to_string(), sequence: self.sequence, }; self.sequence += 1; - self.enqueue(&msg)?; - Ok(()) + self.enqueue(&msg) } fn poll_send(&mut self) -> Option { diff --git a/src/main.rs b/src/main.rs index 2f257c6..53614c3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -71,6 +71,12 @@ async fn main() -> Result<()> { async fn run_client(args: client::Args) -> Result<()> { let mut ctrl_c = signal(SignalKind::interrupt())?; + let (stdin_tx, mut stdin_rx) = tokio::sync::mpsc::channel(1); + std::thread::spawn(move || { + for line in std::io::stdin().lines() { + stdin_tx.blocking_send(line).unwrap(); + } + }); let mut app = client::App::new(args).await?; loop { let ctl = poll_fn(|cx| { @@ -80,6 +86,24 @@ async fn run_client(args: client::Args) -> Result<()> { return Poll::Ready(ControlFlow::Break(Ok(()))); } + match stdin_rx.poll_recv(cx) { + Poll::Pending => {} + Poll::Ready(None) => { + return Poll::Ready(ControlFlow::Break(Err(anyhow!( + "Stdin thread somehow died" + )))); + } + Poll::Ready(Some(line)) => { + let line = line.unwrap(); + cx.waker().wake_by_ref(); + if let Err(err) = app.handle_stdin(line) { + return Poll::Ready(ControlFlow::Break( + Err(err).context("app.handle_stdin"), + )); + } + } + } + match app.poll_run(cx) { Poll::Pending => Poll::Pending, Poll::Ready(Ok(())) => Poll::Ready(ControlFlow::Continue(())), diff --git a/src/prelude.rs b/src/prelude.rs index 7d3653a..5e903d7 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -1,5 +1,5 @@ pub(crate) use crate::messages::{ToClient, ToClientEvent, ToServer}; -pub use anyhow::{Context as _, Result, bail}; +pub use anyhow::{Context as _, Result, anyhow, bail}; pub use bytes::Bytes; pub use futures_core::stream::Stream; pub use futures_sink::Sink;