Exemple #1
0
 public FrFlow(Orientation dir, IEnumerable <Fridget> fridgets)
     : base((size, sMouse, sKey, focus, idSupply) =>
 {
     Cell <Size> desiredSize          = Cell.Constant(new Size(0, 0));
     Cell <DrawableDelegate> drawable = Cell.Constant(new DrawableDelegate(d => { }));
     Stream <long> sChangeFocus       = Stream.Never <long>();
     foreach (Fridget fridget in fridgets)
     {
         CellLoop <Maybe <Size> > childSz = new CellLoop <Maybe <Size> >();
         Output fo = new FrTranslate(fridget,
                                     dir == Orientation.Horizontal
                     ? desiredSize.Map(dsz => new Point(dsz.Width, 0))
                     : desiredSize.Map(dsz => new Point(0, dsz.Height)))
                     .Reify(childSz, sMouse, sKey, focus,
                            idSupply.Child1());
         idSupply = idSupply.Child2();
         childSz.Loop(
             size.Lift(fo.DesiredSize, (mSize, foDsz) =>
                       mSize.Map(s => dir == Orientation.Horizontal
                         ? new Size(foDsz.Width, s.Height)
                         : new Size(s.Width, foDsz.Height))));
         Size LiftDesiredSizeHorizontal(Size dsz, Size foDsz) => new Size(dsz.Width + foDsz.Width, dsz.Height > foDsz.Height ? dsz.Height : foDsz.Height);
         Size LiftDesiredSizeVertical(Size dsz, Size foDsz) => new Size(dsz.Width > foDsz.Width ? dsz.Width : foDsz.Width, dsz.Height + foDsz.Height);
         desiredSize  = desiredSize.Lift(fo.DesiredSize, dir == Orientation.Horizontal ? LiftDesiredSizeHorizontal : (Func <Size, Size, Size>)LiftDesiredSizeVertical);
         drawable     = drawable.Lift(fo.Drawable, (drA, drB) => drA.Append(drB));
         sChangeFocus = sChangeFocus.OrElse(fo.SChangeFocus);
     }
     return(new Output(drawable, desiredSize, sChangeFocus));
 })
 {
 }
Exemple #2
0
 public Outputs Create(Inputs inputs)
 {
     StreamLoop<Fuel> sStart = new StreamLoop<Fuel>();
     Fill fi = new Fill(inputs.SClearSale,
         inputs.SFuelPulses, inputs.Calibration,
         inputs.Price1, inputs.Price2, inputs.Price3,
         sStart);
     NotifyPointOfSale np = new NotifyPointOfSale(
         new LifeCycle(inputs.SNozzle1,
             inputs.SNozzle2,
             inputs.SNozzle3),
         inputs.SClearSale,
         fi);
     sStart.Loop(np.SStart);
     CellLoop<bool> keypadActive = new CellLoop<bool>();
     Keypad ke = new Keypad(inputs.SKeypad,
         inputs.SClearSale,
         keypadActive);
     Preset pr = new Preset(ke.Value, fi, np.FuelFlowing);
     keypadActive.Loop(pr.KeypadActive);
     return new Outputs()
         .SetDelivery(pr.Delivery)
         .SetSaleCostLcd(fi.DollarsDelivered.Map(Formatters.FormatSaleCost))
         .SetSaleQuantityLcd(fi.LitersDelivered.Map(Formatters.FormatSaleQuantity))
         .SetPriceLcd1(ShowDollarsPump.PriceLcd(np.FillActive, fi.Price, Fuel.One, inputs))
         .SetPriceLcd2(ShowDollarsPump.PriceLcd(np.FillActive, fi.Price, Fuel.Two, inputs))
         .SetPriceLcd3(ShowDollarsPump.PriceLcd(np.FillActive, fi.Price, Fuel.Three, inputs))
         .SetSaleComplete(np.SSaleComplete)
         .SetPresetLcd(ke.Value.Map(Formatters.FormatPresetAmount))
         .SetBeep(np.SBeep.OrElse(ke.SBeep));
 }
Exemple #3
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()) });
        }
