Trait cfrp::SignalExt
[−]
[src]
pub trait SignalExt<A>: Signal<A> + Sized where Self: 'static, A: 'static + Send + Clone { fn lift<F, B>(self, f: F) -> LiftSignal<F, A, B> where F: 'static + Send + Fn(A) -> B, B: 'static + Send + Clone { ... } fn lift2<F, SB, B, C>(self, right: SB, f: F) -> Lift2Signal<F, A, B, C> where SB: 'static + Signal<B>, F: 'static + Send + Fn(Value<A>, Value<B>) -> C, B: 'static + Send + Clone, C: 'static + Send + Clone { ... } fn fold<F, B>(self, initial: B, f: F) -> FoldSignal<F, A, B> where F: 'static + Send + Fn(B, A) -> B, B: 'static + Send + Clone { ... } fn add_to(self, builder: &Builder) -> Branch<A> { ... } fn async(self, builder: &Builder) -> Branch<A> { ... } fn map<F, B>(self, f: F) -> LiftSignal<F, A, B> where F: 'static + Send + Fn(A) -> B, B: 'static + Send + Clone { ... } fn zip<SB, B>(self, right: SB) -> Box<Signal<(Value<A>, Value<B>)>> where SB: 'static + Signal<B>, B: 'static + Send + Clone { ... } fn enumerate(self) -> Box<Signal<(usize, A)>> { ... } fn filter<F>(self, f: F) -> Box<Signal<Option<A>>> where F: 'static + Send + Fn(&A) -> bool { ... } fn inspect<F>(self, f: F) -> Box<Signal<A>> where F: 'static + Send + Fn(&A) -> bool { ... } }
Methods for manipulating signals
Provided Methods
fn lift<F, B>(self, f: F) -> LiftSignal<F, A, B> where F: 'static + Send + Fn(A) -> B, B: 'static + Send + Clone
Transform in input signal into an output signal
Example
use std::default::Default; use std::sync::mpsc::*; use cfrp::*; let (in_tx, in_rx) = sync_channel(0); let (out_tx, out_rx) = channel(); spawn_topology(Default::default(), move |t| { t.listen(0, in_rx) .lift(move |i| { out_tx.send(i | (1 << 1)).unwrap(); }) .add_to(t); }); // Initial value assert_eq!(out_rx.recv().unwrap(), 0b00000010); // Lifted value in_tx.send(1).unwrap(); assert_eq!(out_rx.recv().unwrap(), 0b00000011);
fn lift2<F, SB, B, C>(self, right: SB, f: F) -> Lift2Signal<F, A, B, C> where SB: 'static + Signal<B>, F: 'static + Send + Fn(Value<A>, Value<B>) -> C, B: 'static + Send + Clone, C: 'static + Send + Clone
Combine two signals into an output signal
Example
use std::default::Default; use std::sync::mpsc::*; use cfrp::*; let (l_tx, l_rx) = sync_channel(0); let (r_tx, r_rx) = sync_channel(0); let (out_tx, out_rx) = channel(); spawn_topology(Default::default(), move |t| { t.listen(1 << 0, l_rx) .lift2(t.listen(1 << 1, r_rx), move |i,j| { out_tx.send(*i | *j).unwrap() }) .add_to(t); }); // Initial value assert_eq!(out_rx.recv().unwrap(), (1 << 0) | (1 << 1)); l_tx.send(1 << 2).unwrap(); assert_eq!(out_rx.recv().unwrap(), (1 << 2) | (1 << 1)); r_tx.send(1 << 3).unwrap(); assert_eq!(out_rx.recv().unwrap(), (1 << 2) | (1 << 3));
fn fold<F, B>(self, initial: B, f: F) -> FoldSignal<F, A, B> where F: 'static + Send + Fn(B, A) -> B, B: 'static + Send + Clone
Merge data from a signal into an accumulator and return a signal with the accumulator's value
Example
use std::default::Default; use std::sync::mpsc::*; use cfrp::*; let (in_tx, in_rx) = sync_channel(0); let (out_tx, out_rx) = channel(); spawn_topology(Default::default(), move |t| { t.listen(0, in_rx) .fold(out_tx, |tx, i| { tx.send(i | (1 << 1)).unwrap(); tx }) .add_to(t); }); // Initial value assert_eq!(out_rx.recv().unwrap(), 0b00000010); // Lifted value in_tx.send(1).unwrap(); assert_eq!(out_rx.recv().unwrap(), 0b00000011);
fn add_to(self, builder: &Builder) -> Branch<A>
Sugar for Builder::add
fn async(self, builder: &Builder) -> Branch<A>
Sugar for Builder::async
fn map<F, B>(self, f: F) -> LiftSignal<F, A, B> where F: 'static + Send + Fn(A) -> B, B: 'static + Send + Clone
Alias of lift
fn zip<SB, B>(self, right: SB) -> Box<Signal<(Value<A>, Value<B>)>> where SB: 'static + Signal<B>, B: 'static + Send + Clone
Takes two input signals and returns a signal containing 2-tuples of elements from the input signals.
Roughly equivalent to Iterator::zip
, however if one signal
changes but the other doesn't, the most-recent value of the unchanged
signal will be output. In other words, this operation doesn't block
on receiving changes from both inputs.
Example
use std::default::Default; use std::sync::mpsc::*; use cfrp::*; let (l_tx, l_rx): (SyncSender<usize>, Receiver<usize>) = sync_channel(0); let (r_tx, r_rx): (SyncSender<usize>, Receiver<usize>) = sync_channel(0); let (out_tx, out_rx) = channel(); spawn_topology(Default::default(), move |t| { t.listen(0, l_rx) .zip(t.listen(0, r_rx)) .lift(move |i| { out_tx.send(i).unwrap(); }) .add_to(t); }); // Initial value assert_eq!(out_rx.recv().unwrap(), (Value::Unchanged(0), Value::Unchanged(0))); l_tx.send(1).unwrap(); assert_eq!(out_rx.recv().unwrap(), (Value::Changed(1), Value::Unchanged(0))); r_tx.send(1).unwrap(); assert_eq!(out_rx.recv().unwrap(), (Value::Unchanged(1), Value::Changed(1)));
fn enumerate(self) -> Box<Signal<(usize, A)>>
Same as Iterator::enumerate
.
The counter only increments when upstream data changes. To track
the aggregate number of messages processed by a topology consider
Builder::counter()
Example
use std::default::Default; use std::sync::mpsc::*; use cfrp::*; let (in_tx, in_rx) = sync_channel(0); let (out_tx, out_rx) = channel(); spawn_topology(Default::default(), move |t| { t.listen(0, in_rx) .enumerate() .lift(move |i| { out_tx.send(i).unwrap(); }) .add_to(t); }); // Initial value assert_eq!(out_rx.recv().unwrap(), (1, 0)); in_tx.send(1).unwrap(); assert_eq!(out_rx.recv().unwrap(), (2, 1));
fn filter<F>(self, f: F) -> Box<Signal<Option<A>>> where F: 'static + Send + Fn(&A) -> bool
Filter an input stream by a predicate function F
.
In this case 'filtered' is reflected by a value of None
Example
use std::default::Default; use std::sync::mpsc::*; use cfrp::*; let (in_tx, in_rx) = sync_channel(0); let (out_tx, out_rx) = channel(); spawn_topology(Default::default(), move |t| { t.listen(0, in_rx) .filter(|i| { i % 2 == 0 }) .lift(move |i| { out_tx.send(i).unwrap(); }) .add_to(t); }); // Initial value assert_eq!(out_rx.recv().unwrap(), Some(0)); in_tx.send(1).unwrap(); assert_eq!(out_rx.recv().unwrap(), None); in_tx.send(2).unwrap(); assert_eq!(out_rx.recv().unwrap(), Some(2));
fn inspect<F>(self, f: F) -> Box<Signal<A>> where F: 'static + Send + Fn(&A) -> bool
Pass each value in a signal to F
before sending it to an output
signal.
Implementors
impl<A> SignalExt<A> for Channel<A> where A: 'static + Send + Clone
impl<F, A, B> SignalExt<B> for FoldSignal<F, A, B> where F: 'static + Send + Fn(B, A) -> B, A: 'static + Send + Clone, B: 'static + Send + Clone
impl<A> SignalExt<A> for Branch<A> where A: 'static + Send + Clone
impl<F, A, B> SignalExt<B> for LiftSignal<F, A, B> where F: 'static + Send + Fn(A) -> B, A: 'static + Send + Clone, B: 'static + Send + Clone
impl<F, A, B, C> SignalExt<C> for Lift2Signal<F, A, B, C> where F: 'static + Send + Fn(Value<A>, Value<B>) -> C, A: 'static + Send + Clone, B: 'static + Send + Clone, C: 'static + Send + Clone
impl<A> SignalExt<A> for Value<A> where A: 'static + Send + Clone
impl<A> SignalExt<A> for Box<Signal<A>> where A: 'static + Send + Clone