Example #1
0
        internal IWeakListener Listen(
            Node target,
            TransactionInternal trans,
            Action <TransactionInternal, T> action,
            bool suppressEarlierFirings)
        {
            (bool changed, Node <T> .Target nodeTarget) = this.Node.Link(trans, action, target);
            if (changed)
            {
                trans.SetNeedsRegenerating();
            }

            // ReSharper disable once LocalVariableHidesMember
            List <T> firings = this.firings.ToList();

            if (!suppressEarlierFirings && firings.Count > 0)
            {
                trans.Prioritized(
                    target,
                    trans2 =>
                {
                    // Anything sent already in this transaction must be sent now so that
                    // there's no order dependency between send and listen.
                    foreach (T a in firings)
                    {
                        TransactionInternal.InCallback++;
                        try
                        {
                            // Don't allow transactions to interfere with Sodium
                            // internals.
                            action(trans2, a);
                        }
                        finally
                        {
                            TransactionInternal.InCallback--;
                        }
                    }
                });
            }

            return(new ListenerImplementation(this, action, nodeTarget));
        }
Example #2
0
        private Stream <T> Merge(TransactionInternal trans, Stream <T> s)
        {
            Stream <T> @out  = new Stream <T>(this.KeepListenersAlive);
            Node <T>   left  = new Node <T>();
            Node <T>   right = @out.Node;

            (bool changed, Node <T> .Target nodeTarget) = left.Link(trans, (t, v) => { }, right);
            if (changed)
            {
                trans.SetNeedsRegenerating();
            }

            Action <TransactionInternal, T> h = @out.Send;
            IListener l1 = this.Listen(left, h);
            IListener l2 = s.Listen(right, h);

            return(@out.UnsafeAttachListener(l1)
                   .UnsafeAttachListener(l2)
                   .UnsafeAttachListener(ListenerInternal.CreateFromNodeAndTarget(left, nodeTarget)));
        }