private void adjustEqualOrderingValueRangePosition( TOrderingValue orderingValue, OrderedItemInfo <TOrderingValue> orderedItemInfo, int orderedIndex, int previousOrderedIndex, int nextOrderedIndex) { bool isIncludedInRange = false; void tryIncludeInRange(OrderedItemInfo <TOrderingValue> nearbyOrderedItemInfo, int nearbyOrderedIndex) { if (_comparer.Compare(orderingValue, getOrderingValue( nearbyOrderedItemInfo.ItemInfo, this[nearbyOrderedIndex])) == 0) { RangePosition rangePosition = nearbyOrderedItemInfo.RangePosition; orderedItemInfo.RangePosition = rangePosition; _equalOrderingValueRangePositions.ModifyLength(rangePosition.Index, 1); isIncludedInRange = true; } } OrderedItemInfo <TOrderingValue> previousOrderedItemInfo = null; if (orderedIndex > 0) { previousOrderedItemInfo = _orderedItemInfos[orderedIndex - 1]; tryIncludeInRange(previousOrderedItemInfo, previousOrderedIndex); } int count = Count; if (!isIncludedInRange && orderedIndex < count && nextOrderedIndex < count) { tryIncludeInRange(_orderedItemInfos[orderedIndex + 1], nextOrderedIndex); } if (!isIncludedInRange) { orderedItemInfo.RangePosition = previousOrderedItemInfo != null ? _equalOrderingValueRangePositions.Insert(previousOrderedItemInfo.RangePosition.Index + 1, 1) : _equalOrderingValueRangePositions.Insert(0, 1); } }
private void registerSourceItem(TSourceItem sourceItem, int sourceIndex, bool initializing = false) { OrderingItemInfo <TOrderingValue> itemInfo = _sourcePositions.Insert(sourceIndex); Utils.getItemInfoContent( new object[] { sourceItem }, out ExpressionWatcher expressionWatcher, out Func <TOrderingValue> getOrderingValueFunc, out List <IComputingInternal> nestedComputings, _orderingValueSelectorExpression, out _orderingValueSelectorExpressionCallCount, this, _orderingValueSelectorContainsParametrizedLiveLinqCalls, _orderingValueSelectorExpressionInfo); itemInfo.GetOrderingValueFunc = getOrderingValueFunc; itemInfo.ExpressionWatcher = expressionWatcher; itemInfo.NestedComputings = nestedComputings; TOrderingValue orderingValue = getOrderingValue(itemInfo, sourceItem); int orderedIndex = getOrderedIndex(orderingValue); itemInfo.ExpressionWatcher.ValueChanged = expressionWatcher_OnValueChanged; itemInfo.ExpressionWatcher._position = itemInfo; OrderedItemInfo <TOrderingValue> orderedItemInfo = _orderedPositions.Insert(orderedIndex); itemInfo.OrderedItemInfo = orderedItemInfo; orderedItemInfo.ItemInfo = itemInfo; _orderingValues.Insert(orderedIndex, orderingValue); if (_thenOrderingsCount > 0) { adjustEqualOrderingValueRangePosition(orderingValue, orderedItemInfo, orderedIndex, orderedIndex - 1, orderedIndex); } if (initializing) { _items.Insert(orderedIndex, sourceItem); } else { baseInsertItem(orderedIndex, sourceItem); } }
private void processSourceItemChange(int sourceIndex, TSourceItem sourceItem) { void notifyThenOrderings(int newOrderedIndex) { int processedThenOrderingsCount = 0; for (int thenOrderingIndex = 0; thenOrderingIndex < _thenOrderingsCount; thenOrderingIndex++) { IThenOrderingInternal<TSourceItem> thenOrdering = _thenOrderings[thenOrderingIndex]; thenOrdering.ProcessSourceItemChange(newOrderedIndex, sourceItem); processedThenOrderingsCount++; if (processedThenOrderingsCount == _thenOrderingsCount) break; } } OrderingItemInfo<TOrderingValue> itemInfo = _itemInfos[sourceIndex]; OrderedItemInfo<TOrderingValue> orderedItemInfo = itemInfo.OrderedItemInfo; int orderedIndex = orderedItemInfo.Index; TOrderingValue orderingValue = getOrderingValue(itemInfo, sourceItem); if (_comparer.Compare(_orderingValues[orderedIndex], orderingValue) != 0) { int newOrderedIndex = getOrderedIndex(orderingValue); if (newOrderedIndex == Count) newOrderedIndex = newOrderedIndex - 1; else if (newOrderedIndex > orderedIndex) newOrderedIndex--; _orderingValues.RemoveAt(orderedIndex); _orderingValues.Insert(newOrderedIndex, orderingValue); _orderedPositions.Move(orderedIndex, newOrderedIndex); if (_thenOrderingsCount > 0) { RangePosition rangePosition = orderedItemInfo.RangePosition; if (rangePosition.Length == 1) _equalOrderingValueRangePositions.Remove(rangePosition.Index); else _equalOrderingValueRangePositions.ModifyLength(rangePosition.Index, -1); adjustEqualOrderingValueRangePosition( orderingValue, orderedItemInfo, newOrderedIndex, orderedIndex < newOrderedIndex ? newOrderedIndex : newOrderedIndex - 1, orderedIndex > newOrderedIndex ? newOrderedIndex : newOrderedIndex + 1); } if (orderedIndex != newOrderedIndex) { baseMoveItem(orderedIndex, newOrderedIndex); } else if (_thenOrderingsCount > 0) { notifyThenOrderings(newOrderedIndex); } } else if (_thenOrderingsCount > 0) { notifyThenOrderings(orderedIndex); } }