experimental_reactive/
split.rs

1use reactive::*;
2use ext::*;
3use std::marker::PhantomData;
4use std::mem;
5
6/// Splitter just pass value to all connected slots
7/// EmptySplitter is disconnected spliiter type
8pub struct EmptySplitter;
9impl SignalExt for EmptySplitter {}
10
11impl<T, S> Signal<T, S> for EmptySplitter where T: Clone, S: Slot<T> {
12	type Connected = Splitter<T, S, Self>;
13	fn connect_slot(self, slot: S) -> Splitter<T, S, Self> { Splitter(slot, self, PhantomData) }
14}
15
16impl<T> Slot<T> for EmptySplitter where T: Clone {	
17	fn push(&self, value: T) -> Result<(), SlotError<T>> { mem::drop(value); Ok(()) }
18}
19
20/// Splitter is connected spliiter type
21/// All conntects are stored in recursion of Spliiter instances
22pub struct Splitter<T, S, P>(S, P, PhantomData<(T, S)>) where T: Clone, S: Slot<T>;
23impl<T: Clone, U: Slot<T>, P> SignalExt for Splitter<T, U, P> {}
24
25impl<T, S, U, P> Signal<T, S> for Splitter<T, U, P> where T: Clone, S: Slot<T>, U: Slot<T> {
26	type Connected = Splitter<T, S, Self>;
27	fn connect_slot(self, slot: S) -> Splitter<T, S, Self> { Splitter(slot, self, PhantomData) }
28}
29
30impl<T, S, P> Slot<T> for Splitter<T, S, P> where T: Clone, S: Slot<T>, P: Slot<T> {
31	fn push(&self, value: T) -> Result<(), SlotError<T>> {
32		match self.0.push(value.clone()) {
33			Err(Full(value)) => self.1.push(value),
34			_ => self.1.push(value).map_err(|err| match err { Full(_) => SomeFull, other => other })
35		}		
36	}
37}