Exemple #4
0
        public MainWindow()
        {
            this.InitializeComponent();

            Transaction.RunVoid(() =>
            {
                CellLoop <int> value = new CellLoop <int>();
                SLabel lblValue      = new SLabel(value.Map(i => i.ToString()));
                SButton plus         = new SButton {
                    Content = "+", Width = 25, Margin = new Thickness(5, 0, 0, 0)
                };
                SButton minus = new SButton {
                    Content = "-", Width = 25, Margin = new Thickness(5, 0, 0, 0)
                };

                this.Container.Children.Add(lblValue);
                this.Container.Children.Add(plus);
                this.Container.Children.Add(minus);

                Stream <int> sPlusDelta  = plus.SClicked.Map(_ => 1);
                Stream <int> sMinusDelta = minus.SClicked.Map(_ => - 1);
                Stream <int> sDelta      = sPlusDelta.OrElse(sMinusDelta);
                Stream <int> sUpdate     = sDelta.Snapshot(value, (d, v) => v + d).Filter(n => n >= 0);
                value.Loop(sUpdate.Hold(0));
            });
        }
Exemple #5
0
        public void TestLoop()
        {
            (Cell <int> c, CellStreamSink <int> s) = Transaction.Run(() =>
            {
                CellLoop <int> loop         = Cell.CreateLoop <int>();
                Cell <int> cLocal           = loop.Map(v => v * 5);
                CellStreamSink <int> sLocal = new CellStreamSink <int>();
                loop.Loop(sLocal.Hold(3));
                return(cLocal, sLocal);
            });

            List <int> output1 = new List <int>();
            List <int> output2 = new List <int>();
            IListener  l       = c.Listen(output1.Add);
            IListener  l2      = c.Updates.Listen(output2.Add);

            s.Send(5);
            s.Send(7);

            l2.Unlisten();
            l.Unlisten();

            CollectionAssert.AreEqual(new[] { 15, 25, 35 }, output1);
            CollectionAssert.AreEqual(new[] { 25, 35 }, output2);
        }
Exemple #6
0
            public void TestSwitchCDeferredLoopWithBetterApi()
            {
                CellStreamSink <IReadOnlyList <TestObject> > streamSink = Cell.CreateStreamSink <IReadOnlyList <TestObject> >();
                Cell <IReadOnlyList <TestObject> >           cell       = Transaction.Run(() =>
                {
                    CellLoop <IReadOnlyList <TestObject> > cellLoop = new CellLoop <IReadOnlyList <TestObject> >();
                    Cell <IReadOnlyList <TestObject> > cellLocal    = streamSink
                                                                      .OrElse(cellLoop.Map(oo => oo.Select(o => o.Output).Lift(vv => vv.Sum())).SwitchCWithDeferredValues().Filter(sum => sum < 50).Snapshot(cellLoop, (_, items) => (IReadOnlyList <TestObject>)items.Concat(new[] { new TestObject() }).ToArray()))
                                                                      .Hold(Enumerable.Range(1, 10).Select(_ => new TestObject()).ToArray());
                    cellLoop.Loop(cellLocal);
                    return(cellLocal);
                });

                List <int> objectCounts = new List <int>();

                objectCounts.Add(-1);
                cell.Listen(vv => objectCounts.Add(vv.Count));
                objectCounts.Add(-1);
                cell.Sample()[2].Input1.Send(1);
                objectCounts.Add(-1);
                cell.Sample()[1].Input1.Send(-20);
                objectCounts.Add(-1);
                streamSink.Send(new TestObject[0]);
                objectCounts.Add(-1);

                // Ideal result, likely not achievable.
                //CollectionAssert.AreEquivalent(new[] { -1, 10, -1, 11, -1, 15, -1, 10, -1 }, objectCounts);

                // Glitchy result, but correct otherwise.
                CollectionAssert.AreEquivalent(new[] { -1, 10, -1, 11, -1, 12, 13, 14, 15, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, -1 }, objectCounts);
            }
