SMB, GUI imput handler, ThreadSafe SMB

This commit is contained in:
2022-02-01 13:03:00 +01:00
parent c2dcb49016
commit 9824184d90
10 changed files with 265 additions and 48 deletions

View File

@@ -3,6 +3,7 @@ using FileTime.Avalonia.Application;
using FileTime.Avalonia.Services;
using FileTime.Avalonia.ViewModels;
using FileTime.Core.Command;
using FileTime.Core.Interactions;
using Microsoft.Extensions.DependencyInjection;
namespace FileTime.Avalonia
@@ -13,7 +14,8 @@ namespace FileTime.Avalonia
{
return serviceCollection
.AddSingleton<AppState>()
.AddTransient<MainPageViewModel>();
.AddTransient<MainPageViewModel>()
.AddSingleton<IInputInterface, BasicInputHandler>();
}
internal static IServiceCollection AddServices(this IServiceCollection serviceCollection)
{

View File

@@ -15,8 +15,9 @@ namespace FileTime.Avalonia.ViewModels
{
[ViewModel]
[Inject(typeof(ItemNameConverterService))]
public partial class ContainerViewModel : IItemViewModel
public partial class ContainerViewModel : IItemViewModel, IDisposable
{
private bool _disposed;
private bool _isRefreshing;
private bool _isInitialized;
private INewItemProcessor _newItemProcessor;
@@ -128,13 +129,20 @@ namespace FileTime.Avalonia.ViewModels
{
_isRefreshing = true;
var containers = (await _container.GetContainers()).Select(c => AdoptOrCreateItem(c, (c2) => new ContainerViewModel(_newItemProcessor, this, c2, ItemNameConverterService))).ToList();
var elements = (await _container.GetElements()).Select(e => AdoptOrCreateItem(e, (e2) => new ElementViewModel(e2, this, ItemNameConverterService))).ToList();
var containers = (await _container.GetContainers())!.Select(c => AdoptOrReuseOrCreateItem(c, (c2) => new ContainerViewModel(_newItemProcessor, this, c2, ItemNameConverterService))).ToList();
var elements = (await _container.GetElements())!.Select(e => AdoptOrReuseOrCreateItem(e, (e2) => new ElementViewModel(e2, this, ItemNameConverterService))).ToList();
var containersToRemove = _containers.Except(containers);
_containers.Clear();
_elements.Clear();
_items.Clear();
foreach (var containerToRemove in containersToRemove)
{
containerToRemove?.Dispose();
}
foreach (var container in containers)
{
if (initializeChildren) await container.Init(false);
@@ -161,11 +169,14 @@ namespace FileTime.Avalonia.ViewModels
_isRefreshing = false;
}
private TResult AdoptOrCreateItem<T, TResult>(T item, Func<T, TResult> generator) where T : IItem
private TResult AdoptOrReuseOrCreateItem<T, TResult>(T item, Func<T, TResult> generator) where T : class, IItem
{
var itemToAdopt = ChildrenToAdopt.Find(i => i.Item.Name == item.Name);
var itemToAdopt = ChildrenToAdopt.Find(i => i.Item == item);
if (itemToAdopt is TResult itemViewModel) return itemViewModel;
var existingViewModel = _items?.FirstOrDefault(i => i.Item == item);
if (existingViewModel is TResult itemViewModelToReuse) return itemViewModelToReuse;
return generator(item);
}
@@ -177,6 +188,7 @@ namespace FileTime.Avalonia.ViewModels
foreach (var container in _containers)
{
container.Unload(true);
container.Dispose();
container.ChildrenToAdopt.Clear();
}
}
@@ -203,5 +215,25 @@ namespace FileTime.Avalonia.ViewModels
if (!_isInitialized) await Task.Run(Refresh);
return _items;
}
~ContainerViewModel()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
if (!_disposed && disposing)
{
Container.Refreshed.Remove(Container_Refreshed);
}
_disposed = true;
}
}
}

View File

@@ -22,6 +22,7 @@ using FileTime.App.Core.Clipboard;
using Microsoft.Extensions.DependencyInjection;
using FileTime.Core.Command;
using FileTime.Core.Timeline;
using FileTime.Core.Providers;
namespace FileTime.Avalonia.ViewModels
{
@@ -40,7 +41,7 @@ namespace FileTime.Avalonia.ViewModels
private IClipboard _clipboard;
private TimeRunner _timeRunner;
private IEnumerable<IContentProvider>? _contentProviders;
private Action? _inputHandler;
[Property]
@@ -67,6 +68,11 @@ namespace FileTime.Avalonia.ViewModels
{
_clipboard = App.ServiceProvider.GetService<IClipboard>()!;
_timeRunner = App.ServiceProvider.GetService<TimeRunner>()!;
_contentProviders = App.ServiceProvider.GetService<IEnumerable<IContentProvider>>();
var inputInterface = (BasicInputHandler)App.ServiceProvider.GetService<IInputInterface>()!;
inputInterface.InputHandler = ReadInputs2;
App.ServiceProvider.GetService<TopContainer>();
_timeRunner.CommandsChanged += (o, e) => OnPropertyChanged(nameof(TimelineCommands));
InitCommandBindings();
@@ -496,6 +502,19 @@ namespace FileTime.Avalonia.ViewModels
await _timeRunner.Refresh();
}
private async Task GoToContainer()
{
var handler = () =>
{
if (Inputs != null)
{
}
};
ReadInputs(new List<Core.Interactions.InputElement>() { new Core.Interactions.InputElement("Path", InputType.Text) }, handler);
}
[Command]
public void ProcessInputs()
{
@@ -669,6 +688,24 @@ namespace FileTime.Avalonia.ViewModels
_inputHandler = inputHandler;
}
public async Task<string?[]> ReadInputs2(IEnumerable<Core.Interactions.InputElement> fields)
{
var waiting = true;
var result = new string[0];
ReadInputs(fields.ToList(), () =>
{
if(Inputs != null)
{
result = Inputs.Select(i => i.Value).ToArray();
}
waiting = false;
});
while (waiting) await Task.Delay(100);
return result;
}
private void ShowMessageBox(string text, Action inputHandler)
{
MessageBoxText = text;
@@ -847,6 +884,11 @@ namespace FileTime.Avalonia.ViewModels
FileTime.App.Core.Command.Commands.Refresh,
new KeyWithModifiers[]{new KeyWithModifiers(Key.R)},
RefreshCurrentLocation),
new CommandBinding(
"go to",
FileTime.App.Core.Command.Commands.Refresh,
new KeyWithModifiers[]{new KeyWithModifiers(Key.L, ctrl: true)},
GoToContainer),
};
var universalCommandBindings = new List<CommandBinding>()
{