Пример #1
0
        private void expressionWatcher_OnValueChanged(ExpressionWatcher expressionWatcher, object sender, EventArgs eventArgs)
        {
            checkConsistent(sender, eventArgs);

            _handledEventSender = sender;
            _handledEventArgs   = eventArgs;

            _isConsistent = false;

            if (_rootSourceWrapper || _sourceAsList.ChangeMarkerField == _lastProcessedSourceChangeMarker)
            {
                processChangeSourceItem(expressionWatcher._position.Index);
            }
            else
            {
                (_deferredExpressionWatcherChangedProcessings =
                     _deferredExpressionWatcherChangedProcessings
                     ?? new Queue <ExpressionWatcher.Raise>())
                .Enqueue(new ExpressionWatcher.Raise(expressionWatcher, sender, eventArgs));
            }

            _isConsistent = true;
            raiseConsistencyRestored();

            _handledEventSender = null;
            _handledEventArgs   = null;
        }
Пример #2
0
        private void unregisterSourceItem(int sourceIndex)
        {
            int?     removeIndex = null;
            ItemInfo itemInfo    = _itemInfos[sourceIndex];

            ExpressionWatcher watcher = itemInfo.ExpressionWatcher;

            watcher.Dispose();

            Position itemInfoFilteredPosition = itemInfo.FilteredPosition;

            if (itemInfoFilteredPosition != null)
            {
                removeIndex = itemInfoFilteredPosition.Index;
                _filteredPositions.Remove(itemInfoFilteredPosition.Index);
                modifyNextFilteredItemIndex(sourceIndex, itemInfo.NextFilteredItemPosition);
            }

            _sourcePositions.Remove(sourceIndex);

            if (removeIndex.HasValue)
            {
                baseRemoveItem(removeIndex.Value);
            }
        }
Пример #3
0
        private FilteringItemInfo registerSourceItem(TSourceItem sourceItem, int sourceIndex, Position position,
                                                     Position nextItemPosition, ExpressionWatcher watcher = null, Func <bool> predicateFunc = null,
                                                     List <IComputingInternal> nestedComputings           = null)
        {
            FilteringItemInfo itemInfo = _sourcePositions.Insert(sourceIndex);

            itemInfo.FilteredPosition         = position;
            itemInfo.NextFilteredItemPosition = nextItemPosition;

            if (watcher == null /*&& predicateFunc == null*/)
            {
                Utils.getItemInfoContent(
                    new object[] { sourceItem },
                    out watcher,
                    out predicateFunc,
                    out nestedComputings,
                    _predicateExpression,
                    out _predicateExpressionCallCount,
                    this,
                    _predicateContainsParametrizedObservableComputationsCalls,
                    _predicateExpressionInfo);
            }

            itemInfo.PredicateFunc     = predicateFunc;
            watcher.ValueChanged       = _thisAsFiltering.expressionWatcher_OnValueChanged;
            watcher._position          = itemInfo;
            itemInfo.ExpressionWatcher = watcher;
            itemInfo.NestedComputings  = nestedComputings;

            return(itemInfo);
        }
Пример #4
0
        void ISourceItemChangeProcessor.ProcessSourceItemChange(ExpressionWatcher expressionWatcher)
        {
            if (expressionWatcher._disposed)
            {
                return;
            }
            ItemInfo itemInfo = (ItemInfo)expressionWatcher._position;

            if (itemInfo.PredicateResult)
            {
                _predicatePassedCount--;
            }

            if (applyPredicate(_sourceAsList[itemInfo.Index], itemInfo.PredicateFunc))
            {
                _predicatePassedCount++;
                itemInfo.PredicateResult = true;
            }
            else
            {
                itemInfo.PredicateResult = false;
            }

            calculateValue();
        }
