Add AsyncWidgetWrapper and WidgetWrapper

This commit is contained in:
Joscha 2023-04-05 23:51:02 +02:00
parent ff9a16d8a3
commit 3f7ed63064
2 changed files with 73 additions and 3 deletions

View file

@ -32,6 +32,13 @@ use self::widgets::BoxedWidget;
/// Time to spend batch processing events before redrawing the screen. /// Time to spend batch processing events before redrawing the screen.
const EVENT_PROCESSING_TIME: Duration = Duration::from_millis(1000 / 15); // 15 fps const EVENT_PROCESSING_TIME: Duration = Duration::from_millis(1000 / 15); // 15 fps
/// Error for anything that can go wrong while rendering.
#[derive(Debug, thiserror::Error)]
pub enum UiError {
#[error("{0}")]
Io(#[from] io::Error),
}
pub enum UiEvent { pub enum UiEvent {
GraphemeWidthsChanged, GraphemeWidthsChanged,
LogChanged, LogChanged,
@ -51,8 +58,6 @@ enum Mode {
Log, Log,
} }
// TODO Add Error for anything that can go wrong while rendering
pub struct Ui { pub struct Ui {
event_tx: UnboundedSender<UiEvent>, event_tx: UnboundedSender<UiEvent>,

View file

@ -19,7 +19,9 @@ pub mod rules;
pub mod text; pub mod text;
use async_trait::async_trait; use async_trait::async_trait;
use toss::{Frame, Size, WidthDb}; use toss::{AsyncWidget, Frame, Size, WidthDb};
use super::UiError;
// TODO Add Error type and return Result-s (at least in Widget::render) // TODO Add Error type and return Result-s (at least in Widget::render)
@ -42,3 +44,66 @@ impl<W: 'static + Widget + Send + Sync> From<W> for BoxedWidget {
Box::new(widget) Box::new(widget)
} }
} }
/// Wrapper that implements [`Widget`] for an [`AsyncWidget`].
pub struct AsyncWidgetWrapper<I> {
inner: I,
}
impl<I> AsyncWidgetWrapper<I> {
pub fn new(inner: I) -> Self {
Self { inner }
}
}
#[async_trait]
impl<I> Widget for AsyncWidgetWrapper<I>
where
I: AsyncWidget<UiError> + Send + Sync,
{
async fn size(
&self,
widthdb: &mut WidthDb,
max_width: Option<u16>,
max_height: Option<u16>,
) -> Size {
self.inner
.size(widthdb, max_width, max_height)
.await
.unwrap()
}
async fn render(self: Box<Self>, frame: &mut Frame) {
self.inner.draw(frame).await.unwrap();
}
}
/// Wrapper that implements [`AsyncWidget`] for a [`Widget`].
pub struct WidgetWrapper {
inner: BoxedWidget,
}
impl WidgetWrapper {
pub fn new<W: Into<BoxedWidget>>(inner: W) -> Self {
Self {
inner: inner.into(),
}
}
}
#[async_trait]
impl<E> AsyncWidget<E> for WidgetWrapper {
async fn size(
&self,
widthdb: &mut WidthDb,
max_width: Option<u16>,
max_height: Option<u16>,
) -> Result<Size, E> {
Ok(self.inner.size(widthdb, max_width, max_height).await)
}
async fn draw(self, frame: &mut Frame) -> Result<(), E> {
self.inner.render(frame).await;
Ok(())
}
}