Exemple #7
0
            public void TestSwitchSValuesLoop()
            {
                CellStreamSink <IReadOnlyList <TestObject> > streamSink = Cell.CreateStreamSink <IReadOnlyList <TestObject> >();
                Cell <IReadOnlyList <TestObject> >           cell       = Transaction.Run(() =>
                {
                    CellLoop <IReadOnlyList <TestObject> > cellLoop = new CellLoop <IReadOnlyList <TestObject> >();
                    Cell <IReadOnlyList <TestObject> > cellLocal    = streamSink.Map(v => (Func <IReadOnlyList <TestObject>, IReadOnlyList <TestObject> >)(_ => v))
                                                                      .Merge(cellLoop.Map(oo => oo.Select(o => o.Output).Lift(vv => vv.Sum()).Values()).SwitchS().Filter(sum => sum < 50).MapTo((Func <IReadOnlyList <TestObject>, IReadOnlyList <TestObject> >)(v => v.Concat(new[] { new TestObject() }).ToArray())), (f, g) => v => g(f(v)))
                                                                      .Snapshot(cellLoop, (f, v) => f(v))
                                                                      .Hold(Enumerable.Range(1, 10).Select(_ => new TestObject()).ToArray());
                    cellLoop.Loop(cellLocal);
                    return(cellLocal);
                });

                List <int> objectCounts = new List <int>();

                objectCounts.Add(-1);
                cell.Listen(vv => objectCounts.Add(vv.Count));
                objectCounts.Add(-1);
                cell.Sample()[2].Input1.Send(1);
                objectCounts.Add(-1);
                cell.Sample()[1].Input1.Send(-20);
                objectCounts.Add(-1);
                streamSink.Send(new TestObject[0]);
                objectCounts.Add(-1);

                // Ideal result, likely not achievable.
                //CollectionAssert.AreEquivalent(new[] { -1, 10, -1, 11, -1, 15, -1, 10, -1 }, objectCounts);

                // Glitchy result, also not returned by this method.
                //CollectionAssert.AreEquivalent(new[] { -1, 10, -1, 11, -1, 12, 13, 14, 15, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, -1 }, objectCounts);

                // Incorrect result we will see.
                CollectionAssert.AreEquivalent(new[] { -1, 10, -1, 11, -1, 12, -1, 0, -1 }, objectCounts);
            }
Exemple #8
0
 public Keypad(Stream<Key> sKeypad, Stream<Unit> sClear)
 {
     CellLoop<int> value = new CellLoop<int>();
     this.Value = value;
     Stream<int> sKeyUpdate = sKeypad.Snapshot(value, (key, valueLocal) =>
     {
         if (key == Key.Clear)
         {
             return Maybe.Just(0);
         }
         int x10 = valueLocal * 10;
         return x10 >= 1000
             ? Maybe.Nothing<int>()
             : Maybe.Just(
                 key == Key.Zero ? x10 :
                     key == Key.One ? x10 + 1 :
                         key == Key.Two ? x10 + 2 :
                             key == Key.Three ? x10 + 3 :
                                 key == Key.Four ? x10 + 4 :
                                     key == Key.Five ? x10 + 5 :
                                         key == Key.Six ? x10 + 6 :
                                             key == Key.Seven ? x10 + 7 :
                                                 key == Key.Eight ? x10 + 8 :
                                                     x10 + 9);
     }).FilterMaybe();
     value.Loop(sKeyUpdate.OrElse(sClear.Map(u => 0)).Hold(0));
     this.SBeep = sKeyUpdate.Map(_ => Unit.Value);
 }
Exemple #9
0
        private static Stream <DateTime> Periodic(ITimerSystem <DateTime> sys, TimeSpan period)
        {
            Behavior <DateTime>          time   = sys.Time;
            CellLoop <Maybe <DateTime> > oAlarm = new CellLoop <Maybe <DateTime> >();
            Stream <DateTime>            sAlarm = sys.At(oAlarm);

            oAlarm.Loop(sAlarm.Map(t => Maybe.Some(t + period)).Hold(Maybe.Some(time.Sample() + period)));
            return(sAlarm);
        }