Пример #5
0
        private ItemInfo registerSourceItem(TSourceItem sourceItem, int index, ItemInfo itemInfo = null)
        {
            itemInfo = itemInfo == null?_sourcePositions.Insert(index) : _itemInfos[index];

            ExpressionWatcher watcher;

            if (!_selectorContainsParametrizedObservableComputationsCalls)
            {
                watcher = new ExpressionWatcher(_selectorExpressionInfo, sourceItem);
            }
            else
            {
                Expression <Func <TResultItem> > deparametrizedSelectorExpression =
                    (Expression <Func <TResultItem> >)_selectorExpression.ApplyParameters(new object[] { sourceItem });
                Expression <Func <TResultItem> > selectorExpression =
                    (Expression <Func <TResultItem> >)
                    new CallToConstantConverter().Visit(deparametrizedSelectorExpression);
                // ReSharper disable once PossibleNullReferenceException
                itemInfo.SelectorFunc = selectorExpression.Compile();
                watcher = new ExpressionWatcher(ExpressionWatcher.GetExpressionInfo(selectorExpression));
            }

            watcher.ValueChanged       = expressionWatcher_OnValueChanged;
            itemInfo.ExpressionWatcher = watcher;
            watcher._position          = itemInfo;

            return(itemInfo);
        }
        void ISourceItemChangeProcessor.ProcessSourceItemChange(ExpressionWatcher expressionWatcher)
        {
            int index = expressionWatcher._position.Index;

            FilteringUtils.ProcessChangeSourceItem(index, _sourceAsList[index], _itemInfos, this,
                                                   _filteredPositions, this);
        }
Пример #7
0
 protected override void initialize()
 {
     Utils.initializeNestedComputings(_nestedComputings, this);
     _getValueExpressionWatcher = new ExpressionWatcher(_expressionInfo);
     _getValueExpressionWatcher.ValueChanged = getValueExpressionWatcherOnValueChanged;
     setValue(getResult());
 }
Пример #8
0
        private Filtering(Expression <Func <TSourceItem, bool> > predicateExpression,
                          int sourceCapacity, int capacity) : base(capacity)
        {
            _initialCapacity   = capacity;
            _filteredPositions = new Positions <Position>(new List <Position>(_initialCapacity));
            _itemInfos         = new List <ItemInfo>(sourceCapacity);
            _sourcePositions   = new Positions <ItemInfo>(_itemInfos);

            _predicateExpressionOriginal = predicateExpression;

            CallToConstantConverter callToConstantConverter =
                new CallToConstantConverter(predicateExpression.Parameters);

            _predicateExpression =
                (Expression <Func <TSourceItem, bool> >)callToConstantConverter.Visit(predicateExpression);
            _predicateContainsParametrizedObservableComputationsCalls =
                callToConstantConverter.ContainsParametrizedObservableComputationCalls;

            if (!_predicateContainsParametrizedObservableComputationsCalls)
            {
                _predicateExpressionInfo = ExpressionWatcher.GetExpressionInfo(_predicateExpression);
                // ReSharper disable once PossibleNullReferenceException
                _predicateFunc = _predicateExpression.Compile();
            }
        }
Пример #9
0
 private void getValueExpressionWatcherOnValueChanged(ExpressionWatcher expressionWatcher, object sender, EventArgs eventArgs)
 {
     _handledEventSender = sender;
     _handledEventArgs   = eventArgs;
     setValue(getResult());
     _handledEventSender = null;
     _handledEventArgs   = null;
 }
Пример #10
0
 void ISourceItemChangeProcessor.ProcessSourceItemChange(ExpressionWatcher expressionWatcher)
 {
     if (expressionWatcher._disposed) return;
     int sourceIndex = expressionWatcher._position.Index;
     processSourceItemChange(
         sourceIndex, 
         _sourceAsList[sourceIndex]);
 }
Пример #11
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;
            }
        }
Пример #12
0
        private void unregisterSourceItem(int sourceIndex)
        {
            ItemInfo itemInfo = _itemInfos[sourceIndex];

            ExpressionWatcher watcher = itemInfo.ExpressionWatcher;

            watcher.Dispose();

            _sourcePositions.Remove(sourceIndex);
        }
