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);
                }
            }
        }
Esempio n. 2
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();
        }
        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);
        }
        internal static void ProcessMoveSourceItems <TSourceItem1>(int oldSourceIndex, int newSourceIndex1,
                                                                   List <FilteringItemInfo> filteringItemInfos, Positions <Position> filteredPositions,
                                                                   Positions <FilteringItemInfo> sourcePositions, CollectionComputing <TSourceItem1> current)
        {
            if (newSourceIndex1 != oldSourceIndex)
            {
                FilteringItemInfo itemInfoOfOldSourceIndex = filteringItemInfos[oldSourceIndex];
                FilteringItemInfo itemInfoOfNewSourceIndex = filteringItemInfos[newSourceIndex1];

                Position nextPosition1;

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

                    Position 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, filteringItemInfos);

                    sourcePositions.Move(oldSourceIndex, newSourceIndex1);

                    itemInfoOfOldSourceIndex.NextFilteredItemPosition = nextPosition1;

                    modifyNextFilteredItemIndex(newSourceIndex1, newPosition1, filteringItemInfos);

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

                    itemInfoOfOldSourceIndex.NextFilteredItemPosition = nextPosition1;

                    sourcePositions.Move(oldSourceIndex, newSourceIndex1);
                }
            }
        }
        private void processSource(bool replaceSource)
        {
            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,
                    replaceSource);

                _sourceReadAndSubscribed = false;
            }

            if (replaceSource)
            {
                Utils.replaceSource(ref _source, _sourceScalar, _downstreamConsumedComputings, _consumers, this, out _sourceAsList, false);
            }

            if (_source != null && _isActive)
            {
                if (replaceSource)
                {
                    Utils.subscribeSource(
                        _source,
                        ref _sourceAsList,
                        ref _rootSourceWrapper,
                        ref _lastProcessedSourceTickTackVersion,
                        handleSourceCollectionChanged);
                }

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

                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();
        }