From 64106c4d3d4ddba8c7bc2af75376e6d3d3d75601 Mon Sep 17 00:00:00 2001
From:
Date: Mon, 29 Jun 2015 20:16:15 +0000
Subject: Update documentation
---
src/carboxyl/signal.rs.html | 1601 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 1601 insertions(+)
create mode 100644 src/carboxyl/signal.rs.html
(limited to 'src/carboxyl/signal.rs.html')
diff --git a/src/carboxyl/signal.rs.html b/src/carboxyl/signal.rs.html
new file mode 100644
index 0000000..659a0a7
--- /dev/null
+++ b/src/carboxyl/signal.rs.html
@@ -0,0 +1,1601 @@
+
+
+
+ 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
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+678
+679
+680
+681
+682
+683
+684
+685
+686
+687
+688
+689
+690
+691
+692
+693
+694
+695
+696
+697
+698
+699
+700
+701
+702
+703
+704
+705
+706
+707
+708
+709
+710
+711
+712
+713
+714
+715
+716
+717
+718
+719
+720
+721
+722
+723
+724
+725
+726
+727
+728
+729
+730
+731
+732
+733
+734
+735
+736
+737
+738
+739
+740
+741
+742
+743
+744
+745
+746
+747
+748
+749
+750
+751
+752
+
+
+
+use std::sync::{ Arc, Mutex, RwLock };
+use std::ops::Deref;
+use std::fmt;
+#[cfg(test)]
+use quickcheck::{ Arbitrary, Gen };
+
+use source::{ Source, with_weak, CallbackError };
+use stream::{ self, BoxClone, Stream };
+use transaction::{ commit, end };
+use pending::Pending;
+use readonly::{ self, ReadOnly };
+use lift;
+#[cfg(test)]
+use testing::ArcFn;
+
+
+
+struct FuncSignal<A> {
+ func: Box<Fn() -> A + Send + Sync + 'static>,
+ cache: Arc<Mutex<Option<A>>>,
+}
+
+impl<A> FuncSignal<A> {
+ pub fn new<F: Fn() -> A + Send + Sync + 'static>(f: F) -> FuncSignal<A> {
+ FuncSignal {
+ func: Box::new(f),
+ cache: Arc::new(Mutex::new(None)),
+ }
+ }
+}
+
+impl<A: Clone + 'static> FuncSignal<A> {
+
+ pub fn call(&self) -> A {
+ let mut cached = self.cache.lock().unwrap();
+ match &mut *cached {
+ &mut Some(ref value) => value.clone(),
+ cached => {
+
+ let cache = self.cache.clone();
+ end(move || {
+ let mut live = cache.lock().unwrap();
+ *live = None;
+ });
+
+ let value = (self.func)();
+ *cached = Some(value.clone());
+ value
+ },
+ }
+ }
+}
+
+
+pub enum SignalFn<A> {
+ Const(A),
+ Func(FuncSignal<A>),
+}
+
+impl<A> SignalFn<A> {
+ pub fn from_fn<F: Fn() -> A + Send + Sync + 'static>(f: F) -> SignalFn<A> {
+ SignalFn::Func(FuncSignal::new(f))
+ }
+}
+
+impl<A: Clone + 'static> SignalFn<A> {
+ pub fn call(&self) -> A {
+ match *self {
+ SignalFn::Const(ref a) => a.clone(),
+ SignalFn::Func(ref f) => f.call(),
+ }
+ }
+}
+
+
+
+pub fn reg_signal<A, B, F>(parent_source: &mut Source<A>, signal: &Signal<B>, handler: F)
+ where A: Send + Sync + 'static,
+ B: Send + Sync + 'static,
+ F: Fn(A) -> SignalFn<B> + Send + Sync + 'static,
+{
+ let weak_source = signal.source.downgrade();
+ let weak_current = signal.current.downgrade();
+ parent_source.register(move |a|
+ weak_current.upgrade().map(|cur| end(
+ move || { let _ = cur.write().map(|mut cur| cur.update()); }))
+ .ok_or(CallbackError::Disappeared)
+ .and(with_weak(&weak_current, |cur| cur.queue(handler(a))))
+ .and(with_weak(&weak_source, |src| src.send(())))
+ );
+}
+
+
+
+pub fn signal_build<A, K>(func: SignalFn<A>, keep_alive: K) -> Signal<A>
+ where K: Send + Sync + Clone + 'static
+{
+ Signal::build(func, keep_alive)
+}
+
+
+pub fn signal_current<A>(signal: &Signal<A>) -> &Arc<RwLock<Pending<SignalFn<A>>>> {
+ &signal.current
+}
+
+
+pub fn signal_source<A>(signal: &Signal<A>) -> &Arc<RwLock<Source<()>>> {
+ &signal.source
+}
+
+
+pub fn sample_raw<A: Clone + 'static>(signal: &Signal<A>) -> A {
+ signal.current.read().unwrap().call()
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+pub struct Signal<A> {
+ current: Arc<RwLock<Pending<SignalFn<A>>>>,
+ source: Arc<RwLock<Source<()>>>,
+ #[allow(dead_code)]
+ keep_alive: Box<BoxClone>,
+}
+
+impl<A> Clone for Signal<A> {
+ fn clone(&self) -> Signal<A> {
+ Signal {
+ current: self.current.clone(),
+ source: self.source.clone(),
+ keep_alive: self.keep_alive.box_clone(),
+ }
+ }
+}
+
+impl<A> Signal<A> {
+ fn build<K>(func: SignalFn<A>, keep_alive: K) -> Signal<A>
+ where K: Send + Sync + Clone + 'static
+ {
+ Signal {
+ current: Arc::new(RwLock::new(Pending::new(func))),
+ source: Arc::new(RwLock::new(Source::new())),
+ keep_alive: Box::new(keep_alive),
+ }
+ }
+}
+
+impl<A: Clone + 'static> Signal<A> {
+
+ pub fn new(a: A) -> Signal<A> {
+ Signal::build(SignalFn::Const(a), ())
+ }
+
+
+ pub fn sample(&self) -> A {
+ commit(|| sample_raw(self))
+ }
+}
+
+impl<A: Clone + Send + Sync + 'static> Signal<A> {
+
+
+
+
+
+
+
+
+
+
+
+ pub fn cyclic<F>(def: F) -> Signal<A>
+ where F: FnOnce(&Signal<A>) -> Signal<A>
+ {
+ commit(|| {
+ let cycle = SignalCycle::new();
+ let finished = def(&cycle);
+ cycle.define(finished)
+ })
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ pub fn snapshot<B, C, F>(&self, stream: &Stream<B>, f: F) -> Stream<C>
+ where B: Clone + Send + Sync + 'static,
+ C: Clone + Send + Sync + 'static,
+ F: Fn(A, B) -> C + Send + Sync + 'static,
+ {
+ stream::snapshot(self, stream, f)
+ }
+}
+
+impl<A: Clone + Send + Sync + 'static> Signal<Signal<A>> {
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ pub fn switch(&self) -> Signal<A> {
+ fn make_callback<A>(parent: &Signal<Signal<A>>) -> SignalFn<A>
+ where A: Send + Clone + Sync + 'static,
+ {
+
+ let current_signal = parent.current.clone();
+ SignalFn::from_fn(move ||
+ sample_raw(¤t_signal.read().unwrap().call())
+ )
+ }
+ commit(|| {
+ let signal = Signal::build(make_callback(self), ());
+ let parent = self.clone();
+ reg_signal(&mut self.source.write().unwrap(), &signal,
+ move |_| make_callback(&parent));
+ signal
+ })
+ }
+}
+
+#[cfg(test)]
+impl<A, B> Signal<ArcFn<A, B>>
+ where A: Clone + Send + Sync + 'static,
+ B: Clone + Send + Sync + 'static,
+{
+
+
+ fn apply(&self, signal: &Signal<A>) -> Signal<B> {
+ lift::lift2(|f, a| f(a), self, signal)
+ }
+}
+
+#[cfg(test)]
+impl<A: Arbitrary + Sync + Clone + 'static> Arbitrary for Signal<A> {
+ fn arbitrary<G: Gen>(g: &mut G) -> Signal<A> {
+ let values = Vec::<A>::arbitrary(g);
+ if values.is_empty() {
+ Signal::new(Arbitrary::arbitrary(g))
+ } else {
+ let n = Mutex::new(0);
+ lift::lift0(move || {
+ let mut n = n.lock().unwrap();
+ *n += 1;
+ if *n >= values.len() { *n = 0 }
+ values[*n].clone()
+ })
+ }
+ }
+}
+
+impl<A: fmt::Debug + Clone + 'static> fmt::Debug for Signal<A> {
+ fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
+ commit(|| match **self.current.read().unwrap() {
+ SignalFn::Const(ref a) =>
+ fmt.debug_struct("Signal::const").field("value", &a).finish(),
+ SignalFn::Func(ref f) =>
+ fmt.debug_struct("Signal::fn").field("current", &f.call()).finish(),
+ })
+ }
+}
+
+
+
+struct SignalCycle<A> {
+ signal: Signal<A>,
+}
+
+impl<A: Send + Sync + Clone + 'static> SignalCycle<A> {
+
+ pub fn new() -> SignalCycle<A> {
+ const ERR: &'static str = "sampled on forward-declaration of signal";
+ SignalCycle { signal: Signal::build(SignalFn::from_fn(|| panic!(ERR)), ()) }
+ }
+
+
+ pub fn define(self, definition: Signal<A>) -> Signal<A> {
+
+ fn make_callback<A>(current_def: &Arc<RwLock<Pending<SignalFn<A>>>>) -> SignalFn<A>
+ where A: Send + Sync + Clone + 'static
+ {
+ match *current_def.read().unwrap().future() {
+ SignalFn::Const(ref a) => SignalFn::Const(a.clone()),
+ SignalFn::Func(_) => SignalFn::from_fn({
+ let sig = current_def.downgrade();
+ move || {
+ let strong = sig.upgrade().unwrap();
+ let ret = strong.read().unwrap().call();
+ ret
+ }
+ }),
+ }
+ }
+ commit(move || {
+ *self.signal.current.write().unwrap() = Pending::new(make_callback(&definition.current));
+ let weak_parent = definition.current.downgrade();
+ reg_signal(&mut definition.source.write().unwrap(), &self.signal,
+ move |_| make_callback(&weak_parent.upgrade().unwrap()));
+ Signal { keep_alive: Box::new(definition), ..self.signal }
+ })
+ }
+}
+
+impl<A> Deref for SignalCycle<A> {
+ type Target = Signal<A>;
+ fn deref(&self) -> &Signal<A> { &self.signal }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+pub struct SignalMut<A> {
+ inner: Signal<ReadOnly<A>>,
+}
+
+impl<A: Send + Sync + 'static> SignalMut<A> {
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ pub fn snapshot<B, C, F>(&self, stream: &Stream<B>, f: F) -> Stream<C>
+ where B: Clone + Send + Sync + 'static,
+ C: Clone + Send + Sync + 'static,
+ F: Fn(&A, B) -> C + Send + Sync + 'static,
+ {
+ self.inner.snapshot(stream, move |a, b| f(&a.read().unwrap(), b))
+ }
+
+
+
+ pub fn combine<B, C, F>(&self, signal: &Signal<B>, f: F) -> Signal<C>
+ where B: Clone + Send + Sync + 'static,
+ C: Clone + Send + Sync + 'static,
+ F: Fn(&A, B) -> C + Send + Sync + 'static,
+ {
+ lift::lift2(
+ move |a, b| f(&a.read().unwrap(), b),
+ &self.inner, &signal
+ )
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ pub fn combine_mut<B, C, F>(&self, other: &SignalMut<B>, f: F) -> Signal<C>
+ where B: Clone + Send + Sync + 'static,
+ C: Clone + Send + Sync + 'static,
+ F: Fn(&A, &B) -> C + Send + Sync + 'static,
+ {
+ lift::lift2(
+ move |a, b| f(&a.read().unwrap(), &b.read().unwrap()),
+ &self.inner, &other.inner
+ )
+ }
+}
+
+
+
+pub fn hold<A>(initial: A, stream: &Stream<A>) -> Signal<A>
+ where A: Send + Sync + 'static,
+{
+ commit(|| {
+ let signal = Signal::build(SignalFn::Const(initial), stream.clone());
+ reg_signal(&mut stream::source(&stream).write().unwrap(), &signal, SignalFn::Const);
+ signal
+ })
+}
+
+
+
+pub fn scan_mut<A, B, F>(stream: &Stream<A>, initial: B, f: F) -> SignalMut<B>
+ where A: Send + Sync + 'static,
+ B: Send + Sync + 'static,
+ F: Fn(&mut B, A) + Send + Sync + 'static,
+{
+ commit(move || {
+ let state = Arc::new(RwLock::new(initial));
+ let signal = Signal::build(SignalFn::Const(readonly::create(state.clone())), stream.clone());
+ reg_signal(&mut stream::source(&stream).write().unwrap(), &signal,
+ move |a| { f(&mut state.write().unwrap(), a); SignalFn::Const(readonly::create(state.clone())) });
+ SignalMut { inner: signal }
+ })
+}
+
+
+#[cfg(test)]
+mod test {
+ use quickcheck::quickcheck;
+
+ use ::stream::Sink;
+ use ::signal::{ self, Signal, SignalCycle };
+ use ::lift::lift1;
+ use ::testing::{ ArcFn, signal_eq, id, pure_fn, partial_comp };
+
+ #[test]
+ fn functor_identity() {
+ fn check(signal: Signal<i32>) -> bool {
+ let eq = signal_eq(&signal, &lift1(id, &signal));
+ (0..10).all(|_| eq.sample())
+ }
+ quickcheck(check as fn(Signal<i32>) -> bool);
+ }
+
+ #[test]
+ fn functor_composition() {
+ fn check(signal: Signal<i32>) -> bool {
+ fn f(n: i32) -> i32 { 3 * n }
+ fn g(n: i32) -> i32 { n + 2 }
+ let eq = signal_eq(
+ &lift1(|n| f(g(n)), &signal),
+ &lift1(f, &lift1(g, &signal))
+ );
+ (0..10).all(|_| eq.sample())
+ }
+ quickcheck(check as fn(Signal<i32>) -> bool);
+ }
+
+ #[test]
+ fn applicative_identity() {
+ fn check(signal: Signal<i32>) -> bool {
+ let eq = signal_eq(&pure_fn(id).apply(&signal), &signal);
+ (0..10).all(|_| eq.sample())
+ }
+ quickcheck(check as fn(Signal<i32>) -> bool);
+ }
+
+ #[test]
+ fn applicative_composition() {
+ fn check(signal: Signal<i32>) -> bool {
+ fn f(n: i32) -> i32 { n * 4 }
+ fn g(n: i32) -> i32 { n - 3 }
+ let u = pure_fn(f);
+ let v = pure_fn(g);
+ let eq = signal_eq(
+ &pure_fn(partial_comp).apply(&u).apply(&v).apply(&signal),
+ &u.apply(&v.apply(&signal))
+ );
+ (0..10).all(|_| eq.sample())
+ }
+ quickcheck(check as fn(Signal<i32>) -> bool);
+ }
+
+ #[test]
+ fn applicative_homomorphism() {
+ fn check(x: i32) -> bool {
+ fn f(x: i32) -> i32 { x * (-5) }
+ let eq = signal_eq(
+ &pure_fn(f).apply(&Signal::new(x)),
+ &Signal::new(f(x))
+ );
+ (0..10).all(|_| eq.sample())
+ }
+ quickcheck(check as fn(i32) -> bool);
+ }
+
+ #[test]
+ fn applicative_interchange() {
+ fn check(x: i32) -> bool {
+ fn f(x: i32) -> i32 { x * 2 - 7 }
+ let u = pure_fn(f);
+ let eq = signal_eq(
+ &u.apply(&Signal::new(x)),
+ &pure_fn(move |f: ArcFn<i32, i32>| f(x)).apply(&u)
+ );
+ (0..10).all(|_| eq.sample())
+ }
+ quickcheck(check as fn(i32) -> bool);
+ }
+
+ #[test]
+ fn clone() {
+ let b = Signal::new(3);
+ assert_eq!(b.clone().sample(), 3);
+ }
+
+ #[test]
+ fn hold() {
+ let sink = Sink::new();
+ let signal = sink.stream().hold(3);
+ assert_eq!(signal.sample(), 3);
+ sink.send(4);
+ assert_eq!(signal.sample(), 4);
+ }
+
+ #[test]
+ fn hold_implicit_stream() {
+ let sink = Sink::new();
+ let signal = signal::hold(0, &sink.stream().map(|n| 2 * n));
+ assert_eq!(signal.sample(), 0);
+ sink.send(4);
+ assert_eq!(signal.sample(), 8);
+ }
+
+ #[test]
+ fn snapshot() {
+ let sink1: Sink<i32> = Sink::new();
+ let sink2: Sink<f64> = Sink::new();
+ let mut snap_events = sink1.stream().hold(1)
+ .snapshot(&sink2.stream().map(|x| x + 3.0), |a, b| (a, b))
+ .events();
+ sink2.send(4.0);
+ assert_eq!(snap_events.next(), Some((1, 7.0)));
+ }
+
+ #[test]
+ fn snapshot_2() {
+ let ev1 = Sink::new();
+ let beh1 = ev1.stream().hold(5);
+ let ev2 = Sink::new();
+ let snap = beh1.snapshot(&ev2.stream(), |a, b| (a, b));
+ let mut events = snap.events();
+ ev2.send(4);
+ assert_eq!(events.next(), Some((5, 4)));
+ ev1.send(-2);
+ ev2.send(6);
+ assert_eq!(events.next(), Some((-2, 6)));
+ }
+
+ #[test]
+ fn cyclic_snapshot_accum() {
+ let sink = Sink::new();
+ let stream = sink.stream();
+ let accum = SignalCycle::new();
+ let def = accum.snapshot(&stream, |a, s| a + s).hold(0);
+ let accum = accum.define(def);
+ assert_eq!(accum.sample(), 0);
+ sink.send(3);
+ assert_eq!(accum.sample(), 3);
+ sink.send(7);
+ assert_eq!(accum.sample(), 10);
+ sink.send(-21);
+ assert_eq!(accum.sample(), -11);
+ }
+
+ #[test]
+ fn snapshot_order_standard() {
+ let sink = Sink::new();
+ let signal = sink.stream().hold(0);
+ let mut events = signal
+ .snapshot(&sink.stream(), |a, b| (a, b))
+ .events();
+ sink.send(1);
+ assert_eq!(events.next(), Some((0, 1)));
+ }
+
+ #[test]
+ fn snapshot_lift_order_standard() {
+ let sink = Sink::new();
+ let signal = sink.stream().hold(0);
+ let mut events = lift1(|x| x, &signal)
+ .snapshot(&sink.stream(), |a, b| (a, b))
+ .events();
+ sink.send(1);
+ assert_eq!(events.next(), Some((0, 1)));
+ }
+
+ #[test]
+ fn snapshot_order_alternative() {
+ let sink = Sink::new();
+
+
+ let first = sink.stream().map(|x| x);
+ let signal = sink.stream().hold(0);
+ let mut events = signal.snapshot(&first, |a, b| (a, b)).events();
+ sink.send(1);
+ assert_eq!(events.next(), Some((0, 1)));
+ }
+
+ #[test]
+ fn cyclic_signal_intermediate() {
+ let sink = Sink::new();
+ let stream = sink.stream();
+ let mut snap = None;
+ let sum = Signal::cyclic(|a| {
+ let my_snap = a.snapshot(&stream, |a, e| e + a);
+ snap = Some(my_snap.clone());
+ my_snap.hold(0)
+ });
+ let snap = snap.unwrap();
+ let mut events = snap.events();
+
+ sink.send(3);
+ assert_eq!(sum.sample(), 3);
+ assert_eq!(events.next(), Some(3));
+ }
+}
+
+
+