Пример #13
0
        void ISourceItemChangeProcessor.ProcessSourceItemChange(ExpressionWatcher expressionWatcher)
        {
            if (expressionWatcher._disposed)
            {
                return;
            }
            int sourceIndex = expressionWatcher._position.Index;

            baseSetItem(sourceIndex, applySelector((ItemInfo)expressionWatcher._position, _sourceAsList[sourceIndex]));
        }
Пример #14
0
        private void unregisterSourceItem(int index, bool replacing = false)
        {
            ExpressionWatcher watcher = _itemInfos[index].ExpressionWatcher;

            watcher.Dispose();

            if (!replacing)
            {
                _sourcePositions.Remove(index);
            }
        }
Пример #15
0
        public Computing(
            Expression <Func <TResult> > getValueExpression)
        {
            _changeValueAction          = () => setValue(getResult());
            _getValueExpressionOriginal = getValueExpression;

            CallToConstantConverter      callToConstantConverter = new CallToConstantConverter(_getValueExpressionOriginal.Parameters);
            Expression <Func <TResult> > getValueExpression1     =
                (Expression <Func <TResult> >)callToConstantConverter.Visit(_getValueExpressionOriginal);

            // ReSharper disable once PossibleNullReferenceException
            _getValueFunc   = getValueExpression1.Compile();
            _expressionInfo = ExpressionWatcher.GetExpressionInfo(getValueExpression1);
        }
Пример #16
0
 private void getValueExpressionWatcherOnValueChanged(ExpressionWatcher expressionWatcher, object sender, EventArgs eventArgs)
 {
     Utils.processChange(
         sender,
         eventArgs,
         _changeValueAction,
         ref _isConsistent,
         ref _handledEventSender,
         ref _handledEventArgs,
         0, 1,
         ref _deferredProcessings,
         this,
         false);
 }
Пример #17
0
 void IFiltering <TSourceItem> .expressionWatcher_OnValueChanged(ExpressionWatcher expressionWatcher, object sender, EventArgs eventArgs)
 {
     Utils.processSourceItemChange(
         expressionWatcher,
         sender,
         eventArgs,
         _rootSourceWrapper,
         _sourceAsList,
         _lastProcessedSourceChangeMarker,
         _thisAsSourceItemChangeProcessor,
         ref _isConsistent,
         ref _handledEventSender,
         ref _handledEventArgs,
         ref _deferredProcessings,
         2, _deferredQueuesCount, this);
 }
Пример #18
0
 protected override void processSource()
 {
     if (_isActive)
     {
         _getValueExpressionWatcher = new ExpressionWatcher(this, _expressionInfo);
         Utils.initializeExpressionWatcherCurrentComputings(_getValueExpressionWatcher, _expressionInfo._callCount, this);
         _getValueExpressionWatcher.ValueChanged = getValueExpressionWatcherOnValueChanged;
         setValue(getResult());
     }
     else
     {
         _getValueExpressionWatcher.Dispose();
         EventUnsubscriber.QueueSubscriptions(_getValueExpressionWatcher._propertyChangedEventSubscriptions, _getValueExpressionWatcher._methodChangedEventSubscriptions);
         Utils.removeDownstreamConsumedComputing(_getValueExpressionWatcher, this);
         setDefaultValue();
     }
 }
Пример #19
0
        private void getNewExpressionWatcherAndPredicateFunc(TSourceItem sourceItem, out ExpressionWatcher watcher, out Func <bool> predicateFunc)
        {
            predicateFunc = null;

            if (!_predicateContainsParametrizedObservableComputationCalls)
            {
                watcher = new ExpressionWatcher(_predicateExpressionInfo, sourceItem);
            }
            else
            {
                Expression <Func <bool> > deparametrizedPredicateExpression =
                    (Expression <Func <bool> >)_predicateExpression.ApplyParameters(new object[] { sourceItem });
                Expression <Func <bool> > predicateExpression =
                    (Expression <Func <bool> >)
                    new CallToConstantConverter().Visit(deparametrizedPredicateExpression);
                predicateFunc = predicateExpression.Compile();
                watcher       = new ExpressionWatcher(ExpressionWatcher.GetExpressionInfo(predicateExpression));
            }
        }
