Пример #1
0
            private IVirtualChangeSet <TObject, TKey> Virtualise(ISortedChangeSet <TObject, TKey> updates = null)
            {
                if (_isLoaded == false)
                {
                    return(null);
                }

                var previous   = _current;
                var virualised = _all.Skip(_parameters.StartIndex)
                                 .Take(_parameters.Size)
                                 .ToList();

                _current = new KeyValueCollection <TObject, TKey>(virualised, _all.Comparer, updates?.SortedItems.SortReason ?? SortReason.DataChanged, _all.Optimisations);

                ////check for changes within the current virtualised page.  Notify if there have been changes or if the overall count has changed
                var notifications = _changedCalculator.Calculate(_current, previous, updates);

                if (notifications.Count == 0 && (previous.Count != _current.Count))
                {
                    return(null);
                }

                var response = new VirtualResponse(_parameters.Size, _parameters.StartIndex, _all.Count);

                return(new VirtualChangeSet <TObject, TKey>(notifications, _current, response));
            }
Пример #2
0
        private void DoUpdate(ISortedChangeSet <TObject, TKey> updates, IObservableCollection <TObject> list)
        {
            updates.ForEach(update =>
            {
                switch (update.Reason)
                {
                case ChangeReason.Add:
                    list.Insert(update.CurrentIndex, update.Current);
                    break;

                case ChangeReason.Remove:
                    list.RemoveAt(update.CurrentIndex);
                    break;

                case ChangeReason.Moved:
                    list.Move(update.PreviousIndex, update.CurrentIndex);
                    break;

                case ChangeReason.Update:
                    {
                        list.RemoveAt(update.PreviousIndex);
                        list.Insert(update.CurrentIndex, update.Current);
                    }
                    break;
                }
            });
        }