Exemple #10
0
        private Cell <bool> GetFlag(int target, Stream <int> sFlag)
        {
            Stream <int>    sMark   = sFlag.Filter(target.Equals);
            CellLoop <bool> flag    = new CellLoop <bool>();
            Stream <bool>   sInvert = sMark.Snapshot(flag, (_, value) => !value);

            flag.Loop(sInvert.Hold(true));

            return(flag);
        }
 public static Cell<double> Accumulate(
     Stream<Unit> sClearAccumulator,
     Stream<int> sPulses,
     Cell<double> calibration)
 {
     CellLoop<int> total = new CellLoop<int>();
     total.Loop(sClearAccumulator.Map(u => 0)
         .OrElse(sPulses.Snapshot(total, (pulsesLocal, totalLocal) => pulsesLocal + totalLocal))
         .Hold(0));
     return total.Lift(
         calibration,
         (totalLocal, calibrationLocal) => totalLocal * calibrationLocal);
 }
Exemple #12
0
        public static Cell <double> Accumulate(
            Stream <Unit> sClearAccumulator,
            Stream <int> sPulses,
            Cell <double> calibration)
        {
            CellLoop <int> total = new CellLoop <int>();

            total.Loop(sClearAccumulator.Map(u => 0)
                       .OrElse(sPulses.Snapshot(total, (pulsesLocal, totalLocal) => pulsesLocal + totalLocal))
                       .Hold(0));
            return(total.Lift(
                       calibration,
                       (totalLocal, calibrationLocal) => totalLocal * calibrationLocal));
        }
Exemple #13
0
        public void ImperativeCellLoopFailsWhenLoopedTwice()
        {
            InvalidOperationException actual = null;

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

            Assert.IsNotNull(actual);
            Assert.AreEqual("Loop was looped more than once.", actual.Message);
        }
Exemple #14
0
 public LifeCycle(Stream<UpDown> sNozzle1, Stream<UpDown> sNozzle2, Stream<UpDown> sNozzle3)
 {
     Stream<Fuel> sLiftNozzle =
         WhenLifted(sNozzle1, Fuel.One).OrElse(
             WhenLifted(sNozzle2, Fuel.Two).OrElse(
                 WhenLifted(sNozzle3, Fuel.Three)));
     CellLoop<IMaybe<Fuel>> fillActive = new CellLoop<IMaybe<Fuel>>();
     this.FillActive = fillActive;
     this.SStart = sLiftNozzle.Snapshot(fillActive, (newFuel, fillActiveLocal) => fillActiveLocal.Match(_ => Maybe.Nothing<Fuel>(), () => Maybe.Just(newFuel))).FilterMaybe();
     this.SEnd = WhenSetDown(sNozzle1, Fuel.One, fillActive).OrElse(
         WhenSetDown(sNozzle2, Fuel.Two, fillActive).OrElse(
             WhenSetDown(sNozzle3, Fuel.Three, fillActive)));
     fillActive.Loop(
         this.SEnd.Map(e => Maybe.Nothing<Fuel>())
             .OrElse(this.SStart.Map(Maybe.Just))
             .Hold(Maybe.Nothing<Fuel>()));
 }
Exemple #15
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);
        }
Exemple #16
0
        public LifeCycle(Stream <UpDown> sNozzle1, Stream <UpDown> sNozzle2, Stream <UpDown> sNozzle3)
        {
            Stream <Fuel> sLiftNozzle =
                WhenLifted(sNozzle1, Fuel.One).OrElse(
                    WhenLifted(sNozzle2, Fuel.Two).OrElse(
                        WhenLifted(sNozzle3, Fuel.Three)));
            CellLoop <Maybe <Fuel> > fillActive = new CellLoop <Maybe <Fuel> >();

            this.FillActive = fillActive;
            this.SStart     = sLiftNozzle.Snapshot(fillActive, (newFuel, fillActiveLocal) => fillActiveLocal.Match(_ => Maybe.None, () => Maybe.Some(newFuel))).FilterMaybe();
            this.SEnd       = WhenSetDown(sNozzle1, Fuel.One, fillActive).OrElse(
                WhenSetDown(sNozzle2, Fuel.Two, fillActive).OrElse(
                    WhenSetDown(sNozzle3, Fuel.Three, fillActive)));
            fillActive.Loop(
                this.SEnd.Map(e => Maybe <Fuel> .None)
                .OrElse(this.SStart.Map(Maybe.Some))
                .Hold(Maybe.None));
        }
