コード例 #1
0
        private void unregisterSourceItem(int sourceIndex)
        {
            OrderingItemInfo <TOrderingValue> itemInfo = _itemInfos[sourceIndex];

            Utils.disposeExpressionWatcher(itemInfo.ExpressionWatcher, itemInfo.NestedComputings, this, _orderingValueSelectorContainsParametrizedLiveLinqCalls);

            int orderedIndex = itemInfo.OrderedItemInfo.Index;

            _orderedPositions.Remove(orderedIndex);
            _sourcePositions.Remove(sourceIndex);
            _orderingValues.RemoveAt(orderedIndex);

            if (_thenOrderingsCount > 0)
            {
                RangePosition rangePosition = itemInfo.OrderedItemInfo.RangePosition;
                if (rangePosition.Length == 1)
                {
                    _equalOrderingValueRangePositions.Remove(rangePosition.Index);
                }
                else
                {
                    _equalOrderingValueRangePositions.ModifyLength(rangePosition.Index, -1);
                }
            }

            baseRemoveItem(orderedIndex);
        }
コード例 #2
0
        void ISourceCollectionChangeProcessor.processSourceCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            switch (e.Action)
            {
            case NotifyCollectionChangedAction.Add:
                int         newIndex  = e.NewStartingIndex;
                TSourceItem addedItem = (TSourceItem)e.NewItems[0];
                registerSourceItem(addedItem, newIndex);
                break;

            case NotifyCollectionChangedAction.Remove:
                unregisterSourceItem(e.OldStartingIndex);
                break;

            case NotifyCollectionChangedAction.Replace:
                int         replacingSourceIndex = e.NewStartingIndex;
                TSourceItem replacingSourceItem  = (TSourceItem)e.NewItems[0];
                OrderingItemInfo <TOrderingValue> replacingItemInfo = _itemInfos[replacingSourceIndex];
                ExpressionWatcher oldExpressionWatcher = replacingItemInfo.ExpressionWatcher;

                Utils.disposeExpressionWatcher(oldExpressionWatcher, replacingItemInfo.NestedComputings, this,
                                               _orderingValueSelectorContainsParametrizedLiveLinqCalls);

                Utils.getItemInfoContent(
                    new object[] { replacingSourceItem },
                    out ExpressionWatcher newExpressionWatcher,
                    out Func <TOrderingValue> newGetOrderingValueFunc,
                    out List <IComputingInternal> nestedComputings,
                    _orderingValueSelectorExpression,
                    out _orderingValueSelectorExpressionCallCount,
                    this,
                    _orderingValueSelectorContainsParametrizedLiveLinqCalls,
                    _orderingValueSelectorExpressionInfo);

                replacingItemInfo.GetOrderingValueFunc           = newGetOrderingValueFunc;
                replacingItemInfo.ExpressionWatcher              = newExpressionWatcher;
                replacingItemInfo.ExpressionWatcher.ValueChanged = expressionWatcher_OnValueChanged;
                newExpressionWatcher._position     = oldExpressionWatcher._position;
                replacingItemInfo.NestedComputings = nestedComputings;

                baseSetItem(replacingItemInfo.OrderedItemInfo.Index, replacingSourceItem);
                processSourceItemChange(replacingSourceIndex, replacingSourceItem);
                break;

            case NotifyCollectionChangedAction.Move:
                int oldStartingIndex = e.OldStartingIndex;
                int newStartingIndex = e.NewStartingIndex;
                if (oldStartingIndex != newStartingIndex)
                {
                    _sourcePositions.Move(oldStartingIndex, newStartingIndex);
                }
                break;

            case NotifyCollectionChangedAction.Reset:
                processSource();
                break;
            }
        }
コード例 #3
0
		private TOrderingValue getOrderingValue(OrderingItemInfo<TOrderingValue> itemInfo, TSourceItem sourceItem)
		{
            TOrderingValue getValue() => 
                !_orderingValueSelectorContainsParametrizedLiveLinqCalls 
				    ? _orderingValueSelectorFunc(sourceItem) 
				    : itemInfo.GetOrderingValueFunc();

            if (Configuration.TrackComputingsExecutingUserCode)
            {
                var currentThread = Utils.startComputingExecutingUserCode(out var computing, out _userCodeIsCalledFrom, this);
                TOrderingValue result = getValue();
                Utils.endComputingExecutingUserCode(computing, currentThread, out _userCodeIsCalledFrom);
                return result;
            }

            return getValue();
		}
コード例 #4
0
        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);
            }
        }
