Пример #1
0
        internal static Position processAddSourceItem(int newSourceIndex, bool predicateValue, ref Position newItemPosition,
                                                      ref int?newFilteredIndex, List <FilteringItemInfo> filteringItemInfos, Positions <Position> filteredPositions, int count)
        {
            Position nextItemPosition;

            if (newSourceIndex < filteringItemInfos.Count)
            {
                FilteringItemInfo oldItemInfo = filteringItemInfos[newSourceIndex];

                Position oldItemInfoNextFilteredItemPosition = oldItemInfo.NextFilteredItemPosition;
                Position oldItemInfoFilteredPosition         = oldItemInfo.FilteredPosition;
                if (predicateValue)
                {
                    if (oldItemInfoFilteredPosition == null)
                    {
                        newItemPosition  = filteredPositions.Insert(oldItemInfoNextFilteredItemPosition.Index);
                        nextItemPosition = oldItemInfoNextFilteredItemPosition;
                        newFilteredIndex = newItemPosition.Index;
                    }
                    else
                    {
                        int filteredIndex = oldItemInfoFilteredPosition.Index;
                        newFilteredIndex = filteredIndex;
                        newItemPosition  = filteredPositions.Insert(filteredIndex);
                        nextItemPosition = oldItemInfoFilteredPosition;
                    }

                    modifyNextFilteredItemIndex(newSourceIndex, newItemPosition, filteringItemInfos);
                }
                else
                {
                    nextItemPosition = oldItemInfoFilteredPosition ?? oldItemInfoNextFilteredItemPosition;
                }
            }
            else
            {
                if (predicateValue)
                {
                    newItemPosition  = filteredPositions.List[count];
                    newFilteredIndex = count;
                    nextItemPosition = filteredPositions.Add();
                }
                else
                {
                    //здесь newPositionIndex = null; так и должно быть
                    nextItemPosition = filteredPositions.List[count];
                }
            }

            return(nextItemPosition);
        }
