Rework around a saner import popup and decouple logic from interface.

This commit is contained in:
Ottermandias 2023-04-08 22:29:43 +02:00
parent bfb630d317
commit bbfc9a0a6f
16 changed files with 478 additions and 411 deletions

View file

@ -0,0 +1,123 @@
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using Dalamud.Interface.Internal.Notifications;
using Penumbra.Import;
namespace Penumbra.Mods.Manager;
public class ModImportManager : IDisposable
{
private readonly ModManager _modManager;
private readonly Configuration _config;
private readonly ModEditor _modEditor;
private readonly ConcurrentQueue<string[]> _modsToUnpack = new();
/// <summary> Mods need to be added thread-safely outside of iteration. </summary>
private readonly ConcurrentQueue<DirectoryInfo> _modsToAdd = new();
private TexToolsImporter? _import;
public ModImportManager(ModManager modManager, Configuration config, ModEditor modEditor)
{
_modManager = modManager;
_config = config;
_modEditor = modEditor;
}
public void TryUnpacking()
{
if (Importing || !_modsToUnpack.TryDequeue(out var newMods))
return;
var files = newMods.Where(s =>
{
if (File.Exists(s))
return true;
Penumbra.ChatService.NotificationMessage($"Failed to import queued mod at {s}, the file does not exist.", "Warning",
NotificationType.Warning);
return false;
}).Select(s => new FileInfo(s)).ToArray();
if (files.Length == 0)
return;
_import = new TexToolsImporter(files.Length, files, AddNewMod, _config, _modEditor, _modManager);
}
public bool Importing
=> _import != null;
public bool IsImporting([NotNullWhen(true)] out TexToolsImporter? importer)
{
importer = _import;
return _import != null;
}
public void AddUnpack(IEnumerable<string> paths)
=> _modsToUnpack.Enqueue(paths.ToArray());
public void AddUnpack(params string[] paths)
=> _modsToUnpack.Enqueue(paths);
public void ClearImport()
{
_import?.Dispose();
_import = null;
}
public bool AddUnpackedMod([NotNullWhen(true)] out Mod? mod)
{
if (!_modsToAdd.TryDequeue(out var directory))
{
mod = null;
return false;
}
_modManager.AddMod(directory);
mod = _modManager.LastOrDefault();
return mod != null && mod.ModPath == directory;
}
public void Dispose()
{
ClearImport();
_modsToAdd.Clear();
_modsToUnpack.Clear();
}
/// <summary>
/// Clean up invalid directory if necessary.
/// Add successfully extracted mods.
/// </summary>
private void AddNewMod(FileInfo file, DirectoryInfo? dir, Exception? error)
{
if (error != null)
{
if (dir != null && Directory.Exists(dir.FullName))
try
{
Directory.Delete(dir.FullName, true);
}
catch (Exception e)
{
Penumbra.Log.Error($"Error cleaning up failed mod extraction of {file.FullName} to {dir.FullName}:\n{e}");
}
if (error is not OperationCanceledException)
Penumbra.Log.Error($"Error extracting {file.FullName}, mod skipped:\n{error}");
}
else if (dir != null)
{
_modsToAdd.Enqueue(dir);
}
}
}