Ejemplo n.º 1
0
        public void TestHoldIsDelayed()
        {
            StreamSink <int>   s    = Stream.CreateSink <int>();
            DiscreteCell <int> h    = s.Hold(0);
            Stream <string>    pair = s.Snapshot(h.Cell, (a, b) => a + " " + b);
            List <string>      @out = new List <string>();
            IListener          l    = pair.Listen(@out.Add);

            s.Send(2);
            s.Send(3);
            l.Unlisten();
            CollectionAssert.AreEqual(new[] { "2 0", "3 2" }, @out);
        }
Ejemplo n.º 2
0
 public void TestHoldIsDelayed()
 {
     StreamSink<int> s = new StreamSink<int>();
     Cell<int> h = s.Hold(0);
     Stream<string> pair = s.Snapshot(h, (a, b) => a + " " + b);
     List<string> @out = new List<string>();
     using (pair.Listen(@out.Add))
     {
         s.Send(2);
         s.Send(3);
     }
     CollectionAssert.AreEqual(new[] { "2 0", "3 2" }, @out);
 }
Ejemplo n.º 3
0
        public void TestHoldImplicitDelay()
        {
            StreamSink <char> s    = Stream.CreateSink <char>();
            Cell <char>       c    = s.Hold(' ');
            List <char>       @out = new List <char>();
            IListener         l    = s.Snapshot(c).Listen(@out.Add);

            s.Send('C');
            s.Send('B');
            s.Send('A');
            l.Unlisten();
            CollectionAssert.AreEqual(new[] { ' ', 'C', 'B' }, @out);
        }
Ejemplo n.º 4
0
        public void TestHoldImplicitDelay()
        {
            StreamSink <char> s    = new StreamSink <char>();
            Cell <char>       c    = s.Hold(' ');
            List <char>       @out = new List <char>();

            using (s.Snapshot(c).Listen(@out.Add))
            {
                s.Send('C');
                s.Send('B');
                s.Send('A');
            }
            CollectionAssert.AreEqual(new[] { ' ', 'C', 'B' }, @out);
        }
Ejemplo n.º 5
0
        public void TestHoldIsDelayed()
        {
            StreamSink <int> s    = new StreamSink <int>();
            Cell <int>       h    = s.Hold(0);
            Stream <string>  pair = s.Snapshot(h, (a, b) => a + " " + b);
            List <string>    @out = new List <string>();

            using (pair.Listen(@out.Add))
            {
                s.Send(2);
                s.Send(3);
            }
            CollectionAssert.AreEqual(new[] { "2 0", "3 2" }, @out);
        }
Ejemplo n.º 6
0
        public void TestMerge()
        {
            StreamSink <Unit> s = Stream.CreateSink <Unit>();
            var obj             = Transaction.Run(() =>
            {
                StreamLoop <bool> loop          = Stream.CreateLoop <bool>();
                DiscreteCellStreamSink <int> s1 = new DiscreteCellStreamSink <int>();
                DiscreteCellStreamSink <int> s2 = new DiscreteCellStreamSink <int>();
                TestObject[] l = Enumerable.Range(0, 5000).Select(_ => new TestObject(loop, s1, s2)).ToArray();
                loop.Loop(s.Snapshot(l.Select(o => o.Cell).Lift().Cell).Map(o => o.All(v => v == 0)));
                return(l);
            });

            int[] values = obj.Select(v => v.CurrentValue).ToArray();
        }
Ejemplo n.º 7
0
        public void FunctionalStreamLoop()
        {
            StreamSink <int> s      = Stream.CreateSink <int>();
            Stream <int>     result = Stream.Loop <int>().WithoutCaptures(l => s.Snapshot(l.Hold(0), (n, o) => n + o));

            List <int> @out = new List <int>();

            using (result.Listen(@out.Add))
            {
                s.Send(1);
                s.Send(2);
                s.Send(3);
            }

            CollectionAssert.AreEqual(new[] { 1, 3, 6 }, @out);
        }
Ejemplo n.º 8
0
        public void TestSnapshot()
        {
            CellSink <int>    c       = Cell.CreateSink(0);
            StreamSink <long> trigger = Stream.CreateSink <long>();
            List <string>     @out    = new List <string>();
            IListener         l       = trigger.Snapshot(c, (x, y) => x + " " + y).Listen(@out.Add);

            trigger.Send(100L);
            c.Send(2);
            trigger.Send(200L);
            c.Send(9);
            c.Send(1);
            trigger.Send(300L);
            l.Unlisten();
            CollectionAssert.AreEqual(new[] { "100 0", "200 2", "300 1" }, @out);
        }
Ejemplo n.º 9
0
 public void TestSnapshot()
 {
     CellSink<int> c = new CellSink<int>(0);
     StreamSink<long> trigger = new StreamSink<long>();
     List<string> @out = new List<string>();
     using (trigger.Snapshot(c, (x, y) => x + " " + y).Listen(@out.Add))
     {
         trigger.Send(100L);
         c.Send(2);
         trigger.Send(200L);
         c.Send(9);
         c.Send(1);
         trigger.Send(300L);
     }
     CollectionAssert.AreEqual(new[] { "100 0", "200 2", "300 1" }, @out);
 }
Ejemplo n.º 10
0
        public void TestSnapshot()
        {
            CellSink <int>    c       = new CellSink <int>(0);
            StreamSink <long> trigger = new StreamSink <long>();
            List <string>     @out    = new List <string>();

            using (trigger.Snapshot(c, (x, y) => x + " " + y).Listen(@out.Add))
            {
                trigger.Send(100L);
                c.Send(2);
                trigger.Send(200L);
                c.Send(9);
                c.Send(1);
                trigger.Send(300L);
            }
            CollectionAssert.AreEqual(new[] { "100 0", "200 2", "300 1" }, @out);
        }