Пример #2
0
        //TODO Uncomment new feature and write test
        //[ObservableComputationsCall]
        //public Filtering<TSourceItem> TryConstructInsertOrRemoveRequestHandlers()
        //{
        //	ConstructInsertOrRemoveActionsVisitor
        //		constructInsertOrRemoveActionsVisitor =
        //			new ConstructInsertOrRemoveActionsVisitor();

        //	constructInsertOrRemoveActionsVisitor.Visit(_predicateExpressionOriginal);

        //	Action<TSourceItem> transformSourceItemIntoMember =
        //		constructInsertOrRemoveActionsVisitor.TransformSourceItemIntoMember;
        //	if (transformSourceItemIntoMember != null)
        //	{
        //		InsertItemRequestHandler = (index, item) => transformSourceItemIntoMember(item);
        //	}

        //	Action<TSourceItem> transformSourceItemNotIntoMember =
        //		constructInsertOrRemoveActionsVisitor.TransformSourceItemIntoNotMember;
        //	if (transformSourceItemNotIntoMember != null)
        //	{
        //		RemoveItemRequestHandler = index => transformSourceItemNotIntoMember(this[index]);
        //	}

        //	return this;
        //}

        //private class ConstructInsertOrRemoveActionsVisitor : ExpressionVisitor
        //{
        //	public Action<TSourceItem> TransformSourceItemIntoMember;
        //	public Action<TSourceItem> TransformSourceItemIntoNotMember;
        //	#region Overrides of ExpressionVisitor

        //	//TODO !sourceItem.NullableProp.HasValue должно преобразооваться в sourceItem.NullableProp ==  null
        //	// TODO обрабытывать выражения типа '25 == sourceItem.Id'
        //	protected override Expression VisitBinary(BinaryExpression node)
        //	{
        //		ExpressionType nodeType = node.NodeType;
        //		if (nodeType == ExpressionType.Equal || nodeType == ExpressionType.NotEqual)
        //		{
        //			if (node.Left is MemberExpression memberExpression)
        //			{
        //				Expression rightExpression = node.Right;

        //				// ReSharper disable once PossibleNullReferenceException
        //				MemberInfo memberExpressionMember = memberExpression.Member;
        //				Type declaringType = memberExpressionMember.DeclaringType;
        //				// ReSharper disable once PossibleNullReferenceException
        //				if (declaringType.IsConstructedGenericType
        //					&& declaringType.GetGenericTypeDefinition() == typeof(Nullable<>)
        //					&& memberExpressionMember.Name == "Value")
        //				{
        //					memberExpression = (MemberExpression) memberExpression.Expression;
        //					rightExpression = Expression.Convert(rightExpression,
        //						typeof (Nullable<>).MakeGenericType(node.Left.Type));
        //				}

        //				ParameterExpression parameterExpression = getParameterExpression(memberExpression);
        //				if (parameterExpression != null)
        //				{
        //					if (memberExpression.Type != rightExpression.Type)
        //					{
        //						rightExpression = Expression.Convert(rightExpression, memberExpression.Type);
        //					}

        //					if (!memberExpressionMember.IsReadOnly())
        //					{
        //						if (nodeType == ExpressionType.Equal)
        //						{
        //							TransformSourceItemIntoMember = Expression.Lambda<Action<TSourceItem>>(Expression.Assign(memberExpression, rightExpression), parameterExpression).Compile();
        //						}
        //						else if (nodeType == ExpressionType.NotEqual)
        //						{
        //							TransformSourceItemIntoNotMember = Expression.Lambda<Action<TSourceItem>>(Expression.Assign(memberExpression, rightExpression), parameterExpression).Compile();
        //						}
        //					}
        //				}
        //			}
        //		}

        //		return node;
        //	}


        //	private ParameterExpression getParameterExpression(MemberExpression memberExpression)
        //	{
        //		if (memberExpression.Expression is ParameterExpression parameterExpression)
        //		{
        //			return parameterExpression;
        //		}

        //		if (memberExpression.Expression is MemberExpression expressionMemberExpression)
        //		{
        //			return getParameterExpression(expressionMemberExpression); // memberExpression.Expression может быть не MemberExpression
        //		}

        //		return null;
        //	}


        //	#endregion
        //}

        protected override void processSource()
        {
            int originalCount = _items.Count;

            if (_sourceReadAndSubscribed)
            {
                Utils.disposeExpressionItemInfos(_itemInfos, _predicateExpressionCallCount, this);
                Utils.removeDownstreamConsumedComputing(_itemInfos, this);

                _filteredPositions = new Positions <Position>(new List <Position>(_initialCapacity));

                Utils.disposeSource(
                    _sourceScalar,
                    _source,
                    out _itemInfos,
                    out _sourcePositions,
                    _sourceAsList,
                    handleSourceCollectionChanged);

                _sourceReadAndSubscribed = false;
            }

            Utils.changeSource(ref _source, _sourceScalar, _downstreamConsumedComputings, _consumers, this, out _sourceAsList, false);

            if (_source != null && _isActive)
            {
                Utils.initializeFromObservableCollectionWithChangeMarker(
                    _source,
                    ref _sourceAsList,
                    ref _rootSourceWrapper,
                    ref _lastProcessedSourceChangeMarker);

                Position      nextItemPosition = _filteredPositions.Add();
                int           count            = _sourceAsList.Count;
                TSourceItem[] sourceCopy       = new TSourceItem[count];
                _sourceAsList.CopyTo(sourceCopy, 0);

                _sourceAsList.CollectionChanged += handleSourceCollectionChanged;

                int insertingIndex = 0;
                int sourceIndex;

                for (sourceIndex = 0; sourceIndex < count; sourceIndex++)
                {
                    TSourceItem sourceItem = sourceCopy[sourceIndex];
                    Position    currentFilteredItemPosition = null;

                    FilteringItemInfo itemInfo = registerSourceItem(sourceItem, sourceIndex, null, null);

                    if (_thisAsFiltering.applyPredicate(sourceItem, itemInfo.PredicateFunc))
                    {
                        if (originalCount > insertingIndex)
                        {
                            _items[insertingIndex++] = sourceItem;
                        }
                        else
                        {
                            _items.Insert(insertingIndex++, sourceItem);
                        }

                        currentFilteredItemPosition = nextItemPosition;
                        nextItemPosition            = _filteredPositions.Add();
                    }

                    itemInfo.FilteredPosition         = currentFilteredItemPosition;
                    itemInfo.NextFilteredItemPosition = nextItemPosition;
                }

                for (int index = originalCount - 1; index >= insertingIndex; index--)
                {
                    _items.RemoveAt(index);
                }

                _sourceReadAndSubscribed = true;
            }
            else
            {
                _items.Clear();
            }

            reset();
        }
