示例#1
0
        public static IObservable <Tuple <T> > WrapValueToClass <T>(this IObservable <T> source) where T : struct
        {
            int dummy = 0;

            return(Observable.Create(delegate(IObserver <Tuple <T> > observer)
            {
                IObservable <T> observable = source;
                Action <T> onNext = delegate(T x)
                {
                    dummy.GetHashCode();
                    Tuple <T> value = new Tuple <T>(x);
                    observer.OnNext(value);
                };
                IObserver <Tuple <T> > observer2 = observer;
                Action <Exception> onError = observer2.OnError;
                IObserver <Tuple <T> > observer3 = observer;
                return observable.Subscribe(Observer.Create(onNext, onError, observer3.OnCompleted));
            }));
        }
示例#2
0
 public static IObservable <TR> Select <T, TR>(this IObservable <T> source, Func <T, int, TR> selector)
 {
     return(Observable.Create <TR>(observer =>
     {
         var index = 0;
         return source.Subscribe(Observer.Create <T>(x =>
         {
             var v = default(TR);
             try
             {
                 v = selector(x, index++);
             }
             catch (Exception ex)
             {
                 observer.OnError(ex);
                 return;
             }
             observer.OnNext(v);
         }, observer.OnError, observer.OnCompleted));
     }));
 }
            public IDisposable Subscribe(IObserver <T> observer)
            {
                var subscription = new SingleAssignmentDisposable();

#if UNITY_5_0
                // In Unity 5.0.2p1/p2 occures IL2CPP compile error.
                // IL2CPP compile error when script contains method group of interface to delegate conversion
                var safeObserver = Observer.Create <T>(x => observer.OnNext(x), ex => observer.OnError(ex), () => observer.OnCompleted(), subscription);
#else
                var safeObserver = Observer.Create <T>(observer.OnNext, observer.OnError, observer.OnCompleted, subscription);
#endif

                if (Scheduler.IsCurrentThreadSchedulerScheduleRequired)
                {
                    Scheduler.CurrentThread.Schedule(() => subscription.Disposable = subscribe(safeObserver));
                }
                else
                {
                    subscription.Disposable = subscribe(safeObserver);
                }

                return(subscription);
            }
        public static IObservable <IList <TSource> > Buffer <TSource, TWindowBoundary>(this IObservable <TSource> source, IObservable <TWindowBoundary> windowBoundaries)
        {
            return(Observable.Create <IList <TSource> >(observer =>
            {
                var list = new List <TSource>();
                var gate = new object();

                var d = new CompositeDisposable(2);

                d.Add(source.Subscribe(Observer.Create <TSource>(
                                           x =>
                {
                    lock (gate)
                    {
                        list.Add(x);
                    }
                },
                                           ex =>
                {
                    lock (gate)
                    {
                        observer.OnError(ex);
                    }
                },
                                           () =>
                {
                    lock (gate)
                    {
                        var currentList = list;
                        list = new List <TSource>();    // safe
                        observer.OnNext(currentList);
                        observer.OnCompleted();
                    }
                }
                                           )));

                d.Add(windowBoundaries.Subscribe(Observer.Create <TWindowBoundary>(
                                                     w =>
                {
                    List <TSource> currentList;
                    lock (gate)
                    {
                        currentList = list;
                        if (currentList.Count != 0)
                        {
                            list = new List <TSource>();
                        }
                    }
                    if (currentList.Count != 0)
                    {
                        observer.OnNext(currentList);
                    }
                },
                                                     ex =>
                {
                    lock (gate)
                    {
                        observer.OnError(ex);
                    }
                },
                                                     () =>
                {
                    lock (gate)
                    {
                        var currentList = list;
                        list = new List <TSource>();    // safe
                        observer.OnNext(currentList);
                        observer.OnCompleted();
                    }
                }
                                                     )));

                return d;
            }));
        }
示例#5
0
 public static IDisposable Subscribe <T>(this IObservable <T> source, Action <T> onNext, Action <Exception> onError, Action onCompleted)
 {
     return(source.Subscribe(Observer.Create(onNext, onError, onCompleted)));
 }
示例#6
0
 public static IDisposable Subscribe <T>(this IObservable <T> source, Action <T> onNext, Action onCompleted)
 {
     return(source.Subscribe(Observer.Create(onNext, e => { throw e; }, onCompleted)));
 }
示例#7
0
 public static IDisposable Subscribe <T>(this IObservable <T> source)
 {
     return(source.Subscribe(Observer.Create <T>(_ => { }, e => { throw e; }, () => { })));
 }
示例#8
0
 public static IDisposable Subscribe <T>(this IObservable <T> source, Action <T> onNext)
 {
     return(source.Subscribe(Observer.Create(onNext, Stubs.Throw, Stubs.Nop)));
 }
