public Outputs Create(Inputs inputs) { EventLoop<Fuel> eStart = new EventLoop<Fuel>(); Fill fi = new Fill(inputs.EClearSale.Map(u => Unit.UNIT), inputs.EFuelPulses, inputs.Calibration, inputs.Price1, inputs.Price2, inputs.Price3, eStart); NotifyPointOfSale np = new NotifyPointOfSale( new LifeCycle(inputs.ENozzle1, inputs.ENozzle2, inputs.ENozzle3), inputs.EClearSale, fi); eStart.Loop(np.EStart); BehaviorLoop<bool> keypadActive = new BehaviorLoop<bool>(); Keypad ke = new Keypad(inputs.EKeypad, inputs.EClearSale, keypadActive); Preset pr = new Preset(ke.Value, fi, np.FuelFlowing, np.FillActive.Map(o => o.IsPresent)); keypadActive.Loop(pr.KeypadActive); return new Outputs() .SetDelivery(pr.Delivery) .SetSaleCostLcd(fi.DollarsDelivered.Map(q => Formatters.FormatSaleCost(q))) .SetSaleQuantityLcd(fi.LitersDelivered.Map(q => Formatters.FormatSaleQuantity(q))) .SetPriceLcd1(ShowDollarsPump.PriceLCD(np.FillActive, fi.Price, Fuel.ONE, inputs)) .SetPriceLcd2(ShowDollarsPump.PriceLCD(np.FillActive, fi.Price, Fuel.TWO, inputs)) .SetPriceLcd3(ShowDollarsPump.PriceLCD(np.FillActive, fi.Price, Fuel.THREE, inputs)) .SetSaleComplete(np.ESaleComplete) .SetPresetLcd(ke.Value.Map(v => Formatters.FormatSaleCost((double)v))) .SetBeep(np.EBeep.Merge(ke.EBeep)); }
private static Behavior<double> Accumulate( Event<int> ePulses, Behavior<double> calibration) { BehaviorLoop<int> total = new BehaviorLoop<int>(); total.Loop(ePulses.Snapshot(total,(pulses_, total_) => pulses_ + total_).Hold(0)); return Behavior<double>.Lift( (total_, calibration_) => total_ * calibration_, total, calibration); }
private static Behavior <double> Accumulate( Event <int> ePulses, Behavior <double> calibration) { BehaviorLoop <int> total = new BehaviorLoop <int>(); total.Loop(ePulses.Snapshot(total, (pulses_, total_) => pulses_ + total_).Hold(0)); return(Behavior <double> .Lift( (total_, calibration_) => total_ *calibration_, total, calibration)); }
public static Behavior<double> Accumulate( Event<Unit> eClearAccumulator, Event<int> ePulses, Behavior<double> calibration) { BehaviorLoop<int> total = new BehaviorLoop<int>(); total.Loop(ePulses.Snapshot(total, (pulses_, total_) => pulses_ + total_) .Merge(eClearAccumulator.Map(f => 0)) .Hold(0)); return Behavior<double>.Lift( (total_, calibration_) => total_ * calibration_, total, calibration); }
public Keypad(Event <Key> eKeypad, Event <Unit> eClear) { BehaviorLoop <int> value = new BehaviorLoop <int>(); this.Value = value; Event <int> eKeyUpdate = Event <int> .FilterOptional( eKeypad.Snapshot( value, (key, value_) => { if (key == Key.CLEAR) { return(Optional <int> .Of(0)); } else { int x10 = value_ * 10; return(x10 >= 1000 ? Optional <int> .Empty() : Optional <int> .Of( key == Key.ZERO ? x10 : key == Key.ONE ? x10 + 1 : key == Key.TWO ? x10 + 2 : key == Key.THREE ? x10 + 3 : key == Key.FOUR ? x10 + 4 : key == Key.FIVE ? x10 + 5 : key == Key.SIX ? x10 + 6 : key == Key.SEVEN ? x10 + 7 : key == Key.EIGHT ? x10 + 8 : x10 + 9 )); } }) ); value.Loop( eKeyUpdate.Merge(eClear.Map(u => 0)) .Hold(0)); EBeep = eKeyUpdate.Map(k => Unit.UNIT); }
public void ImperativeBehaviorLoopFailsWhenLoopedTwice() { InvalidOperationException actual = null; try { BehaviorSink <int> s = Behavior.CreateSink(0); Transaction.RunVoid( () => { BehaviorLoop <int> l = new BehaviorLoop <int>(); Behavior <int> resultLocal = Operational.Updates(s).Snapshot(l, (n, o) => n + o).Hold(0).AsBehavior(); l.Loop(resultLocal); l.Loop(resultLocal); }); } catch (InvalidOperationException e) { actual = e; } Assert.IsNotNull(actual); Assert.AreEqual("Loop was looped more than once.", actual.Message); }
public static Behavior <double> Accumulate( Event <Unit> eClearAccumulator, Event <int> ePulses, Behavior <double> calibration) { BehaviorLoop <int> total = new BehaviorLoop <int>(); total.Loop(ePulses.Snapshot(total, (pulses_, total_) => pulses_ + total_) .Merge(eClearAccumulator.Map(f => 0)) .Hold(0)); return(Behavior <double> .Lift( (total_, calibration_) => total_ *calibration_, total, calibration)); }
public void TestLoopValueSnapshot() { var @out = new List <string>(); Event <String> eSnap = Transaction.Run(() => { var a = new Behavior <string>("lettuce"); var b = new BehaviorLoop <string>(); Event <String> eSnap_ = a.Value().Snapshot(b, (aa, bb) => aa + " " + bb); b.Loop(new Behavior <String>("cheese")); return(eSnap_); }); Listener l = eSnap.Listen((x) => { @out.Add(x); }); l.Unlisten(); CollectionAssert.AreEqual(new[] { "lettuce cheese" }, @out); }
public void TestLoopValueHold() { var @out = new List <string>(); Behavior <String> value = Transaction.Run(() => { var a = new BehaviorLoop <string>(); Behavior <String> value_ = a.Value().Hold("onion"); a.Loop(new Behavior <String>("cheese")); return(value_); }); var eTick = new EventSink <string>(); Listener l = eTick.Snapshot(value).Listen(x => { @out.Add(x); }); eTick.Send(UnitEnum.Unit); l.Unlisten(); CollectionAssert.AreEqual(new[] { "cheese" }, @out); }
public Keypad(Event<Key> eKeypad, Event<Unit> eClear) { BehaviorLoop<int> value = new BehaviorLoop<int>(); this.Value = value; Event<int> eKeyUpdate = Event<int>.FilterOptional( eKeypad.Snapshot( value, (key, value_) => { if (key == Key.CLEAR) return Optional<int>.Of(0); else { int x10 = value_ * 10; return x10 >= 1000 ? Optional<int>.Empty() : Optional<int>.Of( key == Key.ZERO ? x10 : key == Key.ONE ? x10 + 1 : key == Key.TWO ? x10 + 2 : key == Key.THREE ? x10 + 3 : key == Key.FOUR ? x10 + 4 : key == Key.FIVE ? x10 + 5 : key == Key.SIX ? x10 + 6 : key == Key.SEVEN ? x10 + 7 : key == Key.EIGHT ? x10 + 8 : x10 + 9 ); } }) ); value.Loop( eKeyUpdate.Merge(eClear.Map(u => 0)) .Hold(0)); EBeep = eKeyUpdate.Map(k => Unit.UNIT); }
public void TestLiftLoop() { var @out = new List <string>(); var b = new BehaviorSink <string>("kettle"); Behavior <String> c = Transaction.Run(() => { var a = new BehaviorLoop <string>(); Behavior <String> c_ = Behavior <string> .Lift( (aa, bb) => aa + " " + bb, a, b); a.Loop(new Behavior <String>("tea")); return(c_); }); Listener l = c.Value().Listen(x => { @out.Add(x); }); b.Send("caddy"); l.Unlisten(); CollectionAssert.AreEqual(new[] { "tea kettle", "tea caddy" }, @out); }
public void TestLoopBehavior() { var ea = new EventSink <int>(); Behavior <int> sum_out = Transaction.Run(() => { var sum = new BehaviorLoop <int>(); Behavior <int> sumOut = ea.Snapshot <int, int>(sum, (x, y) => x + y).Hold(0); sum.Loop(sumOut); return(sumOut); }); var @out = new List <int>(); Listener l = sum_out.Value().Listen(x => { @out.Add(x); }); ea.Send(2); ea.Send(3); ea.Send(1); l.Unlisten(); CollectionAssert.AreEqual(new[] { 0, 2, 5, 6 }, @out); Assert.That((int)sum_out.Sample(), Is.EqualTo(6)); }
public LifeCycle(Event<UpDown> eNozzle1, Event<UpDown> eNozzle2, Event<UpDown> eNozzle3) { Event<Fuel> eLiftNozzle = WhenLifted(eNozzle1, Fuel.ONE).Merge( WhenLifted(eNozzle2, Fuel.TWO).Merge( WhenLifted(eNozzle3, Fuel.THREE))); BehaviorLoop<Optional<Fuel>> fillActive = new BehaviorLoop<Optional<Fuel>>(); this.FillActive = fillActive; this.EStart = Event<Fuel>.FilterOptional( eLiftNozzle.Snapshot(fillActive, (newFuel, fillActive_) => fillActive_.IsPresent ? Optional<Fuel>.Empty() : Optional<Fuel>.Of(newFuel))); this.EEnd = WhenSetDown(eNozzle1, Fuel.ONE, fillActive).Merge( WhenSetDown(eNozzle2, Fuel.TWO, fillActive).Merge( WhenSetDown(eNozzle3, Fuel.THREE, fillActive))); fillActive.Loop( EStart.Map(f => Optional<Fuel>.Of(f)) .Merge(EEnd.Map(e => Optional<Fuel>.Empty())) .Hold(Optional<Fuel>.Empty()) ); }
public void ImperativeBehaviorLoop() { BehaviorSink <int> s = Behavior.CreateSink(0); Behavior <int> result = Transaction.Run( () => { BehaviorLoop <int> l = new BehaviorLoop <int>(); Behavior <int> resultLocal = Operational.Updates(s).Snapshot(l, (n, o) => n + o).Hold(0).AsBehavior(); l.Loop(resultLocal); return(resultLocal); }); List <int> @out = new List <int>(); using (Transaction.Run(() => Operational.Value(result).Listen(@out.Add))) { s.Send(1); s.Send(2); s.Send(3); } CollectionAssert.AreEqual(new[] { 0, 1, 3, 6 }, @out); }
public Outputs Create(Inputs inputs) { EventLoop <Fuel> eStart = new EventLoop <Fuel>(); Fill fi = new Fill(inputs.EClearSale.Map(u => Unit.UNIT), inputs.EFuelPulses, inputs.Calibration, inputs.Price1, inputs.Price2, inputs.Price3, eStart); NotifyPointOfSale np = new NotifyPointOfSale( new LifeCycle(inputs.ENozzle1, inputs.ENozzle2, inputs.ENozzle3), inputs.EClearSale, fi); eStart.Loop(np.EStart); BehaviorLoop <bool> keypadActive = new BehaviorLoop <bool>(); Keypad ke = new Keypad(inputs.EKeypad, inputs.EClearSale, keypadActive); Preset pr = new Preset(ke.Value, fi, np.FuelFlowing, np.FillActive.Map(o => o.IsPresent)); keypadActive.Loop(pr.KeypadActive); return(new Outputs() .SetDelivery(pr.Delivery) .SetSaleCostLcd(fi.DollarsDelivered.Map(q => Formatters.FormatSaleCost(q))) .SetSaleQuantityLcd(fi.LitersDelivered.Map(q => Formatters.FormatSaleQuantity(q))) .SetPriceLcd1(ShowDollarsPump.PriceLCD(np.FillActive, fi.Price, Fuel.ONE, inputs)) .SetPriceLcd2(ShowDollarsPump.PriceLCD(np.FillActive, fi.Price, Fuel.TWO, inputs)) .SetPriceLcd3(ShowDollarsPump.PriceLCD(np.FillActive, fi.Price, Fuel.THREE, inputs)) .SetSaleComplete(np.ESaleComplete) .SetPresetLcd(ke.Value.Map(v => Formatters.FormatSaleCost((double)v))) .SetBeep(np.EBeep.Merge(ke.EBeep))); }
public LifeCycle(Event <UpDown> eNozzle1, Event <UpDown> eNozzle2, Event <UpDown> eNozzle3) { Event <Fuel> eLiftNozzle = WhenLifted(eNozzle1, Fuel.ONE).Merge( WhenLifted(eNozzle2, Fuel.TWO).Merge( WhenLifted(eNozzle3, Fuel.THREE))); BehaviorLoop <Optional <Fuel> > fillActive = new BehaviorLoop <Optional <Fuel> >(); this.FillActive = fillActive; this.EStart = Event <Fuel> .FilterOptional( eLiftNozzle.Snapshot(fillActive, (newFuel, fillActive_) => fillActive_.IsPresent ? Optional <Fuel> .Empty() : Optional <Fuel> .Of(newFuel))); this.EEnd = WhenSetDown(eNozzle1, Fuel.ONE, fillActive).Merge( WhenSetDown(eNozzle2, Fuel.TWO, fillActive).Merge( WhenSetDown(eNozzle3, Fuel.THREE, fillActive))); fillActive.Loop( EStart.Map(f => Optional <Fuel> .Of(f)) .Merge(EEnd.Map(e => Optional <Fuel> .Empty())) .Hold(Optional <Fuel> .Empty()) ); }
public void TestLoopValueHold() { var @out = new List<string>(); Behavior<String> value = Transaction.Run(() => { var a = new BehaviorLoop<string>(); Behavior<String> value_ = a.Value().Hold("onion"); a.Loop(new Behavior<String>("cheese")); return value_; }); var eTick = new EventSink<string>(); Listener l = eTick.Snapshot(value).Listen(x => { @out.Add(x); }); eTick.Send(UnitEnum.Unit); l.Unlisten(); CollectionAssert.AreEqual(new[] { "cheese" }, @out); }
public void TestLoopBehavior() { var ea = new EventSink<int>(); Behavior<int> sum_out = Transaction.Run(() => { var sum = new BehaviorLoop<int>(); Behavior<int> sumOut = ea.Snapshot<int, int>(sum, (x, y) => x + y).Hold(0); sum.Loop(sumOut); return sumOut; }); var @out = new List<int>(); Listener l = sum_out.Value().Listen(x => { @out.Add(x); }); ea.Send(2); ea.Send(3); ea.Send(1); l.Unlisten(); CollectionAssert.AreEqual(new[] { 0, 2, 5, 6 }, @out); Assert.That((int)sum_out.Sample(), Is.EqualTo(6)); }
public void TestLoopValueSnapshot() { var @out = new List<string>(); Event<String> eSnap = Transaction.Run(() => { var a = new Behavior<string>("lettuce"); var b = new BehaviorLoop<string>(); Event<String> eSnap_ = a.Value().Snapshot(b, (aa, bb) => aa + " " + bb); b.Loop(new Behavior<String>("cheese")); return eSnap_; }); Listener l = eSnap.Listen((x) => { @out.Add(x); }); l.Unlisten(); CollectionAssert.AreEqual(new[] { "lettuce cheese" }, @out); }
public void TestLiftLoop() { var @out = new List<string>(); var b = new BehaviorSink<string>("kettle"); Behavior<String> c = Transaction.Run(() => { var a = new BehaviorLoop<string>(); Behavior<String> c_ = Behavior<string>.Lift( (aa, bb) => aa + " " + bb, a, b); a.Loop(new Behavior<String>("tea")); return c_; }); Listener l = c.Value().Listen(x => { @out.Add(x); }); b.Send("caddy"); l.Unlisten(); CollectionAssert.AreEqual(new[] { "tea kettle", "tea caddy" }, @out); }