예제 #1
0
        /// <summary>
        ///     Unwrap a stream inside a cell to give a time-varying stream implementation.
        ///     When the cell changes value, the output stream will fire the simultaneous firing (if one exists) from the stream which the cell held at the beginning of the transaction.
        /// </summary>
        /// <typeparam name="T">The type of the stream.</typeparam>
        /// <param name="csa">The cell containing the stream.</param>
        /// <returns>The unwrapped stream.</returns>
        public static Stream <T> SwitchS <T>(this Cell <Stream <T> > csa)
        {
            return(Transaction.Apply(trans1 =>
            {
                Stream <T> @out = new Stream <T>();
                IListener currentListener = null;
                Action <Transaction, Stream <T> > hInitial = (trans2, sa) =>
                {
                    currentListener?.Unlisten();

                    currentListener = sa.Listen(@out.Node, trans2, @out.Send, false);
                };
                Action <Transaction, Stream <T> > h = (trans2, sa) =>
                {
                    trans2.Last(() =>
                    {
                        currentListener?.Unlisten();

                        currentListener = sa.Listen(@out.Node, trans2, @out.Send, true);
                    });
                };
                trans1.Prioritized(new Node <T>(), trans2 => hInitial(trans2, csa.SampleNoTransaction()));
                IListener l1 = csa.Updates(trans1).Listen(@out.Node, trans1, h, false);
                return @out.UnsafeAttachListener(l1);
            }, false));
        }
예제 #2
0
        /// <summary>
        ///     Unwrap a stream inside a cell to give a time-varying stream implementation.
        ///     When the cell changes value, the output stream will fire the simultaneous firing (if one exists) from the stream
        ///     which the cell held at the beginning of the transaction.
        /// </summary>
        /// <typeparam name="T">The type of the stream.</typeparam>
        /// <param name="csa">The cell containing the stream.</param>
        /// <returns>The unwrapped stream.</returns>
        public static Stream <T> SwitchS <T>(this Cell <Stream <T> > csa)
        {
            return(Transaction.Apply(
                       trans1 =>
            {
                Stream <T> @out = new Stream <T>(csa.KeepListenersAlive);
                MutableListener currentListener = new MutableListener();

                void HInitial(Transaction trans2, Stream <T> sa)
                {
                    currentListener.Unlisten();

                    currentListener.SetListener(sa.Listen(@out.Node, trans2, @out.Send, false));
                }

                void H(Transaction trans2, Stream <T> sa)
                {
                    trans2.Last(
                        () =>
                    {
                        currentListener.Unlisten();

                        currentListener.SetListener(sa.Listen(@out.Node, trans2, @out.Send, true));
                    });
                }

                trans1.Prioritized(new Node <T>(), trans2 => HInitial(trans2, csa.SampleNoTransaction()));
                IListener l1 = csa.Updates(trans1).Listen(new Node <T>(), trans1, H, false);
                return @out.UnsafeAttachListener(l1).UnsafeAttachListener(currentListener);
            },
                       false));
        }
예제 #3
0
        /// <summary>
        ///     Unwrap a stream inside a cell to give a time-varying stream implementation.
        /// </summary>
        /// <typeparam name="T">The type of the stream.</typeparam>
        /// <param name="csa">The cell containing the stream.</param>
        /// <returns>The unwrapped stream.</returns>
        public static Stream <T> SwitchS <T>(this Cell <Stream <T> > csa)
        {
            return(Transaction.Apply(trans1 =>
            {
                Stream <T> @out = new Stream <T>();
                IListener currentListener = csa.SampleNoTransaction().Listen(@out.Node, trans1, @out.Send, false);
                Action <Transaction, Stream <T> > h = (trans2, sa) =>
                {
                    trans2.Last(() =>
                    {
                        using (currentListener)
                        {
                        }

                        currentListener = sa.Listen(@out.Node, trans2, @out.Send, true);
                    });
                };
                IListener l1 = csa.Updates(trans1).Listen(@out.Node, trans1, h, false);
                return @out.UnsafeAddCleanup(l1);
            }));
        }