Exemple #17
0
            public void TestSwitchCLoop()
            {
                Exception actual = null;

                try
                {
                    CellStreamSink <IReadOnlyList <TestObject> > streamSink = Cell.CreateStreamSink <IReadOnlyList <TestObject> >();
                    Cell <IReadOnlyList <TestObject> >           cell       = Transaction.Run(() =>
                    {
                        CellLoop <IReadOnlyList <TestObject> > cellLoop = new CellLoop <IReadOnlyList <TestObject> >();
                        Cell <IReadOnlyList <TestObject> > cellLocal    = streamSink.Map(v => (Func <IReadOnlyList <TestObject>, IReadOnlyList <TestObject> >)(_ => v))
                                                                          .Merge(cellLoop.Map(oo => oo.Select(o => o.Output).Lift(vv => vv.Sum())).SwitchC().Updates().Filter(sum => sum < 50).MapTo((Func <IReadOnlyList <TestObject>, IReadOnlyList <TestObject> >)(v => v.Concat(new[] { new TestObject() }).ToArray())), (f, g) => v => g(f(v)))
                                                                          .Snapshot(cellLoop, (f, v) => f(v))
                                                                          .Hold(Enumerable.Range(1, 10).Select(_ => new TestObject()).ToArray());
                        cellLoop.Loop(cellLocal);
                        return(cellLocal);
                    });

                    List <int> objectCounts = new List <int>();
                    objectCounts.Add(-1);
                    cell.Listen(vv => objectCounts.Add(vv.Count));
                    objectCounts.Add(-1);
                    cell.Sample()[2].Input1.Send(1);
                    objectCounts.Add(-1);
                    cell.Sample()[1].Input1.Send(-20);
                    objectCounts.Add(-1);
                    streamSink.Send(new TestObject[0]);
                    objectCounts.Add(-1);
                }
                catch (AggregateException e)
                {
                    actual = e.InnerExceptions.FirstOrDefault(ex => ex.Message == "A dependency cycle was detected.");
                }
                catch (Exception e)
                {
                    actual = e;
                }

                Assert.IsNotNull(actual);
                Assert.AreEqual("A dependency cycle was detected.", actual.Message);
            }
Exemple #18
0
        public async Task TestListenAsync()
        {
            CellSink <int> a  = Cell.CreateSink(1);
            Cell <int>     a1 = a.Map(x => x + 1);
            Cell <int>     a2 = a.Map(x => x * 2);

            (List <int> results, CellLoop <int> called, IListener l) = Transaction.Run(() =>
            {
                Cell <int> result                 = a1.Lift(a2, (x, y) => x + y);
                Stream <Unit> incrementStream     = result.Values().MapTo(Unit.Value);
                StreamSink <Unit> decrementStream = Stream.CreateSink <Unit>();
                CellLoop <int> calledLoop         = Cell.CreateLoop <int>();
                calledLoop.Loop(incrementStream.MapTo(1).Merge(decrementStream.MapTo(-1), (x, y) => x + y).Snapshot(calledLoop, (u, c) => c + u).Hold(0));
                List <int> r     = new List <int>();
                IListener lLocal = result.Listen(v =>
                {
                    Task.Run(async() =>
                    {
                        await Task.Delay(900);
                        r.Add(v);
                        decrementStream.Send(Unit.Value);
                    });
                });
                return(r, calledLoop, lLocal);
            });
            // ReSharper disable once UnusedVariable
            List <int> calledResults = new List <int>();
            IListener  l2            = called.Listen(calledResults.Add);

            await Task.Delay(500);

            a.Send(2);
            await Task.Delay(500);

            a.Send(3);
            await Task.Delay(2500);

            l2.Unlisten();
            l.Unlisten();
        }