コード例 #5
0
		public void ValidateConsistency()
		{
			IList<TSourceItem> source = _sourceScalar.getValue(_source, new ObservableCollection<TSourceItem>()) as IList<TSourceItem>;

			if (_itemInfos.Count != Count) throw new ObservableComputationsException(this, "Consistency violation: Ordering.7");

			List<TSourceItem> copy = this.ToList();			
			// ReSharper disable once PossibleNullReferenceException
			for (int sourceIndex = 0; sourceIndex < source.Count; sourceIndex++)
			{
				TSourceItem sourceItem = source[sourceIndex];
				if (!copy.Remove(sourceItem)) throw new ObservableComputationsException(this, "Consistency violation: Ordering.1");
			}

			_orderedPositions.ValidateConsistency();

			Func<TSourceItem, TOrderingValue> orderingValueSelector = _orderingValueSelectorExpression.Compile();
			IComparer<TOrderingValue> comparer = _comparerScalar.getValue(_comparer) ?? Comparer<TOrderingValue>.Default;
			ListSortDirection listSortDirection = _sortDirectionScalar.getValue(_sortDirection);

			if (_orderingValues.Count != Count) 
				throw new ObservableComputationsException(this, "Consistency violation: Ordering.14");

			if (_thenOrderingsCount > 0)
			{
				_equalOrderingValueRangePositions.ValidateConsistency();
			}

			RangePosition rangePosition = null;
			int equalOrderingValueItemsCount = 0;
			int rangePositionIndex = 0;
			for (int orderedIndex = 0; orderedIndex < Count; orderedIndex++)
			{
				TSourceItem orderedItem = this[orderedIndex];

				if (orderedIndex > 0)
				{
					int compareResult = comparer.Compare(orderingValueSelector(this[orderedIndex - 1]), orderingValueSelector(this[orderedIndex]));
					if ((compareResult < 0 && listSortDirection == ListSortDirection.Descending)
						|| (compareResult > 0 && listSortDirection == ListSortDirection.Ascending)) 
						throw new ObservableComputationsException(this, "Consistency violation: Ordering.3");

					if (_thenOrderingsCount > 0)
					{
						if (compareResult == 0)
						{
							equalOrderingValueItemsCount++;
							if (rangePosition !=  _orderedItemInfos[orderedIndex].RangePosition)
								throw new ObservableComputationsException(this, "Consistency violation: Ordering.17");
						}
						else				
						{
                            // ReSharper disable once PossibleNullReferenceException
                            if (rangePosition.Length != equalOrderingValueItemsCount)
								throw new ObservableComputationsException(this, "Consistency violation: Ordering.20");

							if (rangePosition.Index != rangePositionIndex)
								throw new ObservableComputationsException(this, "Consistency violation: Ordering.21");

							rangePositionIndex++;
							equalOrderingValueItemsCount = 1;

							rangePosition = _orderedItemInfos[orderedIndex].RangePosition;
						}
					}
				}
				else
				{
					if (_thenOrderingsCount > 0)
					{
						rangePosition = _orderedItemInfos[orderedIndex].RangePosition;
						equalOrderingValueItemsCount = 1;
					}
				}

				OrderingItemInfo<TOrderingValue> itemInfo = _orderedItemInfos[orderedIndex].ItemInfo;
				if (itemInfo.OrderedItemInfo.Index != orderedIndex) throw new ObservableComputationsException(this, "Consistency violation: Ordering.13");

				if (!EqualityComparer<TOrderingValue>.Default.Equals(_orderingValues[orderedIndex], orderingValueSelector(orderedItem)))
					throw new ObservableComputationsException(this, "Consistency violation: Ordering.10");
			}

			if (_thenOrderingsCount > 0 && Count > 0)
			{
                // ReSharper disable once PossibleNullReferenceException
                if (rangePosition.Length != equalOrderingValueItemsCount)
					throw new ObservableComputationsException(this, "Consistency violation: Ordering.22");

				if (rangePosition.Index != rangePositionIndex)
					throw new ObservableComputationsException(this, "Consistency violation: Ordering.23");
			}

			_sourcePositions.ValidateConsistency();

			if (_sourcePositions.List.Count != source.Count)
				throw new ObservableComputationsException(this, "Consistency violation: Ordering.15");

			for (int sourceIndex = 0; sourceIndex < source.Count; sourceIndex++)
			{
				TSourceItem sourceItem = source[sourceIndex];
				OrderingItemInfo<TOrderingValue> itemInfo = _itemInfos[sourceIndex];
				if (itemInfo.ExpressionWatcher._position != _sourcePositions.List[sourceIndex])
					throw new ObservableComputationsException(this, "Consistency violation: Ordering.8");
				if (!EqualityComparer<TOrderingValue>.Default.Equals(_orderingValues[itemInfo.OrderedItemInfo.Index], orderingValueSelector(sourceItem)))
					throw new ObservableComputationsException(this, "Consistency violation: Ordering.9");

				if (!_orderedItemInfos.Contains(_itemInfos[sourceIndex].OrderedItemInfo))
					throw new ObservableComputationsException(this, "Consistency violation: Ordering.11");

				if (!_sourcePositions.List.Contains(_itemInfos[sourceIndex].ExpressionWatcher._position))
					throw new ObservableComputationsException(this, "Consistency violation: Ordering.12");

				if (_itemInfos[sourceIndex].ExpressionWatcher._position.Index != sourceIndex)
					throw new ObservableComputationsException(this, "Consistency violation: Ordering.16");
			}
		}
コード例 #6
0
		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);
			}
		}