Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/ranfdev/ev-stream-gtk-rs
https://github.com/ranfdev/ev-stream-gtk-rs
Last synced: 23 days ago
JSON representation
- Host: GitHub
- URL: https://github.com/ranfdev/ev-stream-gtk-rs
- Owner: ranfdev
- License: mit
- Created: 2022-01-03T17:31:44.000Z (about 3 years ago)
- Default Branch: master
- Last Pushed: 2022-01-08T10:31:32.000Z (about 3 years ago)
- Last Synced: 2024-10-31T14:06:12.111Z (2 months ago)
- Language: Rust
- Size: 5.86 KB
- Stars: 0
- Watchers: 3
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# ev-stream-gtk-rs
This is a little macro to help you handle gtk-rs events in an async way, by treating them as streams.Example:
```rust
let my_stream = ev_stream!(button, clicked, |target|);
```### Advantages
#### Streams can have inner state
Instead of having mutable shared state, streams can have some inner state.
Skipping shared state means less cloning => more performance and better ergonomics.Let's say I want to print the number of times a button gets clicked:
```rust
let click_stream = ev_stream!(button, clicked, |target|);
let fut = click_stream
.zip(0..)
.for_each(|(_, n)| println!("Clicked {} times!", n));
```You can also keep some data between one event and the next, using fold.
I use this to keep a request in the background, until a new event comes.
When the next event comes, the previous request gets dropped and cancelled (automatically).
```rust
let search_changed = ev_stream!(search_text_box, search_changed, |target|);
let fut = search_changed
.fold(None::>, |state, target| {
fetch_data(target.text())
});
```#### Multiple streams can be combined:
```rust
// Basic:
let stream1 = /*...*/;
let stream2 = /*...*/;
let stream3 = /*...*/;
let big_stream = stream1.chain(stream2).chain(stream3);// Print "Hi" one time. Then print "Hi" again after every click.
let click_stream = /*as before*/;
let click_stream_tokenized = click_stream.map(|_| ())
let fut = future::once(async {()})
.chain(click_stream_tokenized)
.for_each(|_| println!("Hi"));
```
The last example in a real context may become: "Load data once, then load next data when `bottom_reached` event is fired" (I use this in my app).#### They do automatic cleanup
The callback gets disconnected from the target widget when the stream is dropped.#### They require a single async ctx.
It's true that streams must be awaited for them to work.
But you can await multiple streams in a single async ctx, without the need to create an async ctx for each
callback!```rust
spawn!(async move {
join!(button_clicked, bottom_reached)
});
```