Пример #20
0
        internal static bool ProcessChangeSourceItem <TSourceItem>(int sourceIndex,
                                                                   TSourceItem sourceItem,
                                                                   List <FilteringItemInfo> filteringItemInfos,
                                                                   IFiltering <TSourceItem> filtering,
                                                                   Positions <Position> filteredPositions,
                                                                   CollectionComputing <TSourceItem> current,
                                                                   ExpressionWatcher expressionWatcher)
        {
            if (expressionWatcher._disposed)
            {
                return(false);
            }

            FilteringItemInfo itemInfo = filteringItemInfos[sourceIndex];

            bool newPredicateValue = filtering.applyPredicate(sourceItem, itemInfo.PredicateFunc);
            bool oldPredicateValue = itemInfo.FilteredPosition != null;

            if (newPredicateValue != oldPredicateValue)
            {
                if (newPredicateValue)
                {
                    int newIndex = itemInfo.NextFilteredItemPosition.Index;
                    itemInfo.FilteredPosition = filteredPositions.Insert(newIndex);
                    newIndex = itemInfo.FilteredPosition.Index;
                    modifyNextFilteredItemIndex(sourceIndex, itemInfo.FilteredPosition, filteringItemInfos);
                    current.baseInsertItem(newIndex, sourceItem);
                    return(true);
                }
                else // if (oldPredicaeValue)
                {
                    int index = itemInfo.FilteredPosition.Index;
                    filteredPositions.Remove(index);
                    itemInfo.FilteredPosition = null;
                    modifyNextFilteredItemIndex(sourceIndex, itemInfo.NextFilteredItemPosition, filteringItemInfos);
                    current.baseRemoveItem(index);
                    return(true);
                }
            }

            return(false);
        }
Пример #21
0
        public Computing(
            Expression <Func <TResult> > getValueExpression)
        {
            if (getValueExpression != null)
            {
                _getValueExpressionOriginal = getValueExpression;
                Expression <Func <TResult> > getValueExpression1 =
                    (Expression <Func <TResult> >) new CallToConstantConverter(_getValueExpressionOriginal.Parameters).Visit(_getValueExpressionOriginal);
                // ReSharper disable once PossibleNullReferenceException
                _getValueFunc = getValueExpression1.Compile();
                _getValueExpressionWatcher = new ExpressionWatcher(ExpressionWatcher.GetExpressionInfo(getValueExpression1));
                _getValueExpressionWatcher.ValueChanged = getValueExpressionWatcherOnValueChanged;

                setValue(getResult());
            }
            else
            {
                _isDefaulted = true;
                setValue(default(TResult));
            }
        }
Пример #22
0
        internal static bool  ProcessReplaceSourceItem <TExpression, TSourceItem>(
            FilteringItemInfo replacingItemInfo,
            TSourceItem sourceItem,
            object[] sourceItems,
            int sourceIndex, bool predicateContainsParametrizedObservableComputationsCalls,
            Expression <TExpression> predicateExpression,
            out int predicateExpressionCallCount,
            ExpressionWatcher.ExpressionInfo orderingValueSelectorExpressionInfo,
            List <FilteringItemInfo> filteringItemInfos,
            Positions <Position> filteredPositions, IFiltering <TSourceItem> thisAsFiltering,
            CollectionComputing <TSourceItem> current)
        {
            ExpressionWatcher oldExpressionWatcher = replacingItemInfo.ExpressionWatcher;

            Utils.disposeExpressionWatcher(oldExpressionWatcher, replacingItemInfo.NestedComputings, thisAsFiltering,
                                           predicateContainsParametrizedObservableComputationsCalls);

            Utils.getItemInfoContent(
                sourceItems,
                out ExpressionWatcher watcher,
                out Func <bool> predicateFunc,
                out List <IComputingInternal> nestedComputings1,
                predicateExpression,
                out predicateExpressionCallCount,
                thisAsFiltering,
                predicateContainsParametrizedObservableComputationsCalls,
                orderingValueSelectorExpressionInfo);

            replacingItemInfo.PredicateFunc = predicateFunc;
            watcher.ValueChanged            = thisAsFiltering.expressionWatcher_OnValueChanged;
            watcher._position = oldExpressionWatcher._position;
            replacingItemInfo.ExpressionWatcher = watcher;
            replacingItemInfo.NestedComputings  = nestedComputings1;
            bool replace = !ProcessChangeSourceItem(sourceIndex, sourceItem, filteringItemInfos, thisAsFiltering,
                                                    filteredPositions, current) &&
                           replacingItemInfo.FilteredPosition != null;

            return(replace);
        }