Exemple #19
0
        public MainWindow()
        {
            this.InitializeComponent();

            Transaction.RunVoid(() =>
            {
                CellLoop<int> value = new CellLoop<int>();
                SLabel lblValue = new SLabel(value.Map(i => i.ToString()));
                SButton plus = new SButton { Content = "+", Width = 25, Margin = new Thickness(5, 0, 0, 0) };
                SButton minus = new SButton { Content = "-", Width = 25, Margin = new Thickness(5, 0, 0, 0) };

                this.Container.Children.Add(lblValue);
                this.Container.Children.Add(plus);
                this.Container.Children.Add(minus);

                Stream<int> sPlusDelta = plus.SClicked.Map(_ => 1);
                Stream<int> sMinusDelta = minus.SClicked.Map(_ => -1);
                Stream<int> sDelta = sPlusDelta.OrElse(sMinusDelta);
                Stream<int> sUpdate = sDelta.Snapshot(value, (d, v) => v + d).Filter(n => n >= 0);
                value.Loop(sUpdate.Hold(0));
            });
        }
Exemple #20
0
        public void ImperativeCellLoop()
        {
            CellSink <int> s      = Cell.CreateSink(0);
            Cell <int>     result = Transaction.Run(
                () =>
            {
                CellLoop <int> l       = new CellLoop <int>();
                Cell <int> resultLocal = s.Updates().Snapshot(l, (n, o) => n + o).Hold(0);
                l.Loop(resultLocal);
                return(resultLocal);
            });

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

            using (Transaction.Run(() => result.Values().Listen(@out.Add)))
            {
                s.Send(1);
                s.Send(2);
                s.Send(3);
            }

            CollectionAssert.AreEqual(new[] { 0, 1, 3, 6 }, @out);
        }
Exemple #21
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()) });
 }
Exemple #22
0
 public FrFlow(Orientation dir, IEnumerable<Fridget> fridgets)
     : base((size, sMouse, sKey, focus, idSupply) =>
     {
         Cell<Size> desiredSize = Cell.Constant(new Size(0, 0));
         Cell<DrawableDelegate> drawable = Cell.Constant(new DrawableDelegate(d => { }));
         Stream<long> sChangeFocus = Stream.Never<long>();
         foreach (Fridget fridget in fridgets)
         {
             CellLoop<IMaybe<Size>> childSz = new CellLoop<IMaybe<Size>>();
             Output fo = new FrTranslate(fridget,
                 dir == Orientation.Horizontal
                     ? desiredSize.Map(dsz => new Point(dsz.Width, 0))
                     : desiredSize.Map(dsz => new Point(0, dsz.Height)))
                 .Reify(childSz, sMouse, sKey, focus,
                     idSupply.Child1());
             idSupply = idSupply.Child2();
             childSz.Loop(
                 size.Lift(fo.DesiredSize, (mSize, foDsz) =>
                     mSize.Match(s => Maybe.Just(dir == Orientation.Horizontal
                         ? new Size(foDsz.Width, s.Height)
                         : new Size(s.Width, foDsz.Height)),
                         Maybe.Nothing<Size>)));
             Func<Size, Size, Size> liftDesiredSizeHorizontal = (dsz, foDsz) => new Size(
                 dsz.Width + foDsz.Width,
                 dsz.Height > foDsz.Height ? dsz.Height : foDsz.Height);
             Func<Size, Size, Size> liftDesiredSizeVertical = (dsz, foDsz) => new Size(
                 dsz.Width > foDsz.Width ? dsz.Width : foDsz.Width,
                 dsz.Height + foDsz.Height);
             desiredSize = desiredSize.Lift(fo.DesiredSize, dir == Orientation.Horizontal ? liftDesiredSizeHorizontal : liftDesiredSizeVertical);
             drawable = drawable.Lift(fo.Drawable, (drA, drB) => drA.Append(drB));
             sChangeFocus = sChangeFocus.OrElse(fo.SChangeFocus);
         }
         return new Output(drawable, desiredSize, sChangeFocus);
     })
 {
 }
