refactor: remove control cache to fix bugs

This commit is contained in:
estrogen elf
2025-06-17 11:51:08 -05:00
parent 50cc15cafb
commit 910d26c00d
2 changed files with 1 additions and 53 deletions

View File

@@ -27,7 +27,6 @@
<PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="11.2.8" /> <PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="11.2.8" />
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.2.8" /> <PackageReference Include="Avalonia.Themes.Fluent" Version="11.2.8" />
<PackageReference Include="AvaloniaEdit.TextMate" Version="11.3.0" /> <PackageReference Include="AvaloniaEdit.TextMate" Version="11.3.0" />
<PackageReference Include="BitFaster.Caching" Version="2.5.3" />
<PackageReference Include="BlossomiShymae.Briar" Version="0.2.0" /> <PackageReference Include="BlossomiShymae.Briar" Version="0.2.0" />
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" /> <PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
<PackageReference Include="DebounceThrottle" Version="3.0.1" /> <PackageReference Include="DebounceThrottle" Version="3.0.1" />

View File

@@ -1,60 +1,15 @@
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Controls.Templates; using Avalonia.Controls.Templates;
using Avalonia.VisualTree;
using BitFaster.Caching;
using BitFaster.Caching.Lru;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
namespace Needlework.Net namespace Needlework.Net
{ {
public class ViewLocator : IDataTemplate public class ViewLocator : IDataTemplate
{ {
private class ObjectComparer : IEqualityComparer<object>
{
public new bool Equals(object? x, object? y)
{
if (ReferenceEquals(x, y))
return true;
if (x == null || y == null)
return false;
return x.Equals(y);
}
public int GetHashCode([DisallowNull] object obj)
{
return obj.GetHashCode();
}
}
private readonly ICache<object, Control> _controlCache = new ConcurrentLruBuilder<object, Control>()
.WithExpireAfterAccess(TimeSpan.FromMinutes(5))
.WithKeyComparer(new ObjectComparer())
.WithCapacity(1024)
.WithMetrics()
.Build();
private readonly Dictionary<Type, Func<Control>> _viewRegister = []; private readonly Dictionary<Type, Func<Control>> _viewRegister = [];
public ViewLocator()
{
_controlCache.Events.Value!.ItemRemoved += (source, args) =>
{
var descendants = args.Value!.GetVisualDescendants();
foreach (var descendant in descendants)
{
if (descendant.DataContext is INotifyPropertyChanged key)
{
_controlCache.TryRemove(key, out _);
}
}
};
}
public void Register<T>(Func<Control> viewActivator) public void Register<T>(Func<Control> viewActivator)
where T : INotifyPropertyChanged where T : INotifyPropertyChanged
{ {
@@ -68,13 +23,7 @@ namespace Needlework.Net
throw new Exception("Data type has no registered view activator."); throw new Exception("Data type has no registered view activator.");
} }
bool isCold = !_controlCache.TryGet(data!, out var res); var res = activator();
if (isCold)
{
res ??= activator();
_controlCache.AddOrUpdate(data!, res);
}
res!.DataContext = data; res!.DataContext = data;
return res; return res;
} }