Пример #1
0
        public void TestMapMemory()
        {
            int? beforeListenerCount = null;
            int? duringListenerCount = null;
            int? afterListenerCount = null;

            StreamSink<int> s = new StreamSink<int>();
            Stream<string> m = s.Map(x => (x + 2).ToString());
            List<string> @out = new List<string>();

            dotMemory.Check(memory => beforeListenerCount = memory.GetObjects(where => where.Interface.Is<IListener>()).ObjectsCount);

            ((Action)(() =>
            {
                using (m.Listen(@out.Add))
                {
                    dotMemory.Check(memory => duringListenerCount = memory.GetObjects(where => where.Interface.Is<IListener>()).ObjectsCount);
                    s.Send(5);
                    s.Send(3);
                }
                CollectionAssert.AreEqual(new[] { "7", "5" }, @out);
            }))();

            dotMemory.Check(memory => afterListenerCount = memory.GetObjects(where => where.Interface.Is<IListener>()).ObjectsCount);

            Assert.IsNotNull(beforeListenerCount);
            Assert.IsNotNull(duringListenerCount);
            Assert.IsNotNull(afterListenerCount);

            Assert.AreEqual(beforeListenerCount, afterListenerCount, "Before == After");
            Assert.IsTrue(duringListenerCount > beforeListenerCount, "During > Before");
        }
Пример #2
0
 public void TestCoalesce2()
 {
     StreamSink<int> s = new StreamSink<int>((x, y) => x + y);
     List<int> @out = new List<int>();
     using (s.Listen(@out.Add))
     {
         Transaction.RunVoid(() =>
         {
             s.Send(1);
             s.Send(2);
             s.Send(3);
             s.Send(4);
             s.Send(5);
         });
         Transaction.RunVoid(() =>
         {
             s.Send(6);
             s.Send(7);
             s.Send(8);
             s.Send(9);
             s.Send(10);
         });
     }
     CollectionAssert.AreEqual(new[] { 15, 40 }, @out.ToArray());
 }
Пример #3
0
 public void TestBaseSend1()
 {
     StreamSink<string> s = new StreamSink<string>();
     List<string> @out = new List<string>();
     using (s.Listen(@out.Add))
     {
         s.Send("a");
         s.Send("b");
     }
     CollectionAssert.AreEqual(new[] { "a", "b" }, @out);
 }
Пример #4
0
 public void TestHoldUpdates()
 {
     StreamSink<int> s = new StreamSink<int>();
     Cell<int> c = s.Hold(0);
     List<int> @out = new List<int>();
     using (Operational.Updates(c).Listen(@out.Add))
     {
         s.Send(2);
         s.Send(9);
     }
     CollectionAssert.AreEqual(new[] { 2, 9 }, @out);
 }
Пример #5
0
 public void TestHold()
 {
     StreamSink<int> e = new StreamSink<int>();
     Cell<int> b = e.Hold(0);
     List<int> @out = new List<int>();
     using (b.Listen(@out.Add))
     {
         e.Send(2);
         e.Send(9);
     }
     CollectionAssert.AreEqual(new[] { 0, 2, 9 }, @out);
 }
Пример #6
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);
 }
Пример #7
0
 public void Run()
 {
     StreamSink<int> sX = new StreamSink<int>();
     Stream<int> sXPlus1 = sX.Map(x => x + 1);
     using (Transaction.Run(() =>
     {
         sX.Send(1);
         return sXPlus1.Listen(Console.WriteLine);
     }))
     {
         sX.Send(2);
         sX.Send(3);
     }
 }
Пример #8
0
 public void TestAccum()
 {
     StreamSink<int> sa = new StreamSink<int>();
     List<int> @out = new List<int>();
     Cell<int> sum = sa.Accum(100, (a, s) => a + s);
     using (sum.Listen(@out.Add))
     {
         sa.Send(5);
         sa.Send(7);
         sa.Send(1);
         sa.Send(2);
         sa.Send(3);
     }
     CollectionAssert.AreEqual(new[] { 100, 105, 112, 113, 115, 118 }, @out);
 }
