1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
//! bottles
//! ===
//! An enum-less typed message passing mechanism
//!
//! This crate allows to put a message in form of any 'static type in a bottles, which then
//! can be dispatched to subscribers of that type.
//!
//! There are 2 main types in this crate: [`Dispatcher`] and [`Queue`]
//!
//! ### Dispatcher
//! A simple mapping between a types and a list of subscribers to a message of that type.
//! The subscriber is a closure which takes a single argument of type `Rc<T>` which will be called
//! whenever a message with that type is dispatched.
//!
//! Most often it is cumbersome to react to messages without any *context*, one would have to rely
//! on `Rc<RefCell<Context>>` capturing in the closure in order to mutate the outside world.
//! The easiest solution provided is to use a [`Queue`] to act as an intermediate component between
//! the [`Dispatcher`] and the callback itself.
//!
//! ### Queue
//!
//! Queue allows one to collect messages from one or several dispatchers and queue them internally
//! to be dispatched on a call to the [`Queue.poll`] method which *allows* for providing a "context"
//! value to all subscribers.
//!
//! The Queue subscriber is a closure taking exactly 2 arguments: a `&mut` reference to the context
//! variable and a `Rc<T>` for message of type `T`
//!
//! ### Examples
//!
//! Send a greeting to a subscriber
//! ```
//! use std::rc::Rc;
//! use bottles::Dispatcher;
//!
//! struct Greeting {
//! greeting: String
//! }
//!
//! fn callback(msg: Rc<Greeting>) {
//! println!("Greeting: {}", msg.greeting);
//! }
//!
//! let mut dispatcher = Dispatcher::new();
//!
//! // Every message type has to be registered explicitly
//! // It is a design choice to have a error when subscribing for a message type which is
//! // not registered by the particular Dispatcher, to error out as quickly as possible
//! dispatcher.register::<Greeting>();
//!
//! dispatcher.subscribe(callback);
//!
//! dispatcher.dispatch(Rc::new(Greeting { greeting: "Hello there!".to_string() }));
//!
//! ```
//!
//! Create a callback which has a mutable context
//! ```
//! use std::rc::Rc;
//! use bottles::{Dispatcher, Queue};
//!
//! struct Add(i32);
//!
//! struct Context {
//! state: i32
//! }
//!
//! fn add(ctx: &mut Context, msg: Rc<Add>) {
//! ctx.state += msg.0;
//! }
//!
//! let mut dispatcher = Dispatcher::new();
//! let mut queue = Queue::new();
//!
//! queue.register::<Add>(&mut dispatcher);
//!
//! queue.subscribe(&mut dispatcher, add);
//!
//! // `queue` will receive the message and enqueue it for retrieval when polled.
//! dispatcher.dispatch(Rc::new(Add(42)));
//!
//! let mut context = Context {
//! state: 0
//! };
//!
//! // Very important: Queue has works by being polled, because this allows to pass a reference
//! // to the context without resorting to any interior mutability patterns.
//! queue.poll(&mut context);
//!
//! assert_eq!(context.state, 42);
//! ```
//!
//! [`Dispatcher`]: dispatcher/struct.Dispatcher.html
//! [`Queue`]: queue/struct.Queue.html
//! [`Queue.poll`]: queue/struct.Queue.html#method.poll
///
///
///
pub use ;
///