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); } }
protected override void uninitialize() { _getValueExpressionWatcher.Dispose(); EventUnsubscriber.QueueSubscriptions(_getValueExpressionWatcher._propertyChangedEventSubscriptions, _getValueExpressionWatcher._methodChangedEventSubscriptions); Utils.removeDownstreamConsumedComputing(_getValueExpressionWatcher, this); Utils.uninitializeNestedComputings(_nestedComputings, this); setDefaultValue(); }
private void unregisterSourceItem(int sourceIndex) { ItemInfo itemInfo = _itemInfos[sourceIndex]; ExpressionWatcher watcher = itemInfo.ExpressionWatcher; watcher.Dispose(); _sourcePositions.Remove(sourceIndex); }
private void unregisterSourceItem(int index, bool replacing = false) { ExpressionWatcher watcher = _itemInfos[index].ExpressionWatcher; watcher.Dispose(); if (!replacing) { _sourcePositions.Remove(index); } }
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(); } }
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); } } }
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; }
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; }
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(); }