Пример #1
0
        public IDisposable Subscribe(IObserver <ListChange <T> > observer)
        {
            var mapper = new WhereChangeMapper();
            var gate   = new object();

            return(_source.Subscribe(
                       Observer.Create <ListChange <T> >(
                           onNext: change =>
            {
                lock (gate)
                {
                    var newChanges = new List <ListChange <T> >();

                    change(
                        insert: (index, item) => newChanges.AddRange(mapper.Insert(index, item, _predicate(item))),
                        replace: (index, item) => newChanges.AddRange(mapper.Replace(index, item, _predicate(item))),
                        remove: index => newChanges.AddRange(mapper.Remove <T>(index)),
                        clear: () => newChanges.AddRange(mapper.Clear <T>()));

                    if (newChanges.Count > 0)
                    {
                        observer.OnNext(ListChange.Combine(newChanges));
                    }
                }
            },
                           onCompleted: observer.OnCompleted,
                           onError: observer.OnError)));
        }
Пример #2
0
            IObserver <ListChange <T> > LeftObserver()
            {
                return(Observer.Create <ListChange <T> >(
                           onNext: changes =>
                {
                    lock (_gate)
                    {
                        var newChanges = new List <ListChange <T> >();
                        changes(
                            insert: (index, item) =>
                        {
                            newChanges.Add(ListChange.Insert(index, item));
                            ++_leftCount;
                        },
                            replace: (index, item) => { newChanges.Add(ListChange.Replace(index, item)); },
                            remove: index =>
                        {
                            newChanges.Add(ListChange.Remove <T>(index));
                            --_leftCount;
                        },
                            clear: () =>
                        {
                            if (_rightCount == 0)
                            {
                                newChanges.Add(ListChange.Clear <T>());
                            }
                            else
                            {
                                for (var i = _leftCount - 1; i >= 0; --i)
                                {
                                    newChanges.Add(ListChange.Remove <T>(i));
                                }
                            }

                            _leftCount = 0;
                        });
                        if (newChanges.Count > 0)
                        {
                            _observer.OnNext(ListChange.Combine(newChanges));
                        }
                    }
                },
                           onCompleted: () =>
                {
                    lock (_gate)
                    {
                        if (_rightCompleted)
                        {
                            _observer.OnCompleted();
                        }

                        _leftCompleted = true;
                    }
                },
                           onError: e =>
                {
                    lock (_gate)
                        _observer.OnError(e);
                }));
            }
Пример #3
0
        public ListBehaviorSubject(IEnumerable <T> value)
            : this()
        {
            var change = ListChange.Combine(value.Select((item, index) => ListChange.Insert(index, item)).ToArray());

            OnNext(change);
        }
Пример #4
0
        public IDisposable Subscribe(IObserver <ListChange <T> > observer)
        {
            lock (_gate)
            {
                if (_value.Count > 0)
                {
                    var changes = ListChange.Combine(_value.Select((item, index) => ListChange.Insert(index, item)));
                    observer.OnNext(changes);
                }

                switch (_state)
                {
                case State.Unconnected:
                case State.Connected:
                    _observers = _observers.Add(observer);
                    return(Disposable.Create(() =>
                    {
                        lock (_gate)
                            _observers = _observers.Remove(observer);
                    }));

                case State.Completed:
                    observer.OnCompleted();
                    return(Disposable.Empty);

                case State.Error:
                    observer.OnError(_error);
                    return(Disposable.Empty);

                default:
                    throw new Exception("ReplayObservableList.Subscribe: Impossible");
                }
            }
        }
Пример #5
0
 public IDisposable Subscribe(IObserver <ListChange <T> > observer)
 {
     if (_changes == null)
     {
         _changes = ListChange.Combine(_value.Select((t, i) => ListChange.Insert(i, t)));
     }
     observer.OnNext(_changes);
     observer.OnCompleted();
     return(Disposable.Empty);
 }
Пример #6
0
        public IDisposable Subscribe(IObserver <ListChange <T> > observer)
        {
            lock (_mutex)
            {
                var change = ListChange.Combine(_value.Select((item, index) => ListChange.Insert(index, item)).ToArray());
                observer.OnNext(change);

                return(_subject.Subscribe(observer));
            }
        }
Пример #7
0
        public static IObservableList <T> SeparateBy <T>(this IObservableList <T> self, Func <T> separator)
        {
            return(self
                   .SelectWithState(
                       0,
                       (changes, res) =>
            {
                var newChanges = new List <ListChange <T> >();
                var count = res;
                changes(
                    insert: (i, item) =>
                {
                    if (i == count)                                             // inserting at the end
                    {
                        if (count == 0)                                         // inserting first element: skip the separator
                        {
                            newChanges.Add(ListChange.Insert(0, item));
                        }
                        else                                                 // add separator before item
                        {
                            newChanges.Add(ListChange.Insert(i * 2 - 1, separator()));
                            newChanges.Add(ListChange.Insert(i * 2, item));
                        }
                    }
                    else                                             // add separator after item
                    {
                        newChanges.Add(ListChange.Insert(i * 2, item));
                        newChanges.Add(ListChange.Insert(i * 2 + 1, separator()));
                    }
                    ++count;
                },
                    replace: (i, item) =>
                {
                    newChanges.Add(ListChange.Replace(i * 2, item));
                },
                    remove: i =>
                {
                    if (i == count - 1)                                             // removing at the end
                    {
                        if (i == 0)                                                 // removing first element: no separator to remove
                        {
                            newChanges.Add(ListChange.Remove <T>(0));
                        }
                        else                                                  // remove separator before item
                        {
                            newChanges.Add(ListChange.Remove <T>(i * 2));
                            newChanges.Add(ListChange.Remove <T>(i * 2 - 1));
                        }
                    }
                    else                                             // remove separator after item
                    {
                        newChanges.Add(ListChange.Remove <T>(i * 2 + 1));
                        newChanges.Add(ListChange.Remove <T>(i * 2));
                    }
                    --count;
                },
                    clear: () =>
                {
                    newChanges.Add(ListChange.Clear <T>());
                    count = 0;
                });

                return SelectResult.Create(ListChange.Combine(newChanges), count);
            })
                   .UnsafeAsObservableList());
        }