Пример #9
0
        public void TestNestedMapGarbageCollection()
        {
            int? beforeStreamCount = null;
            int? beforeListenerCount = null;
            int? duringStreamCount = null;
            int? duringListenerCount = null;
            int? afterStreamCount = null;
            int? afterListenerCount = null;

            StreamSink<int> s = new StreamSink<int>();
            List<string> @out = new List<string>();

            dotMemory.Check(memory => beforeStreamCount = memory.GetObjects(where => where.Type.Is<Stream<int>>()).ObjectsCount + memory.GetObjects(where => where.Type.Is<Stream<string>>()).ObjectsCount);
            dotMemory.Check(memory => beforeListenerCount = memory.GetObjects(where => where.Interface.Is<IListener>()).ObjectsCount);

            ((Action)(() =>
            {
                Stream<string> m = s.Map(x => x + 2).Map(x => 2 * x).Map(x => x + 1).Map(x => x.ToString());
                using (m.Listen(@out.Add))
                {
                    dotMemory.Check(memory => duringStreamCount = memory.GetObjects(where => where.Type.Is<Stream<int>>()).ObjectsCount + memory.GetObjects(where => where.Type.Is<Stream<string>>()).ObjectsCount);
                    dotMemory.Check(memory => duringListenerCount = memory.GetObjects(where => where.Interface.Is<IListener>()).ObjectsCount);
                    s.Send(5);
                    s.Send(3);
                }
                CollectionAssert.AreEqual(new[] { "15", "11" }, @out);
            }))();

            dotMemory.Check(memory => afterStreamCount = memory.GetObjects(where => where.Type.Is<Stream<int>>()).ObjectsCount + memory.GetObjects(where => where.Type.Is<Stream<string>>()).ObjectsCount);
            dotMemory.Check(memory => afterListenerCount = memory.GetObjects(where => where.Interface.Is<IListener>()).ObjectsCount);

            // although all listeners and streams have been cleand up, the nodes will not be disconnected until the stream fires next
            Assert.AreEqual(1, s.Node.GetListeners().Count);
            s.Send(1);
            Assert.AreEqual(0, s.Node.GetListeners().Count);

            Assert.IsNotNull(beforeStreamCount);
            Assert.IsNotNull(beforeListenerCount);
            Assert.IsNotNull(duringStreamCount);
            Assert.IsNotNull(duringListenerCount);
            Assert.IsNotNull(afterStreamCount);
            Assert.IsNotNull(afterListenerCount);

            Assert.AreEqual(beforeStreamCount, afterStreamCount, "Before Streams == After Streams");
            Assert.AreEqual(beforeListenerCount, afterListenerCount, "Before Listeners == After Listeners");
            Assert.IsTrue(duringStreamCount > beforeStreamCount, "During Streams > Before Streams");
            Assert.IsTrue(duringListenerCount > beforeListenerCount, "During Listeners > Before Listeners");
        }
Пример #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);
 }
Пример #11
0
 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);
 }
