예제 #1
0
 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));
 }
예제 #2
0
 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);
 }
예제 #3
0
        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);
 }
예제 #5
0
파일: KeyPad.cs 프로젝트: yuhangwang/sodium
        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);
        }
예제 #6
0
        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));
        }
예제 #7
0
        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);
        }
예제 #8
0
        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);
        }
예제 #9
0
 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);
 }
예제 #10
0
        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);
        }
예제 #11
0
        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));
        }
예제 #12
0
 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())
     );
 }
예제 #13
0
        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);
        }
예제 #14
0
        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)));
        }
예제 #15
0
        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())
                );
        }
예제 #16
0
        public void ImperativeBehaviorLoopFailsWhenLoopedInSeparateTransaction()
        {
            InvalidOperationException actual = null;

            BehaviorLoop <int> l = null;

            new Thread(
                () =>
                Transaction.RunVoid(
                    () =>
            {
                l = new BehaviorLoop <int>();
                Thread.Sleep(500);
            })).Start();

            try
            {
                BehaviorSink <int> s = Behavior.CreateSink(0);
                Transaction.RunVoid(
                    () =>
                {
                    Thread.Sleep(250);
                    Behavior <int> resultLocal = Operational.Updates(s).Snapshot(l, (n, o) => n + o).Hold(0).AsBehavior();
                    l.Loop(resultLocal);
                });
            }
            catch (InvalidOperationException e)
            {
                actual = e;
            }

            Thread.Sleep(500);

            Assert.IsNotNull(actual);
            Assert.AreEqual("Loop must be looped in the same transaction that it was created in.", actual.Message);
        }
예제 #17
0
        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);
        }
예제 #18
0
 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);
 }
예제 #19
0
 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));
 }
예제 #20
0
 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);
 }
예제 #21
0
 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);
 }