Ejemplo n.º 11
0
        public void TestRunConstruct2()
        {
            var(objectsAndIsSelected, selectAllStream, objects) = Transaction.Run(() =>
            {
                CellLoop <bool?> allSelectedCellLoop           = Cell.CreateLoop <bool?>();
                StreamSink <Unit> toggleAllSelectedStreamLocal = Stream.CreateSink <Unit>();
                Stream <bool> selectAllStreamLocal             = toggleAllSelectedStreamLocal.Snapshot(allSelectedCellLoop).Map(a => a != true);

                IReadOnlyList <TestObject2> o2 = Enumerable.Range(0, 10000).Select(n => new TestObject2(n, n < 1500, selectAllStreamLocal)).ToArray();
                CellSink <IReadOnlyList <TestObject2> > objectsLocal = Cell.CreateSink(o2);

                var objectsAndIsSelectedLocal = objectsLocal.Map(oo => oo.Select(o => o.IsSelected.Map(s => new { Object = o, IsSelected = s })).Lift()).SwitchC();

                bool defaultValue        = o2.Count < 1;
                Cell <bool?> allSelected =
                    objectsAndIsSelectedLocal.Map(
                        oo =>
                        !oo.Any()
                                ? defaultValue
                                : (oo.All(o => o.IsSelected)
                                    ? true
                                    : (oo.All(o => !o.IsSelected) ? (bool?)false : null)));
                allSelectedCellLoop.Loop(allSelected);

                return(objectsAndIsSelectedLocal, selectAllStreamLocal, objectsLocal);
            });

            List <int> @out = new List <int>();

            using (Transaction.Run(
                       () => objectsAndIsSelected.Map(oo => oo.Count(o => o.IsSelected))
                       .Values.Listen(@out.Add)))
            {
                Transaction.Run(() =>
                {
                    objects.Send(
                        Enumerable.Range(0, 20000)
                        .Select(n => new TestObject2(n, n < 500, selectAllStream))
                        .ToArray());
                    return(Unit.Value);
                });
            }

            CollectionAssert.AreEqual(new[] { 1500, 500 }, @out);
        }
Ejemplo n.º 12
0
        public void TestDiscreteCellLoop()
        {
            StreamSink <int>   s    = new StreamSink <int>();
            DiscreteCell <int> cell = Transaction.Run(() =>
            {
                DiscreteCellLoop <int> cellLoop = new DiscreteCellLoop <int>();
                DiscreteCell <int> cellLocal    = s.Snapshot(cellLoop, (x, y) => x + y).Hold(1);
                cellLoop.Loop(cellLocal);
                return(cellLocal);
            });
            List <int> @out = new List <int>();
            IListener  l    = cell.Listen(@out.Add);

            s.Send(3);
            s.Send(4);
            s.Send(7);
            s.Send(8);
            l.Unlisten();

            CollectionAssert.AreEqual(new[] { 1, 4, 8, 15, 23 }, @out);
        }
Ejemplo n.º 13
0
        public void FunctionalStreamLoopWithCaptures()
        {
            StreamSink <int> s = Stream.CreateSink <int>();

            (Stream <int> result, Stream <int> s2) = Stream.Loop <int>()
                                                     .WithCaptures(l => (Stream: s.Snapshot(l.Hold(0), (n, o) => n + o), Captures: s.Map(v => 2 * v)));

            List <int> @out = new List <int>();
            List <int> out2 = new List <int>();

            using (result.Listen(@out.Add))
                using (s2.Listen(out2.Add))

                {
                    s.Send(1);
                    s.Send(2);
                    s.Send(3);
                }

            CollectionAssert.AreEqual(new[] { 1, 3, 6 }, @out);
            CollectionAssert.AreEqual(new[] { 2, 4, 6 }, out2);
        }
Ejemplo n.º 14
0
        public void TestStreamLoop()
        {
            StreamSink <int> streamSink = Stream.CreateSink <int>();
            Stream <int>     s          = Transaction.Run(() =>
            {
                StreamLoop <int> sl = new StreamLoop <int>();
                Cell <int> c        = sl.Map(v => v + 2).Hold(0);
                Stream <int> s2     = streamSink.Snapshot(c, (x, y) => x + y);
                sl.Loop(s2);
                return(s2);
            });
            List <int> @out = new List <int>();
            IListener  l    = s.Listen(@out.Add);

            streamSink.Send(3);
            streamSink.Send(4);
            streamSink.Send(7);
            streamSink.Send(8);
            l.Unlisten();

            CollectionAssert.AreEqual(new[] { 3, 9, 18, 28 }, @out);
        }
Ejemplo n.º 15
0
        public void ImperativeStreamLoop()
        {
            StreamSink <int> s      = Stream.CreateSink <int>();
            Stream <int>     result = Transaction.Run(
                () =>
            {
                StreamLoop <int> l       = new StreamLoop <int>();
                Stream <int> resultLocal = s.Snapshot(l.Hold(0), (n, o) => n + o);
                l.Loop(resultLocal);
                return(resultLocal);
            });

            List <int> @out = new List <int>();

            using (result.Listen(@out.Add))
            {
                s.Send(1);
                s.Send(2);
                s.Send(3);
            }

            CollectionAssert.AreEqual(new[] { 1, 3, 6 }, @out);
        }
