pub trait Observable: ObservableOutput + WithPrimaryCategory {
type Subscription<Destination: 'static + Subscriber<In = Self::Out, InError = Self::OutError>>: 'static + SubscriptionWithTeardown + Drop + Send + Sync;
// Required method
fn subscribe<Destination>(
&mut self,
destination: Destination,
) -> Self::Subscription<<Destination as UpgradeableObserver>::Upgraded>
where Destination: 'static + UpgradeableObserver<In = Self::Out, InError = Self::OutError> + Send + Sync;
}Expand description
§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
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 will result in a
Subscription that will contain the one (or more)
Teardowns 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_bevynew 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, hencesubscribeis#[must_use]!
Required Associated Types§
Sourcetype Subscription<Destination: 'static + Subscriber<In = Self::Out, InError = Self::OutError>>: 'static + SubscriptionWithTeardown + Drop + Send + Sync
type Subscription<Destination: 'static + Subscriber<In = Self::Out, InError = Self::OutError>>: 'static + SubscriptionWithTeardown + Drop + Send + Sync
The subscription produced by this Observable. As this is the only kind of subscription that is handled directly by users, only here are subscriptions required to implement Drop to ensure resources are released when the subscription is dropped.
Required Methods§
Sourcefn subscribe<Destination>(
&mut self,
destination: Destination,
) -> Self::Subscription<<Destination as UpgradeableObserver>::Upgraded>where
Destination: 'static + UpgradeableObserver<In = Self::Out, InError = Self::OutError> + Send + Sync,
fn subscribe<Destination>(
&mut self,
destination: Destination,
) -> Self::Subscription<<Destination as UpgradeableObserver>::Upgraded>where
Destination: 'static + UpgradeableObserver<In = Self::Out, InError = Self::OutError> + Send + Sync,
Create a Subscription for this Observable. This action allocates resources to execute the behavior this Observable defines, essentially creating an instance of it.
The returned Subscription can be used to release the allocated resources and stop the subscription by calling unsubscribe
§Subscription Drop Behavior
If a subscription has not been unsubscribed manually, they will always attempt to unsubscribe themselves on drop.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.