Пример #12
0
 public void TestOperationalDeferSimultaneous()
 {
     StreamSink<string> a = new StreamSink<string>();
     StreamSink<string> b = new StreamSink<string>();
     Stream<string> c = Operational.Defer(a).OrElse(Operational.Defer(b));
     List<string> @out = new List<string>();
     using (c.Listen(@out.Add))
     {
         b.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" }, out2);
 }
Пример #13
0
        public SButton(Cell<bool> enabled)
        {
            StreamSink<Unit> sClickedSink = new StreamSink<Unit>();
            this.SClicked = sClickedSink;
            this.Click += (sender, args) => sClickedSink.Send(Unit.Value);

            // Set the initial value at the end of the transaction so it works with CellLoops.
            Transaction.Post(() => this.IsEnabled = enabled.Sample());

            // ReSharper disable once UseObjectOrCollectionInitializer
            List<IListener> listeners = new List<IListener>();
            listeners.Add(Operational.Updates(enabled).Listen(e => this.Dispatcher.InvokeIfNecessary(() => this.IsEnabled = e)));
            this.listeners = listeners;
        }
Пример #14
0
 public FrView(Window window, Fridget fr, IListener l)
 {
     StreamSink<MouseEvent> sMouse = new StreamSink<MouseEvent>();
     StreamSink<KeyEvent> sKey = new StreamSink<KeyEvent>();
     this.MouseDown += (sender, args) => sMouse.Send(new MouseEvent(args, () => args.GetPosition(this)));
     this.MouseUp += (sender, args) => sMouse.Send(new MouseEvent(args, () => args.GetPosition(this)));
     this.MouseMove += (sender, args) => sMouse.Send(new MouseEvent(args, () => args.GetPosition(this)));
     CellSink<IMaybe<Size>> size = new CellSink<IMaybe<Size>>(Maybe.Nothing<Size>());
     this.SizeChanged += (sender, args) => size.Send(Maybe.Just(args.NewSize));
     window.KeyDown += (sender, args) =>
     {
         Key key = args.Key == Key.System ? args.SystemKey : args.Key;
         if (key == Key.Back)
         {
             sKey.Send(new BackspaceKeyEvent());
         }
     };
     window.TextInput += (sender, args) => sKey.Send(new StringKeyEvent(args.Text));
     CellLoop<long> focus = new CellLoop<long>();
     Fridget.Output fo = fr.Reify(size, sMouse, sKey, focus, new Supply());
     focus.Loop(fo.SChangeFocus.Hold(-1));
     this.drawable = fo.Drawable;
     this.l = new ImmutableCompositeListener(new[] { l, Operational.Updates(this.drawable).Listen(d => this.InvalidateVisual()) });
 }
Пример #15
0
            public async Task Run()
            {
                Console.WriteLine("*** test 1");
                {
                    StreamSink<string> s1 = new StreamSink<string>();
                    Task<string> t1 = s1.ListenOnce();
                    s1.Send("Early");
                    Console.WriteLine(await t1);
                }

                Console.WriteLine();

                Console.WriteLine("*** test 2");
                {
                    StreamSink<string> s1 = new StreamSink<string>();
                    Task t1 = s1.ListenOnce().ContinueWith(t => Console.WriteLine(t.Result), TaskContinuationOptions.ExecuteSynchronously);
                    s1.Send("Late");
                    await t1;
                }
            }
Пример #16
0
        public void TestOrElseSimultaneous1()
        {
            StreamSink <int> s1   = Stream.CreateSink <int>((_, r) => r);
            StreamSink <int> s2   = Stream.CreateSink <int>((_, r) => r);
            List <int>       @out = new List <int>();
            IListener        l    = s2.OrElse(s1).Listen(@out.Add);

            Transaction.RunVoid(() =>
            {
                s1.Send(7);
                s2.Send(60);
            });
            Transaction.RunVoid(() =>
            {
                s1.Send(9);
            });
            Transaction.RunVoid(() =>
            {
                s1.Send(7);
                s1.Send(60);
                s2.Send(8);
                s2.Send(90);
            });
            Transaction.RunVoid(() =>
            {
                s2.Send(8);
                s2.Send(90);
                s1.Send(7);
                s1.Send(60);
            });
            Transaction.RunVoid(() =>
            {
                s2.Send(8);
                s1.Send(7);
                s2.Send(90);
                s1.Send(60);
            });
            l.Unlisten();
            CollectionAssert.AreEqual(new[] { 60, 9, 90, 90, 90 }, @out);
        }
Пример #17
0
        public SButton(Cell <Square> square)
        {
            StreamSink <Unit> sClickedSink = Stream.CreateSink <Unit>();

            SClicked = sClickedSink;
            Click   += (sender, args) => sClickedSink.Send(Unit.Value);

            StreamSink <Unit> sClickedRightSink = Stream.CreateSink <Unit>();

            SClickedRight         = sClickedRightSink;
            MouseRightButtonDown += (sender, args) => sClickedRightSink.Send(Unit.Value);

            // Set the initial value at the end of the transaction so it works with CellLoops.
            Transaction.Post(() =>
            {
                var sample = square.Sample();

                Content    = sample.Content;
                FontWeight = sample.FontWeight;
                Foreground = sample.Foreground;
                Background = sample.Background;
                IsEnabled  = sample.IsEnabled;
            });

            // ReSharper disable once UseObjectOrCollectionInitializer
            List <IListener> listeners = new List <IListener>();

            listeners.Add(square.Updates().Listen(e => Dispatcher.InvokeIfNecessary(() =>
            {
                Content    = e.Content;
                FontWeight = e.FontWeight;
                Foreground = e.Foreground;
                Background = e.Background;
                IsEnabled  = e.IsEnabled;
            })));
            this.listeners = listeners;
        }
Пример #18
0
        public void SwitchEarlySCatchFirst()
        {
            List <int> output = new List <int>();

            ValueTuple <Stream <int>, StreamSink <int>, StreamSink <int>, CellSink <Stream <int> >, IListener> t = Transaction.Run(() =>
            {
                StreamSink <int> c1        = Stream.CreateSink <int>();
                StreamSink <int> c2        = Stream.CreateSink <int>();
                CellSink <Stream <int> > s = Cell.CreateSink(c1.AsStream());
                Stream <int> c             = s.SwitchEarlyS();

                c1.Send(2);
                c2.Send(12);
                s.Send(c2);

                IListener l = c.Listen(output.Add);

                return(ValueTuple.Create(c, c1, c2, s, l));
            });

            t.Item2.Send(3);
            t.Item3.Send(13);

            Transaction.RunVoid(() =>
            {
                t.Item2.Send(4);
                t.Item3.Send(14);
                t.Item4.Send(t.Item2);
            });

            t.Item2.Send(5);
            t.Item3.Send(15);

            t.Item5.Unlisten();

            CollectionAssert.AreEqual(new[] { 12, 13, 4, 5 }, output);
        }
Пример #19
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();
            };
        }
