async_event_streams/lib.rs
1//!
2//! Library for publishing events for multiple consumers using asynchromous streams
3//!
4//! Library provides [EventStreams<T: 'static + Send + Sync>](EventStreams) object which translates events of type ```T```
5//! to arbitrary number of [EventStream] objects, which implements standard [futures::Stream] interface
6//!
7//! # Usage sample
8//!
9//! ```
10//! use futures::{executor::LocalPool, task::LocalSpawnExt, StreamExt};
11//! use async_event_streams::EventStreams;
12//!
13//! let mut pool = LocalPool::new();
14//!
15//! let streams = EventStreams::new();
16//! let mut stream = streams.create_event_stream();
17//!
18//! let sender_task = async move {
19//! assert!(streams.count() == 1);
20//! streams.send_event(42, None).await;
21//! streams.send_event(451, None).await;
22//! streams.send_event(1984, None).await;
23//! };
24//!
25//! let receiver_task = async move {
26//! let mut values = Vec::new();
27//! while let Some(event) = stream.next().await {
28//! values.push(*event);
29//! }
30//! // next() returns none when 'streams' is dropped
31//! assert!(values == vec![42, 451, 1984]);
32//! };
33//!
34//! pool.spawner().spawn_local(sender_task);
35//! pool.spawner().spawn_local(receiver_task);
36//! pool.run();
37//! ```
38//!
39//! # Event processing order
40//!
41//! When event is put to [EventStreams] it becomes immediately available for all [EventStream] objects, created by this ```EventStreams```.
42//! Events comes from each stream exactly in order as they being sent.
43//!
44//! Since reveivers work in asynchronous environment it's possible that streams are emptied unevenly. I.e. if events 1,2,3,4,5 put to [EventStreams],
45//! one [EventStream] subscriber could process all 5 events while another is still waiting for first.
46//!
47//! Sometimes it's undesirable. So the mechanism to guarantee that all events '1' are handled before sending event '2' is implemented.
48//!
49//! To achieve this the [send_event](EventStreams::send_event) function returns future [SentEvent]. Each [EventStream] instance receives clone
50//! of [Event\<T\>](Event) object which all wraps the same instance of event. Subscribers get these ```Event``` instances and
51//! may hold them as long as they need it. ```SentEvent``` future is released only when all instances of this
52//! ```Event``` are dropped. This guarantees that next event is sent only when previous one has been processed by all subscribers.
53//!
54//! If such blocking is not necessary, the [post_event](EventStreams::post_event) can be used instead.
55//!
56//! # Dependent Events
57//!
58//! Received events may cause firing new events. For example mouse button click handler is sending mouse click events. These clicks causes
59//! GUI buttons to send button press events. It may be important to guarantee that button press events are not handled in order different
60//! than mouse clicks order.
61//!
62//! For example consider two buttons A and B. Click C1 causes button A send press
63//! P1, click C2 causes button B send press P2. It's guaranteed that P2 is *sent* after P1 (because P1 is reaction to C1,
64//! P2 is reaction to C2, and both C1 and C2 comes from same ```send_event```). But there is still no guarantee that P2 is *processed* after P1,
65//! because P1 and P2 are sent by different ```send_event```s so the blocking mechanism decribed above doesn't help.
66//!
67//! This may cause problems. For example: user clicks "Apply" button and then "Close" button in the dialog. But press event from "Close"
68//! button comes earlier than from "Apply". "Close" handler destroys the dialog, "Apply" is not processed, user's data is lost.
69//!
70//! To avoid this the [send_event](EventStreams::send_event) and [post_event](EventStreams::post_event) have
71//! the additional optional parameter ```source``` - event which was the cause of the sent one. Reference to this 'source' event is saved
72//! inside [Event] wrapper of new event and therefore source ```send_event``` is blocked until all derived events are dropped.
73//! So sending second click event in example above is delayed until "Apply" handler (which holds first click event) finishes.
74//!
75//! # Event sources, sinks and pipes
76//!
77//! There are typical repeating operations with event streams. Object may generate events of different types ([EventSource])
78//! and react to events ([EventSink]). Connecting event source to event sink can be performed by spawing asynchronous task with
79//! [spawn_event_pipe]
80//!
81
82mod event;
83mod event_queue;
84mod event_stream;
85mod event_streams;
86mod pipes;
87
88pub use event::{Event, EventBox};
89pub use event_stream::EventStream;
90pub use event_streams::{EventStreams, SentEvent};
91pub use pipes::{
92 spawn_event_pipe, spawn_event_pipe_with_handle, EventSink, EventSinkExt, EventSource,
93};