private IChangeSet <T> ProcessImpl(IChangeSet <T> changes) { changes.ForEach(change => { switch (change.Reason) { case ListChangeReason.Add: { var current = change.Item.Current; Insert(current); break; } case ListChangeReason.AddRange: { var ordered = change.Range.OrderBy(t => t, _comparer).ToList(); if (_innerList.Count == 0) { _innerList.AddRange(ordered); } else { ordered.ForEach(Insert); } break; } case ListChangeReason.Replace: { var current = change.Item.Current; //TODO: check whether an item should stay in the same position //i.e. update and move Remove(change.Item.Previous.Value); Insert(current); break; } case ListChangeReason.Remove: { var current = change.Item.Current; Remove(current); break; } case ListChangeReason.RemoveRange: { _innerList.RemoveMany(change.Range); break; } case ListChangeReason.Clear: { _innerList.Clear(); break; } } }); return(_innerList.CaptureChanges()); }
private IChangeSet <TDestination> Process(ChangeAwareList <TDestination> transformed, IChangeSet <TSource> source) { //TODO: This is very inefficient as it flattens range operation //need to find a means of re-forming ranges var children = source.Unified().SelectMany(change => { var many = _manyselector(change.Current); return(many.Select(m => new TransformedItem <TDestination>(change.Reason, m))); }); foreach (var child in children) { switch (child.Reason) { case ListChangeReason.Add: transformed.Add(child.Current); break; case ListChangeReason.Replace: transformed.Remove(child.Previous.Value); transformed.Add(child.Current); break; case ListChangeReason.Remove: transformed.Remove(child.Current); break; case ListChangeReason.Clear: transformed.Clear(); break; } } return(transformed.CaptureChanges()); }
private IChangeSet <T> ProcessImpl(ChangeAwareList <T> target, IChangeSet <T> changes) { foreach (var change in changes) { switch (change.Reason) { case ListChangeReason.Add: { var current = change.Item.Current; Insert(target, current); break; } case ListChangeReason.AddRange: { var ordered = change.Range.OrderBy(t => t, _comparer).ToList(); if (target.Count == 0) { target.AddRange(ordered); } else { ordered.ForEach(item => Insert(target, item)); } break; } case ListChangeReason.Replace: { var current = change.Item.Current; //TODO: check whether an item should stay in the same position //i.e. update and move Remove(target, change.Item.Previous.Value); Insert(target, current); break; } case ListChangeReason.Remove: { var current = change.Item.Current; Remove(target, current); break; } case ListChangeReason.RemoveRange: { target.RemoveMany(change.Range); break; } case ListChangeReason.Clear: { target.Clear(); break; } } } return(target.CaptureChanges()); }
private IChangeSet <T> Reset(ChangeAwareList <T> original, ChangeAwareList <T> target) { var sorted = original.OrderBy(t => t, _comparer).ToList(); target.Clear(); target.AddRange(sorted); return(target.CaptureChanges()); }
private IChangeSet <T> ChangeComparer(ChangeAwareList <T> target, IComparer <T> comparer) { _comparer = comparer; var sorted = target.OrderBy(t => t, _comparer).ToList(); target.Clear(); target.AddRange(sorted); return(target.CaptureChanges()); }
private IChangeSet <TValue> Process(IChangeSet <ItemWithValue <T, TValue> > updates) { Action <TValue> addAction = value => _valueCounters.Lookup(value) .IfHasValue(count => _valueCounters[value] = count + 1) .Else(() => { _valueCounters[value] = 1; _result.Add(value); }); Action <TValue> removeAction = value => { var counter = _valueCounters.Lookup(value); if (!counter.HasValue) { return; } //decrement counter var newCount = counter.Value - 1; _valueCounters[value] = newCount; if (newCount != 0) { return; } //if there are none, then remove and notify _result.Remove(value); }; foreach (var change in updates) { switch (change.Reason) { case ListChangeReason.Add: { var value = change.Item.Current.Value; addAction(value); break; } case ListChangeReason.AddRange: { change.Range.Select(item => item.Value).ForEach(addAction); break; } // case ListChangeReason.Evaluate: case ListChangeReason.Replace: { var value = change.Item.Current.Value; var previous = change.Item.Previous.Value.Value; if (value.Equals(previous)) { return(_result.CaptureChanges()); } removeAction(previous); addAction(value); break; } case ListChangeReason.Remove: { var previous = change.Item.Current.Value; removeAction(previous); break; } case ListChangeReason.RemoveRange: { change.Range.Select(item => item.Value).ForEach(removeAction); break; } case ListChangeReason.Clear: { _result.Clear(); _valueCounters.Clear(); break; } } } return(_result.CaptureChanges()); }