Пример #20
0
        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);
        }
Пример #21
0
        public void TestListenWeakWithMap()
        {
            StreamSink <int> s = Stream.CreateSink <int>();

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

            ((Action)(() =>
            {
                Stream <int> s2 = s.Map(v => v + 1);

                ((Action)(() =>
                {
                    // ReSharper disable once UnusedVariable
                    IWeakListener l = s2.ListenWeak(@out.Add);

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

                GC.Collect(0, GCCollectionMode.Forced);

                ((Action)(() =>
                {
                    // ReSharper disable once UnusedVariable
                    IWeakListener l = s2.ListenWeak(@out.Add);

                    s.Send(3);
                    s.Send(4);
                    s.Send(5);
                }))();
            }))();

            GC.Collect(0, GCCollectionMode.Forced);
            s.Send(6);
            s.Send(7);

            Assert.AreEqual(5, @out.Count);
        }
Пример #22
0
            public async Task Run()
            {
                Console.WriteLine("*** test");
                {
                    StreamSink<string> s1 = new StreamSink<string>();
                    Task<string> t1 = s1.ListenOnce();

                    new Thread(() =>
                    {
                        s1.Send("Sent");
                    }).Start();

                    Console.WriteLine(await t1);
                }
            }
Пример #23
0
            public async Task Run()
            {
                Console.WriteLine("*** Simple test");
                {
                    StreamSink<string> sa = new StreamSink<string>();
                    StreamSink<string> sb = new StreamSink<string>();
                    Task<string> ta = sa.ListenOnce();
                    Task<string> tb = sb.ListenOnce();

                    new Thread(() =>
                    {
                        sa.Send("Hello");
                        sb.Send("World");
                    }).Start();

                    Console.WriteLine(await ta + " " + await tb);
                }

                Console.WriteLine();

                Console.WriteLine("*** Simultaneous case");
                {
                    StreamSink<string> sa = new StreamSink<string>();
                    StreamSink<string> sb = new StreamSink<string>();
                    Task<string> ta = sa.ListenOnce();
                    Task<string> tb = sb.ListenOnce();

                    new Thread(() =>
                    {
                        Transaction.RunVoid(() =>
                        {
                            sa.Send("Hello");
                            sb.Send("World");
                        });
                    }).Start();

                    Console.WriteLine(await ta + " " + await tb);
                }
            }
Пример #24
0
        private static Tuple <Stream <T>, Dictionary <int, Action> > MkStream <T>(Dictionary <int, T> firings)
        {
            StreamSink <T>           s = Stream.CreateSink <T>();
            Dictionary <int, Action> f = firings.ToDictionary(firing => firing.Key, firing => (Action)(() => s.Send(firing.Value)));

            if (f.Keys.Any(k => k < 0))
            {
                throw new InvalidOperationException("All firings must occur at T >= 0.");
            }
            Stream <T> returnStream = s;

            return(Tuple.Create(returnStream, f));
        }
Пример #25
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
                });
            }
Пример #26
0
            public async Task Run()
            {
                Console.WriteLine("*** Simple test");
                {
                    StreamSink<string> sa = new StreamSink<string>();
                    StreamSink<string> sb = new StreamSink<string>();
                    Task<string> ta = sa.ListenOnce();
                    Task<string> tb = sb.ListenOnce();
                    Func<Task<string>> t = async () => await ta + " " + await tb;
                    sa.Send("Hello");
                    Func<Task> task = () => t().ContinueWith(t1 => Console.WriteLine(t1.Result), TaskContinuationOptions.ExecuteSynchronously);
                    sb.Send("World");
                    await task();
                }

                Console.WriteLine();

                Console.WriteLine("*** Simultaneous case");
                {
                    StreamSink<string> sa = new StreamSink<string>();
                    StreamSink<string> sb = new StreamSink<string>();
                    Task<string> ta = sa.ListenOnce();
                    Task<string> tb = sb.ListenOnce();
                    Func<Task<string>> t = async () => await ta + " " + await tb;
                    Func<Task> task = () => t().ContinueWith(t1 => Console.WriteLine(t1.Result), TaskContinuationOptions.ExecuteSynchronously);
                    Transaction.RunVoid(() =>
                    {
                        sa.Send("Hello");
                        sb.Send("World");
                    });
                    await task();
                }
            }