Пример #23
0
        private Selecting(Expression <Func <TSourceItem, TResultItem> > selectorExpression, int capacity) : base(capacity)
        {
            _itemInfos       = new List <ItemInfo>(capacity);
            _sourcePositions = new Positions <ItemInfo>(_itemInfos);

            _selectorExpressionOriginal = selectorExpression;
            CallToConstantConverter callToConstantConverter =
                new CallToConstantConverter(_selectorExpressionOriginal.Parameters);

            _selectorExpression =
                (Expression <Func <TSourceItem, TResultItem> >)callToConstantConverter.Visit(
                    _selectorExpressionOriginal);
            _selectorContainsParametrizedObservableComputationsCalls =
                callToConstantConverter.ContainsParametrizedObservableComputationCalls;

            if (!_selectorContainsParametrizedObservableComputationsCalls)
            {
                _selectorExpressionInfo = ExpressionWatcher.GetExpressionInfo(_selectorExpression);
                // ReSharper disable once PossibleNullReferenceException
                _selectorFunc = _selectorExpression.Compile();
            }
        }
Пример #24
0
        private void processExpressionWatcherValueChanged(ExpressionWatcher expressionWatcher)
        {
            int      sourceIndex = expressionWatcher._position.Index;
            ItemInfo itemInfo    = _itemInfos[sourceIndex];

            if (itemInfo.PredicateResult)
            {
                _predicatePassedCount--;
            }

            if (ApplyPredicate(sourceIndex))
            {
                _predicatePassedCount++;
                itemInfo.PredicateResult = true;
            }
            else
            {
                itemInfo.PredicateResult = false;
            }

            calculateValue();
        }
Пример #25
0
        private void processExpressionWatcherValueChanged(ExpressionWatcher expressionWatcher)
        {
            int sourceIndex = expressionWatcher._position.Index;

            baseSetItem(sourceIndex, ApplySelector(sourceIndex));
        }
Пример #26
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();
        }
