gtk-rs-core icon indicating copy to clipboard operation
gtk-rs-core copied to clipboard

[FEATURE REQUEST] Events as streams

Open ranfdev opened this issue 3 years ago • 4 comments

Rust has great support for iterators, so I thought... Why not use them for event handling?

Also, the current callback situation is a pain when dealing with async methods, because the user has to spawn a future each time.

Providing a stream (which is async by conception) should provide a better API. With a stream API, the user doesn't have to worry about spawning the future. The spawning part is already handled by the Stream methods.

Example of API usage with my proposal:

button.ev_clicked().1
  .zip(0..)
  .then(|_, n| fetch_page(n))
  .map(|p| println!("Page content: {}", p));

API proposal:

fn connect_clicked() -> SignalHandlerId;
// For each `connect_*` method there's a corresponding `ev_*` method.
// calling `ev_clicked()` connects to the event and provides a stream. 
fn ev_clicked() -> (SignalHandlerId, Stream<EventData>);

Alternative, realistic solution

I do understand creating a corresponding ev_*() for each event is asking a bit too much. As an alternative, we could provide a macro to transform a connect_* method to an ev_* method.

Imagine having a macro like this:

let (signal_id, stream) = event_stream!(button.connect_clicked);

Would you accept a PR introducing this event_stream! macro?

ranfdev avatar Dec 21 '21 17:12 ranfdev

I would prefer to experiment with such API first by having it implemented on top of the bindings externally. If that indeed turns out to be useable and an improvement, then we can consider including such API.

You might also want to take a look at relm btw.

sdroege avatar Dec 21 '21 17:12 sdroege

By the way, if anyone is interested, I've created a crate to do this: https://github.com/ranfdev/ev-stream-gtk-rs.

ranfdev avatar Jan 03 '22 18:01 ranfdev

That's nice. Do you have an example application making use of this, ideally even with a comparison to the same thing with callbacks?

sdroege avatar Jan 04 '22 08:01 sdroege

Back when I found your futures post I was really hoping this would exist.

Since I wanted async signals and didn't find anything (I had come across the above link pretty late!), I also rolled my own (specifically, I wanted it for describing wp bindings). I took the approach of using traits instead of macros though (aside from a macro for simplifying trait boilerplate), so it can also cover #214 . The generics do get messy around closures unfortunately, mostly because rust still doesn't have proper Fn traits :disappointed:

arcnmx avatar Mar 17 '22 21:03 arcnmx