Exemple #23
0
        private FrTextField(string initText, CellLoop<string> text)
            : base((size, sMouse, sKey, focus, idSupply) =>
            {
                Stream<double> sPressed = sMouse.Snapshot(size, (e, mSize) =>
                    mSize.Match(
                        s =>
                        {
                            MouseButtonEventArgs b = e.Args as MouseButtonEventArgs;
                            Point p = e.GetPosition();
                            return b != null && b.ChangedButton == MouseButton.Left && b.ButtonState == MouseButtonState.Pressed
                                   && p.X >= 2 && p.X < s.Width - 2 && p.Y >= 2 && p.Y < s.Height - 2
                                ? Maybe.Just(p.X - 2)
                                : Maybe.Nothing<double>();
                        },
                        Maybe.Nothing<double>)).FilterMaybe();
                CellLoop<int> x = new CellLoop<int>();
                long myId = idSupply.Get();
                Cell<bool> haveFocus = focus.Map(fId => fId == myId);
                Typeface typeface = new Typeface(new FontFamily("Helvetica"), FontStyles.Normal, FontWeights.Normal, FontStretches.Normal);
                Stream<TextUpdate> sTextUpdate = sKey.Gate(haveFocus).Snapshot(text, (key, txt) =>
                {
                    int xValue = x.Sample();
                    if (key is BackspaceKeyEvent)
                    {
                        return xValue > 0 ? Maybe.Just(new TextUpdate(
                            txt.Substring(0, xValue - 1) +
                            txt.Substring(xValue),
                            xValue - 1)) : Maybe.Nothing<TextUpdate>();
                    }

                    StringKeyEvent stringKey = key as StringKeyEvent;
                    if (stringKey == null)
                    {
                        throw new InvalidOperationException("Unexpected type encountered for " + typeof(KeyEvent).FullName + ": " + key.GetType().FullName + ".");
                    }

                    string keyString = stringKey.String;
                    return keyString == "\b" ? Maybe.Nothing<TextUpdate>() :
                        Maybe.Just(new TextUpdate(
                            txt.Substring(0, xValue) +
                            keyString +
                            txt.Substring(xValue),
                            xValue + 1));
                }).FilterMaybe();
                x.Loop(sPressed.Snapshot(text,
                    (xCoord, txt) =>
                    {
                        for (int i = 1; i <= txt.Length; i++)
                        {
                            if (xCoord < FontUtilities.MeasureString(txt.Substring(0, i), typeface, 13).Width)
                            {
                                return i - 1;
                            }
                        }
                        return txt.Length;
                    })
                    .OrElse(sTextUpdate.Map(tu => tu.NewX))
                    .Hold(0));
                text.Loop(sTextUpdate.Map(tu => tu.Txt).Hold(initText));
                Cell<Size> desiredSize = text.Map(txt =>
                {
                    Size s = FontUtilities.MeasureString(txt, typeface, 13);
                    return new Size(s.Width + 14, s.Height + 10);
                });
                return new Output(
                    text.Lift(
                        x, haveFocus, size,
                        (txt, xValue, haveFocusValue, mSize) => new DrawableDelegate(d =>
                        {
                            mSize.Match(
                                sz =>
                                {
                                    d.DrawRectangle(Brushes.White, new Pen(Brushes.Black, 1), new Rect(new Point(2, 2), new Size(sz.Width - 5, sz.Height - 5)));
                                    FormattedText t = FontUtilities.GetStandardFormattedText(txt, typeface, 13, Brushes.Black);
                                    FormattedText tCursor = FontUtilities.GetStandardFormattedText(txt.Substring(0, xValue), typeface, 13, Brushes.Black);
                                    d.DrawText(t, new Point(4, (sz.Height - t.Height) / 2));
                                    if (haveFocusValue)
                                    {
                                        double cursorX = tCursor.Width;
                                        d.DrawLine(new Pen(Brushes.Red, 1), new Point(4 + cursorX, 4), new Point(4 + cursorX, sz.Height - 5));
                                    }
                                },
                                () => { });
                        })),
                    desiredSize,
                    sPressed.Map(_ => myId));
            })
        {
            this.Text = text;
        }
Exemple #24
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();
        }