Пример #27
0
 public void TestOrElseLeftBias()
 {
     StreamSink<int> s = new StreamSink<int>();
     Stream<int> s2 = s.Map(x => 2 * x);
     List<int> @out = new List<int>();
     using (s2.OrElse(s).Listen(@out.Add))
     {
         s.Send(7);
         s.Send(9);
     }
     CollectionAssert.AreEqual(new[] { 14, 18 }, @out);
 }
Пример #28
0
        private static Tuple <Stream <T>, ILookup <int, Action> > MkStream <T>(IReadOnlyList <Tuple <int, T> > firings, Func <T, T, T> coalesce)
        {
            StreamSink <T>        s = Stream.CreateSink <T>(coalesce);
            ILookup <int, Action> f = firings.ToLookup(firing => firing.Item1, firing => (Action)(() => s.Send(firing.Item2)));

            if (f.Any(g => g.Key < 0))
            {
                throw new InvalidOperationException("All firings must occur at T >= 0.");
            }
            Stream <T> returnStream = s;

            return(Tuple.Create(returnStream, f));
        }
Пример #29
0
 public void TestCollect()
 {
     StreamSink<int> sa = new StreamSink<int>();
     List<int> @out = new List<int>();
     Stream<int> sum = sa.Collect(Tuple.Create(100, true), (a, s) =>
     {
         int outputValue = s.Item1 + (s.Item2 ? a * 3 : a);
         return Tuple.Create(outputValue, Tuple.Create(outputValue, outputValue % 2 == 0));
     });
     using (sum.Listen(@out.Add))
     {
         sa.Send(5);
         sa.Send(7);
         sa.Send(1);
         sa.Send(2);
         sa.Send(3);
     }
     CollectionAssert.AreEqual(new[] { 115, 122, 125, 127, 130 }, @out);
 }
Пример #30
0
 public void TestDefer()
 {
     StreamSink<char> s = new StreamSink<char>();
     Cell<char> b = s.Hold(' ');
     List<char> @out = new List<char>();
     using (Operational.Defer(s).Snapshot(b).Listen(@out.Add))
     {
         s.Send('C');
         s.Send('B');
         s.Send('A');
     }
     CollectionAssert.AreEqual(new[] { 'C', 'B', 'A' }, @out);
 }
Пример #31
0
 public void TestStreamSend()
 {
     StreamSink<int> s = new StreamSink<int>();
     List<int> @out = new List<int>();
     using (s.Listen(@out.Add))
     {
         s.Send(5);
     }
     CollectionAssert.AreEqual(new[] { 5 }, @out);
     s.Send(6);
     CollectionAssert.AreEqual(new[] { 5 }, @out);
 }
