示例#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();
                 }
             }
         }
     })));
 }
示例#2
0
        public Optional <ListChange <T> > Insert <T>(int index, T item, bool predicateTrue)
        {
            var toIndex = _items.Sum(index);

            _items = _items.Insert(index, predicateTrue ? 1 : 0);

            return(predicateTrue
                                ? ListChange.Insert(toIndex, item)
                                : Optional.None <ListChange <T> >());
        }
示例#3
0
        public Optional <ListChange <T> > Clear <T>()
        {
            var oldTrueCount = _items.Sum();

            _items = _items.Clear();

            return(oldTrueCount == 0
                                ? Optional.None <ListChange <T> >()
                                : ListChange.Clear <T>());
        }
示例#4
0
 public void OnError(Exception error)
 {
     lock (_gate)
     {
         _observer.OnError(error);
         Disposable.Combine(_innerSubscriptions).Dispose();
         _innerSubscriptions.Clear();
         _innerCompleted = SumTree <bool> .Empty(false, (d1, d2) => d1 && d2);
     }
 }
示例#5
0
        public Optional <ListChange <T> > Remove <T>(int index)
        {
            var toIndex       = _items.Sum(index);
            var predicateTrue = _items[index] == 1;

            _items = _items.RemoveAt(index);

            return(predicateTrue
                                ? ListChange.Remove <T>(toIndex)
                                : Optional.None <ListChange <T> >());
        }
示例#6
0
 public static IObservable <T> AggregateAssoc <T>(
     this IObservableList <T> self,
     T seed,
     Func <T, T, T> associativeAccumulator)
 {
     return(self
            .Scan(
                SumTree <T> .Empty(seed, associativeAccumulator),
                (tree, changes) => changes.Apply(tree))
            .Select(tree => tree.Sum()));
 }
示例#7
0
        public static SumTree <T> Apply <T>(this ListChange <T> changes, SumTree <T> tree)
        {
            var result = tree;

            changes(
                insert: (i, x) => result  = result.Insert(i, x),
                replace: (i, x) => result = result.ReplaceAt(i, x),
                remove: i => result       = result.RemoveAt(i),
                clear: () => result       = result.Clear());
            return(result);
        }
示例#8
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);
                        }
                    });
                }
            }
示例#9
0
        public Optional <ListChange <T> > Replace <T>(int index, T item, bool predicateTrue)
        {
            var toIndex = _items.Sum(index);

            var oldPredicateTrue = _items[index] == 1;

            _items = _items.ReplaceAt(index, predicateTrue ? 1 : 0);

            if (predicateTrue)
            {
                return(oldPredicateTrue
                                        ? ListChange.Replace(toIndex, item)
                                        : ListChange.Insert(toIndex, item));
            }
            else
            {
                return(oldPredicateTrue
                                        ? ListChange.Remove <T>(toIndex)
                                        : Optional.None <ListChange <T> >());
            }
        }
示例#10
0
 public void InsertFalse(int index)
 {
     _items = _items.Insert(index, 0);
 }