Пример #27
0
        private void handleSourceCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            checkConsistent(sender, e);
            if (!_rootSourceWrapper && _lastProcessedSourceChangeMarker == _sourceAsList.ChangeMarkerField)
            {
                return;
            }

            _handledEventSender = sender;
            _handledEventArgs   = e;

            _lastProcessedSourceChangeMarker = !_lastProcessedSourceChangeMarker;

            switch (e.Action)
            {
            case NotifyCollectionChangedAction.Add:
                _isConsistent = false;
                int         newSourceIndex  = e.NewStartingIndex;
                TSourceItem addedSourceItem = _sourceAsList[newSourceIndex];
                Position    newItemPosition = null;
                Position    nextItemPosition;

                int?newFilteredIndex = null;

                getNewExpressionWatcherAndPredicateFunc(addedSourceItem, out ExpressionWatcher newWatcher, out Func <bool> newPredicateFunc);

                if (newSourceIndex < _itemInfos.Count)
                {
                    ItemInfo oldItemInfo = _itemInfos[newSourceIndex];

                    Position oldItemInfoNextFilteredItemPosition = oldItemInfo.NextFilteredItemPosition;
                    Position oldItemInfoFilteredPosition         = oldItemInfo.FilteredPosition;
                    if (applyPredicate(addedSourceItem, newPredicateFunc))
                    {
                        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);
                    }
                    else
                    {
                        nextItemPosition = oldItemInfoFilteredPosition ?? oldItemInfoNextFilteredItemPosition;
                    }
                }
                else
                {
                    if (applyPredicate(addedSourceItem, newPredicateFunc))
                    {
                        newItemPosition  = _filteredPositions.List[Count];
                        newFilteredIndex = Count;
                        nextItemPosition = _filteredPositions.Add();
                    }
                    else
                    {
                        //здесь newPositionIndex = null; так и должно быть
                        nextItemPosition = _filteredPositions.List[Count];
                    }
                }

                registerSourceItem(addedSourceItem, newSourceIndex, newItemPosition, nextItemPosition, newWatcher, newPredicateFunc);

                if (newFilteredIndex != null)
                {
                    baseInsertItem(newFilteredIndex.Value, addedSourceItem);
                }

                _isConsistent = true;
                raiseConsistencyRestored();
                break;

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

            case NotifyCollectionChangedAction.Move:
                _isConsistent = false;
                int newSourceIndex1 = e.NewStartingIndex;
                int oldSourceIndex  = e.OldStartingIndex;

                if (newSourceIndex1 != oldSourceIndex)
                {
                    ItemInfo itemInfoOfOldSourceIndex = _itemInfos[oldSourceIndex];
                    ItemInfo itemInfoOfNewSourceIndex = _itemInfos[newSourceIndex1];

                    Position newPosition1;
                    Position nextPosition1;

                    Position itemInfoOfOldSourceIndexFilteredPosition         = itemInfoOfOldSourceIndex.FilteredPosition;
                    Position itemInfoOfNewSourceIndexNextFilteredItemPosition = itemInfoOfNewSourceIndex.NextFilteredItemPosition;
                    Position itemInfoOfNewSourceIndexFilteredPosition         = itemInfoOfNewSourceIndex.FilteredPosition;
                    if (itemInfoOfOldSourceIndexFilteredPosition != null)
                    {
                        int oldFilteredIndex = itemInfoOfOldSourceIndexFilteredPosition.Index;
                        int newFilteredIndex1;

                        newPosition1 = itemInfoOfOldSourceIndexFilteredPosition;
                        if (itemInfoOfNewSourceIndexFilteredPosition == null)
                        {
                            //nextPositionIndex = itemInfoOfNewSourceIndex.NextFilteredItemIndex;
                            nextPosition1 =
                                itemInfoOfNewSourceIndexNextFilteredItemPosition != itemInfoOfOldSourceIndexFilteredPosition
                                                                                ? itemInfoOfNewSourceIndexNextFilteredItemPosition
                                                                                : itemInfoOfOldSourceIndex.NextFilteredItemPosition;
                            newFilteredIndex1 = oldSourceIndex < newSourceIndex1 ?
                                                itemInfoOfNewSourceIndexNextFilteredItemPosition.Index - 1 :
                                                itemInfoOfNewSourceIndexNextFilteredItemPosition.Index;
                        }
                        else
                        {
                            nextPosition1 = oldSourceIndex < newSourceIndex1 ?
                                            itemInfoOfNewSourceIndexNextFilteredItemPosition :
                                            itemInfoOfNewSourceIndexFilteredPosition;
                            newFilteredIndex1 = itemInfoOfNewSourceIndexFilteredPosition.Index;
                        }

                        _filteredPositions.Move(
                            oldFilteredIndex,
                            newFilteredIndex1);

                        modifyNextFilteredItemIndex(oldSourceIndex, itemInfoOfOldSourceIndex.NextFilteredItemPosition);

                        _sourcePositions.Move(oldSourceIndex, newSourceIndex1);

                        itemInfoOfOldSourceIndex.NextFilteredItemPosition = nextPosition1;

                        modifyNextFilteredItemIndex(newSourceIndex1, newPosition1);

                        baseMoveItem(oldFilteredIndex, newFilteredIndex1);
                    }
                    else
                    {
                        nextPosition1 = oldSourceIndex < newSourceIndex1
                                                                ? itemInfoOfNewSourceIndexNextFilteredItemPosition
                                                                : (itemInfoOfNewSourceIndexFilteredPosition ?? itemInfoOfNewSourceIndexNextFilteredItemPosition);

                        itemInfoOfOldSourceIndex.NextFilteredItemPosition = nextPosition1;

                        _sourcePositions.Move(oldSourceIndex, newSourceIndex1);
                    }
                }
                _isConsistent = true;
                raiseConsistencyRestored();
                break;

            case NotifyCollectionChangedAction.Reset:
                _isConsistent = false;
                initializeFromSource();
                _isConsistent = true;
                raiseConsistencyRestored();
                break;

            case NotifyCollectionChangedAction.Replace:
                _isConsistent = false;
                int               sourceIndex          = e.NewStartingIndex;
                ItemInfo          replacingItemInfo    = _itemInfos[sourceIndex];
                ExpressionWatcher oldExpressionWatcher = replacingItemInfo.ExpressionWatcher;
                oldExpressionWatcher.Dispose();

                ExpressionWatcher watcher;
                Func <bool>       predicateFunc;
                TSourceItem       replacingSourceItem = _sourceAsList[sourceIndex];
                getNewExpressionWatcherAndPredicateFunc(replacingSourceItem, out watcher, out predicateFunc);
                replacingItemInfo.PredicateFunc = predicateFunc;
                watcher.ValueChanged            = expressionWatcher_OnValueChanged;
                watcher._position = oldExpressionWatcher._position;
                replacingItemInfo.ExpressionWatcher = watcher;

                if (!processChangeSourceItem(sourceIndex) && replacingItemInfo.FilteredPosition != null)
                {
                    baseSetItem(replacingItemInfo.FilteredPosition.Index, replacingSourceItem);
                }
                _isConsistent = true;
                raiseConsistencyRestored();
                break;
            }

            _isConsistent = false;
            if (_deferredExpressionWatcherChangedProcessings != null)
            {
                while (_deferredExpressionWatcherChangedProcessings.Count > 0)
                {
                    ExpressionWatcher.Raise expressionWatcherRaise = _deferredExpressionWatcherChangedProcessings.Dequeue();
                    if (!expressionWatcherRaise.ExpressionWatcher._disposed)
                    {
                        _handledEventSender = expressionWatcherRaise.EventSender;
                        _handledEventArgs   = expressionWatcherRaise.EventArgs;
                        processChangeSourceItem(expressionWatcherRaise.ExpressionWatcher._position.Index);
                    }
                }
            }

            _isConsistent = true;
            raiseConsistencyRestored();

            _handledEventSender = null;
            _handledEventArgs   = null;
        }