Пример #32
0
        public void TestDiscreteCellLoopComplex()
        {
            StreamSink <int> s = new StreamSink <int>();
            StreamSink <Tuple <int, int> >             addItemStreamSink     = new StreamSink <Tuple <int, int> >();
            StreamSink <IReadOnlyList <TestObject> >   removeItemsStreamSink = new StreamSink <IReadOnlyList <TestObject> >();
            DiscreteCell <IReadOnlyList <TestObject> > listCell = Transaction.Run(() =>
            {
                DiscreteCellLoop <IReadOnlyList <TestObject> > listCellLoop = new DiscreteCellLoop <IReadOnlyList <TestObject> >();
                DiscreteCell <IReadOnlyList <TestObject> > listCellLocal    =
                    addItemStreamSink.OrElse(s.Map(v => Tuple.Create(v, v))).Map <Func <IReadOnlyList <TestObject>, IReadOnlyList <TestObject> > >(o => c => c.Concat(new[] { new TestObject(o.Item1, o.Item2) }).ToArray())
                    .Merge(removeItemsStreamSink.Map <Func <IReadOnlyList <TestObject>, IReadOnlyList <TestObject> > >(o => c => c.Except(o).ToArray()), (f, g) => c => g(f(c)))
                    .Snapshot(listCellLoop, (f, c) => f(c))
                    .Hold(new TestObject[0]);
                listCellLoop.Loop(listCellLocal);
                return(listCellLocal);
            });
            IListener l2 = Transaction.Run(() =>
            {
                return(listCell.Values.Listen(c => Transaction.Post(() =>
                {
                    if (c.Any())
                    {
                        Tuple <int, int> t = c.Last().BothNumbersCell.Cell.Sample();
                        if (t.Item1 == 9 && t.Item2 == 9)
                        {
                            addItemStreamSink.Send(Tuple.Create(0, 0));
                        }
                    }
                })));
            });
            IListener l3 = Transaction.Run(() =>
                                           listCell.Map(c => c.Select(o => o.RemoveStream.MapTo(new[] { o })).Merge((x, y) => x.Concat(y).ToArray())).SwitchS().Listen(o => Transaction.Post(() => removeItemsStreamSink.Send(o))));
            IListener l4 = Transaction.Run(() =>
                                           listCell.Map(c => c.Any() ? c.Last().Number1Cell.Lift(c.Last().Number2Cell, (x, y) => x == 9 && y == 9).Updates : Stream.Never <bool>()).SwitchS().Filter(v => v).Listen(_ => Transaction.Post(() => addItemStreamSink.Send(Tuple.Create(0, 0)))));
            List <IReadOnlyList <Tuple <int, int> > > @out = new List <IReadOnlyList <Tuple <int, int> > >();
            IListener l = listCell.Map(c => c.Select(o => o.Number1Cell.Lift(o.Number2Cell, Tuple.Create)).Lift()).SwitchC().Listen(@out.Add);

            addItemStreamSink.Send(Tuple.Create(5, 2));
            addItemStreamSink.Send(Tuple.Create(9, 2));
            listCell.Cell.Sample()[0].Remove();
            addItemStreamSink.Send(Tuple.Create(2, 9));
            listCell.Cell.Sample()[1].ChangeNumber1(9);
            addItemStreamSink.Send(Tuple.Create(9, 9));
            s.Send(5);
            s.Send(9);
            Transaction.RunVoid(() =>
            {
                addItemStreamSink.Send(Tuple.Create(5, 5));
                s.Send(5);
            });
            listCell.Cell.Sample()[8].ChangeNumber2(9);
            listCell.Cell.Sample()[8].ChangeNumber1(9);
            l.Unlisten();
            l2.Unlisten();
            l3.Unlisten();
            l4.Unlisten();

            Tuple <int, int>[][] expected =
            {
                new Tuple <int, int> [0],
                new[] { Tuple.Create(5,2) },
                new[] { Tuple.Create(5,2), Tuple.Create(9,   2) },
                new[] { Tuple.Create(9,2) },
                new[] { Tuple.Create(9,2), Tuple.Create(2,   9) },
                new[] { Tuple.Create(9,2), Tuple.Create(9,   9) },
                new[] { Tuple.Create(9,2), Tuple.Create(9, 9), Tuple.Create(0, 0) },
                new[] { Tuple.Create(9,2), Tuple.Create(9, 9), Tuple.Create(0, 0), Tuple.Create(9, 9) },
                new[] { Tuple.Create(9,2), Tuple.Create(9, 9), Tuple.Create(0, 0), Tuple.Create(9, 9), Tuple.Create(0, 0) },
                new[] { Tuple.Create(9,2), Tuple.Create(9, 9), Tuple.Create(0, 0), Tuple.Create(9, 9), Tuple.Create(0, 0), Tuple.Create(5, 5) },
                new[] { Tuple.Create(9,2), Tuple.Create(9, 9), Tuple.Create(0, 0), Tuple.Create(9, 9), Tuple.Create(0, 0), Tuple.Create(5, 5), Tuple.Create(9, 9) },
                new[] { Tuple.Create(9,2), Tuple.Create(9, 9), Tuple.Create(0, 0), Tuple.Create(9, 9), Tuple.Create(0, 0), Tuple.Create(5, 5), Tuple.Create(9, 9), Tuple.Create(0, 0) },
                new[] { Tuple.Create(9,2), Tuple.Create(9, 9), Tuple.Create(0, 0), Tuple.Create(9, 9), Tuple.Create(0, 0), Tuple.Create(5, 5), Tuple.Create(9, 9), Tuple.Create(0, 0), Tuple.Create(5, 5) },
                new[] { Tuple.Create(9,2), Tuple.Create(9, 9), Tuple.Create(0, 0), Tuple.Create(9, 9), Tuple.Create(0, 0), Tuple.Create(5, 5), Tuple.Create(9, 9), Tuple.Create(0, 0), Tuple.Create(5, 9) },
                new[] { Tuple.Create(9,2), Tuple.Create(9, 9), Tuple.Create(0, 0), Tuple.Create(9, 9), Tuple.Create(0, 0), Tuple.Create(5, 5), Tuple.Create(9, 9), Tuple.Create(0, 0), Tuple.Create(9, 9) },
                new[] { Tuple.Create(9,2), Tuple.Create(9, 9), Tuple.Create(0, 0), Tuple.Create(9, 9), Tuple.Create(0, 0), Tuple.Create(5, 5), Tuple.Create(9, 9), Tuple.Create(0, 0), Tuple.Create(9, 9), Tuple.Create(0, 0) }
            };
            Assert.AreEqual(expected.Length, @out.Count);
            for (int i = 0; i < 16; i++)
            {
                CollectionAssert.AreEqual(@out[i], expected[i]);
            }
        }
