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
use crate::;
/// # [ObservableOutput]
///
/// Defines the outputs of an [Observable]. Also used for [Operator]s to define
/// the new outputs once the operator is applied.
/// # [Observable]
///
/// An observable is a signal-source-descriptor that can be subscribed to,
/// allowing you to observe its signals.
///
/// > Simply creating an observable instance will do nothing as it just defines
/// > how the subscriptions behave that it can create on subscribe.
///
/// ## Signals
///
/// Anything an observable can push is a signal, not just the values you
/// subscribe for, but errors, completions and unsubscribes too. These are the
/// actions an observable can take.
///
/// ## [Subscribe][Observable::subscribe]
///
/// To subscribe to an observable, you must provide a destination, an observer,
/// to which values and other observable signals will be forwarded to.
///
/// Calling [`subscribe`][Observable::subscribe] will result in a
/// [Subscription][crate::SubscriptionLike] that will contain the one (or more)
/// [Teardown][crate::Teardown]s that can be used to release resources
/// associated with this subscription, after which it is always safe to drop
/// regardless of the kind of [Context][crate::SubscriptionContext] used.
///
/// ## [Contexts][crate::SubscriptionContext]
///
/// Since everything is stored in subscription, the unit of execution is the
/// subscription value. But not everything can be stored here: In some
/// environments to react to an observed signal, a reference to something
/// temporary is needed. For example, if you're storing subscriptions in an ECS
/// as a component on an entity, then to release that subscription, you must
/// interact with the ECS. And since subscriptions can only interact with what
/// they contain, that would mean we either store some reference under a lock
/// to it, which would inevitably result in deadlocks, or since actions can only
/// happen when something is pushed, we can also just pass in a context along
/// with every pushed signal.
///
/// This is what contexts are for, to provide temporary references to things
/// that may only live for the instant you're pushing a signal.
///
/// > This is possible because in `rx_bevy` new values cannot be produced
/// > without explicit action, like when a subscription is established, or when
/// > you push a new signal into an observer. But then how can timer-like
/// > Observables work like the IntervalObservable that emits a new value
/// > periodically? The answer is ticking. To signal the passage of time,
/// > a subscription must be "ticked", which will result in moving the internal
/// > clocks of the subscriptions forward, and this action can result in
/// > additional signals, which is why ticking also require a context.
///
/// ## Dropping Subscriptions
///
/// Subscriptions that were not unsubscribed when they are dropped will try to
/// unsubscribe themselves. If you use a
/// [DropUnsafeSubscriptionContext][crate::DropUnsafeSubscriptionContext], one that can't
/// just be created from the subscription itself (like unit `()`), this will
/// result in a panic. But do not worry, such contexts are only ever
/// explicitly used, and are usually used in managed environment where you
/// don't directly handle subscriptions, such as in an ECS where everything
/// is wrapped into components and events.
///
/// > Note that not assigning the subscription to a variable (or assigning it to
/// > `let _ =`) will cause it to be immediately dropped, hence `subscribe` is
/// > `#[must_use]`!