Пример #28
0
        private ItemInfo registerSourceItem(TSourceItem sourceItem, int sourceIndex, Position position, Position nextItemPosition, ExpressionWatcher watcher = null, Func <bool> predicateFunc = null)
        {
            ItemInfo itemInfo = _sourcePositions.Insert(sourceIndex);

            itemInfo.FilteredPosition         = position;
            itemInfo.NextFilteredItemPosition = nextItemPosition;

            if (watcher == null /*&& predicateFunc == null*/)
            {
                getNewExpressionWatcherAndPredicateFunc(sourceItem, out watcher, out predicateFunc);
            }

            itemInfo.PredicateFunc     = predicateFunc;
            watcher.ValueChanged       = expressionWatcher_OnValueChanged;
            watcher._position          = itemInfo;
            itemInfo.ExpressionWatcher = watcher;

            return(itemInfo);
        }
Пример #29
0
        private void handleSourceCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            checkConsistent(sender, e);
            if (!_rootSourceWrapper && _lastProcessedSourceChangeMarker == _sourceAsList.ChangeMarkerField)
            {
                return;
            }

            _handledEventSender = sender;
            _handledEventArgs   = e;

            _lastProcessedSourceChangeMarker = !_lastProcessedSourceChangeMarker;

            switch (e.Action)
            {
            case NotifyCollectionChangedAction.Add:
                _isConsistent = false;
                int         newSourceIndex  = e.NewStartingIndex;
                TSourceItem addedSourceItem = _sourceAsList[newSourceIndex];
                ItemInfo    itemInfo        = registerSourceItem(addedSourceItem, newSourceIndex);
                if (ApplyPredicate(newSourceIndex))
                {
                    _predicatePassedCount++;
                    itemInfo.PredicateResult = true;
                }

                calculateValue();
                _isConsistent = true;
                raiseConsistencyRestored();
                break;

            case NotifyCollectionChangedAction.Remove:
                int oldStartingIndex = e.OldStartingIndex;
                if (_itemInfos[oldStartingIndex].PredicateResult)
                {
                    _predicatePassedCount--;
                }
                unregisterSourceItem(oldStartingIndex);
                calculateValue();
                break;

            case NotifyCollectionChangedAction.Move:
                int newSourceIndex1 = e.NewStartingIndex;
                int oldSourceIndex  = e.OldStartingIndex;

                if (newSourceIndex1 != oldSourceIndex)
                {
                    _sourcePositions.Move(oldSourceIndex, newSourceIndex1);
                }

                break;

            case NotifyCollectionChangedAction.Reset:
                _isConsistent = false;
                initializeFromSource();
                _isConsistent = true;
                raiseConsistencyRestored();
                break;

            case NotifyCollectionChangedAction.Replace:
                _isConsistent = false;
                int               newStartingIndex     = e.NewStartingIndex;
                ItemInfo          replacingItemInfo    = _itemInfos[newStartingIndex];
                ExpressionWatcher oldExpressionWatcher = replacingItemInfo.ExpressionWatcher;
                oldExpressionWatcher.Dispose();
                if (replacingItemInfo.PredicateResult)
                {
                    _predicatePassedCount--;
                }

                ExpressionWatcher watcher;
                Func <bool>       predicateFunc;
                TSourceItem       replacingSourceItem = _sourceAsList[newStartingIndex];
                getNewExpressionWatcherAndPredicateFunc(replacingSourceItem, out watcher, out predicateFunc);
                replacingItemInfo.PredicateFunc = predicateFunc;
                watcher.ValueChanged            = expressionWatcher_OnValueChanged;
                watcher._position = oldExpressionWatcher._position;
                replacingItemInfo.ExpressionWatcher = watcher;

                if (ApplyPredicate(newStartingIndex))
                {
                    _predicatePassedCount++;
                    replacingItemInfo.PredicateResult = true;
                }
                else
                {
                    replacingItemInfo.PredicateResult = false;
                }

                calculateValue();
                _isConsistent = true;
                raiseConsistencyRestored();
                break;
            }

            _isConsistent = false;
            if (_deferredExpressionWatcherChangedProcessings != null)
            {
                while (_deferredExpressionWatcherChangedProcessings.Count > 0)
                {
                    ExpressionWatcher.Raise expressionWatcherRaise = _deferredExpressionWatcherChangedProcessings.Dequeue();
                    if (!expressionWatcherRaise.ExpressionWatcher._disposed)
                    {
                        _handledEventSender = expressionWatcherRaise.EventSender;
                        _handledEventArgs   = expressionWatcherRaise.EventArgs;
                        processExpressionWatcherValueChanged(expressionWatcherRaise.ExpressionWatcher);
                    }
                }
            }

            _isConsistent = true;
            raiseConsistencyRestored();

            _handledEventSender = null;
            _handledEventArgs   = null;
        }
Пример #30
0
        private void initializeFromSource()
        {
            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);

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

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

                _sourceNotifyCollectionChangedEventHandler = null;
            }

            _predicatePassedCount = 0;
            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;

                int count = _sourceAsList.Count;
                for (int sourceIndex = 0; sourceIndex < count; sourceIndex++)
                {
                    TSourceItem sourceItem = _sourceAsList[sourceIndex];
                    ItemInfo    itemInfo   = registerSourceItem(sourceItem, sourceIndex);

                    if (ApplyPredicate(sourceIndex))
                    {
                        _predicatePassedCount++;
                        itemInfo.PredicateResult = true;
                    }
                }

                _sourceNotifyCollectionChangedEventHandler = handleSourceCollectionChanged;

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

                    _sourceAsList.CollectionChanged += _sourceWeakNotifyCollectionChangedEventHandler.Handle;
                }

                calculateValue();
            }
            else
            {
                if (_value)
                {
                    setValue(false);
                }
            }
        }