Exemple #1
0
        private IChangeSet <T> Page(IChangeSet <T> changeset = null)
        {
            if (changeset != null)
            {
                _all.Clone(changeset);
            }

            var previous = _paged;

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

            var current = _all.Skip(skip)
                          .Take(_parameters.Size)
                          .ToList();

            var adds    = current.Except(previous);
            var removes = previous.Except(current);

            _paged.RemoveMany(removes);

            adds.ForEach(t =>
            {
                var index = current.IndexOf(t);
                _paged.Insert(index, t);
            });

            var startIndex = skip;

            var moves = changeset.EmptyIfNull()
                        .Where(change => change.Reason == ListChangeReason.Moved &&
                               change.MovedWithinRange(startIndex, startIndex + _parameters.Size));

            foreach (var change in moves)
            {
                //check whether an item has moved within the same page
                var currentIndex  = change.Item.CurrentIndex - startIndex;
                var previousIndex = change.Item.PreviousIndex - startIndex;
                _paged.Move(previousIndex, currentIndex);
            }

            //find replaces [Is this ever the case that it can be reached]
            for (int i = 0; i < current.Count; i++)
            {
                var currentItem  = current[i];
                var previousItem = previous[i];

                if (ReferenceEquals(currentItem, previousItem))
                {
                    continue;
                }

                var index = _paged.IndexOf(currentItem);
                _paged.Move(i, index);
            }
            return(_paged.CaptureChanges());
        }
Exemple #2
0
        private IChangeSet <T> Virtualise(List <T> all, ChangeAwareList <T> virtualised, IChangeSet <T> changeset = null)
        {
            if (changeset != null)
            {
                all.Clone(changeset);
            }

            var previous = virtualised;

            var current = all.Skip(_parameters.StartIndex)
                          .Take(_parameters.Size)
                          .ToList();

            var adds    = current.Except(previous);
            var removes = previous.Except(current);

            virtualised.RemoveMany(removes);

            adds.ForEach(t =>
            {
                var index = current.IndexOf(t);
                virtualised.Insert(index, t);
            });

            var moves = changeset.EmptyIfNull()
                        .Where(change => change.Reason == ListChangeReason.Moved &&
                               change.MovedWithinRange(_parameters.StartIndex, _parameters.StartIndex + _parameters.Size));

            foreach (var change in moves)
            {
                //check whether an item has moved within the same page
                var currentIndex  = change.Item.CurrentIndex - _parameters.StartIndex;
                var previousIndex = change.Item.PreviousIndex - _parameters.StartIndex;
                virtualised.Move(previousIndex, currentIndex);
            }

            //find replaces [Is this ever the case that it can be reached]
            for (var i = 0; i < current.Count; i++)
            {
                var currentItem  = current[i];
                var previousItem = previous[i];

                if (ReferenceEquals(currentItem, previousItem))
                {
                    continue;
                }

                var index = virtualised.IndexOf(currentItem);
                virtualised.Move(i, index);
            }
            return(virtualised.CaptureChanges());
        }
Exemple #3
0
        private void Transform(ChangeAwareList <TransformedItemContainer> transformed, IChangeSet <TSource> changes)
        {
            if (changes == null)
            {
                throw new ArgumentNullException(nameof(changes));
            }

            transformed.EnsureCapacityFor(changes);

            foreach (var item in changes)
            {
                switch (item.Reason)
                {
                case ListChangeReason.Add:
                {
                    var change = item.Item;
                    if (change.CurrentIndex < 0 | change.CurrentIndex >= transformed.Count)
                    {
                        transformed.Add(_containerFactory(change.Current));
                    }
                    else
                    {
                        transformed.Insert(change.CurrentIndex, _containerFactory(change.Current));
                    }
                    break;
                }

                case ListChangeReason.AddRange:
                {
                    transformed.AddOrInsertRange(item.Range.Select(_containerFactory), item.Range.Index);
                    break;
                }

                case ListChangeReason.Replace:
                {
                    var change = item.Item;
                    if (change.CurrentIndex == change.PreviousIndex)
                    {
                        transformed[change.CurrentIndex] = _containerFactory(change.Current);
                    }
                    else
                    {
                        transformed.RemoveAt(change.PreviousIndex);
                        transformed.Insert(change.CurrentIndex, _containerFactory(change.Current));
                    }

                    break;
                }

                case ListChangeReason.Remove:
                {
                    var  change   = item.Item;
                    bool hasIndex = change.CurrentIndex >= 0;

                    if (hasIndex)
                    {
                        transformed.RemoveAt(item.Item.CurrentIndex);
                    }
                    else
                    {
                        var toremove = transformed.FirstOrDefault(t => ReferenceEquals(t.Source, t));

                        if (toremove != null)
                        {
                            transformed.Remove(toremove);
                        }
                    }

                    break;
                }

                case ListChangeReason.RemoveRange:
                {
                    if (item.Range.Index >= 0)
                    {
                        transformed.RemoveRange(item.Range.Index, item.Range.Count);
                    }
                    else
                    {
                        var toremove = transformed.Where(t => ReferenceEquals(t.Source, t)).ToArray();
                        transformed.RemoveMany(toremove);
                    }

                    break;
                }

                case ListChangeReason.Clear:
                {
                    //i.e. need to store transformed reference so we can correctly clear
                    var toClear = new Change <TransformedItemContainer>(ListChangeReason.Clear, transformed);
                    transformed.ClearOrRemoveMany(toClear);

                    break;
                }

                case ListChangeReason.Moved:
                {
                    var  change   = item.Item;
                    bool hasIndex = change.CurrentIndex >= 0;
                    if (!hasIndex)
                    {
                        throw new UnspecifiedIndexException("Cannot move as an index was not specified");
                    }

                    var collection = transformed as IExtendedList <TransformedItemContainer>;
                    if (collection != null)
                    {
                        collection.Move(change.PreviousIndex, change.CurrentIndex);
                    }
                    else
                    {
                        var current = transformed[change.PreviousIndex];
                        transformed.RemoveAt(change.PreviousIndex);
                        transformed.Insert(change.CurrentIndex, current);
                    }
                    break;
                }
                }
            }
        }
Exemple #4
0
        private void Insert(ChangeAwareList <T> target, T item)
        {
            var index = GetInsertPosition(target, item);

            target.Insert(index, item);
        }
Exemple #5
0
        private void Insert(T item)
        {
            var index = GetInsertPosition(item);

            _innerList.Insert(index, item);
        }