- tweak: less memory tweak part 2

This commit is contained in:
2026-03-13 20:29:53 +03:00
parent 8f66bf9f09
commit 830cb38d9f
15 changed files with 151 additions and 122 deletions

View File

@@ -5,7 +5,7 @@ using Nebula.Launcher.ServerListProviders;
namespace Nebula.Launcher.Models;
public record ListItemTemplate(Type ModelType, string IconKey, string Label);
public record ServerListTabTemplate(BaseServerListProvider ServerListProvider, string TabName);
public record ServerListTabTemplate(IServerListProvider ServerListProvider, string TabName);
public record ServerHubRecord(
[property:JsonPropertyName("name")] string Name,
[property:JsonPropertyName("url")] string MainUrl);

View File

@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Avalonia;
using Avalonia.Collections;
using Avalonia.Controls;
using Avalonia.Layout;
using Avalonia.Media;
@@ -18,38 +19,32 @@ using Nebula.Shared.Utils;
namespace Nebula.Launcher.ServerListProviders;
[ServiceRegister, ConstructGenerator]
public sealed partial class FavoriteServerListProvider : BaseServerListProvider
public sealed partial class FavoriteServerListProvider : IServerListProvider
{
[GenerateProperty] private ConfigurationService ConfigurationService { get; }
[GenerateProperty] private IServiceProvider ServiceProvider { get; }
[GenerateProperty] private ServerViewContainer ServerViewContainer { get; }
//[GenerateProperty] private ServerOverviewModel ServerOverviewModel { get; }
public Action? OnRefreshRequired;
private string[] _rawServerLists = [];
public override void LoadServerList(
ObservableCollection<IListEntryModelView> servers,
ObservableCollection<Exception> exceptions)
public void LoadServerList(
AvaloniaList<IListEntryModelView> servers,
AvaloniaList<Exception> exceptions)
{
base.LoadServerList(servers, exceptions);
foreach (var server in _rawServerLists)
{
var container = ServerViewContainer.Get(server.ToRobustUrl());
var container = ServerViewContainer.Get(server);
servers.Add(container);
}
servers.Add(new AddFavoriteButton(ServiceProvider));
}
public override void Dispose()
public void AddFavorite(ServerEntryViewModel entryViewModel)
{
}
public void AddFavorite(ServerEntryModelView entryModelView)
{
AddFavorite(entryModelView.Address);
AddFavorite(entryViewModel.Address);
}
public void AddFavorite(RobustUrl robustUrl)
@@ -60,10 +55,10 @@ public sealed partial class FavoriteServerListProvider : BaseServerListProvider
if(ServerViewContainer.Get(robustUrl) is IFavoriteEntryModelView favoriteView) favoriteView.IsFavorite = true;
}
public void RemoveFavorite(ServerEntryModelView entryModelView)
public void RemoveFavorite(ServerEntryViewModel entryViewModel)
{
var servers = GetFavoriteEntries();
servers.Remove(entryModelView.Address.ToString());
servers.Remove(entryViewModel.Address.ToString());
ConfigurationService.SetConfigValue(LauncherConVar.Favorites, servers.ToArray());
}
@@ -93,7 +88,7 @@ public sealed partial class FavoriteServerListProvider : BaseServerListProvider
}
_rawServerLists = value;
//ServerOverviewModel.UpdateRequired();
OnRefreshRequired?.Invoke();
}
private void InitialiseInDesignMode(){}

View File