Exemple #25
0
        private FrTextField(string initText, CellLoop <string> text)
            : base((size, sMouse, sKey, focus, idSupply) =>
        {
            Stream <double> sPressed = sMouse.Snapshot(size, (e, mSize) =>
                                                       mSize.Match(
                                                           s =>
            {
                MouseButtonEventArgs b = e.Args as MouseButtonEventArgs;
                Point p = e.GetPosition();
                return(b != null && b.ChangedButton == MouseButton.Left && b.ButtonState == MouseButtonState.Pressed &&
                       p.X >= 2 && p.X < s.Width - 2 && p.Y >= 2 && p.Y < s.Height - 2
                                ? Maybe.Just(p.X - 2)
                                : Maybe.Nothing <double>());
            },
                                                           Maybe.Nothing <double>)).FilterMaybe();
            CellLoop <int> x                = new CellLoop <int>();
            long myId                       = idSupply.Get();
            Cell <bool> haveFocus           = focus.Map(fId => fId == myId);
            Typeface typeface               = new Typeface(new FontFamily("Helvetica"), FontStyles.Normal, FontWeights.Normal, FontStretches.Normal);
            Stream <TextUpdate> sTextUpdate = sKey.Gate(haveFocus).Snapshot(text, (key, txt) =>
            {
                int xValue = x.Sample();
                if (key is BackspaceKeyEvent)
                {
                    return(xValue > 0 ? Maybe.Just(new TextUpdate(
                                                       txt.Substring(0, xValue - 1) +
                                                       txt.Substring(xValue),
                                                       xValue - 1)) : Maybe.Nothing <TextUpdate>());
                }

                StringKeyEvent stringKey = key as StringKeyEvent;
                if (stringKey == null)
                {
                    throw new InvalidOperationException("Unexpected type encountered for " + typeof(KeyEvent).FullName + ": " + key.GetType().FullName + ".");
                }

                string keyString = stringKey.String;
                return(keyString == "\b" ? Maybe.Nothing <TextUpdate>() :
                       Maybe.Just(new TextUpdate(
                                      txt.Substring(0, xValue) +
                                      keyString +
                                      txt.Substring(xValue),
                                      xValue + 1)));
            }).FilterMaybe();
            x.Loop(sPressed.Snapshot(text,
                                     (xCoord, txt) =>
            {
                for (int i = 1; i <= txt.Length; i++)
                {
                    if (xCoord < FontUtilities.MeasureString(txt.Substring(0, i), typeface, 13).Width)
                    {
                        return(i - 1);
                    }
                }
                return(txt.Length);
            })
                   .OrElse(sTextUpdate.Map(tu => tu.NewX))
                   .Hold(0));
            text.Loop(sTextUpdate.Map(tu => tu.Txt).Hold(initText));
            Cell <Size> desiredSize = text.Map(txt =>
            {
                Size s = FontUtilities.MeasureString(txt, typeface, 13);
                return(new Size(s.Width + 14, s.Height + 10));
            });
            return(new Output(
                       text.Lift(
                           x, haveFocus, size,
                           (txt, xValue, haveFocusValue, mSize) => new DrawableDelegate(d =>
            {
                mSize.Match(
                    sz =>
                {
                    d.DrawRectangle(Brushes.White, new Pen(Brushes.Black, 1), new Rect(new Point(2, 2), new Size(sz.Width - 5, sz.Height - 5)));
                    FormattedText t = FontUtilities.GetStandardFormattedText(txt, typeface, 13, Brushes.Black);
                    FormattedText tCursor = FontUtilities.GetStandardFormattedText(txt.Substring(0, xValue), typeface, 13, Brushes.Black);
                    d.DrawText(t, new Point(4, (sz.Height - t.Height) / 2));
                    if (haveFocusValue)
                    {
                        double cursorX = tCursor.Width;
                        d.DrawLine(new Pen(Brushes.Red, 1), new Point(4 + cursorX, 4), new Point(4 + cursorX, sz.Height - 5));
                    }
                },
                    () => { });
            })),
                       desiredSize,
                       sPressed.Map(_ => myId)));
        })
        {
            this.Text = text;
        }