Пример #1
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;
                }
                }
            }
        }
Пример #2
0
        private void Transform(ChangeAwareList <TransformedItemContainer> transformed, IChangeSet <TSource> changes)
        {
            if (changes == null)
            {
                throw new ArgumentNullException(nameof(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, Optional <TDestination> .None, transformed.Count));
                    }
                    else
                    {
                        var converted = _containerFactory(change.Current, Optional <TDestination> .None, change.CurrentIndex);
                        transformed.Insert(change.CurrentIndex, converted);
                    }
                    break;
                }

                case ListChangeReason.AddRange:
                {
                    var startIndex = item.Range.Index < 0 ? transformed.Count : item.Range.Index;

                    transformed.AddOrInsertRange(item.Range
                                                 .Select((t, idx) => _containerFactory(t, Optional <TDestination> .None, idx + startIndex)),
                                                 item.Range.Index);

                    break;
                }

                case ListChangeReason.Refresh:
                {
                    if (_transformOnRefresh)
                    {
                        var change = item.Item;
                        Optional <TDestination> previous = transformed[change.CurrentIndex].Destination;
                        var refreshed = _containerFactory(change.Current, previous, change.CurrentIndex);

                        transformed[change.CurrentIndex] = refreshed;
                    }
                    else
                    {
                        transformed.RefreshAt(item.Item.CurrentIndex);
                    }
                    break;
                }

                case ListChangeReason.Replace:
                {
                    var change = item.Item;
                    Optional <TDestination> previous = transformed[change.PreviousIndex].Destination;
                    if (change.CurrentIndex == change.PreviousIndex)
                    {
                        transformed[change.CurrentIndex] = _containerFactory(change.Current, previous, change.CurrentIndex);
                    }
                    else
                    {
                        transformed.RemoveAt(change.PreviousIndex);
                        transformed.Insert(change.CurrentIndex, _containerFactory(change.Current, Optional <TDestination> .None, change.CurrentIndex));
                    }

                    break;
                }

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

                    if (hasIndex)
                    {
                        transformed.RemoveAt(change.CurrentIndex);
                    }
                    else
                    {
                        var toRemove = transformed.FirstOrDefault(t => ReferenceEquals(t.Source, change.Current));

                        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 => item.Range.Any(current => ReferenceEquals(t.Source, current)));
                        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");
                    }

                    transformed.Move(change.PreviousIndex, change.CurrentIndex);
                    break;
                }
                }
            }
        }
Пример #3
0
        private async Task Transform(ChangeAwareList <TransformedItemContainer> transformed, IChangeSet <TSource> changes)
        {
            if (changes is null)
            {
                throw new ArgumentNullException(nameof(changes));
            }

            foreach (var item in changes)
            {
                switch (item.Reason)
                {
                case ListChangeReason.Add:
                {
                    var change = item.Item;
                    if (change.CurrentIndex < 0 | change.CurrentIndex >= transformed.Count)
                    {
                        var container = await _containerFactory(item.Item.Current).ConfigureAwait(false);

                        transformed.Add(container);
                    }
                    else
                    {
                        var container = await _containerFactory(item.Item.Current).ConfigureAwait(false);

                        transformed.Insert(change.CurrentIndex, container);
                    }

                    break;
                }

                case ListChangeReason.AddRange:
                {
                    var tasks      = item.Range.Select(_containerFactory);
                    var containers = await Task.WhenAll(tasks).ConfigureAwait(false);

                    transformed.AddOrInsertRange(containers, item.Range.Index);
                    break;
                }

                case ListChangeReason.Replace:
                {
                    var change    = item.Item;
                    var container = await _containerFactory(item.Item.Current).ConfigureAwait(false);

                    if (change.CurrentIndex == change.PreviousIndex)
                    {
                        transformed[change.CurrentIndex] = container;
                    }
                    else
                    {
                        transformed.RemoveAt(change.PreviousIndex);
                        transformed.Insert(change.CurrentIndex, container);
                    }

                    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 is not 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");
                    }

                    if (transformed is IExtendedList <TransformedItemContainer> collection)
                    {
                        collection.Move(change.PreviousIndex, change.CurrentIndex);
                    }
                    else
                    {
                        var current = transformed[change.PreviousIndex];
                        transformed.RemoveAt(change.PreviousIndex);
                        transformed.Insert(change.CurrentIndex, current);
                    }

                    break;
                }
                }
            }
        }