Example #1
0
 IDisposable SubscribeInner(IObservable <T> obs, IndexTrackerList <SingleAssignmentDisposable> .IndexedItem indexedItem)
 {
     return(obs.Subscribe(
                Observer.Create <T>(
                    onNext: item =>
     {
         lock (_gate)
             foreach (var currentIndex in indexedItem.Index)
             {
                 foreach (var change in _changeMapper.Replace(currentIndex, item, true))
                 {
                     _observer.OnNext(change);
                 }
             }
     },
                    onError: OnError,
                    onCompleted: () =>
     {
         lock (_gate)
         {
             foreach (var currentIndex in indexedItem.Index)
             {
                 _innerSubscriptions[currentIndex].Dispose();
                 _innerCompleted = _innerCompleted.ReplaceAt(currentIndex, true);
                 if (_outerCompleted && _innerCompleted.Sum())
                 {
                     Disposable.Combine(_innerSubscriptions).Dispose();
                     _innerSubscriptions.Clear();
                     _observer.OnCompleted();
                 }
             }
         }
     })));
 }
Example #2
0
            public void OnNext(ListChange <IObservable <T> > changes)
            {
                lock (_gate)
                {
                    changes(
                        insert: (index, obs) =>
                    {
                        var indexedItem = new IndexTrackerList <SingleAssignmentDisposable> .IndexedItem(new SingleAssignmentDisposable());
                        _innerSubscriptions.Insert(index, indexedItem);
                        _changeMapper.InsertFalse(index);
                        _innerCompleted = _innerCompleted.Insert(index, false);

                        indexedItem.Value.Disposable = SubscribeInner(obs, indexedItem);
                    },
                        replace: (index, obs) =>
                    {
                        _innerSubscriptions[index].Dispose();
                        var indexedItem = new IndexTrackerList <SingleAssignmentDisposable> .IndexedItem(new SingleAssignmentDisposable());
                        _innerSubscriptions.Replace(index, indexedItem);
                        _innerCompleted = _innerCompleted.ReplaceAt(index, false);

                        indexedItem.Value.Disposable = SubscribeInner(obs, indexedItem);
                        // The new observable hasn't produced any values left, so remove any leftover old values
                        foreach (var change in _changeMapper.ReplaceFalse <T>(index))
                        {
                            _observer.OnNext(change);
                        }
                    },
                        remove: (index) =>
                    {
                        _innerSubscriptions[index].Dispose();
                        _innerSubscriptions.Remove(index);
                        _innerCompleted = _innerCompleted.RemoveAt(index);
                        foreach (var change in _changeMapper.Remove <T>(index))
                        {
                            _observer.OnNext(change);
                        }
                    },
                        clear: () =>
                    {
                        Disposable.Combine(_innerSubscriptions).Dispose();
                        _innerSubscriptions.Clear();
                        _innerCompleted = SumTree <bool> .Empty(false, (d1, d2) => d1 && d2);
                        foreach (var change in _changeMapper.Clear <T>())
                        {
                            _observer.OnNext(change);
                        }
                    });
                }
            }