Ejemplo n.º 16
0
        public void ImperativeStreamLoopFailsWhenLoopedTwice()
        {
            InvalidOperationException actual = null;

            try
            {
                StreamSink <int> s = Stream.CreateSink <int>();
                Transaction.RunVoid(
                    () =>
                {
                    StreamLoop <int> l       = new StreamLoop <int>();
                    Stream <int> resultLocal = s.Snapshot(l.Hold(0), (n, o) => n + o);
                    l.Loop(resultLocal);
                    l.Loop(resultLocal);
                });
            }
            catch (InvalidOperationException e)
            {
                actual = e;
            }

            Assert.IsNotNull(actual);
            Assert.AreEqual("Loop was looped more than once.", actual.Message);
        }
Ejemplo n.º 17
0
        public void ImperativeStreamLoopFailsWhenLoopedInSeparateTransaction()
        {
            InvalidOperationException actual = null;

            StreamLoop <int> l = null;

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

            try
            {
                StreamSink <int> s = Stream.CreateSink <int>();
                Transaction.RunVoid(
                    () =>
                {
                    Thread.Sleep(250);
                    Stream <int> resultLocal = s.Snapshot(l.Hold(0), (n, o) => n + o);
                    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);
        }
Ejemplo n.º 18
0
        public MainWindow()
        {
            this.InitializeComponent();

            this.Loaded += async(sender, args) =>
            {
                ITimerSystem <DateTime> sys   = new SystemClockTimerSystem(e => this.Dispatcher.Invoke(() => { throw e; }));
                Cell <DateTime>         time  = sys.Time;
                StreamSink <Unit>       sMain = new StreamSink <Unit>();
                IListener l = Transaction.Run(() =>
                {
                    DateTime t0  = time.Sample();
                    IListener l1 = Periodic(sys, TimeSpan.FromSeconds(1)).Listen(t => this.AddMessage(t - t0 + " timer"));
                    IListener l2 = sMain.Snapshot(time).Listen(t => this.AddMessage(t - t0 + " main"));
                    return(new CompositeListener(new[] { l1, l2 }));
                });
                for (int i = 0; i < 5; i++)
                {
                    sMain.Send(Unit.Value);
                    await Task.Delay(990);
                }
                l.Unlisten();
            };
        }
Ejemplo n.º 19
0
        public static void Main(string[] args)
        {
            Console.WriteLine("Press any key");
            Console.ReadKey();

            var(toggleAllSelectedStream, objectsAndIsSelected, selectAllStream, objects) = Transaction.Run(() =>
            {
                CellLoop <bool?> allSelectedCellLoop           = Cell.CreateLoop <bool?>();
                StreamSink <Unit> toggleAllSelectedStreamLocal = Stream.CreateSink <Unit>();
                Stream <bool> selectAllStreamLocal             = toggleAllSelectedStreamLocal.Snapshot(allSelectedCellLoop).Map(a => a != true);

                IReadOnlyList <TestObject> o2 = Enumerable.Range(0, 10000).Select(n => new TestObject(n, selectAllStreamLocal)).ToArray();
                DiscreteCellSink <IReadOnlyList <TestObject> > objectsLocal =
                    DiscreteCell.CreateSink((IReadOnlyList <TestObject>) new TestObject[0]);

                var objectsAndIsSelectedLocal = objectsLocal.Map(oo => oo.Select(o => o.IsSelected.Map(s => new { Object = o, IsSelected = s })).Lift()).SwitchC();

                bool defaultValue = o2.Count < 1;
                DiscreteCell <bool?> allSelected =
                    objectsAndIsSelectedLocal.Map(
                        oo =>
                        !oo.Any()
                                ? defaultValue
                                : (oo.All(o => o.IsSelected)
                                    ? true
                                    : (oo.All(o => !o.IsSelected) ? (bool?)false : null)));
                allSelectedCellLoop.Loop(allSelected.Cell);

                return(toggleAllSelectedStreamLocal, objectsAndIsSelectedLocal, selectAllStreamLocal, objectsLocal);
            });

            // ReSharper disable once UnusedVariable
            IListener l = Transaction.Run(() => objectsAndIsSelected.Map(oo => oo.Count(o => o.IsSelected)).Updates.Listen(v => Console.WriteLine($"{v} selected")));

            Console.WriteLine("Press any key");
            Console.ReadKey();

            Stopwatch sw = new Stopwatch();

            sw.Start();

            toggleAllSelectedStream.Send(Unit.Value);
            toggleAllSelectedStream.Send(Unit.Value);
            toggleAllSelectedStream.Send(Unit.Value);
            SendMore(objects, selectAllStream);
            Thread.Sleep(500);
            SendMore(objects, selectAllStream);
            Thread.Sleep(500);
            SendMore(objects, selectAllStream);
            Thread.Sleep(500);
            SendMore(objects, selectAllStream);
            Thread.Sleep(500);
            SendMore(objects, selectAllStream);
            Thread.Sleep(500);
            SendMore(objects, selectAllStream);
            Thread.Sleep(500);
            SendMore(objects, selectAllStream);
            Thread.Sleep(500);
            SendMore(objects, selectAllStream);
            Thread.Sleep(500);
            SendMore(objects, selectAllStream);
            Thread.Sleep(500);
            SendMore(objects, selectAllStream);
            Thread.Sleep(500);
            SendMore(objects, selectAllStream);
            Thread.Sleep(500);
            SendMore(objects, selectAllStream);
            Thread.Sleep(500);
            SendMore(objects, selectAllStream);
            Thread.Sleep(500);
            SendMore(objects, selectAllStream);
            Thread.Sleep(500);
            SendMore(objects, selectAllStream);
            Thread.Sleep(500);
            SendMore(objects, selectAllStream);
            Thread.Sleep(500);
            SendMore(objects, selectAllStream);
            Thread.Sleep(500);
            SendMore(objects, selectAllStream);
            Thread.Sleep(500);
            SendMore(objects, selectAllStream);
            Thread.Sleep(500);
            SendMore(objects, selectAllStream);
            Thread.Sleep(500);
            SendMore(objects, selectAllStream);
            Thread.Sleep(500);
            SendMore(objects, selectAllStream);
            Thread.Sleep(500);
            SendMore(objects, selectAllStream);
            Thread.Sleep(500);
            SendMore(objects, selectAllStream);
            Thread.Sleep(500);
            SendMore(objects, selectAllStream);
            objects.Cell.Sample()[2].IsSelectedStreamSink.Send(true);
            Transaction.RunVoid(() =>
            {
                objects.Cell.Sample()[3].IsSelectedStreamSink.Send(true);
                objects.Cell.Sample()[4].IsSelectedStreamSink.Send(true);
            });
            Transaction.RunVoid(() =>
            {
                objects.Send(Enumerable.Range(0, 2500).Select(n => new TestObject(n, selectAllStream)).ToArray());
                toggleAllSelectedStream.Send(Unit.Value);
            });
            toggleAllSelectedStream.Send(Unit.Value);
            toggleAllSelectedStream.Send(Unit.Value);
            toggleAllSelectedStream.Send(Unit.Value);
            toggleAllSelectedStream.Send(Unit.Value);
            toggleAllSelectedStream.Send(Unit.Value);
            toggleAllSelectedStream.Send(Unit.Value);
            toggleAllSelectedStream.Send(Unit.Value);
            toggleAllSelectedStream.Send(Unit.Value);
            toggleAllSelectedStream.Send(Unit.Value);
            toggleAllSelectedStream.Send(Unit.Value);
            toggleAllSelectedStream.Send(Unit.Value);
            toggleAllSelectedStream.Send(Unit.Value);
            toggleAllSelectedStream.Send(Unit.Value);
            toggleAllSelectedStream.Send(Unit.Value);
            toggleAllSelectedStream.Send(Unit.Value);
            toggleAllSelectedStream.Send(Unit.Value);
            toggleAllSelectedStream.Send(Unit.Value);
            toggleAllSelectedStream.Send(Unit.Value);
            toggleAllSelectedStream.Send(Unit.Value);
            toggleAllSelectedStream.Send(Unit.Value);
            toggleAllSelectedStream.Send(Unit.Value);
            toggleAllSelectedStream.Send(Unit.Value);
            toggleAllSelectedStream.Send(Unit.Value);
            toggleAllSelectedStream.Send(Unit.Value);
            toggleAllSelectedStream.Send(Unit.Value);
            toggleAllSelectedStream.Send(Unit.Value);
            toggleAllSelectedStream.Send(Unit.Value);
            toggleAllSelectedStream.Send(Unit.Value);
            toggleAllSelectedStream.Send(Unit.Value);
            toggleAllSelectedStream.Send(Unit.Value);
            toggleAllSelectedStream.Send(Unit.Value);
            toggleAllSelectedStream.Send(Unit.Value);
            toggleAllSelectedStream.Send(Unit.Value);
            toggleAllSelectedStream.Send(Unit.Value);
            toggleAllSelectedStream.Send(Unit.Value);
            toggleAllSelectedStream.Send(Unit.Value);
            toggleAllSelectedStream.Send(Unit.Value);
            toggleAllSelectedStream.Send(Unit.Value);
            toggleAllSelectedStream.Send(Unit.Value);
            toggleAllSelectedStream.Send(Unit.Value);
            toggleAllSelectedStream.Send(Unit.Value);
            toggleAllSelectedStream.Send(Unit.Value);
            toggleAllSelectedStream.Send(Unit.Value);
            objects.Send(new TestObject[0]);

            sw.Stop();

            Console.WriteLine();
            Console.WriteLine();
            Console.WriteLine($"Elapsed: {sw.ElapsedMilliseconds}ms");

            Console.WriteLine();
            Console.WriteLine("Press any key");
            Console.ReadKey();
        }
Ejemplo n.º 20
0
            public Implementation(PetrolPumpWindow petrolPump)
            {
                SComboBox<IPump> logic = new SComboBox<IPump>(
                    new IPump[]
                    {
                        new LifeCyclePump(),
                        new AccumulatePulsesPump(),
                        new ShowDollarsPump(),
                        new ClearSalePump(),
                        new KeypadPump(),
                        new PresetAmountPump()
                    },
                    p => p.GetType().FullName);
                petrolPump.LogicComboBoxPlaceholder.Children.Add(logic);

                STextField textPrice1 = new STextField("2.149") { Width = 100 };
                petrolPump.Price1Placeholder.Children.Add(textPrice1);

                STextField textPrice2 = new STextField("2.341") { Width = 100 };
                petrolPump.Price2Placeholder.Children.Add(textPrice2);

                STextField textPrice3 = new STextField("1.499") { Width = 100 };
                petrolPump.Price3Placeholder.Children.Add(textPrice3);

                Func<string, double> parseDoubleSafe = s =>
                {
                    double n;
                    if (double.TryParse(s, out n))
                    {
                        return n;
                    }

                    return 0.0;
                };

                StreamSink<Key> sKey = new StreamSink<Key>();
                Dictionary<Key, FrameworkElement> containersByKey = new Dictionary<Key, FrameworkElement>
                {
                    { Key.One, petrolPump.Keypad1Button },
                    { Key.Two, petrolPump.Keypad2Button },
                    { Key.Three, petrolPump.Keypad3Button },
                    { Key.Four, petrolPump.Keypad4Button },
                    { Key.Five, petrolPump.Keypad5Button },
                    { Key.Six, petrolPump.Keypad6Button },
                    { Key.Seven, petrolPump.Keypad7Button },
                    { Key.Eight, petrolPump.Keypad8Button },
                    { Key.Nine, petrolPump.Keypad9Button },
                    { Key.Zero, petrolPump.Keypad0Button },
                    { Key.Clear, petrolPump.KeypadClearButton }
                };
                foreach (KeyValuePair<Key, FrameworkElement> containerAndKey in containersByKey)
                {
                    containerAndKey.Value.MouseDown += async (sender, args) =>
                    {
                        if (args.LeftButton == MouseButtonState.Pressed)
                        {
                            await Task.Run(() => sKey.Send(containerAndKey.Key));
                        }
                    };
                }

                CellLoop<UpDown> nozzle1 = new CellLoop<UpDown>();
                CellLoop<UpDown> nozzle2 = new CellLoop<UpDown>();
                CellLoop<UpDown> nozzle3 = new CellLoop<UpDown>();

                Cell<double> calibration = Cell.Constant(0.001);
                Cell<double> price1 = textPrice1.Text.Map(parseDoubleSafe);
                Cell<double> price2 = textPrice2.Text.Map(parseDoubleSafe);
                Cell<double> price3 = textPrice3.Text.Map(parseDoubleSafe);
                CellSink<Stream<Unit>> csClearSale = new CellSink<Stream<Unit>>(Sodium.Stream.Never<Unit>());
                Stream<Unit> sClearSale = csClearSale.SwitchS();

                StreamSink<int> sFuelPulses = new StreamSink<int>();
                Cell<Outputs> outputs = logic.SelectedItem.Map(
                    pump => pump.Create(new Inputs(
                        Operational.Updates(nozzle1),
                        Operational.Updates(nozzle2),
                        Operational.Updates(nozzle3),
                        sKey,
                        sFuelPulses,
                        calibration,
                        price1,
                        price2,
                        price3,
                        sClearSale)));

                Cell<Delivery> delivery = outputs.Map(o => o.Delivery).SwitchC();
                Cell<string> presetLcd = outputs.Map(o => o.PresetLcd).SwitchC();
                Cell<string> saleCostLcd = outputs.Map(o => o.SaleCostLcd).SwitchC();
                Cell<string> saleQuantityLcd = outputs.Map(o => o.SaleQuantityLcd).SwitchC();
                Cell<string> priceLcd1 = outputs.Map(o => o.PriceLcd1).SwitchC();
                Cell<string> priceLcd2 = outputs.Map(o => o.PriceLcd2).SwitchC();
                Cell<string> priceLcd3 = outputs.Map(o => o.PriceLcd3).SwitchC();
                Stream<Unit> sBeep = outputs.Map(o => o.SBeep).SwitchS();
                Stream<Sale> sSaleComplete = outputs.Map(o => o.SSaleComplete).SwitchS();

                SoundPlayer beepPlayer = new SoundPlayer(GetResourceStream(@"sounds\beep.wav"));
                this.listeners.Add(sBeep.Listen(_ => new Thread(() => beepPlayer.PlaySync()) { IsBackground = true }.Start()));

                SoundPlayer fastRumblePlayer = new SoundPlayer(GetResourceStream(@"sounds\fast.wav"));
                Action stopFast = () => { };
                Action playFast = () =>
                {
                    ManualResetEvent mre = new ManualResetEvent(false);
                    new Thread(() =>
                    {
                        fastRumblePlayer.PlayLooping();
                        mre.WaitOne();
                        fastRumblePlayer.Stop();
                    })
                    { IsBackground = true }.Start();
                    stopFast = () => mre.Set();
                };

                SoundPlayer slowRumblePlayer = new SoundPlayer(GetResourceStream(@"sounds\slow.wav"));
                Action stopSlow = () => { };
                Action playSlow = () =>
                {
                    ManualResetEvent mre = new ManualResetEvent(false);
                    new Thread(() =>
                    {
                        slowRumblePlayer.PlayLooping();
                        mre.WaitOne();
                        slowRumblePlayer.Stop();
                    })
                    { IsBackground = true }.Start();
                    stopSlow = () => mre.Set();
                };

                this.listeners.Add(delivery.Changes().Listen(d =>
                {
                    petrolPump.Dispatcher.InvokeIfNecessary(() =>
                    {
                        if (d == Delivery.Fast1 || d == Delivery.Fast2 || d == Delivery.Fast3)
                        {
                            playFast();
                        }
                        else
                        {
                            stopFast();
                        }

                        if (d == Delivery.Slow1 || d == Delivery.Slow2 || d == Delivery.Slow3)
                        {
                            playSlow();
                        }
                        else
                        {
                            stopSlow();
                        }
                    });
                }));

                StackPanel presetLcdStackPanel = new StackPanel { Orientation = Orientation.Horizontal };
                petrolPump.PresetPlaceholder.Children.Add(presetLcdStackPanel);
                this.listeners.Add(presetLcd.Listen(t => petrolPump.Dispatcher.InvokeIfNecessary(() => petrolPump.SetLcdDigits(presetLcdStackPanel, t, 5, true))));

                StackPanel saleCostStackPanel = new StackPanel { Orientation = Orientation.Horizontal };
                petrolPump.DollarsPlaceholder.Children.Add(saleCostStackPanel);
                this.listeners.Add(saleCostLcd.Listen(t => petrolPump.Dispatcher.InvokeIfNecessary(() => petrolPump.SetLcdDigits(saleCostStackPanel, t, 5, true))));

                StackPanel saleQuantityLcdStackPanel = new StackPanel { Orientation = Orientation.Horizontal };
                petrolPump.LitersPlaceholder.Children.Add(saleQuantityLcdStackPanel);
                this.listeners.Add(saleQuantityLcd.Listen(t => petrolPump.Dispatcher.InvokeIfNecessary(() => petrolPump.SetLcdDigits(saleQuantityLcdStackPanel, t, 5, true))));

                StackPanel priceLcd1StackPanel = new StackPanel { Orientation = Orientation.Horizontal };
                petrolPump.Fuel1Placeholder.Children.Add(priceLcd1StackPanel);
                this.listeners.Add(priceLcd1.Listen(t => petrolPump.Dispatcher.InvokeIfNecessary(() => petrolPump.SetLcdDigits(priceLcd1StackPanel, t, 5, false))));

                StackPanel priceLcd2StackPanel = new StackPanel { Orientation = Orientation.Horizontal };
                petrolPump.Fuel2Placeholder.Children.Add(priceLcd2StackPanel);
                this.listeners.Add(priceLcd2.Listen(t => petrolPump.Dispatcher.InvokeIfNecessary(() => petrolPump.SetLcdDigits(priceLcd2StackPanel, t, 5, false))));

                StackPanel priceLcd3StackPanel = new StackPanel { Orientation = Orientation.Horizontal };
                petrolPump.Fuel3Placeholder.Children.Add(priceLcd3StackPanel);
                this.listeners.Add(priceLcd3.Listen(t => petrolPump.Dispatcher.InvokeIfNecessary(() => petrolPump.SetLcdDigits(priceLcd3StackPanel, t, 5, false))));

                Dictionary<CellLoop<UpDown>, Image> nozzles = new Dictionary<CellLoop<UpDown>, Image>
                {
                    { nozzle1, petrolPump.Nozzle1Image },
                    { nozzle2, petrolPump.Nozzle2Image },
                    { nozzle3, petrolPump.Nozzle3Image }
                };
                this.listeners.AddRange(nozzles.Select(nozzle => nozzle.Key.Listen(p => petrolPump.Dispatcher.InvokeIfNecessary(() => nozzle.Value.Margin = p == UpDown.Up ? new Thickness(0, 0, 0, 0) : new Thickness(0, 30, 0, 0)))));

                foreach (KeyValuePair<CellLoop<UpDown>, Image> nozzle in nozzles)
                {
                    StreamSink<Unit> nozzleClicks = new StreamSink<Unit>();
                    nozzle.Value.MouseDown += async (sender, args) =>
                    {
                        if (args.LeftButton == MouseButtonState.Pressed)
                        {
                            await Task.Run(() => nozzleClicks.Send(Unit.Value));
                        }
                    };
                    nozzle.Key.Loop(nozzleClicks.Snapshot(nozzle.Key, (_, n) => n == UpDown.Down ? UpDown.Up : UpDown.Down).Hold(UpDown.Down));
                }

                this.listeners.Add(sSaleComplete.Listen(sale =>
                {
                    Task.Run(() =>
                    {
                        petrolPump.Dispatcher.InvokeIfNecessary(() =>
                        {
                            SaleCompleteDialog dialog = new SaleCompleteDialog(
                                sale.Fuel.ToString(),
                                Formatters.FormatPrice(sale.Price, null),
                                Formatters.FormatSaleCost(sale.Cost),
                                Formatters.FormatSaleQuantity(sale.Quantity));
                            dialog.Owner = petrolPump;
                            csClearSale.Send(dialog.SOkClicked);
                            dialog.Show();
                            IListener l = null;
                            // ReSharper disable once RedundantAssignment
                            l = dialog.SOkClicked.Listen(_ =>
                            {
                                petrolPump.Dispatcher.InvokeIfNecessary(() => dialog.Close());

                                // ReSharper disable once AccessToModifiedClosure
                                using (l)
                                {
                                }
                            });
                        });
                    });
                }));

                Task.Run(async () =>
                {
                    while (true)
                    {
                        Transaction.RunVoid(() =>
                        {
                            switch (delivery.Sample())
                            {
                                case Delivery.Fast1:
                                case Delivery.Fast2:
                                case Delivery.Fast3:
                                    sFuelPulses.Send(40);
                                    break;
                                case Delivery.Slow1:
                                case Delivery.Slow2:
                                case Delivery.Slow3:
                                    sFuelPulses.Send(2);
                                    break;
                            }
                        });

                        await Task.Delay(200).ConfigureAwait(false);
                    }
                    // ReSharper disable once FunctionNeverReturns
                });
            }
Ejemplo n.º 21
0
 public void TestHoldImplicitDelay()
 {
     StreamSink<char> s = new StreamSink<char>();
     Cell<char> b = s.Hold(' ');
     List<char> @out = new List<char>();
     using (s.Snapshot(b).Listen(@out.Add))
     {
         s.Send('C');
         s.Send('B');
         s.Send('A');
     }
     CollectionAssert.AreEqual(new[] { ' ', 'C', 'B' }, @out);
 }
Ejemplo n.º 22
0
            public Implementation(PetrolPumpWindow petrolPump)
            {
                SComboBox <IPump> logic = new SComboBox <IPump>(
                    new IPump[]
                {
                    new LifeCyclePump(),
                    new AccumulatePulsesPump(),
                    new ShowDollarsPump(),
                    new ClearSalePump(),
                    new KeypadPump(),
                    new PresetAmountPump()
                },
                    p => p.GetType().FullName);

                petrolPump.LogicComboBoxPlaceholder.Children.Add(logic);

                STextField textPrice1 = new STextField("2.149")
                {
                    Width = 100
                };

                petrolPump.Price1Placeholder.Children.Add(textPrice1);

                STextField textPrice2 = new STextField("2.341")
                {
                    Width = 100
                };

                petrolPump.Price2Placeholder.Children.Add(textPrice2);

                STextField textPrice3 = new STextField("1.499")
                {
                    Width = 100
                };

                petrolPump.Price3Placeholder.Children.Add(textPrice3);

                Func <string, double> parseDoubleSafe = s =>
                {
                    double n;
                    if (double.TryParse(s, out n))
                    {
                        return(n);
                    }

                    return(0.0);
                };

                StreamSink <Key> sKey = new StreamSink <Key>();
                Dictionary <Key, FrameworkElement> containersByKey = new Dictionary <Key, FrameworkElement>
                {
                    { Key.One, petrolPump.Keypad1Button },
                    { Key.Two, petrolPump.Keypad2Button },
                    { Key.Three, petrolPump.Keypad3Button },
                    { Key.Four, petrolPump.Keypad4Button },
                    { Key.Five, petrolPump.Keypad5Button },
                    { Key.Six, petrolPump.Keypad6Button },
                    { Key.Seven, petrolPump.Keypad7Button },
                    { Key.Eight, petrolPump.Keypad8Button },
                    { Key.Nine, petrolPump.Keypad9Button },
                    { Key.Zero, petrolPump.Keypad0Button },
                    { Key.Clear, petrolPump.KeypadClearButton }
                };

                foreach (KeyValuePair <Key, FrameworkElement> containerAndKey in containersByKey)
                {
                    containerAndKey.Value.MouseDown += async(sender, args) =>
                    {
                        if (args.LeftButton == MouseButtonState.Pressed)
                        {
                            await Task.Run(() => sKey.Send(containerAndKey.Key));
                        }
                    };
                }

                DiscreteCellLoop <UpDown> nozzle1 = new DiscreteCellLoop <UpDown>();
                DiscreteCellLoop <UpDown> nozzle2 = new DiscreteCellLoop <UpDown>();
                DiscreteCellLoop <UpDown> nozzle3 = new DiscreteCellLoop <UpDown>();

                DiscreteCell <double>             calibration = DiscreteCell.Constant(0.001);
                DiscreteCell <double>             price1      = textPrice1.Text.Map(parseDoubleSafe);
                DiscreteCell <double>             price2      = textPrice2.Text.Map(parseDoubleSafe);
                DiscreteCell <double>             price3      = textPrice3.Text.Map(parseDoubleSafe);
                DiscreteCellSink <Stream <Unit> > csClearSale = new DiscreteCellSink <Stream <Unit> >(Sodium.Stream.Never <Unit>());
                Stream <Unit> sClearSale = csClearSale.SwitchS();

                StreamSink <int> sFuelPulses = new StreamSink <int>();
                Cell <Outputs>   outputs     = logic.SelectedItem.Map(
                    pump => pump.Create(new Inputs(
                                            nozzle1.Updates,
                                            nozzle2.Updates,
                                            nozzle3.Updates,
                                            sKey,
                                            sFuelPulses,
                                            calibration,
                                            price1,
                                            price2,
                                            price3,
                                            sClearSale)));

                DiscreteCell <Delivery> delivery        = outputs.Map(o => o.Delivery).SwitchC();
                DiscreteCell <string>   presetLcd       = outputs.Map(o => o.PresetLcd).SwitchC();
                DiscreteCell <string>   saleCostLcd     = outputs.Map(o => o.SaleCostLcd).SwitchC();
                DiscreteCell <string>   saleQuantityLcd = outputs.Map(o => o.SaleQuantityLcd).SwitchC();
                DiscreteCell <string>   priceLcd1       = outputs.Map(o => o.PriceLcd1).SwitchC();
                DiscreteCell <string>   priceLcd2       = outputs.Map(o => o.PriceLcd2).SwitchC();
                DiscreteCell <string>   priceLcd3       = outputs.Map(o => o.PriceLcd3).SwitchC();
                Stream <Unit>           sBeep           = outputs.Map(o => o.SBeep).SwitchS();
                Stream <Sale>           sSaleComplete   = outputs.Map(o => o.SSaleComplete).SwitchS();

                SoundPlayer beepPlayer = new SoundPlayer(GetResourceStream(@"sounds\beep.wav"));

                this.listeners.Add(sBeep.Listen(_ => new Thread(() => beepPlayer.PlaySync())
                {
                    IsBackground = true
                }.Start()));

                SoundPlayer fastRumblePlayer = new SoundPlayer(GetResourceStream(@"sounds\fast.wav"));
                Action      stopFast         = () => { };

                void PlayFast()
                {
                    ManualResetEvent mre = new ManualResetEvent(false);

                    new Thread(() =>
                    {
                        fastRumblePlayer.PlayLooping();
                        mre.WaitOne();
                        fastRumblePlayer.Stop();
                    })
                    {
                        IsBackground = true
                    }.Start();
                    stopFast = () =>
                    {
                        mre.Set();
                        stopFast = () => { };
                    };
                }

                SoundPlayer slowRumblePlayer = new SoundPlayer(GetResourceStream(@"sounds\slow.wav"));
                Action      stopSlow         = () => { };

                void PlaySlow()
                {
                    ManualResetEvent mre = new ManualResetEvent(false);

                    new Thread(() =>
                    {
                        slowRumblePlayer.PlayLooping();
                        mre.WaitOne();
                        slowRumblePlayer.Stop();
                    })
                    {
                        IsBackground = true
                    }.Start();
                    stopSlow = () =>
                    {
                        mre.Set();
                        stopSlow = () => { };
                    };
                }

                this.listeners.Add(delivery.Changes().Listen(d =>
                {
                    petrolPump.Dispatcher.InvokeIfNecessary(() =>
                    {
                        if (d == Delivery.Fast1 || d == Delivery.Fast2 || d == Delivery.Fast3)
                        {
                            PlayFast();
                        }
                        else
                        {
                            stopFast();
                        }

                        if (d == Delivery.Slow1 || d == Delivery.Slow2 || d == Delivery.Slow3)
                        {
                            PlaySlow();
                        }
                        else
                        {
                            stopSlow();
                        }
                    });
                }));

                StackPanel presetLcdStackPanel = new StackPanel {
                    Orientation = Orientation.Horizontal
                };

                petrolPump.PresetPlaceholder.Children.Add(presetLcdStackPanel);
                this.listeners.Add(presetLcd.Listen(t => petrolPump.Dispatcher.InvokeIfNecessary(() => petrolPump.SetLcdDigits(presetLcdStackPanel, t, 5, true))));

                StackPanel saleCostStackPanel = new StackPanel {
                    Orientation = Orientation.Horizontal
                };

                petrolPump.DollarsPlaceholder.Children.Add(saleCostStackPanel);
                this.listeners.Add(saleCostLcd.Listen(t => petrolPump.Dispatcher.InvokeIfNecessary(() => petrolPump.SetLcdDigits(saleCostStackPanel, t, 5, true))));

                StackPanel saleQuantityLcdStackPanel = new StackPanel {
                    Orientation = Orientation.Horizontal
                };

                petrolPump.LitersPlaceholder.Children.Add(saleQuantityLcdStackPanel);
                this.listeners.Add(saleQuantityLcd.Listen(t => petrolPump.Dispatcher.InvokeIfNecessary(() => petrolPump.SetLcdDigits(saleQuantityLcdStackPanel, t, 5, true))));

                StackPanel priceLcd1StackPanel = new StackPanel {
                    Orientation = Orientation.Horizontal
                };

                petrolPump.Fuel1Placeholder.Children.Add(priceLcd1StackPanel);
                this.listeners.Add(priceLcd1.Listen(t => petrolPump.Dispatcher.InvokeIfNecessary(() => petrolPump.SetLcdDigits(priceLcd1StackPanel, t, 5, false))));

                StackPanel priceLcd2StackPanel = new StackPanel {
                    Orientation = Orientation.Horizontal
                };

                petrolPump.Fuel2Placeholder.Children.Add(priceLcd2StackPanel);
                this.listeners.Add(priceLcd2.Listen(t => petrolPump.Dispatcher.InvokeIfNecessary(() => petrolPump.SetLcdDigits(priceLcd2StackPanel, t, 5, false))));

                StackPanel priceLcd3StackPanel = new StackPanel {
                    Orientation = Orientation.Horizontal
                };

                petrolPump.Fuel3Placeholder.Children.Add(priceLcd3StackPanel);
                this.listeners.Add(priceLcd3.Listen(t => petrolPump.Dispatcher.InvokeIfNecessary(() => petrolPump.SetLcdDigits(priceLcd3StackPanel, t, 5, false))));

                Dictionary <DiscreteCellLoop <UpDown>, Image> nozzles = new Dictionary <DiscreteCellLoop <UpDown>, Image>
                {
                    { nozzle1, petrolPump.Nozzle1Image },
                    { nozzle2, petrolPump.Nozzle2Image },
                    { nozzle3, petrolPump.Nozzle3Image }
                };

                this.listeners.AddRange(nozzles.Select(nozzle => nozzle.Key.Listen(p => petrolPump.Dispatcher.InvokeIfNecessary(() => nozzle.Value.Margin = p == UpDown.Up ? new Thickness(0, 0, 0, 0) : new Thickness(0, 30, 0, 0)))));

                foreach (KeyValuePair <DiscreteCellLoop <UpDown>, Image> nozzle in nozzles)
                {
                    StreamSink <Unit> nozzleClicks = new StreamSink <Unit>();
                    nozzle.Value.MouseDown += async(sender, args) =>
                    {
                        if (args.LeftButton == MouseButtonState.Pressed)
                        {
                            await Task.Run(() => nozzleClicks.Send(Unit.Value));
                        }
                    };
                    nozzle.Key.Loop(nozzleClicks.Snapshot(nozzle.Key, (_, n) => n == UpDown.Down ? UpDown.Up : UpDown.Down).Hold(UpDown.Down));
                }

                this.listeners.Add(sSaleComplete.Listen(sale =>
                {
                    Task.Run(() =>
                    {
                        petrolPump.Dispatcher.InvokeIfNecessary(() =>
                        {
                            SaleCompleteDialog dialog = new SaleCompleteDialog(
                                sale.Fuel.ToString(),
                                Formatters.FormatPrice(sale.Price, null),
                                Formatters.FormatSaleCost(sale.Cost),
                                Formatters.FormatSaleQuantity(sale.Quantity));
                            dialog.Owner = petrolPump;
                            csClearSale.Send(dialog.SOkClicked);
                            dialog.Show();
                            IListener l = null;
                            // ReSharper disable once RedundantAssignment
                            l = dialog.SOkClicked.Listen(_ =>
                            {
                                petrolPump.Dispatcher.InvokeIfNecessary(() => dialog.Close());

                                // ReSharper disable once AccessToModifiedClosure
                                l?.Unlisten();
                            });
                        });
                    });
                }));

                Task.Run(async() =>
                {
                    while (true)
                    {
                        Transaction.RunVoid(() =>
                        {
                            switch (delivery.Cell.Sample())
                            {
                            case Delivery.Fast1:
                            case Delivery.Fast2:
                            case Delivery.Fast3:
                                sFuelPulses.Send(40);
                                break;

                            case Delivery.Slow1:
                            case Delivery.Slow2:
                            case Delivery.Slow3:
                                sFuelPulses.Send(2);
                                break;
                            }
                        });

                        await Task.Delay(200).ConfigureAwait(false);
                    }
                    // ReSharper disable once FunctionNeverReturns
                });
            }