Fixed more edge cases

This commit is contained in:
TheXamlGuy
2024-05-21 20:32:42 +01:00
parent 1190303044
commit 83fef5e399
18 changed files with 153 additions and 63 deletions
@@ -54,7 +54,10 @@ public class ContentControlHandler :
control.Unloaded += HandleUnloaded;
control.DataContext = args.Content;
contentControl.Content = null;
contentControl.Content = control;
await taskCompletionSource.Task;
}
}
+23 -3
View File
@@ -1,5 +1,5 @@
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Immutable;
using System.Reactive.Disposables;
namespace Toolkit.Foundation;
@@ -10,6 +10,12 @@ public class Cache<TValue>(IDisposer disposer,
{
private readonly SortedSet<TValue> cache = new(comparer);
public int IndexOf(TValue value)
{
ImmutableSortedSet<TValue> hashSet = cache.ToImmutableSortedSet(comparer);
return hashSet.IndexOf(value);
}
public void Add(TValue value)
{
if (value is null)
@@ -21,6 +27,17 @@ public class Cache<TValue>(IDisposer disposer,
cache.Add(value);
}
public bool TryGetValue(TValue key, out TValue? value)
{
if (cache.TryGetValue(key, out value))
{
return true;
}
value = default;
return false;
}
public void Clear() => cache.Clear();
public IEnumerator<TValue> GetEnumerator() => cache.GetEnumerator();
@@ -30,14 +47,15 @@ public class Cache<TValue>(IDisposer disposer,
public bool Remove(TValue value) => cache.Remove(value);
}
public class Cache<TKey, TValue> :
public class Cache<TKey, TValue>(IDisposer disposer,
IComparer<TKey> comparer) :
ICache<TKey, TValue>
where TKey :
notnull
where TValue :
notnull
{
private readonly ConcurrentDictionary<TKey, TValue> cache = new();
private readonly SortedList<TKey, TValue> cache = new(comparer);
public void Add(TKey key,
TValue value)
@@ -49,6 +67,8 @@ public class Cache<TKey, TValue> :
public bool ContainsKey(TKey key) => cache.ContainsKey(key);
public int IndexOf(TKey key) => cache.IndexOfKey(key);
public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator() => cache.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
+10
View File
@@ -0,0 +1,10 @@
namespace Toolkit.Foundation;
public record Created
{
public static CreatedEventArgs<TValue> As<TValue>(TValue value) =>
new(value);
public static CreatedEventArgs<TValue> As<TValue>() where TValue : new() =>
new(new TValue());
}
+3
View File
@@ -0,0 +1,3 @@
namespace Toolkit.Foundation;
public record CreatedEventArgs<TValue>(TValue Value);
+7 -2
View File
@@ -7,7 +7,11 @@ public interface ICache<TValue> :
void Clear();
int IndexOf(TValue value);
bool Remove(TValue value);
bool TryGetValue(TValue key, out TValue? value);
}
public interface ICache<TKey, TValue> :
@@ -17,13 +21,14 @@ public interface ICache<TKey, TValue> :
where TValue :
notnull
{
void Add(TKey key,
TValue value);
void Add(TKey key, TValue value);
void Clear();
bool ContainsKey(TKey key);
int IndexOf(TKey key);
bool Remove(TKey key);
bool TryGetValue(TKey key, out TValue? value);
@@ -1,9 +1,5 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.FileProviders.Physical;
using Microsoft.Extensions.Hosting;
using System.Text.Json;
namespace Toolkit.Foundation;
+7
View File
@@ -0,0 +1,7 @@
namespace Toolkit.Foundation;
public record Modified
{
public static ModifiedEventArgs<TValue> As<TValue>(TValue oldValue, TValue newValue) =>
new(oldValue, newValue);
}
+3
View File
@@ -0,0 +1,3 @@
namespace Toolkit.Foundation;
public record ModifiedEventArgs<TValue>(TValue OldView, TValue NewValue);
+17 -4
View File
@@ -8,12 +8,25 @@ public class NavigateHandler(NamedComponent scope,
{
public Task Handle(NavigateEventArgs args)
{
INavigationScope? navigationScope;
if (args.Scope == "self" && args.Sender is IServiceProviderRequired requireServiceProvider)
INavigationScope? navigationScope = null;
if (args.Scope is "self" || args.Scope is "new")
{
navigationScope = requireServiceProvider.Provider.GetRequiredService<INavigationScope>();
if (args.Sender is IServiceProviderRequired requireServiceProvider)
{
if (args.Scope is "self")
{
navigationScope = requireServiceProvider.Provider.GetRequiredService<INavigationScope>();
}
if (args.Scope is "new")
{
IServiceScope serviceScope = requireServiceProvider.Provider.CreateScope();
navigationScope = serviceScope.ServiceProvider.GetRequiredService<INavigationScope>();
}
}
}
else
if (navigationScope is null)
{
ComponentScopeDescriptor? descriptor = componentScopeProvider.Get(args.Scope ?? scope.Name);
navigationScope = descriptor?.Services?.GetRequiredService<INavigationScope>();
+1 -1
View File
@@ -63,7 +63,7 @@ public partial class Observable :
public virtual Task OnDeactivating() =>
Task.CompletedTask;
public void Dispose()
public virtual void Dispose()
{
GC.SuppressFinalize(this);
Disposer.Dispose(this);
+53 -43
View File
@@ -24,12 +24,14 @@ public partial class ObservableCollection<TItem> :
IPublisherRequired,
IDisposerRequired,
INotificationHandler<RemoveEventArgs<TItem>>,
INotificationHandler<RemoveAtEventArgs<TItem>>,
INotificationHandler<RemoveAndInsertAtEventArgs<TItem>>,
INotificationHandler<CreateEventArgs<TItem>>,
INotificationHandler<InsertEventArgs<TItem>>,
INotificationHandler<MoveEventArgs<TItem>>,
INotificationHandler<ReplaceEventArgs<TItem>>
where TItem :
notnull
IDisposable
{
private readonly System.Collections.ObjectModel.ObservableCollection<TItem> collection = [];
@@ -111,12 +113,6 @@ public partial class ObservableCollection<TItem> :
set => SetItem(index, value);
}
public void ResetAndAddRange(Action<ObservableCollection<TItem>> args)
{
Clear();
args.Invoke(this);
}
object? IList.this[int index]
{
get => collection[index];
@@ -136,18 +132,13 @@ public partial class ObservableCollection<TItem> :
}
}
public TItem Add() =>
public TItem Add() =>
Add<TItem>(null, false);
public TItem Add<T>(params object?[] parameters)
where T : TItem => Add<T>(null, false, parameters);
where T : TItem => Add<T>(false, parameters);
public TItem Add<T>(IDisposable? owner,
params object?[] parameters)
where T : TItem => Add<T>(owner, false, parameters);
public TItem Add<T>(IDisposable? owner = null,
bool scope = false,
public TItem Add<T>(bool scope = false,
params object?[] parameters)
where T :
TItem
@@ -162,17 +153,6 @@ public partial class ObservableCollection<TItem> :
T? item = factory is not null ? factory.Create<T>(parameters) : Factory.Create<T>(parameters);
Add(item);
if (owner is not null)
{
Disposer.Add(owner, Disposable.Create(() =>
{
if (item is IRemovable)
{
Remove(item);
}
}));
}
return item;
}
@@ -213,6 +193,20 @@ public partial class ObservableCollection<TItem> :
}
}
public void BeginAggregation()
{
if (this.GetAttribute<AggerateAttribute>() is AggerateAttribute attribute)
{
if (attribute.Mode == AggerateMode.Reset)
{
Clear();
}
object? key = this.GetPropertyValue(() => attribute.Key) is { } value ? value : attribute.Key;
Publisher.PublishUI(OnPrepareAggregation(key));
}
}
public void Clear()
{
clearing = true;
@@ -220,6 +214,7 @@ public partial class ObservableCollection<TItem> :
foreach (TItem item in this.ToList())
{
Disposer.Dispose(item);
Disposer.Remove(this, item);
}
ClearItems();
@@ -250,20 +245,6 @@ public partial class ObservableCollection<TItem> :
Disposer.Dispose(this);
}
public void BeginAggregation()
{
if (this.GetAttribute<AggerateAttribute>() is AggerateAttribute attribute)
{
if (attribute.Mode == AggerateMode.Reset)
{
Clear();
}
object? key = this.GetPropertyValue(() => attribute.Key) is { } value ? value : attribute.Key;
Publisher.PublishUI(OnPrepareAggregation(key));
}
}
public IEnumerator<TItem> GetEnumerator() =>
collection.GetEnumerator();
@@ -323,6 +304,27 @@ public partial class ObservableCollection<TItem> :
return Task.CompletedTask;
}
public Task Handle(RemoveAtEventArgs<TItem> args)
{
if (args.Index >= 0 && args.Index <= Count - 1)
{
RemoveAt(args.Index);
}
return Task.CompletedTask;
}
public Task Handle(RemoveAndInsertAtEventArgs<TItem> args)
{
if (args.OldIndex >= 0 && args.OldIndex <= Count - 1 && args.Value is TItem item)
{
RemoveAt(args.OldIndex);
Insert(args.NewIndex, item);
}
return Task.CompletedTask;
}
public int IndexOf(TItem item) =>
collection.IndexOf(item);
@@ -385,8 +387,10 @@ public partial class ObservableCollection<TItem> :
{
return false;
}
Disposer.Dispose(item);
Disposer.Remove(this, item);
RemoveItem(index);
return true;
@@ -419,6 +423,12 @@ public partial class ObservableCollection<TItem> :
return true;
}
public void ResetAndAddRange(Action<ObservableCollection<TItem>> args)
{
Clear();
args.Invoke(this);
}
protected virtual void ClearItems() =>
collection.Clear();
@@ -439,7 +449,7 @@ public partial class ObservableCollection<TItem> :
}
}));
collection.Insert(index, item);
collection.Insert(index > Count ? Count : index, item);
}
protected virtual IAggerate OnPrepareAggregation(object? key) =>
@@ -476,7 +486,7 @@ public partial class ObservableCollection<TValue, TViewModel>(IServiceProvider p
IMediator mediator,
IPublisher publisher,
ISubscription subscriber, IDisposer disposer) : ObservableCollection<TViewModel>(provider, factory, mediator, publisher, subscriber, disposer)
where TViewModel : notnull
where TViewModel : IDisposable
{
[ObservableProperty]
private TValue? value;
+7
View File
@@ -0,0 +1,7 @@
namespace Toolkit.Foundation;
public record RemoveAndInsertAt
{
public static RemoveAndInsertAtEventArgs<TValue> As<TValue>(int oldIndex, int newIndex, TValue value) =>
new(oldIndex, newIndex, value);
}
@@ -0,0 +1,3 @@
namespace Toolkit.Foundation;
public record RemoveAndInsertAtEventArgs<TValue>(int OldIndex, int NewIndex, TValue Value);
+7
View File
@@ -0,0 +1,7 @@
namespace Toolkit.Foundation;
public record RemoveAt
{
public static RemoveAtEventArgs<TValue> As<TValue>(int index) =>
new(index);
}
+3
View File
@@ -0,0 +1,3 @@
namespace Toolkit.Foundation;
public record RemoveAtEventArgs<TValue>(int Index);
+2
View File
@@ -1,3 +1,5 @@
namespace Toolkit.Foundation;
public record RemoveEventArgs<TValue>(TValue Value);
public record RemoveAndInsertEventArgs<TValue>(TValue Value);
+4 -5
View File
@@ -21,7 +21,7 @@ public class Subscription(SubscriptionCollection subscriptions,
return collection;
});
disposer.Add(subscriber, Disposable.Create(() => RemoveSubscriber(subscriber, argumentType)));
disposer.Add(subscriber, Disposable.Create(() => RemoveSubscriber(subscriber, subscriptionKey)));
}
}
}
@@ -51,10 +51,9 @@ public class Subscription(SubscriptionCollection subscriptions,
private void RemoveSubscriber(object subscriber,
Type argumentType)
string key)
{
string subscriptionKey = $"{argumentType}";
if (subscriptions.TryGetValue(subscriptionKey, out List<WeakReference>? subscribers))
if (subscriptions.TryGetValue(key, out List<WeakReference>? subscribers))
{
for (int i = subscribers.Count - 1; i >= 0; i--)
{
@@ -66,7 +65,7 @@ public class Subscription(SubscriptionCollection subscriptions,
if (subscribers.Count == 0)
{
subscriptions.TryRemove(subscriptionKey, out _);
subscriptions.TryRemove(key, out _);
}
}
}
-1
View File
@@ -1,6 +1,5 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Primitives;
using Avalonia.Metadata;
using Avalonia.Xaml.Interactivity;
using Toolkit.Foundation;