示例#9
0
 public static IDisposable Subscribe <T>(this IObservable <T> source)
 {
     return(source.Subscribe(Observer.Create <T>(Stubs.Ignore <T>, Stubs.Throw, Stubs.Nop)));
 }
        /// <summary>
        /// Returns a task that will receive the last value or the exception produced by the observable sequence.
        /// </summary>
        /// <typeparam name="TResult">The type of the elements in the source sequence.</typeparam>
        /// <param name="observable">Observable sequence to convert to a task.</param>
        /// <param name="cancellationToken">Cancellation token that can be used to cancel the task, causing unsubscription from the observable sequence.</param>
        /// <param name="state">The state to use as the underlying task's AsyncState.</param>
        /// <returns>A task that will receive the last element or the exception produced by the observable sequence.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="observable"/> is null.</exception>
        public static Task <TResult> ToTask <TResult>(this IObservable <TResult> observable, CancellationToken cancellationToken, object state)
        {
            if (observable == null)
            {
                throw new ArgumentNullException("observable");
            }

            var hasValue   = false;
            var lastValue  = default(TResult);
            var tcs        = new TaskCompletionSource <TResult>(state);
            var disposable = new SingleAssignmentDisposable();
            var ctr        = default(CancellationTokenRegistration);

            if (cancellationToken.CanBeCanceled)
            {
                ctr = cancellationToken.Register(() =>
                {
                    disposable.Dispose();
                    tcs.TrySetCanceled(cancellationToken);
                });
            }

            var taskCompletionObserver = Observer.Create <TResult>(
                value =>
            {
                hasValue  = true;
                lastValue = value;
            },
                ex =>
            {
                tcs.TrySetException(ex);
                ctr.Dispose(); // no null-check needed (struct)
                disposable.Dispose();
            },
                () =>
            {
                if (hasValue)
                {
                    tcs.TrySetResult(lastValue);
                }
                else
                {
                    tcs.TrySetException(new InvalidOperationException("Strings_Linq.NO_ELEMENTS"));
                }

                ctr.Dispose(); // no null-check needed (struct)
                disposable.Dispose();
            }
                );

            //
            // Subtle race condition: if the source completes before we reach the line below, the SingleAssigmentDisposable
            // will already have been disposed. Upon assignment, the disposable resource being set will be disposed on the
            // spot, which may throw an exception. (Similar to TFS 487142)
            //
            try
            {
                //
                // [OK] Use of unsafe Subscribe: we're catching the exception here to set the TaskCompletionSource.
                //
                // Notice we could use a safe subscription to route errors through OnError, but we still need the
                // exception handling logic here for the reason explained above. We cannot afford to throw here
                // and as a result never set the TaskCompletionSource, so we tunnel everything through here.
                //
                disposable.Disposable = observable.Subscribe/*Unsafe*/ (taskCompletionObserver);
            }
            catch (Exception ex)
            {
                tcs.TrySetException(ex);
            }

            return(tcs.Task);
        }
示例#11
0
 public static IObserver <T> Create <T>(Action <T> onNext, Action onCompleted)
 {
     return(Observer.Create <T>(onNext, Stubs.Throw, onCompleted));
 }
示例#12
0
 public static IObserver <T> Create <T>(Action <T> onNext, Action <Exception> onError)
 {
     return(Observer.Create <T>(onNext, onError, Stubs.Nop));
 }
示例#13
0
 public static IObserver <T> Create <T>(Action <T> onNext)
 {
     return(Observer.Create <T>(onNext, Stubs.Throw, Stubs.Nop));
 }
        static IObservable <T> RepeatUntilCore <T>(this IEnumerable <IObservable <T> > sources, IObservable <Unit> trigger, GameObject lifeTimeChecker)
        {
            return(Observable.Create <T>(observer =>
            {
                var isFirstSubscribe = true;
                var isDisposed = false;
                var isStopped = false;
                var e = sources.AsSafeEnumerable().GetEnumerator();
                var subscription = new SerialDisposable();
                var schedule = new SingleAssignmentDisposable();
                var gate = new object();

                var stopper = trigger.Subscribe(_ =>
                {
                    lock (gate)
                    {
                        isStopped = true;
                        e.Dispose();
                        subscription.Dispose();
                        schedule.Dispose();
                        observer.OnCompleted();
                    }
                }, observer.OnError);

                schedule.Disposable = Scheduler.CurrentThread.Schedule(self =>
                {
                    lock (gate)
                    {
                        if (isDisposed)
                        {
                            return;
                        }
                        if (isStopped)
                        {
                            return;
                        }

                        var current = default(IObservable <T>);
                        var hasNext = false;
                        var ex = default(Exception);

                        try
                        {
                            hasNext = e.MoveNext();
                            if (hasNext)
                            {
                                current = e.Current;
                                if (current == null)
                                {
                                    throw new InvalidOperationException("sequence is null.");
                                }
                            }
                            else
                            {
                                e.Dispose();
                            }
                        }
                        catch (Exception exception)
                        {
                            ex = exception;
                            e.Dispose();
                        }

                        if (ex != null)
                        {
                            stopper.Dispose();
                            observer.OnError(ex);
                            return;
                        }

                        if (!hasNext)
                        {
                            stopper.Dispose();
                            observer.OnCompleted();
                            return;
                        }

                        var source = e.Current;
                        var d = new SingleAssignmentDisposable();
                        subscription.Disposable = d;

                        var repeatObserver = Observer.Create <T>(observer.OnNext, observer.OnError, self);

                        if (isFirstSubscribe)
                        {
                            isFirstSubscribe = false;
                            d.Disposable = source.Subscribe(repeatObserver);
                        }
                        else
                        {
                            MainThreadDispatcher.SendStartCoroutine(SubscribeAfterEndOfFrame(d, source, repeatObserver, lifeTimeChecker));
                        }
                    }
                });

                return new CompositeDisposable(schedule, subscription, stopper, Disposable.Create(() =>
                {
                    lock (gate)
                    {
                        isDisposed = true;
                        e.Dispose();
                    }
                }));
            }));
        }
 public static IObserver <T> Create <T>(Action <T> onNext, Action <Exception> onError, Action onCompleted)
 {
     return(Observer.Create <T>(onNext, onError, onCompleted, Disposable.Empty));
 }
示例#16
0
 public static IDisposable Subscribe <T>(this IObservable <T> source, Action <T> onNext, Action <Exception> onError)
 {
     return(source.Subscribe(Observer.Create <T>(onNext, onError, Stubs.Nop)));
 }