public void TestSwitchCDeferredLoop() { CellStreamSink <IReadOnlyList <TestObject> > streamSink = Cell.CreateStreamSink <IReadOnlyList <TestObject> >(); Cell <IReadOnlyList <TestObject> > cell = Transaction.Run(() => { CellLoop <IReadOnlyList <TestObject> > cellLoop = new CellLoop <IReadOnlyList <TestObject> >(); Cell <IReadOnlyList <TestObject> > cellLocal = streamSink .OrElse(Operational.Defer(cellLoop.Map(oo => oo.Select(o => o.Output).Lift(vv => vv.Sum())).SwitchC().Values()).Filter(sum => sum < 50).Snapshot(cellLoop, (_, items) => (IReadOnlyList <TestObject>)items.Concat(new[] { new TestObject() }).ToArray())) .Hold(Enumerable.Range(1, 10).Select(_ => new TestObject()).ToArray()); cellLoop.Loop(cellLocal); return(cellLocal); }); List <int> objectCounts = new List <int>(); objectCounts.Add(-1); cell.Listen(vv => objectCounts.Add(vv.Count)); objectCounts.Add(-1); cell.Sample()[2].Input1.Send(1); objectCounts.Add(-1); cell.Sample()[1].Input1.Send(-20); objectCounts.Add(-1); streamSink.Send(new TestObject[0]); objectCounts.Add(-1); // Ideal result, likely not achievable. //CollectionAssert.AreEquivalent(new[] { -1, 10, -1, 11, -1, 15, -1, 10, -1 }, objectCounts); // Glitchy result, but correct otherwise. CollectionAssert.AreEquivalent(new[] { -1, 10, -1, 11, -1, 12, 13, 14, 15, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, -1 }, objectCounts); }
public void Issue151_PoolDoubleSubtraction_Fixed() { CellSink <int> threshold = new CellSink <int>(10); StreamSink <int> addPoolSink = new StreamSink <int>(); (Stream <int> input, Cell <int> pool) = Transaction.Run(() => { StreamLoop <int> submitPooledAmount = new StreamLoop <int>(); // Ways that the pool is modified. Stream <Func <int, int> > poolAddByInput = addPoolSink.Map <Func <int, int> >(i => x => x + i); Stream <Func <int, int> > poolRemoveByUsage = Operational.Defer(submitPooledAmount.Map <Func <int, int> >(i => x => x - i)); // The current level of the pool Cell <int> poolLocal = poolAddByInput .Merge(poolRemoveByUsage, (f, g) => x => g(f(x))) .Accum(0, (f, x) => f(x)); // The current input changes combined with the pool as a stream Stream <int> inputByAdded = poolAddByInput .Snapshot( poolLocal, threshold, (f, x, t) => f(x) >= t ? Maybe.Some(f(x)) : Maybe.None) .FilterMaybe(); // Simple rising edge on pool threshold satisfaction. Stream <int> inputBySatisfaction = poolLocal.Updates .Snapshot( poolLocal, threshold, (neu, alt, t) => neu >= t && alt < t ? Maybe.Some(neu) : Maybe.None) .FilterMaybe(); submitPooledAmount.Loop(inputByAdded.Merge(inputBySatisfaction, Math.Max)); return(submitPooledAmount, poolLocal); }); List <int> submissions = new List <int>(); using (input.Listen(submissions.Add)) { // Add amount which can be immediately used based on threshold. // Pool should remain zero after the transaction is complete. addPoolSink.Send(10); } Assert.AreEqual(1, submissions.Count); Assert.AreEqual(10, submissions[0]); Assert.AreEqual(0, pool.Sample()); }
public void TestDefer() { StreamSink <char> s = Stream.CreateSink <char>(); Cell <char> c = s.Hold(' '); List <char> @out = new List <char>(); IListener l = Operational.Defer(s).Snapshot(c).Listen(@out.Add); s.Send('C'); s.Send('B'); s.Send('A'); l.Unlisten(); CollectionAssert.AreEqual(new[] { 'C', 'B', 'A' }, @out); }
public void TestDefer() { StreamSink <char> s = new StreamSink <char>(); Cell <char> c = s.Hold(' '); List <char> @out = new List <char>(); using (Operational.Defer(s).Snapshot(c).Listen(@out.Add)) { s.Send('C'); s.Send('B'); s.Send('A'); } CollectionAssert.AreEqual(new[] { 'C', 'B', 'A' }, @out); }
public void TestOperationalDefer1() { StreamSink <string> a = Stream.CreateSink <string>(); Stream <string> b = Operational.Defer(a); List <string> @out = new List <string>(); IListener l = b.Listen(@out.Add); a.Send("a"); l.Unlisten(); CollectionAssert.AreEqual(new[] { "a" }, @out); List <string> out2 = new List <string>(); IListener l2 = b.Listen(out2.Add); a.Send("b"); l2.Unlisten(); CollectionAssert.AreEqual(new[] { "b" }, out2); }
public void TestStreamLoopDefer() { StreamSink <int> streamSink = Stream.CreateSink <int>(); Stream <int> stream = Transaction.Run(() => { StreamLoop <int> streamLoop = new StreamLoop <int>(); Stream <int> streamLocal = Operational.Defer(streamSink.OrElse(streamLoop).Filter(v => v < 5).Map(v => v + 1)); streamLoop.Loop(streamLocal); return(streamLocal); }); List <int> @out = new List <int>(); IListener l = stream.Listen(@out.Add); streamSink.Send(2); l.Unlisten(); CollectionAssert.AreEqual(new[] { 3, 4, 5 }, @out); }
public void TestOperationalDefer1() { StreamSink <string> a = new StreamSink <string>(); Stream <string> b = Operational.Defer(a); List <string> @out = new List <string>(); using (b.Listen(@out.Add)) { a.Send("a"); } CollectionAssert.AreEqual(new[] { "a" }, @out); List <string> out2 = new List <string>(); using (b.Listen(out2.Add)) { a.Send("b"); } CollectionAssert.AreEqual(new[] { "b" }, out2); }
public void TestOperationalDefer2() { StreamSink <string> a = Stream.CreateSink <string>(); StreamSink <string> b = Stream.CreateSink <string>(); Stream <string> c = Operational.Defer(a).OrElse(b); List <string> @out = new List <string>(); IListener l = c.Listen(@out.Add); a.Send("a"); l.Unlisten(); CollectionAssert.AreEqual(new[] { "a" }, @out); List <string> out2 = new List <string>(); IListener l2 = c.Listen(out2.Add); Transaction.RunVoid(() => { a.Send("b"); b.Send("B"); }); l2.Unlisten(); CollectionAssert.AreEqual(new[] { "B", "b" }, out2); }
public void TestOperationalDefer2() { StreamSink <string> a = new StreamSink <string>(); StreamSink <string> b = new StreamSink <string>(); Stream <string> c = Operational.Defer(a).OrElse(b); List <string> @out = new List <string>(); using (c.Listen(@out.Add)) { a.Send("a"); } CollectionAssert.AreEqual(new[] { "a" }, @out); List <string> out2 = new List <string>(); using (c.Listen(out2.Add)) { Transaction.RunVoid(() => { a.Send("b"); b.Send("B"); }); } CollectionAssert.AreEqual(new[] { "B", "b" }, out2); }
public static Stream <T> SwitchCWithDeferredValues <T>(this Cell <Cell <T> > cca) { return(Operational.Defer(cca.SwitchC().Values())); }
public static Stream <T> SwitchCWithDeferredUpdates <T>(this DiscreteCell <DiscreteCell <T> > cca) { return(Operational.Defer(cca.SwitchC().Updates)); }