Пример #3
0
        /// <summary>
        /// Maintains the specified collection from the changes
        /// </summary>
        /// <param name="changes">The changes.</param>
        /// <param name="collection">The collection.</param>
        public void Adapt(ISortedChangeSet <TObject, TKey> changes, IObservableCollection <TObject> collection)
        {
            switch (changes.SortedItems.SortReason)
            {
            case SortReason.InitialLoad:
            {
                if (changes.Count > _refreshThreshold())
                {
                    using (collection.SuspendNotifications())
                    {
                        collection.Load(changes.SortedItems.Select(kv => kv.Value));
                    }
                }
                else
                {
                    using (collection.SuspendCount())
                    {
                        DoUpdate(changes, collection);
                    }
                }
            }
            break;

            case SortReason.ComparerChanged:
            case SortReason.Reset:
                using (collection.SuspendNotifications())
                {
                    collection.Load(changes.SortedItems.Select(kv => kv.Value));
                }
                break;

            case SortReason.DataChanged:
                if (changes.Count > _refreshThreshold())
                {
                    using (collection.SuspendNotifications())
                    {
                        collection.Load(changes.SortedItems.Select(kv => kv.Value));
                    }
                }
                else
                {
                    using (collection.SuspendCount())
                    {
                        DoUpdate(changes, collection);
                    }
                }
                break;

            case SortReason.Reorder:
                //Updates will only be moves, so appply logic
                using (collection.SuspendCount())
                {
                    DoUpdate(changes, collection);
                }
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
        private void DoUpdate(ISortedChangeSet <TObject, TKey> changes)
        {
            foreach (var change in changes)
            {
                switch (change.Reason)
                {
                case ChangeReason.Add:
                    _list.Insert(change.CurrentIndex, change.Current);
                    break;

                case ChangeReason.Remove:
                    _list.RemoveAt(change.CurrentIndex);
                    break;

                case ChangeReason.Moved:
                    _list.RemoveAt(change.PreviousIndex);
                    _list.Insert(change.CurrentIndex, change.Current);
                    break;

                case ChangeReason.Update:
                    _list.RemoveAt(change.PreviousIndex);
                    _list.Insert(change.CurrentIndex, change.Current);
                    break;
                }
            }
        }
Пример #5
0
            private IPagedChangeSet <TObject, TKey>?Paginate(ISortedChangeSet <TObject, TKey>?updates = null)
            {
                if (_isLoaded == false)
                {
                    return(null);
                }

                var previous = _current;

                int pages = CalculatePages();
                int page  = _request.Page > pages ? pages : _request.Page;
                int skip  = _request.Size * (page - 1);

                var paged = _all.Skip(skip).Take(_request.Size).ToList();

                _current = new KeyValueCollection <TObject, TKey>(paged, _all.Comparer, updates?.SortedItems.SortReason ?? SortReason.DataChanged, _all.Optimisations);

                // check for changes within the current virtualised page.  Notify if there have been changes or if the overall count has changed
                var notifications = FilteredIndexCalculator <TObject, TKey> .Calculate(_current, previous, updates);

                if (notifications.Count == 0 && (previous.Count != _current.Count))
                {
                    return(null);
                }

                var response = new PageResponse(_request.Size, _all.Count, page, pages);

                return(new PagedChangeSet <TObject, TKey>(_current, notifications, response));
            }
Пример #6
0
        private void DoUpdate(ISortedChangeSet <TObject, TKey> updates, IObservableCollection <TObject> list)
        {
            foreach (var update in updates)
            {
                switch (update.Reason)
                {
                case ChangeReason.Add:
                    list.Insert(update.CurrentIndex, update.Current);
                    break;

                case ChangeReason.Remove:
                    list.RemoveAt(update.CurrentIndex);
                    break;

                case ChangeReason.Moved:
                    list.Move(update.PreviousIndex, update.CurrentIndex);
                    break;

                case ChangeReason.Update:
                    if (update.PreviousIndex != update.CurrentIndex)
                    {
                        list.RemoveAt(update.PreviousIndex);
                        list.Insert(update.CurrentIndex, update.Current);
                    }
                    else
                    {
                        list.Replace(update.Previous.Value, update.Current);
                    }

                    break;
                }
            }
        }
        /// <inheritdoc />
        public void Adapt(ISortedChangeSet <TObject, TKey> changes)
        {
            if (changes == null)
            {
                throw new ArgumentNullException(nameof(changes));
            }

            switch (changes.SortedItems.SortReason)
            {
            case SortReason.InitialLoad:
            case SortReason.ComparerChanged:
            case SortReason.Reset:
                using (new BindingListEventsSuspender <TObject>(_list))
                {
                    _list.Clear();
                    _list.AddRange(changes.SortedItems.Select(kv => kv.Value));
                }

                break;

            case SortReason.DataChanged:
                if (changes.Count - changes.Refreshes > _refreshThreshold)
                {
                    using (new BindingListEventsSuspender <TObject>(_list))
                    {
                        _list.Clear();
                        _list.AddRange(changes.SortedItems.Select(kv => kv.Value));
                    }
                }
                else
                {
                    DoUpdate(changes);
                }

                break;

            case SortReason.Reorder:
                DoUpdate(changes);
                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(changes));
            }
        }
Пример #8
0
        /// <summary>
        /// Adapts the specified sorted changeset
        /// </summary>
        /// <param name="changes">The changes.</param>
        public void Adapt(ISortedChangeSet <TObject, TKey> changes)
        {
            switch (changes.SortedItems.SortReason)
            {
            case SortReason.InitialLoad:
            case SortReason.ComparerChanged:
            case SortReason.Reset:
            {
                using (_target.SuppressChangeNotifications())
                {
                    _target.Clear();
                    _target.AddRange(changes.SortedItems.Select(kv => kv.Value));
                }
            }
            break;

            case SortReason.DataChanged:
            {
                if (changes.Count > _resetThreshold)
                {
                    using (_target.SuppressChangeNotifications())
                    {
                        _target.Clear();
                        _target.AddRange(changes.SortedItems.Select(kv => kv.Value));
                    }
                }
                else
                {
                    DoUpdate(changes);
                }
            }
            break;

            case SortReason.Reorder:

                //Updates will only be moves, so appply logic
                DoUpdate(changes);
                break;


            default:
                throw new ArgumentOutOfRangeException();
            }
        }
Пример #9
0
        public void TreatMovesAsRemoveAdd()
        {
            var cache = new SourceCache <Person, string>(p => p.Name);

            var people       = Enumerable.Range(0, 10).Select(age => new Person("Person" + age, age)).ToList();
            var importantGuy = people.First();

            cache.AddOrUpdate(people);

            ISortedChangeSet <Person, string> latestSetWithoutMoves = null;
            ISortedChangeSet <Person, string> latestSetWithMoves    = null;

            var boundList1 = new ReactiveList <Person>();
            var boundList2 = new ReactiveList <Person>();


            using (cache.Connect()
                   .AutoRefresh(p => p.Age)
                   .Sort(SortExpressionComparer <Person> .Ascending(p => p.Age))
                   .TreatMovesAsRemoveAdd()
                   .Bind(boundList1)
                   .Subscribe(set => latestSetWithoutMoves = set))

                using (cache.Connect()
                       .AutoRefresh(p => p.Age)
                       .Sort(SortExpressionComparer <Person> .Ascending(p => p.Age))
                       .Bind(boundList2)
                       .Subscribe(set => latestSetWithMoves = set))
                {
                    importantGuy.Age = importantGuy.Age + 200;


                    latestSetWithoutMoves.Removes.Should().Be(1);
                    latestSetWithoutMoves.Adds.Should().Be(1);
                    latestSetWithoutMoves.Moves.Should().Be(0);
                    latestSetWithoutMoves.Updates.Should().Be(0);

                    latestSetWithMoves.Moves.Should().Be(1);
                    latestSetWithMoves.Updates.Should().Be(0);
                    latestSetWithMoves.Removes.Should().Be(0);
                    latestSetWithMoves.Adds.Should().Be(0);
                }
        }
        public void TreatMovesAsRemoveAdd()
        {
            var cache = new SourceCache <Person, string>(p => p.Name);

            var people       = Enumerable.Range(0, 10).Select(age => new Person("Person" + age, age)).ToList();
            var importantGuy = people.First();

            cache.AddOrUpdate(people);

            ISortedChangeSet <Person, string>?latestSetWithoutMoves = null;
            ISortedChangeSet <Person, string>?latestSetWithMoves    = null;

            var boundList1 = new ObservableCollectionExtended <Person>();
            var boundList2 = new ObservableCollectionExtended <Person>();

            using (cache.Connect().AutoRefresh(p => p.Age).Sort(SortExpressionComparer <Person> .Ascending(p => p.Age)).TreatMovesAsRemoveAdd().Bind(boundList1).Subscribe(set => latestSetWithoutMoves = set))

                using (cache.Connect().AutoRefresh(p => p.Age).Sort(SortExpressionComparer <Person> .Ascending(p => p.Age)).Bind(boundList2).Subscribe(set => latestSetWithMoves = set))
                {
                    if (latestSetWithoutMoves is null)
                    {
                        throw new InvalidOperationException(nameof(latestSetWithoutMoves));
                    }

                    if (latestSetWithMoves is null)
                    {
                        throw new InvalidOperationException(nameof(latestSetWithMoves));
                    }

                    importantGuy.Age += 200;
                    latestSetWithoutMoves.Should().NotBeNull();
                    latestSetWithoutMoves.Removes.Should().Be(1);
                    latestSetWithoutMoves.Adds.Should().Be(1);
                    latestSetWithoutMoves.Moves.Should().Be(0);
                    latestSetWithoutMoves.Updates.Should().Be(0);

                    latestSetWithMoves.Moves.Should().Be(1);
                    latestSetWithMoves.Updates.Should().Be(0);
                    latestSetWithMoves.Removes.Should().Be(0);
                    latestSetWithMoves.Adds.Should().Be(0);
                }
        }
Пример #11
0
 public IVirtualChangeSet <TObject, TKey> Update(ISortedChangeSet <TObject, TKey> updates)
 {
     _isLoaded = true;
     _all      = updates.SortedItems;
     return(Virtualise(updates));
 }
Пример #12
0
 public IPagedChangeSet <TObject, TKey>?Update(ISortedChangeSet <TObject, TKey> updates)
 {
     _isLoaded = true;
     _all      = updates.SortedItems;
     return(Paginate(updates));
 }