Esempio n. 1
0
        public IObservable <IChangeSet <T> > Run()
        {
            return(Observable.Create <IChangeSet <T> >(observer =>
            {
                var disposable = new CompositeDisposable();
                var sourceLists = new List <ReferenceCountTracker <T> >();
                var resultList = new ChangeAwareListWithRefCounts <T>();

                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, sourceLists, resultList);
                            if (notifications.Count != 0)
                            {
                                observer.OnNext(notifications);
                            }
                        }));
                    }
                }
                return disposable;
            }));
        }
Esempio n. 2
0
        private static void CloneSourceList(ReferenceCountTracker <T> tracker, IChangeSet <T> changes)
        {
            foreach (var change in changes)
            {
                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;
                }
            }
        }