@@ -1,22 +1,20 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Threading;
using System.Threading.Tasks;
using Avalonia.Collections;
using Avalonia.Controls;
using Avalonia.Threading;
using Nebula.Launcher.Models;
using Nebula.Launcher.Services;
using Nebula.Launcher.ViewModels.Pages;
using Nebula.Shared;
using Nebula.Shared.Models;
using Nebula.Shared.Services;
using Nebula.Shared.Utils;
namespace Nebula.Launcher.ServerListProviders;
[ServiceRegister(null, false), ConstructGenerator]
public sealed partial class HubServerListProvider : BaseServerListProvider
public sealed partial class HubServerListProvider : IServerListProvider, IDisposable
{
private CancellationTokenSource? _cts;
private readonly SemaphoreSlim _loadLock = new(1, 1);
@@ -32,34 +30,27 @@ public sealed partial class HubServerListProvider : BaseServerListProvider
return this;
}
public override void LoadServerList(
ObservableCollection<IListEntryModelView> servers,
ObservableCollection<Exception> exceptions)
public void LoadServerList(
AvaloniaList<IListEntryModelView> servers,
AvaloniaList<Exception> exceptions)
{
base.LoadServerList(servers, exceptions);
servers.Add(new LoadingServerEntry());
Task.Run(() => LoadServerListAsync(servers, exceptions));
}
private void SyncServers(List<IListEntryModelView> servers,
ObservableCollection<IListEntryModelView> collection)
AvaloniaList<IListEntryModelView> collection)
{
collection.Clear();
foreach (var server in servers)
{
collection.Add(server);
}
collection.AddRange(servers);
}
private async Task LoadServerListAsync(
ObservableCollection<IListEntryModelView> servers,
ObservableCollection<Exception> exceptions)
AvaloniaList<IListEntryModelView> servers,
AvaloniaList<Exception> exceptions)
{
CancellationTokenSource localCts;
var serverList = new List<IListEntryModelView>();
await _loadLock.WaitAsync();
try
{
@@ -84,26 +75,25 @@ public sealed partial class HubServerListProvider : BaseServerListProvider
serversRaw.Sort(new ServerComparer());
localCts.Token.ThrowIfCancellationRequested();
foreach (var info in serversRaw)
{
var viewContainer =
ServerViewContainer.Get(info.Address.ToRobustUrl(), info.StatusData);
serverList.Add(viewContainer);
}
Dispatcher.UIThread.Invoke(() =>
{
var serverList = new List<IListEntryModelView>();
foreach (var info in serversRaw)
{
serverList.Add(ServerViewContainer.Get(info.Address, info.StatusData));
}
SyncServers(serverList, servers);
});
}
catch (OperationCanceledException)
{
// Ignore cancel think
}
catch (Exception e)
{
Console.WriteLine(e);
exceptions.Add(
new Exception(
$"Some error while loading server list from {_hubUrl}. See inner exception",
@@ -116,7 +106,7 @@ public sealed partial class HubServerListProvider : BaseServerListProvider
private void Initialise(){}
private void InitialiseInDesignMode(){}
public override void Dispose()
public void Dispose()
{
_cts?.Dispose();
}

View File

@@ -1,19 +1,12 @@
using System;
using System.Collections.ObjectModel;
using CommunityToolkit.Mvvm.ComponentModel;
using Avalonia.Collections;
using Nebula.Launcher.ViewModels.Pages;
namespace Nebula.Launcher.ServerListProviders;
public abstract class BaseServerListProvider : ObservableObject, IDisposable
public interface IServerListProvider
{
public virtual void LoadServerList(
ObservableCollection<IListEntryModelView> servers,
ObservableCollection<Exception> exceptions)
{
servers.Clear();
exceptions.Clear();
}
public abstract void Dispose();
public void LoadServerList(
AvaloniaList<IListEntryModelView> servers,
AvaloniaList<Exception> exceptions);
}

View File

@@ -1,26 +1,21 @@
using System;
using System.Collections.ObjectModel;
using Avalonia.Collections;
using Nebula.Launcher.ViewModels;
using Nebula.Launcher.ViewModels.Pages;
namespace Nebula.Launcher.ServerListProviders;
public sealed class TestServerList : BaseServerListProvider
public sealed class TestServerList : IServerListProvider
{
public override void LoadServerList(
ObservableCollection<IListEntryModelView> servers,
ObservableCollection<Exception> exceptions)
public void LoadServerList(
AvaloniaList<IListEntryModelView> servers,
AvaloniaList<Exception> exceptions)
{
base.LoadServerList(servers, exceptions);
servers.Add(new ServerEntryModelView());
servers.Add(new ServerEntryModelView());
servers.Add(new ServerEntryViewModel());
servers.Add(new ServerEntryViewModel());
exceptions.Add(new Exception("Oh no!"));
}
public override void Dispose()
{
}
}

View File

@@ -3,13 +3,18 @@ using System.Collections.Generic;
using Nebula.Launcher.Models;
using Nebula.Launcher.ProcessHelper;
using Nebula.Launcher.ViewModels;
using Nebula.Launcher.ViewModels.Pages;
using Nebula.Shared;
using Nebula.Shared.Services;
namespace Nebula.Launcher.Services;
[ServiceRegister]
public sealed class InstanceRunningContainer(PopupMessageService popupMessageService, DebugService debugService)
public sealed class InstanceRunningContainer(
PopupMessageService popupMessageService,
DebugService debugService,
ServerViewContainer container
)
{
private readonly InstanceKeyPool _keyPool = new();
private readonly Dictionary<InstanceKey, ProcessRunHandler> _processCache = new();

View File

@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading;
using Avalonia.Controls;
using CommunityToolkit.Mvvm.ComponentModel;
using JetBrains.Annotations;
using Microsoft.Extensions.DependencyInjection;
@@ -14,6 +15,7 @@ using Nebula.Launcher.Views.Pages;
using Nebula.Shared;
using Nebula.Shared.Models;
using Nebula.Shared.Services;
using Nebula.Shared.Utils;
using Nebula.Shared.ViewHelper;
namespace Nebula.Launcher.ViewModels.Pages;
@@ -49,9 +51,16 @@ public partial class ServerOverviewModel : ViewModelBase
//real think
protected override void Initialise()
{
FavoriteServerListProvider.OnRefreshRequired += OnFavoriteRefreshRequired;
ConfigurationService.SubscribeVarChanged(LauncherConVar.Hub, OnHubListChanged, true);
}
private void OnFavoriteRefreshRequired()
{
if(CurrentServerList.Provider is FavoriteServerListProvider favoriteServerListProvider)
UpdateRequired();
}
private void OnHubListChanged(ServerHubRecord[]? value)
{
var tempItems = new List<ServerListTabTemplate>();
@@ -147,6 +156,8 @@ public sealed class ServerViewContainer
_entries.Clear();
}
public IListEntryModelView Get(string url, ServerStatus? serverStatus = null) => Get(url.ToRobustUrl(), serverStatus);
public IListEntryModelView Get(RobustUrl url, ServerStatus? serverStatus = null)
{
var key = url.ToString();
@@ -154,36 +165,13 @@ public sealed class ServerViewContainer
lock (_entries)
{
_customNames.TryGetValue(key, out var customName);
if (_entries.TryGetValue(key, out var weakEntry)
&& weakEntry.TryGetTarget(out entry))
{
return entry;
}
if (serverStatus is not null)
{
entry = _viewHelperService
.GetViewModel<ServerEntryModelView>()
.WithData(url, customName, serverStatus);
}
else
{
entry = _viewHelperService
.GetViewModel<ServerCompoundEntryViewModel>()
.LoadServerEntry(url, customName, CancellationToken.None);
}
if (entry is IFavoriteEntryModelView fav)
{
fav.IsFavorite = _favorites.Contains(key);
}
if (entry is IFilterConsumer filterConsumer)
{
filterConsumer.ProcessFilter(_currentFilter);
}
entry = Create(url, serverStatus);
_entries[key] = new WeakReference<IListEntryModelView>(entry);
}
@@ -191,6 +179,40 @@ public sealed class ServerViewContainer
return entry;
}
private IListEntryModelView Create(RobustUrl url, ServerStatus? serverStatus = null)
{
IListEntryModelView? entry;
var key = url.ToString();
_customNames.TryGetValue(key, out var customName);
if (serverStatus is not null)
{
//entry = new ExampleEntry(serverStatus.Name);
entry = _viewHelperService
.GetViewModel<ServerEntryViewModel>()
.WithData(url, customName, serverStatus);
}
else
{
entry = _viewHelperService
.GetViewModel<ServerCompoundEntryViewModel>()
.LoadServerEntry(url, customName, CancellationToken.None);
}
if (entry is IFavoriteEntryModelView fav)
{
fav.IsFavorite = _favorites.Contains(key);
}
if (entry is IFilterConsumer filterConsumer)
{
filterConsumer.ProcessFilter(_currentFilter);
}
return entry;
}
public void ApplyFilter(ServerFilter? filter)
{
_currentFilter = filter;
@@ -276,6 +298,19 @@ public interface IListEntryModelView : IDisposable
}
public sealed class ExampleEntry : StackPanel, IListEntryModelView
{
public ExampleEntry(string name)
{
Children.Add(new Label { Content = name });
}
public void Dispose()
{
}
}
public interface IFavoriteEntryModelView
{
public bool IsFavorite { get; set; }

View File

@@ -55,4 +55,10 @@ public partial class AddFavoriteViewModel : PopupViewModelBase
_logger.Error(e);
}
}
protected override void OnDispose()
{
base.OnDispose();
_logger.Dispose();
}
}

View File

@@ -9,7 +9,7 @@ namespace Nebula.Launcher.ViewModels.Popup;
[ConstructGenerator, ViewModelRegister(typeof(IsLoginCredentialsNullPopupView))]
public partial class IsLoginCredentialsNullPopupViewModel : PopupViewModelBase
{
private ServerEntryModelView _entry;
private ServerEntryViewModel _entryView;
[GenerateProperty] public override PopupMessageService PopupMessageService { get; }
[GenerateProperty, DesignConstruct] private ViewHelperService ViewHelperService { get; }
@@ -22,15 +22,15 @@ public partial class IsLoginCredentialsNullPopupViewModel : PopupViewModelBase
{
}
public IsLoginCredentialsNullPopupViewModel WithServerEntry(ServerEntryModelView entryModelView)
public IsLoginCredentialsNullPopupViewModel WithServerEntry(ServerEntryViewModel entryViewModel)
{
_entry = entryModelView;
_entryView = entryViewModel;
return this;
}
public void Proceed()
{
_entry.RunInstanceIgnoreAuth();
_entryView.RunInstanceIgnoreAuth();
Dispose();
}

View File

@@ -26,7 +26,7 @@ public sealed partial class ServerCompoundEntryViewModel :
private RobustUrl? _url;
private ServerFilter? _currentFilter;
public ServerEntryModelView? CurrentEntry
public ServerEntryViewModel? CurrentEntry
{
get;
set
@@ -74,7 +74,7 @@ public sealed partial class ServerCompoundEntryViewModel :
{
}
public ServerCompoundEntryViewModel LoadWithEntry(ServerEntryModelView? entry)
public ServerCompoundEntryViewModel LoadWithEntry(ServerEntryViewModel? entry)
{
CurrentEntry = entry;
return this;
@@ -101,7 +101,7 @@ public sealed partial class ServerCompoundEntryViewModel :
Message = "Loading server entry...";
var status = await RestService.GetAsync<ServerStatus>(_url.StatusUri, CancellationToken.None);
CurrentEntry = ServiceProvider.GetService<ServerEntryModelView>()!.WithData(_url, null, status);
CurrentEntry = ServiceProvider.GetService<ServerEntryViewModel>()!.WithData(_url, null, status);
Loading = false;
}

View File

@@ -21,7 +21,7 @@ namespace Nebula.Launcher.ViewModels;
[ViewModelRegister(typeof(ServerEntryView), false)]
[ConstructGenerator]
public sealed partial class ServerEntryModelView : ViewModelBase, IFilterConsumer, IListEntryModelView, IFavoriteEntryModelView, IEntryNameHolder
public sealed partial class ServerEntryViewModel : ViewModelBase, IFilterConsumer, IListEntryModelView, IFavoriteEntryModelView, IEntryNameHolder
{
[ObservableProperty] private string _description = "Fetching info...";
[ObservableProperty] private bool _expandInfo;
@@ -129,7 +129,7 @@ public sealed partial class ServerEntryModelView : ViewModelBase, IFilterConsume
OnPropertyChanged(nameof(Status));
}
public ServerEntryModelView WithData(RobustUrl url, string? name, ServerStatus serverStatus)
public ServerEntryViewModel WithData(RobustUrl url, string? name, ServerStatus serverStatus)
{
Address = url;
SetStatus(serverStatus);

View File

@@ -1,5 +1,6 @@
using System;
using System.Collections.ObjectModel;
using Avalonia.Collections;
using Nebula.Launcher.ServerListProviders;
using Nebula.Launcher.ViewModels.Pages;
using Nebula.Launcher.Views;
@@ -8,24 +9,31 @@ using Nebula.Shared.ViewHelper;
namespace Nebula.Launcher.ViewModels;
[ViewModelRegister(typeof(ServerListView), false)]
public partial class ServerListViewModel : ViewModelBase
public class ServerListViewModel : ViewModelBase
{
public ObservableCollection<IListEntryModelView> ServerList { get; private set; } = new();
public ObservableCollection<Exception> ErrorList { get; private set; } = new();
private BaseServerListProvider? _provider;
public AvaloniaList<IListEntryModelView> ServerList { get; private set; } = new();
public AvaloniaList<Exception> ErrorList { get; private set; } = new();
public IServerListProvider? Provider { get; private set; }
public void ClearProvider()
{
foreach (var serverEntry in ServerList)
{
if (serverEntry is IDisposable disposable)
{
disposable.Dispose();
}
}
ServerList.Clear();
ErrorList.Clear();
GC.Collect();
GC.WaitForPendingFinalizers();
}
public void SetProvider(BaseServerListProvider provider)
public void SetProvider(IServerListProvider provider)
{
_provider = provider;
Provider = provider;
OnPropertyChanged(nameof(ServerList));
OnPropertyChanged(nameof(ErrorList));
@@ -35,7 +43,7 @@ public partial class ServerListViewModel : ViewModelBase
public void RefreshFromProvider()
{
_provider?.LoadServerList(ServerList, ErrorList);
Provider?.LoadServerList(ServerList, ErrorList);
}
protected override void InitialiseInDesignMode()

View File

@@ -3,7 +3,7 @@
d:DesignWidth="800"
mc:Ignorable="d"
x:Class="Nebula.Launcher.Views.ServerEntryView"
x:DataType="viewModels:ServerEntryModelView"
x:DataType="viewModels:ServerEntryViewModel"
xmlns="https://github.com/avaloniaui"
xmlns:converters="clr-namespace:Nebula.Launcher.Converters"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
@@ -16,7 +16,7 @@
xmlns:services="clr-namespace:Nebula.Launcher.Services"
IsVisible="{Binding IsVisible}">
<Design.DataContext>
<viewModels:ServerEntryModelView />
<viewModels:ServerEntryViewModel />
</Design.DataContext>
<Border
@@ -213,7 +213,7 @@
BoxShadow="0 0 13 -1 #121212"
CornerRadius="10">
<Button
Command="{Binding $parent[views:ServerEntryView].((viewModels:ServerEntryModelView)DataContext).OnLinkGo}"
Command="{Binding $parent[views:ServerEntryView].((viewModels:ServerEntryViewModel)DataContext).OnLinkGo}"
CommandParameter="{Binding Url}"
Margin="3">
<StackPanel Orientation="Horizontal" Spacing="5">

View File

@@ -14,12 +14,10 @@
Margin="5,0,0,10"
Padding="0,0,10,0">
<StackPanel Margin="0,0,0,30">
<ItemsControl
ItemsSource="{Binding ErrorList}"
Margin="10,0,10,0" />
<ItemsControl
ItemsSource="{Binding ServerList}"
Padding="0" />
<ItemsControl ItemsSource="{Binding ErrorList}"
Margin="10,0,10,0" />
<ItemsControl ItemsSource="{Binding ServerList}"
Padding="0" />
</StackPanel>
</ScrollViewer>
</UserControl>

View File

@@ -28,6 +28,7 @@
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AFuncValueConverter_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003Fe91c13e7e24d7ba324e0e6eb12a24ea8c7761299d3c4703e55c86dd120835e61_003FFuncValueConverter_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AFunc_00601_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fa6b7f037ba7b44df80b8d3aa7e58eeb2e8e938_003Fab_003F4dac48f4_003FFunc_00601_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AFuture_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003Fb3575a2f41d7c2dbfaa36e866b8a361e11dd7223ff82bc574c1d5d4b7522f735_003FFuture_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AGC_002ECoreCLR_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003Fb35fce9cd25198662cd7a8324941fd794f2d31c98c32a35a18b355bc79386_003FGC_002ECoreCLR_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AHttpBaseStream_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F5c9ea82983a677ae263ed0c49dd93a5e32866ad7ae97beea733f6df197e995_003FHttpBaseStream_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AHttpClient_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003Fc439425da351c75ac7d966a1cc8324b51a9c471865af79d2f2f3fcb65e392_003FHttpClient_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AHttpClient_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003Fd1d7280b53be4f32b5e9b2587f54915348ec89107b99282d2748ac94b8c1_003FHttpClient_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
@@ -41,6 +42,7 @@
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AHttpRequestMessage_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F86529590f9604f327a3b1b19aec3ff2310f0654aa06bb8cef2e3d820ea3bfd_003FHttpRequestMessage_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AHttpResponseMessage_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F4cfeb8b377bc81e1fbb5f7d7a02492cb6ac23e88c8c9d7155944f0716f3d4b_003FHttpResponseMessage_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AIDispatcherImpl_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F22d92db124764b1ab49745245c66f01b1e1a00_003F0f_003F01061787_003FIDispatcherImpl_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AIDisposable_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F24f5857a073841e189d805de9660178ef49910_003F4a_003Ff21bf9b5_003FIDisposable_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AIDisposable_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fa6b7f037ba7b44df80b8d3aa7e58eeb2e8e938_003F98_003Fd1b23281_003FIDisposable_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AIEnumerable_00601_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F24f5857a073841e189d805de9660178ef49910_003Fbc_003F64378026_003FIEnumerable_00601_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AIGeometryContext_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F22d92db124764b1ab49745245c66f01b1e1a00_003F_005F2c742_003FIGeometryContext_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
@@ -63,6 +65,7 @@
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AObservableCollection_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F3e2c48e6b3ec8b39cf721287f93972c7f3df25d306753bcc539eaad73126c68_003FObservableCollection_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AObservableObject_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F3e432edeee9469b7cfdb81d6e6bd278cf57afb9e54ab75649b8bb2f52cdde69_003FObservableObject_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AObsoleteAttribute_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003Fd6ed53c3c6ac5794ce2e51aa4bcfdb5734b7f78ccfeccd5ba93ac6a0da3b2_003FObsoleteAttribute_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003APanelContainerGenerator_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F66d34460cd4eaf18a9301eeb1e7ae63cfc928ce72cc7e064e398d2bcfb9628_003FPanelContainerGenerator_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003APanel_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F9b699722324e3615b57977447b25bf953fccb2d6e912ae584f16b7e691ad9d3_003FPanel_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AParallel_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F36fd1a9641998bb3afbf2091e26eafa6aaafabcb494bc746c0ba7471db513143_003FParallel_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AParallel_002EForEachAsync_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003Fc1d1ed6be2d5d4de542b4af5b36e82f6d1d1a389a35a4e4f9748d137d1c651_003FParallel_002EForEachAsync_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
@@ -86,6 +89,7 @@
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AStyle_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003Fcfbd5689fdab68d1c02f6a9b3c5921abcc409b8743dcc958da77cc1cfcb8e_003FStyle_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ATextBox_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F43273dba3ac6a4e11aefe78fbbccf5d36f07542ca37ecebffb25c95d1a1c16b_003FTextBox_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AType_002ECoreCLR_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F5cde391207de75962d7bacb899ca2bd3985c86911b152d185b58999a422bf0_003FType_002ECoreCLR_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AType_002ECoreCLR_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F76bfc310d2c1ee89b5a3bb7f318b5c55015f66ebdf298211386b17a57fc25b_003FType_002ECoreCLR_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AUri_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F6a1fb5a19c4883d19f63515be2d0cce5e0e9929bb30469a912a58ad2e1e6152_003FUri_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AUserControl_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F0ceaca09f3944680b668dee8e1e0370b100a00_003F76_003F1f1e9043_003FUserControl_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AValuePrinter_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FUsers_003FCinka_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F80d1676fb411442983574149e0b6aebc72e00_003F2f_003F26a40f58_003FValuePrinter_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>