using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; using System.Windows; using System.Windows.Threading; using PettingZoo.Core.Generator; using PettingZoo.Core.Settings; using PettingZoo.Tapeti.AssemblyLoader; using PettingZoo.Tapeti.NuGet; using PettingZoo.Tapeti.UI.ClassSelection; using PettingZoo.Tapeti.UI.PackageProgress; using PettingZoo.Tapeti.UI.PackageSelection; namespace PettingZoo.Tapeti { public class TapetiClassLibraryExampleGenerator : IExampleGenerator { public void Select(object? ownerWindow, Action onExampleSelected) { var packageManager = new NuGetPackageManager() .WithSourcesFrom(Path.Combine(PettingZooPaths.InstallationRoot, @"nuget.config")) .WithSourcesFrom(Path.Combine(PettingZooPaths.AppDataRoot, @"nuget.config")); var dispatcher = Dispatcher.CurrentDispatcher; var viewModel = new PackageSelectionViewModel(packageManager); var selectionWindow = new PackageSelectionWindow(viewModel) { Owner = ownerWindow as Window }; viewModel.Select += (_, args) => { dispatcher.Invoke(() => { var windowBounds = selectionWindow.RestoreBounds; selectionWindow.Close(); var progressWindow = new PackageProgressWindow(); progressWindow.Left = windowBounds.Left + (windowBounds.Width - progressWindow.Width) / 2; progressWindow.Left = windowBounds.Top + (windowBounds.Height - progressWindow.Height) / 2; progressWindow.Show(); Task.Run(async () => { try { // TODO allow cancelling (by closing the progress window and optionally a Cancel button) var assemblies = await args.Assemblies.GetAssemblies(progressWindow, CancellationToken.None); // var classes = var examples = LoadExamples(assemblies); dispatcher.Invoke(() => { progressWindow.Close(); progressWindow = null; var classSelectionViewModel = new ClassSelectionViewModel(examples); var classSelectionWindow = new ClassSelectionWindow(classSelectionViewModel) { Top = windowBounds.Top, Left = windowBounds.Left, Width = windowBounds.Width, Height = windowBounds.Height }; classSelectionViewModel.Select += (_, example) => { classSelectionWindow.Close(); onExampleSelected(example); }; classSelectionWindow.ShowDialog(); }); } catch (Exception e) { dispatcher.Invoke(() => { // ReSharper disable once ConstantConditionalAccessQualifier - if I remove it, there's a "Dereference of a possibly null reference" warning instead progressWindow?.Close(); MessageBox.Show($"Error while loading assembly: {e.Message}", "Petting Zoo - Exception", MessageBoxButton.OK, MessageBoxImage.Error); }); } }); }); }; selectionWindow.ShowDialog(); } private static IEnumerable LoadExamples(IEnumerable assemblies) { // TODO support folder with additional assemblies to load, or implement a proper NuGet install (with dependencies) instead var assemblyParser = new AssemblyParser.AssemblyParser(); return assemblies .SelectMany(a => { using var stream = a.GetStream(); return assemblyParser.GetExamples(stream).ToArray(); }) .ToArray(); } } }