Пример #33
0
 public void TestOrElseSimultaneous2()
 {
     StreamSink<int> s = new StreamSink<int>();
     Stream<int> s2 = s.Map(x => 2 * x);
     List<int> @out = new List<int>();
     using (s.OrElse(s2).Listen(@out.Add))
     {
         s.Send(7);
         s.Send(9);
     }
     CollectionAssert.AreEqual(new[] { 7, 9 }, @out);
 }
Пример #34
0
 public void TestOrElseSimultaneous1()
 {
     StreamSink<int> s1 = new StreamSink<int>((l, r) => r);
     StreamSink<int> s2 = new StreamSink<int>((l, r) => r);
     List<int> @out = new List<int>();
     using (s2.OrElse(s1).Listen(@out.Add))
     {
         Transaction.RunVoid(() =>
         {
             s1.Send(7);
             s2.Send(60);
         });
         Transaction.RunVoid(() =>
         {
             s1.Send(9);
         });
         Transaction.RunVoid(() =>
         {
             s1.Send(7);
             s1.Send(60);
             s2.Send(8);
             s2.Send(90);
         });
         Transaction.RunVoid(() =>
         {
             s2.Send(8);
             s2.Send(90);
             s1.Send(7);
             s1.Send(60);
         });
         Transaction.RunVoid(() =>
         {
             s2.Send(8);
             s1.Send(7);
             s2.Send(90);
             s1.Send(60);
         });
     }
     CollectionAssert.AreEqual(new[] { 60, 9, 90, 90, 90 }, @out);
 }
Пример #35
0
        public void TestCalm()
        {
            StreamSink <int> s    = Stream.CreateSink <int>();
            List <int>       @out = new List <int>();
            IListener        l    = s.Calm().Listen(@out.Add);

            s.Send(2);
            s.Send(2);
            s.Send(2);
            s.Send(4);
            s.Send(2);
            s.Send(4);
            s.Send(4);
            s.Send(2);
            s.Send(2);
            s.Send(2);
            s.Send(2);
            s.Send(2);
            s.Send(4);
            s.Send(2);
            s.Send(4);
            s.Send(4);
            s.Send(2);
            s.Send(2);
            s.Send(2);
            s.Send(2);
            s.Send(2);
            s.Send(4);
            s.Send(2);
            s.Send(4);
            s.Send(4);
            s.Send(2);
            s.Send(2);
            s.Send(2);
            s.Send(2);
            s.Send(2);
            s.Send(4);
            s.Send(2);
            s.Send(4);
            s.Send(4);
            s.Send(2);
            s.Send(2);
            s.Send(2);
            s.Send(2);
            s.Send(2);
            s.Send(4);
            s.Send(2);
            s.Send(4);
            s.Send(4);
            s.Send(2);
            s.Send(2);
            l.Unlisten();
            CollectionAssert.AreEqual(new[] { 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2 }, @out);
        }
