// *** Protected Methods *** protected void PostUpdate(DataListUpdate update) { foreach (IUpdatableCollection collection in updateSubscriptions) { collection.Update(update); } }
// *** Private Methods *** private void ProcessUpdate_Add(DataListUpdate update) { // If the update is outside of the bounds of the 'count' then simply consume the event if (update.Index >= count) { return; } // Forward the 'Add' update to any subscribers // NB: The number of items added may need to be trimmed if they will exceed the bounds of the Take int itemsAdded = Math.Min(update.Count, count - update.Index); PostUpdate(new DataListUpdate(DataListUpdateAction.Add, update.Index, itemsAdded)); // If the 'Add' operation has pushed some items outside of the bounds of the Take then these will need to be removed int oldCount = Math.Min(sourceCount, count); int itemsRemoved = oldCount + itemsAdded - count; if (itemsRemoved > 0) { PostUpdate(new DataListUpdate(DataListUpdateAction.Remove, count, itemsRemoved)); } // Set the last known source count sourceCount += update.Count; }
private void ProcessUpdate_Remove(DataListUpdate update) { // If the update is outside of the bounds of the 'count' then simply consume the event if (update.Index >= count) { return; } // Forward the 'Remove' update to any subscribers // NB: The number of items removed may need to be trimmed if they exceed the bounds of the Take int itemsRemoved = Math.Min(update.Count, count - update.Index); PostUpdate(new DataListUpdate(DataListUpdateAction.Remove, update.Index, itemsRemoved)); // If the 'Remove' operation has pulled in some items outside of the bounds of the Take then these will need to be added int itemsAvailable = sourceCount - Math.Max(update.Index + update.Count, count); int itemsAdded = Math.Min(itemsRemoved, itemsAvailable); if (itemsAdded > 0) { PostUpdate(new DataListUpdate(DataListUpdateAction.Add, count - itemsRemoved, itemsAdded)); } // Set the last known source count sourceCount -= update.Count; }
protected virtual void ProcessUpdate(DataListUpdate update) { // Unsubscribe from future updates if all subscribers have been garbage collected or removed UnsubscribeFromSourceIfNoSubscribers(); // If the derived class does not implement ProcessUpdate then simply forward the update PostUpdate(update); }
private void Update_Add(DataListUpdate update) { // If the entire update is outside of the visible collection then ignore it if (update.Index > currentCount) { return; } currentCount += update.Count; base.OnItemsAdded(update.Index, update.Count); }
private void Update_Remove(DataListUpdate update) { // If the entire update is outside of the visible collection then ignore it if (update.Index >= currentCount) { return; } // If the update overlaps the boundary of the visible collection then only remove visible items int removedItemCount = Math.Min(update.Count, currentCount - update.Index); currentCount -= removedItemCount; base.OnItemsRemoved(update.Index, removedItemCount); }
protected override void ProcessUpdate(DataListUpdate update) { switch (update.Action) { case DataListUpdateAction.Add: ProcessUpdate_Add(update); break; case DataListUpdateAction.Remove: ProcessUpdate_Remove(update); break; default: PostUpdate(update); break; } }
// *** IUpdatableCollection Members *** void IUpdatableCollection.Update(DataListUpdate update) { switch (update.Action) { case DataListUpdateAction.Add: base.OnItemsAdded(update.Index, update.Count); break; case DataListUpdateAction.Remove: base.OnItemsRemoved(update.Index, update.Count); break; case DataListUpdateAction.Reset: base.Reset(); break; } }
// *** IUpdatableCollection Members *** void IUpdatableCollection.Update(DataListUpdate update) { switch (update.Action) { case DataListUpdateAction.Add: Update_Add(update); break; case DataListUpdateAction.Remove: Update_Remove(update); break; case DataListUpdateAction.Reset: Update_Reset(); break; } }
// *** Private Methods *** private void ProcessUpdate_Add(DataListUpdate update) { // Determine the index that the subscribers will see items added at // - If the update is before the start of the window, then items will flow into the start // - If the update is within the window then the items will be placed there int oldCount = Math.Max(0, sourceCount - count); int newCount = Math.Max(0, sourceCount + update.Count - count); if (oldCount != newCount) { int addIndex = Math.Max(0, update.Index - count); PostUpdate(new DataListUpdate(DataListUpdateAction.Add, addIndex, newCount - oldCount)); } // Set the last known source count sourceCount += update.Count; }
private void ProcessUpdate_Remove(DataListUpdate update) { // Determine the index that the subscribers will see items removed from // - If the update is before the start of the window, then items will flow out from the start // - If the update is within the window then the items will be removed there int oldCount = Math.Max(0, sourceCount - count); int newCount = Math.Max(0, sourceCount - update.Count - count); if (oldCount != newCount) { int removeIndex = Math.Max(0, update.Index - count); PostUpdate(new DataListUpdate(DataListUpdateAction.Remove, removeIndex, oldCount - newCount)); } // Set the last known source count sourceCount += update.Count; }
// *** IUpdatableCollection Methods *** void IUpdatableCollection.Update(DataListUpdate update) { // Process the update to perform any side-effects or conversions required and forward to any subscribers ProcessUpdate(update); }
public void Constructor_Remove_SetsCountProperty() { DataListUpdate update = new DataListUpdate(DataListUpdateAction.Remove, 2, 5); Assert.AreEqual(5, update.Count); }
public void Constructor_Remove_SetsIndexProperty() { DataListUpdate update = new DataListUpdate(DataListUpdateAction.Remove, 2, 5); Assert.AreEqual(2, update.Index); }
public void Constructor_Add_SetsActionProperty() { DataListUpdate update = new DataListUpdate(DataListUpdateAction.Add, 2, 5); Assert.AreEqual(DataListUpdateAction.Add, update.Action); }
public void Constructor_Reset_SetsActionProperty() { DataListUpdate update = new DataListUpdate(DataListUpdateAction.Reset); Assert.AreEqual(DataListUpdateAction.Reset, update.Action); }