예제 #1
0
 public PublisherZip2(ISubscriber <R> actual, Func <T1, T2, R> zipper, int bufferSize)
 {
     this.actual     = actual;
     this.zipper     = zipper;
     this.bufferSize = bufferSize;
     this.inner1     = new PublisherZipInner <T1>(this, bufferSize);
     this.inner2     = new PublisherZipInner <T2>(this, bufferSize);
 }
예제 #2
0
 public PublisherZip(ISubscriber <R> actual, int n, Func <T[], R> zipper, int bufferSize)
 {
     this.actual     = actual;
     this.zipper     = zipper;
     this.bufferSize = bufferSize;
     PublisherZipInner <T>[] a = new PublisherZipInner <T> [n];
     for (int i = 0; i < n; i++)
     {
         a[i] = new PublisherZipInner <T>(this, bufferSize);
     }
     this.subscribers = a;
 }
예제 #3
0
        public void Drain()
        {
            if (!bp.Enter())
            {
                return;
            }

            ISubscriber <R> a = actual;

            PublisherZipInner <T>[] inners = subscribers;

            int missed = 1;

            for (;;)
            {
                long r = bp.Requested();
                long e = 0L;

                for (;;)
                {
                    if (bp.IsCancelled())
                    {
                        return;
                    }

                    Exception ex = Volatile.Read(ref error);
                    if (ex != null)
                    {
                        Cancel();

                        ExceptionHelper.Terminate(ref error, out ex);

                        a.OnError(ex);

                        return;
                    }

                    int len = inners.Length;

                    T[]  values = new T[len];
                    bool full   = true;

                    for (int i = 0; i < len; i++)
                    {
                        PublisherZipInner <T> inner = inners[i];
                        bool d1 = inner.IsDone();

                        T    t;
                        bool empty1 = !inner.Peek(out t);
                        if (d1 && empty1)
                        {
                            Cancel();

                            a.OnComplete();

                            return;
                        }

                        if (empty1)
                        {
                            full = false;
                            break;
                        }

                        values[i] = t;
                    }

                    if (full)
                    {
                        if (r != e)
                        {
                            R v;
                            try
                            {
                                v = zipper(values);
                            }
                            catch (Exception ex1)
                            {
                                Cancel();

                                ExceptionHelper.Add(ref error, ex1);
                                ExceptionHelper.Terminate(ref error, out ex1);

                                a.OnError(ex1);
                                return;
                            }

                            a.OnNext(v);

                            foreach (PublisherZipInner <T> inner in inners)
                            {
                                inner.Drop();
                            }

                            e++;
                        }
                        else
                        {
                            if (e != 0)
                            {
                                bp.Produced(e);

                                foreach (PublisherZipInner <T> inner in inners)
                                {
                                    inner.Request(e);
                                }
                            }
                            break;
                        }
                    }
                    else
                    {
                        break;
                    }
                }

                missed = bp.Leave(missed);
                if (missed == 0)
                {
                    break;
                }
            }
        }