improvements, fixes
This commit is contained in:
parent
dd5dc68862
commit
e0666027b3
|
|
@ -0,0 +1,152 @@
|
|||
using System.Collections;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Collections.Specialized;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace AyCode.Core.Helpers
|
||||
{
|
||||
public interface IAcFastObservableCollection
|
||||
{
|
||||
public void AddRange(IEnumerable other);
|
||||
public void Replace(IEnumerable other);
|
||||
public void RemoveRange(IEnumerable other);
|
||||
public void Synchronize(NotifyCollectionChangedEventArgs args);
|
||||
}
|
||||
|
||||
public interface IAcFastObservableCollection<T> : IAcFastObservableCollection
|
||||
{
|
||||
public void Replace(IEnumerable<T> other);
|
||||
public void Sort(IComparer<T> comparer);
|
||||
public void SortAndReplace(IEnumerable<T> other, IComparer<T> comparer);
|
||||
}
|
||||
|
||||
public class AcFastObservableCollection<T> : ObservableCollection<T>, IAcFastObservableCollection<T>
|
||||
{
|
||||
private bool _suppressChangedEvent;
|
||||
|
||||
public void Replace(IEnumerable<T> other)
|
||||
{
|
||||
_suppressChangedEvent = true;
|
||||
|
||||
Clear();
|
||||
AddRange(other);
|
||||
}
|
||||
|
||||
public void Replace(IEnumerable other)
|
||||
{
|
||||
_suppressChangedEvent = true;
|
||||
|
||||
Clear();
|
||||
foreach (T item in other) Add(item);
|
||||
|
||||
_suppressChangedEvent = false;
|
||||
|
||||
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
|
||||
OnPropertyChanged(new PropertyChangedEventArgs(nameof(Count)));
|
||||
}
|
||||
|
||||
public void AddRange(IEnumerable other)
|
||||
{
|
||||
_suppressChangedEvent = true;
|
||||
|
||||
foreach (var item in other)
|
||||
{
|
||||
if (item is T tItem) Add(tItem);
|
||||
}
|
||||
|
||||
_suppressChangedEvent = false;
|
||||
|
||||
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
|
||||
OnPropertyChanged(new PropertyChangedEventArgs(nameof(Count)));
|
||||
}
|
||||
|
||||
public void RemoveRange(IEnumerable other)
|
||||
{
|
||||
_suppressChangedEvent = true;
|
||||
|
||||
foreach (var item in other)
|
||||
{
|
||||
if (item is T tItem) Remove(tItem);
|
||||
}
|
||||
|
||||
_suppressChangedEvent = false;
|
||||
|
||||
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
|
||||
OnPropertyChanged(new PropertyChangedEventArgs(nameof(Count)));
|
||||
}
|
||||
|
||||
public void SortAndReplace(IEnumerable<T> other, IComparer<T> comparer)
|
||||
{
|
||||
List<T> values = new(other);
|
||||
|
||||
values.Sort(comparer);
|
||||
Replace(values);
|
||||
}
|
||||
|
||||
public void Sort(IComparer<T> comparer)
|
||||
{
|
||||
List<T> values = new(this);
|
||||
|
||||
values.Sort(comparer);
|
||||
Replace(values);
|
||||
}
|
||||
|
||||
public void Synchronize(NotifyCollectionChangedEventArgs args)
|
||||
{
|
||||
switch (args.Action)
|
||||
{
|
||||
case NotifyCollectionChangedAction.Add when args.NewItems != null:
|
||||
AddRange(args.NewItems);
|
||||
break;
|
||||
case NotifyCollectionChangedAction.Remove when args.OldItems != null:
|
||||
RemoveRange(args.OldItems);
|
||||
break;
|
||||
case NotifyCollectionChangedAction.Reset:
|
||||
Clear();
|
||||
break;
|
||||
case NotifyCollectionChangedAction.Replace:
|
||||
case NotifyCollectionChangedAction.Move:
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnPropertyChanged(PropertyChangedEventArgs e)
|
||||
{
|
||||
if (_suppressChangedEvent)
|
||||
return;
|
||||
|
||||
base.OnPropertyChanged(e);
|
||||
}
|
||||
|
||||
protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
if (_suppressChangedEvent)
|
||||
return;
|
||||
|
||||
base.OnCollectionChanged(e);
|
||||
}
|
||||
|
||||
//protected override void ClearItems()
|
||||
//{
|
||||
// base.ClearItems();
|
||||
//}
|
||||
|
||||
//protected override void InsertItem(int index, T item)
|
||||
//{
|
||||
// base.InsertItem(index, item);
|
||||
//}
|
||||
|
||||
//protected override void MoveItem(int oldIndex, int newIndex)
|
||||
//{
|
||||
// base.MoveItem(oldIndex, newIndex);
|
||||
//}
|
||||
|
||||
//public override event NotifyCollectionChangedEventHandler? CollectionChanged
|
||||
//{
|
||||
// add => base.CollectionChanged += value;
|
||||
// remove => base.CollectionChanged -= value;
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
|
@ -61,18 +61,18 @@ namespace AyCode.Services.Server.SignalRs
|
|||
|
||||
public class ChangeTracking<TDataItem, TId> /*: IEnumerable<TrackingItem<T>>*/where TDataItem : class, IId<TId> where TId : struct
|
||||
{
|
||||
private readonly EqualityComparer<TId> _equalityComparer = EqualityComparer<TId>.Default;
|
||||
private readonly EqualityComparer<TId> _equalityComparerId = EqualityComparer<TId>.Default;
|
||||
private readonly List<TrackingItem<TDataItem, TId>> _trackingItems = []; //TODO: Dictionary... - J.
|
||||
|
||||
//protected abstract bool HasIdValue(TDataItem dataItem);
|
||||
//protected abstract int FindIndex(TDataItem newValue);
|
||||
//public abstract bool TryGetTrackingItem(TId id, [NotNullWhen(true)] out TrackingItem<TDataItem, TId>? trackingItem);
|
||||
|
||||
private bool HasIdValue(TDataItem dataItem) => !_equalityComparer.Equals(dataItem.Id, default);//dataItem.Id.IsNullOrEmpty();
|
||||
public int FindIndex(TDataItem newValue) => _trackingItems.FindIndex(x => _equalityComparer.Equals(x.CurrentValue.Id, newValue.Id));
|
||||
private bool HasIdValue(TDataItem dataItem) => !_equalityComparerId.Equals(dataItem.Id, default);//dataItem.Id.IsNullOrEmpty();
|
||||
public int FindIndex(TDataItem newValue) => _trackingItems.FindIndex(x => _equalityComparerId.Equals(x.CurrentValue.Id, newValue.Id));
|
||||
public bool TryGetTrackingItem(TId id, [NotNullWhen(true)] out TrackingItem<TDataItem, TId>? trackingItem)
|
||||
{
|
||||
trackingItem = _trackingItems.FirstOrDefault(x => _equalityComparer.Equals(x.CurrentValue.Id, id));
|
||||
trackingItem = _trackingItems.FirstOrDefault(x => _equalityComparerId.Equals(x.CurrentValue.Id, id));
|
||||
return trackingItem != null;
|
||||
}
|
||||
|
||||
|
|
@ -165,7 +165,7 @@ namespace AyCode.Services.Server.SignalRs
|
|||
where TIList : class, IList<TDataItem>
|
||||
{
|
||||
private readonly object _syncRoot = new();
|
||||
private readonly EqualityComparer<TId> _equalityComparer = EqualityComparer<TId>.Default;
|
||||
private readonly EqualityComparer<TId> _equalityComparerId = EqualityComparer<TId>.Default;
|
||||
|
||||
protected TIList InnerList = Activator.CreateInstance<TIList>();// []; //TODO: Dictionary??? - J.
|
||||
protected readonly ChangeTracking<TDataItem, TId> TrackingItems = new();
|
||||
|
|
@ -184,8 +184,8 @@ namespace AyCode.Services.Server.SignalRs
|
|||
//protected abstract int FindIndexInnerList(TId id);
|
||||
//protected abstract TDataItem? FirstOrDefaultInnerList(TId id);
|
||||
|
||||
protected bool HasIdValue(TDataItem dataItem) => !_equalityComparer.Equals(dataItem.Id, default);//dataItem.Id.IsNullOrEmpty();
|
||||
protected bool IdEquals(TId id1, TId id2) => _equalityComparer.Equals(id1, id2);
|
||||
protected bool HasIdValue(TDataItem dataItem) => !_equalityComparerId.Equals(dataItem.Id, default);//dataItem.Id.IsNullOrEmpty();
|
||||
protected bool IdEquals(TId id1, TId id2) => _equalityComparerId.Equals(id1, id2);
|
||||
protected int FindIndexInnerList(TId id) => InnerList.FindIndex(x => IdEquals(x.Id, id));
|
||||
protected TDataItem? FirstOrDefaultInnerList(TId id) => InnerList.FirstOrDefault(x => IdEquals(x.Id, id));
|
||||
|
||||
|
|
@ -265,11 +265,20 @@ namespace AyCode.Services.Server.SignalRs
|
|||
|
||||
protected void AddRange(IEnumerable<TDataItem> source, TIList destination)
|
||||
{
|
||||
if (destination is List<TDataItem> dest) dest.AddRange(source);
|
||||
else
|
||||
switch (destination)
|
||||
{
|
||||
foreach (var dataItem in source)
|
||||
destination.Add(dataItem);
|
||||
case IAcFastObservableCollection dest:
|
||||
dest.AddRange(source);
|
||||
break;
|
||||
case List<TDataItem> dest:
|
||||
dest.AddRange(source);
|
||||
break;
|
||||
default:
|
||||
{
|
||||
foreach (var dataItem in source)
|
||||
destination.Add(dataItem);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -371,7 +380,7 @@ namespace AyCode.Services.Server.SignalRs
|
|||
|
||||
public void Add(TDataItem newValue)
|
||||
{
|
||||
if (!HasIdValue(newValue)) throw new ArgumentNullException(nameof(newValue), @"Add->newValue.Id.IsNullOrEmpty()");
|
||||
if (!HasIdValue(newValue)) throw new ArgumentNullException(nameof(newValue), @"Add->HasIdValue(newValue) == false");
|
||||
|
||||
Monitor.Enter(_syncRoot);
|
||||
|
||||
|
|
@ -854,7 +863,7 @@ namespace AyCode.Services.Server.SignalRs
|
|||
throw new NullReferenceException($"SaveItemUnsafe; result == null");
|
||||
}
|
||||
|
||||
ProcessSavedResponseItem(x.Result, trackingState);
|
||||
ProcessSavedResponseItem(x.Result, trackingState, item.Id);
|
||||
return x.Result;
|
||||
});
|
||||
}
|
||||
|
|
@ -877,7 +886,7 @@ namespace AyCode.Services.Server.SignalRs
|
|||
throw new NullReferenceException($"SaveItemUnsafeAsync; result.Status != SignalResponseStatus.Success || result.ResponseData == null; Status: {SignalResponseStatus.Success}");
|
||||
}
|
||||
|
||||
return ProcessSavedResponseItem(response.ResponseData, trackingState);
|
||||
return ProcessSavedResponseItem(response.ResponseData, trackingState, item.Id);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
|
@ -886,14 +895,14 @@ namespace AyCode.Services.Server.SignalRs
|
|||
});
|
||||
}
|
||||
|
||||
private Task ProcessSavedResponseItem(TDataItem? resultItem, TrackingState trackingState)
|
||||
private Task ProcessSavedResponseItem(TDataItem? resultItem, TrackingState trackingState, TId originalId)
|
||||
{
|
||||
if (resultItem == null) return Task.CompletedTask;
|
||||
|
||||
if (TryGetTrackingItem(resultItem.Id, out var trackingItem))
|
||||
if (TryGetTrackingItem(originalId, out var trackingItem))
|
||||
TrackingItems.Remove(trackingItem);
|
||||
|
||||
if (TryGetIndex(resultItem.Id, out var index))
|
||||
if (TryGetIndex(originalId, out var index))
|
||||
InnerList[index] = resultItem;
|
||||
|
||||
var eventArgs = new ItemChangedEventArgs<TDataItem>(resultItem, trackingState);
|
||||
|
|
|
|||
|
|
@ -207,7 +207,7 @@ public abstract class AcWebSignalRHubBase<TSignalRTags, TLogger>(IConfiguration
|
|||
if (Context.User != null)
|
||||
{
|
||||
userName = Context.User.Identity?.Name;
|
||||
Guid.TryParse((string?)Context.User.FindFirstValue(ClaimTypes.NameIdentifier), out userId);
|
||||
Guid.TryParse(Context.User.FindFirstValue(ClaimTypes.NameIdentifier), out userId);
|
||||
}
|
||||
|
||||
if (AcDomain.IsDeveloperVersion) Logger.WarningConditional($"SignalR.Context; userName: {userName}; userId: {userId}");
|
||||
|
|
|
|||
Loading…
Reference in New Issue