Esempio n. 1
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");
                }
            }
        }
Esempio n. 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);
                }));
            }
Esempio n. 3
0
        public ListBehaviorSubject(IEnumerable <T> value)
            : this()
        {
            var change = ListChange.Combine(value.Select((item, index) => ListChange.Insert(index, item)).ToArray());

            OnNext(change);
        }
Esempio n. 4
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)));
        }
Esempio n. 5
0
 public void OnNext(ListChange <T> change)
 {
     lock (_mutex)
     {
         _value = change.Apply(_value);
         _subject.OnNext(change);
     }
 }
Esempio n. 6
0
 public static void ApplyLegacy <T>(this ListChange <T> changes, IList list)
 {
     changes(
         insert: (i, x) => list.Insert(i, x),
         replace: (i, x) => list[i] = x,
         remove: list.RemoveAt,
         clear: list.Clear);
 }
Esempio n. 7
0
 public static ListChange <TResult> Select <TSource, TResult>(this ListChange <TSource> self, Func <TSource, TResult> select)
 {
     return((insert, replace, remove, clear) =>
            self(
                insert: (i, x) => insert(i, select(x)),
                replace: (i, x) => replace(i, select(x)),
                remove: remove,
                clear: clear));
 }
Esempio n. 8
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);
 }
Esempio n. 9
0
        public Optional <ListChange <T> > Clear <T>()
        {
            var oldTrueCount = _items.Sum();

            _items = _items.Clear();

            return(oldTrueCount == 0
                                ? Optional.None <ListChange <T> >()
                                : ListChange.Clear <T>());
        }
Esempio n. 10
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> >());
        }
Esempio n. 11
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));
            }
        }
Esempio n. 12
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> >());
        }
Esempio n. 13
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);
        }
Esempio n. 14
0
        public static ImmutableList <T> Apply <T>(this ListChange <T> changes, ImmutableList <T> list)
        {
            var result = list;

            changes(
                insert: (i, x) => result  = result.Insert(i, x),
                replace: (i, x) => result = result.SetItem(i, x),
                remove: i => result       = result.RemoveAt(i),
                clear: () => result       = ImmutableList <T> .Empty);
            return(result);
        }
Esempio n. 15
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);
                        }
                    });
                }
            }
Esempio n. 16
0
 public static IObservableList <T> ToObservableList <T>(this IObservable <IImmutableList <T> > self)
 {
     return(self
            .Scan(
                new
     {
         PrevList = (IImmutableList <T>)ImmutableList <T> .Empty,
         Changes = Optional.None <ListChange <T> >()
     },
                (acc, newList) => new
     {
         PrevList = newList,
         Changes = ListChange.IncrementalChanges(acc.PrevList, newList),
     })
            .SelectMany(acc => acc.Changes)
            .UnsafeAsObservableList());
 }
Esempio n. 17
0
        public static string ToString <T>(this ListChange <T> self)
        {
            var results = new List <string>();

            self(
                insert: (index, item) => results.Add("ListChange.Insert(" + index + ", " + item + ")"),
                replace: (index, item) => results.Add("ListChange.Replace(" + index + ", " + item + ")"),
                remove: index => results.Add("ListChange.Remove(" + index + ")"),
                clear: () => results.Add("ListChange.Clear()"));

            if (results.Count == 0)
            {
                return("ListChange.None()");
            }
            if (results.Count == 1)
            {
                return(results[0]);
            }
            return("ListChange.Combine(" + results.Join(", ") + ")");
        }
Esempio n. 18
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> >());
            }
        }
Esempio n. 19
0
 public T this[int i]
 {
     get { return(_value[i]); }
     set { OnNext(ListChange.Replace(i, value)); }
 }
Esempio n. 20
0
 public void OnInsert(int index, T item)
 {
     OnNext(ListChange.Insert(index, item));
 }
Esempio n. 21
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());
        }
Esempio n. 22
0
 public void OnRemove(int index)
 {
     OnNext(ListChange.Remove <T>(index));
 }
Esempio n. 23
0
 public void OnReplace(int index, T item)
 {
     OnNext(ListChange.Replace(index, item));
 }
Esempio n. 24
0
 public void OnClear()
 {
     OnNext(ListChange.Clear <T>());
 }
Esempio n. 25
0
 public void OnAdd(T item)
 {
     lock (_mutex)
         OnNext(ListChange.Insert(_value.Count, item));
 }
Esempio n. 26
0
 public static IObservableList <T> Switch <T>(this IObservable <IObservableList <T> > self)
 {
     return(self.Select(ol => ol.StartWith(ListChange.Clear <T>())).Switch().UnsafeAsObservableList());
 }