Пример #36
0
        public static Stream <IMaybe <string> > Lookup(Stream <string> sWord)
        {
            StreamSink <IMaybe <string> > sDefinition = new StreamSink <IMaybe <string> >();
            IListener listener = sWord.ListenWeak(wrd =>
            {
                Task.Run(() =>
                {
                    //System.out.println("look up " + wrd);
                    IMaybe <string> def = Maybe.Nothing <string>();
                    try
                    {
                        Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                        s.Connect("dict.org", 2628);
                        NetworkStream ns = new NetworkStream(s);
                        StreamReader r   = new StreamReader(ns);
                        StreamWriter w   = new StreamWriter(ns);
                        try
                        {
                            r.ReadLine();
                            w.WriteLine("DEFINE ! " + wrd);
                            w.Flush();

                            string result = r.ReadLine();

                            if (result != null && result.StartsWith("150"))
                            {
                                result = r.ReadLine();
                            }

                            if (result != null && result.StartsWith("151"))
                            {
                                StringBuilder b = new StringBuilder();
                                while (true)
                                {
                                    string l = r.ReadLine();
                                    if (l == ".")
                                    {
                                        break;
                                    }
                                    b.AppendLine(l);
                                }
                                def = Maybe.Just(b.ToString());
                            }
                            else
                            {
                                MessageBox.Show("ERROR: " + result);
                            }
                        }
                        finally
                        {
                            try
                            {
                                s.Close();
                                s.Dispose();
                            }
                            catch
                            {
                                // ignored
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        MessageBox.Show("ERROR: " + e);
                    }
                    finally
                    {
                        sDefinition.Send(def);
                    }
                });
            });

            return(sDefinition.AddCleanup(listener));
        }
Пример #37
0
        public void TestCalm()
        {
            StreamSink <int> s    = new StreamSink <int>();
            List <int>       @out = new List <int>();

            using (s.Calm().Listen(@out.Add))
            {
                s.Send(2);
                s.Send(2);
                s.Send(2);
                s.Send(4);
                s.Send(2);
                s.Send(4);
                s.Send(4);
                s.Send(2);
                s.Send(2);
                s.Send(2);
                s.Send(2);
                s.Send(2);
                s.Send(4);
                s.Send(2);
                s.Send(4);
                s.Send(4);
                s.Send(2);
                s.Send(2);
                s.Send(2);
                s.Send(2);
                s.Send(2);
                s.Send(4);
                s.Send(2);
                s.Send(4);
                s.Send(4);
                s.Send(2);
                s.Send(2);
                s.Send(2);
                s.Send(2);
                s.Send(2);
                s.Send(4);
                s.Send(2);
                s.Send(4);
                s.Send(4);
                s.Send(2);
                s.Send(2);
                s.Send(2);
                s.Send(2);
                s.Send(2);
                s.Send(4);
                s.Send(2);
                s.Send(4);
                s.Send(4);
                s.Send(2);
                s.Send(2);
            }
            CollectionAssert.AreEqual(new[] { 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2, 4, 2 }, @out);
        }
Пример #38
0
 public void TestOrElseNonSimultaneous()
 {
     StreamSink<int> s1 = new StreamSink<int>();
     StreamSink<int> s2 = new StreamSink<int>();
     List<int> @out = new List<int>();
     using (s1.OrElse(s2).Listen(@out.Add))
     {
         s1.Send(7);
         s2.Send(9);
         s1.Send(8);
     }
     CollectionAssert.AreEqual(new[] { 7, 9, 8 }, @out);
 }
Пример #39
0
 public void TestMergeSimultaneous()
 {
     StreamSink<int> s = new StreamSink<int>();
     Stream<int> s2 = s.Map(x => 2 * x);
     List<int> @out = new List<int>();
     using (s.Merge(s2, (x, y) => x + y).Listen(@out.Add))
     {
         s.Send(7);
         s.Send(9);
     }
     CollectionAssert.AreEqual(new[] { 21, 27 }, @out);
 }
Пример #40
0
 public SButton()
 {
     StreamSink<Unit> sClickedSink = new StreamSink<Unit>();
     this.SClicked = sClickedSink;
     this.Click += async (sender, args) => await Task.Run(() => sClickedSink.Send(Unit.Value));
 }
Пример #41
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
                });
            }
Пример #42
0
 public void TestOnce()
 {
     StreamSink<char> s = new StreamSink<char>();
     List<char> @out = new List<char>();
     using (s.Once().Listen(@out.Add))
     {
         s.Send('A');
         s.Send('B');
         s.Send('C');
     }
     CollectionAssert.AreEqual(new[] { 'A' }, @out);
 }
Пример #43
-1
        public STextBox(Stream<string> setText, string initText, Cell<bool> enabled)
        {
            base.Text = initText;

            List<IListener> listeners = new List<IListener>();

            StreamSink<int> sDecrement = new StreamSink<int>();
            Cell<bool> allow = setText.Map(_ => 1).OrElse(sDecrement).Accum(0, (b, d) => b + d).Map(b => b == 0);

            StreamSink<string> sUserChanges = new StreamSink<string>();
            this.SUserChanges = sUserChanges;
            this.Text = sUserChanges.Gate(allow).OrElse(setText).Hold(initText);

            TextChangedEventHandler textChangedEventHandler = (sender, args) =>
            {
                string text = base.Text;
                this.Dispatcher.InvokeAsync(() => sUserChanges.Send(text));
            };

            this.TextChanged += textChangedEventHandler;

            // Set the initial value at the end of the transaction so it works with CellLoops.
            Transaction.Post(() => this.Dispatcher.InvokeIfNecessary(() => this.IsEnabled = enabled.Sample()));

            listeners.Add(setText.Listen(t =>
            {
                this.Dispatcher.InvokeAsync(() =>
                {
                    this.TextChanged -= textChangedEventHandler;
                    base.Text = t;
                    this.TextChanged += textChangedEventHandler;
                    sDecrement.Send(-1);
                });
            }));

            listeners.Add(Operational.Updates(enabled).Listen(e => this.Dispatcher.InvokeIfNecessary(() => this.IsEnabled = e)));

            this.disposeListeners = () =>
            {
                foreach (IListener l in listeners)
                {
                    using (l)
                    {
                    }
                }
            };
        }