wishawa / async_ui

Lifetime-Friendly, Component-Based, Retained-Mode UI Powered by Async Rust
Mozilla Public License 2.0
551 stars 11 forks source link

Helper function to render the latest future in a stream of futures #11

Open ChocolateLoverRaj opened 4 months ago

ChocolateLoverRaj commented 4 months ago

I made this helper function to easily show certain elements based on the value of a signal using futures-signals.

use std::future::Future;
use futures::{FutureExt, Stream, StreamExt};
use async_ui_web::race;
use async_ui_web::shortcut_traits::ShortcutRenderStr;

pub trait StreamRenderExt<F: Future> {
    async fn render(self);
}

impl<F: Future, S: Stream<Item=F> + Unpin> StreamRenderExt<F> for S {
    async fn render(mut self) {
        let mut value = None::<F>;
        loop {
            value = race((
                async {
                    match value {
                        Some(future) => {
                            future.await;
                        }
                        None => {
                            "".render().await;
                        }
                    }
                }.map(|_| None),
                self.next()
            )).await;
        }
    }
}

It can be used like this:

saved_value.signal_cloned().to_stream().map(|value| value.render()).render()

Should this helper function be added to this library?

wishawa commented 2 months ago

Hi! There is currently DynamicSlot which serves the purpose of rendering changing futures. But it's API is imperative rather than stream-based like what you suggested. In fact, most of async_ui right now is quite imperative.

I want to build a crate of functional and/or stream-based helpers for async_ui - with enough functionality so that one can, say, make a todo list app without imperative manipulation. This crate will definitely include the component you have here. But since I haven't used futures-signals that much myself yet, I am not sure what other functionalities should the crate provide. If you have more component implementations/suggestions, please share them!

ChocolateLoverRaj commented 2 months ago

I haven't used async_ui lately so I can't think of something right now. But is async_ui even the best way to show UI? It is fun to code with, but I'm not sure about the performance or ability to do more complex things like canvas games.

wishawa commented 2 months ago

Okay. Thanks anyway!

Re best way: async_ui is very likely not the best tool for canvas games (anything canvas should be done in immediate mode IMO). If we try to use it for canvas rendering anyway, I think the API would be cumbersome but performance shouldn't be too bad.