Skip to content

Commit

Permalink
v. 1.4.0
Browse files Browse the repository at this point in the history
  • Loading branch information
IgorBuchelnikov committed Apr 18, 2020
1 parent b1aaa11 commit af0e50f
Show file tree
Hide file tree
Showing 9 changed files with 172 additions and 94 deletions.
12 changes: 11 additions & 1 deletion README-RU.md
Original file line number Diff line number Diff line change
Expand Up @@ -1221,12 +1221,22 @@ namespace ObservableComputationsExamples

### Блокировка установки значений свойств обработчиков запросов на изменение результатов вычислений

Свойства обработчиков запросов на изменение вычислений являются публичными. По умолчанию любой код, который имеет ссылку на вычисление может установить или перезаписать значение этого свойства. Есть возможность управлять возможностью установки значений этих свойств с помощью методов класса [*CollectionComputing<TItem>*](#полный-список-операторов):
Свойства обработчиков запросов на изменение вычислений являются публичными. По умолчанию любой код, который имеет ссылку на вычисление может установить или перезаписать значение этого свойства. Есть возможность управлять возможностью установки значений этих свойств с помощью

методов класса [*CollectionComputing<TItem>*](#полный-список-операторов):

* void LockModifyChangeAction(CollectionChangeAction collectionChangeAction, object key)
* void UnlockModifyChangeAction(CollectionChangeAction collectionChangeAction, object key)
* bool IsModifyChangeActionLocked(CollectionChangeAction collectionChangeAction)

и методов класса [*ScalarComputing<TValue>*](#полный-список-операторов):

* void LockModifySetValueAction(object key)
* void UnlockModifySetValueAction(object key)
* bool IsModifySetValueActionLocked()



## Обработка изменений результатов вычислений
### Обработка измениний в ObservableCollection<T>

Expand Down
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1213,12 +1213,20 @@ Properties similar to *InsertItemAction* exist for all other operations: ([remov

### Lock setting properties of computation result change request handlers

Properties of the computation change request handlers are public. By default, any code that has a reference to the computation can set or overwrite the value of this property. It is possible to control the ability to set the values of these properties using methods of [*CollectionComputing<TItem>* class](#full-list-of-operators):
Properties of the computation change request handlers are public. By default, any code that has a reference to the computation can set or overwrite the value of this property. It is possible to control the ability to set the values of these properties using

methods of [*CollectionComputing<TItem>* class](#full-list-of-operators):

* void LockModifyChangeAction(CollectionChangeAction collectionChangeAction, object key)
* void UnlockModifyChangeAction(CollectionChangeAction collectionChangeAction, object key)
* bool IsModifyChangeActionLocked(CollectionChangeAction collectionChangeAction)

and methods of [*ScalarComputing<TValue>* class](#full-list-of-operators):

* void LockModifySetValueAction(object key)
* void UnlockModifySetValueAction(object key)
* bool IsModifySetValueActionLocked()

## Processing changes of computation results
### Change handling in ObservableCollection<T>

Expand Down
94 changes: 56 additions & 38 deletions src/ObservableComputations/Collections/ItemsProcessing.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,11 @@ public class ItemsProcessing<TSourceItem, TReturnValue> : CollectionComputing<TR

public Func<TSourceItem, ItemsProcessing<TSourceItem, TReturnValue>, object, EventArgs, TReturnValue> NewItemProcessor => _newItemProcessor;
public Action<TSourceItem, ItemsProcessing<TSourceItem, TReturnValue>, TReturnValue, object, EventArgs> OldItemProcessor => _oldItemProcessor;
public Action<TSourceItem, ItemsProcessing<TSourceItem, TReturnValue>, TReturnValue, object, EventArgs> MoveItemProcessor => _moveItemProcessor;

private readonly Func<TSourceItem, ItemsProcessing<TSourceItem, TReturnValue>, object, EventArgs, TReturnValue> _newItemProcessor;
private readonly Action<TSourceItem, ItemsProcessing<TSourceItem, TReturnValue>, TReturnValue, object, EventArgs> _oldItemProcessor;
private readonly Action<TSourceItem, ItemsProcessing<TSourceItem, TReturnValue>, TReturnValue, object, EventArgs> _moveItemProcessor;

// ReSharper disable once PrivateFieldCanBeConvertedToLocalVariable
private readonly PropertyChangedEventHandler _sourceScalarPropertyChangedEventHandler;
Expand All @@ -45,7 +47,8 @@ public class ItemsProcessing<TSourceItem, TReturnValue> : CollectionComputing<TR
public ItemsProcessing(
IReadScalar<INotifyCollectionChanged> sourceScalar,
Func<TSourceItem, ItemsProcessing<TSourceItem, TReturnValue>, object, EventArgs, TReturnValue> newItemProcessor = null,
Action<TSourceItem, ItemsProcessing<TSourceItem, TReturnValue>, TReturnValue, object, EventArgs> oldItemProcessor = null) : this(newItemProcessor, oldItemProcessor, Utils.getCapacity(sourceScalar))
Action<TSourceItem, ItemsProcessing<TSourceItem, TReturnValue>, TReturnValue, object, EventArgs> oldItemProcessor = null,
Action<TSourceItem, ItemsProcessing<TSourceItem, TReturnValue>, TReturnValue, object, EventArgs> moveItemProcessor = null) : this(newItemProcessor, oldItemProcessor, moveItemProcessor, Utils.getCapacity(sourceScalar))
{
_sourceScalar = sourceScalar;
_sourceScalarPropertyChangedEventHandler = handleSourceScalarValueChanged;
Expand All @@ -59,19 +62,22 @@ public class ItemsProcessing<TSourceItem, TReturnValue> : CollectionComputing<TR
public ItemsProcessing(
INotifyCollectionChanged source,
Func<TSourceItem, ItemsProcessing<TSourceItem, TReturnValue>, object, EventArgs, TReturnValue> newItemProcessor = null,
Action<TSourceItem, ItemsProcessing<TSourceItem, TReturnValue>, TReturnValue, object, EventArgs> oldItemProcessor = null) : this(newItemProcessor, oldItemProcessor, Utils.getCapacity(source))
Action<TSourceItem, ItemsProcessing<TSourceItem, TReturnValue>, TReturnValue, object, EventArgs> oldItemProcessor = null,
Action<TSourceItem, ItemsProcessing<TSourceItem, TReturnValue>, TReturnValue, object, EventArgs> moveItemProcessor = null) : this(newItemProcessor, oldItemProcessor, moveItemProcessor, Utils.getCapacity(source))
{
_source = source;
initializeFromSource(null, null);
}

private ItemsProcessing(
Func<TSourceItem, ItemsProcessing<TSourceItem, TReturnValue>, object, EventArgs, TReturnValue> newItemProcessor,
Action<TSourceItem, ItemsProcessing<TSourceItem, TReturnValue>, TReturnValue, object, EventArgs> oldItemProcessor,
Action<TSourceItem, ItemsProcessing<TSourceItem, TReturnValue>, TReturnValue, object, EventArgs> oldItemProcessor,
Action<TSourceItem, ItemsProcessing<TSourceItem, TReturnValue>, TReturnValue, object, EventArgs> moveItemProcessor,
int capacity) : base(capacity)
{
_newItemProcessor = newItemProcessor;
_oldItemProcessor = oldItemProcessor;
_moveItemProcessor = moveItemProcessor;
}

private void initializeFromSource(object sender, EventArgs eventArgs)
Expand All @@ -86,7 +92,7 @@ private void initializeFromSource(object sender, EventArgs eventArgs)
TSourceItem sourceItem = _sourceAsList[i];
TReturnValue returnValue = this[0];
baseRemoveItem(0);
processOldItem(sourceItem, returnValue, sender, eventArgs);
if (_oldItemProcessor != null) processOldItem(sourceItem, returnValue, sender, eventArgs);
}

if (_rootSourceWrapper)
Expand Down Expand Up @@ -125,7 +131,7 @@ private void initializeFromSource(object sender, EventArgs eventArgs)
for (int index = 0; index < count; index++)
{
TSourceItem sourceItem = _sourceAsList[index];
TReturnValue returnValue = processNewItem(sourceItem, sender, eventArgs);
TReturnValue returnValue = _newItemProcessor != null ? processNewItem(sourceItem, sender, eventArgs) : default(TReturnValue);

baseInsertItem(index, returnValue);
}
Expand Down Expand Up @@ -172,7 +178,7 @@ private void handleSourceCollectionChanged(object sender, NotifyCollectionChange
_isConsistent = false;
int newStartingIndex = e.NewStartingIndex;
TSourceItem addedItem = _sourceAsList[newStartingIndex];
TReturnValue returnValue = processNewItem(addedItem, sender, e);
TReturnValue returnValue = _newItemProcessor != null ? processNewItem(addedItem, sender, e) : default(TReturnValue);

baseInsertItem(newStartingIndex, returnValue);
_isConsistent = true;
Expand All @@ -184,7 +190,7 @@ private void handleSourceCollectionChanged(object sender, NotifyCollectionChange
TSourceItem removedItem = (TSourceItem) e.OldItems[0];
TReturnValue returnValue1 = this[oldStartingIndex];
baseRemoveItem(oldStartingIndex);
processOldItem(removedItem, returnValue1, sender, e);
if (_oldItemProcessor != null) processOldItem(removedItem, returnValue1, sender, e);
_isConsistent = true;
raiseConsistencyRestored();
break;
Expand All @@ -195,9 +201,9 @@ private void handleSourceCollectionChanged(object sender, NotifyCollectionChange
TSourceItem newItem = _sourceAsList[newStartingIndex1];
TReturnValue returnValueOld = this[newStartingIndex1];

TReturnValue returnValue2 = processNewItem(newItem, sender, e);
TReturnValue returnValue2 = _newItemProcessor != null ? processNewItem(newItem, sender, e) : default;
baseSetItem(newStartingIndex1, returnValue2);
processOldItem(oldItem, returnValueOld, sender, e);
if (_oldItemProcessor != null) processOldItem(oldItem, returnValueOld, sender, e);
_isConsistent = true;
raiseConsistencyRestored();
break;
Expand All @@ -207,6 +213,7 @@ private void handleSourceCollectionChanged(object sender, NotifyCollectionChange
if (oldStartingIndex2 != newStartingIndex2)
{
baseMoveItem(oldStartingIndex2, newStartingIndex2);
if (_moveItemProcessor!= null) processMovedItem(_sourceAsList[newStartingIndex2], this[newStartingIndex2], sender, e);
}
break;
case NotifyCollectionChangedAction.Reset:
Expand All @@ -220,46 +227,57 @@ private void handleSourceCollectionChanged(object sender, NotifyCollectionChange

private TReturnValue processNewItem(TSourceItem sourceItem, object sender, EventArgs eventArgs)
{
if (_newItemProcessor != null)
if (Configuration.TrackComputingsExecutingUserCode)
{
if (Configuration.TrackComputingsExecutingUserCode)
{
Thread currentThread = Thread.CurrentThread;
DebugInfo._computingsExecutingUserCode.TryGetValue(currentThread, out IComputing computing);
DebugInfo._computingsExecutingUserCode[currentThread] = this;

TReturnValue returnValue = _newItemProcessor(sourceItem, this, sender, eventArgs);
Thread currentThread = Thread.CurrentThread;
DebugInfo._computingsExecutingUserCode.TryGetValue(currentThread, out IComputing computing);
DebugInfo._computingsExecutingUserCode[currentThread] = this;

TReturnValue returnValue = _newItemProcessor(sourceItem, this, sender, eventArgs);

if (computing == null) DebugInfo._computingsExecutingUserCode.Remove(currentThread);
else DebugInfo._computingsExecutingUserCode[currentThread] = computing;
return returnValue;
}

if (computing == null) DebugInfo._computingsExecutingUserCode.Remove(currentThread);
else DebugInfo._computingsExecutingUserCode[currentThread] = computing;
return returnValue;
}
return _newItemProcessor(sourceItem, this, sender, eventArgs);
}

private void processOldItem(TSourceItem sourceItem, TReturnValue returnValue, object sender, EventArgs eventArgs)
{
if (Configuration.TrackComputingsExecutingUserCode)
{
Thread currentThread = Thread.CurrentThread;
DebugInfo._computingsExecutingUserCode.TryGetValue(currentThread, out IComputing computing);
DebugInfo._computingsExecutingUserCode[currentThread] = this;

_oldItemProcessor(sourceItem, this, returnValue, sender, eventArgs);

return _newItemProcessor(sourceItem, this, sender, eventArgs);
if (computing == null) DebugInfo._computingsExecutingUserCode.Remove(currentThread);
else DebugInfo._computingsExecutingUserCode[currentThread] = computing;
return;
}

return default;
_oldItemProcessor(sourceItem, this, returnValue, sender, eventArgs);
}

private void processOldItem(TSourceItem sourceItem, TReturnValue returnValue, object sender, EventArgs eventArgs)

private void processMovedItem(TSourceItem sourceItem, TReturnValue returnValue, object sender, EventArgs eventArgs)
{
if (_oldItemProcessor != null)
if (Configuration.TrackComputingsExecutingUserCode)
{
if (Configuration.TrackComputingsExecutingUserCode)
{
Thread currentThread = Thread.CurrentThread;
DebugInfo._computingsExecutingUserCode.TryGetValue(currentThread, out IComputing computing);
DebugInfo._computingsExecutingUserCode[currentThread] = this;

_oldItemProcessor(sourceItem, this, returnValue, sender, eventArgs);

if (computing == null) DebugInfo._computingsExecutingUserCode.Remove(currentThread);
else DebugInfo._computingsExecutingUserCode[currentThread] = computing;
return;
}
Thread currentThread = Thread.CurrentThread;
DebugInfo._computingsExecutingUserCode.TryGetValue(currentThread, out IComputing computing);
DebugInfo._computingsExecutingUserCode[currentThread] = this;

_moveItemProcessor(sourceItem, this, returnValue, sender, eventArgs);

_oldItemProcessor(sourceItem, this, returnValue, sender, eventArgs);
if (computing == null) DebugInfo._computingsExecutingUserCode.Remove(currentThread);
else DebugInfo._computingsExecutingUserCode[currentThread] = computing;
return;
}

_moveItemProcessor(sourceItem, this, returnValue, sender, eventArgs);
}

~ItemsProcessing()
Expand Down
Loading

0 comments on commit af0e50f

Please sign in to comment.