Пример #3
0
        private void initializeFromSource()
        {
            int originalCount = _items.Count;

            if (_sourceNotifyCollectionChangedEventHandler != null)
            {
                int itemInfosCount = _itemInfos.Count;
                for (int index = 0; index < itemInfosCount; index++)
                {
                    ItemInfo          itemInfo          = _itemInfos[index];
                    ExpressionWatcher expressionWatcher = itemInfo.ExpressionWatcher;
                    expressionWatcher.Dispose();
                }

                int capacity = _sourceScalar != null?Utils.getCapacity(_sourceScalar) : Utils.getCapacity(_source);

                _filteredPositions = new Positions <Position>(new List <Position>(_initialCapacity));
                _itemInfos         = new List <ItemInfo>(capacity);
                _sourcePositions   = new Positions <ItemInfo>(_itemInfos);

                if (_rootSourceWrapper)
                {
                    _sourceAsList.CollectionChanged -= _sourceNotifyCollectionChangedEventHandler;
                }
                else
                {
                    _sourceAsList.CollectionChanged -= _sourceWeakNotifyCollectionChangedEventHandler.Handle;
                    _sourceWeakNotifyCollectionChangedEventHandler = null;
                }

                _sourceNotifyCollectionChangedEventHandler = null;
            }

            if (_sourceScalar != null)
            {
                _source = _sourceScalar.Value;
            }
            _sourceAsList = null;

            if (_source != null)
            {
                if (_source is ObservableCollectionWithChangeMarker <TSourceItem> sourceAsList)
                {
                    _sourceAsList      = sourceAsList;
                    _rootSourceWrapper = false;
                }
                else
                {
                    _sourceAsList      = new RootSourceWrapper <TSourceItem>(_source);
                    _rootSourceWrapper = true;
                }

                _lastProcessedSourceChangeMarker = _sourceAsList.ChangeMarkerField;

                Position nextItemPosition = _filteredPositions.Add();
                int      count            = _sourceAsList.Count;
                int      insertingIndex   = 0;
                int      sourceIndex;

                for (sourceIndex = 0; sourceIndex < count; sourceIndex++)
                {
                    TSourceItem sourceItem = _sourceAsList[sourceIndex];
                    Position    currentFilteredItemPosition = null;

                    ItemInfo itemInfo = registerSourceItem(sourceItem, sourceIndex, null, null);

                    if (ApplyPredicate(sourceIndex))
                    {
                        if (originalCount > insertingIndex)
                        {
                            _items[insertingIndex++] = sourceItem;
                        }
                        else
                        {
                            _items.Insert(insertingIndex++, sourceItem);
                        }

                        currentFilteredItemPosition = nextItemPosition;
                        nextItemPosition            = _filteredPositions.Add();
                    }

                    itemInfo.FilteredPosition         = currentFilteredItemPosition;
                    itemInfo.NextFilteredItemPosition = nextItemPosition;
                }

                for (int index = originalCount - 1; index >= insertingIndex; index--)
                {
                    _items.RemoveAt(index);
                }

                _sourceNotifyCollectionChangedEventHandler = handleSourceCollectionChanged;

                if (_rootSourceWrapper)
                {
                    _sourceAsList.CollectionChanged += _sourceNotifyCollectionChangedEventHandler;
                }
                else
                {
                    _sourceWeakNotifyCollectionChangedEventHandler =
                        new WeakNotifyCollectionChangedEventHandler(_sourceNotifyCollectionChangedEventHandler);

                    _sourceAsList.CollectionChanged += _sourceWeakNotifyCollectionChangedEventHandler.Handle;
                }
            }
            else
            {
                _items.Clear();
            }

            reset();
        }