public IObservable <IChangeSet <T> > Run() { return(Observable.Create <IChangeSet <T> >(observer => { var disposable = new CompositeDisposable(); lock (_locker) { foreach (var item in _source) { var list = new ReferenceCountTracker <T>(); _sourceLists.Add(list); disposable.Add(item.Synchronize(_locker).Subscribe(changes => { CloneSourceList(list, changes); var notifications = UpdateResultList(changes); if (notifications.Count != 0) { observer.OnNext(notifications); } })); } } return disposable; })); }
private void CloneSourceList(ReferenceCountTracker <T> tracker, IChangeSet <T> changes) { changes.ForEach(change => { switch (change.Reason) { case ListChangeReason.Add: tracker.Add(change.Item.Current); break; case ListChangeReason.AddRange: foreach (var t in change.Range) { tracker.Add(t); } break; case ListChangeReason.Replace: tracker.Remove(change.Item.Previous.Value); tracker.Add(change.Item.Current); break; case ListChangeReason.Remove: tracker.Remove(change.Item.Current); break; case ListChangeReason.RemoveRange: case ListChangeReason.Clear: foreach (var t in change.Range) { tracker.Remove(t); } break; //case ListChangeReason.Clear: // tracker.Clear(); // break; } }); }