mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-13 12:14:16 +01:00
refactor UpdatePluginsAsync() to take a list of plugins to update instead
This commit is contained in:
parent
8d18940108
commit
bc2edf765f
3 changed files with 51 additions and 38 deletions
|
|
@ -711,8 +711,12 @@ internal class PluginInstallerWindow : Window, IDisposable
|
|||
{
|
||||
this.updateStatus = OperationStatus.InProgress;
|
||||
this.loadingIndicatorKind = LoadingIndicatorKind.UpdatingAll;
|
||||
|
||||
var toUpdate = this.pluginListUpdatable
|
||||
.Where(x => x.InstalledPlugin.IsLoaded)
|
||||
.ToList();
|
||||
|
||||
Task.Run(() => pluginManager.UpdatePluginsAsync(true, false))
|
||||
Task.Run(() => pluginManager.UpdatePluginsAsync(toUpdate, false))
|
||||
.ContinueWith(task =>
|
||||
{
|
||||
this.updateStatus = OperationStatus.Complete;
|
||||
|
|
|
|||
|
|
@ -255,8 +255,6 @@ internal class AutoUpdateManager : IServiceType
|
|||
|
||||
private async Task RunAutoUpdates(ICollection<AvailablePluginUpdate> updatablePlugins)
|
||||
{
|
||||
var pluginStates = new List<PluginUpdateStatus>();
|
||||
|
||||
Log.Information("Found {UpdatablePluginsCount} plugins to update", updatablePlugins.Count);
|
||||
|
||||
if (updatablePlugins.Count == 0)
|
||||
|
|
@ -274,35 +272,16 @@ internal class AutoUpdateManager : IServiceType
|
|||
Icon = INotificationIcon.From(FontAwesomeIcon.Download),
|
||||
Minimized = false,
|
||||
});
|
||||
|
||||
var numDone = 0;
|
||||
// TODO: This is NOT correct, we need to do this inside PM to be able to avoid notifying for each of these and avoid
|
||||
// refreshing the plugin list until we're done. See PluginManager::UpdatePluginsAsync().
|
||||
// Maybe have a function in PM that can take a list of AvailablePluginUpdate instead and update them all,
|
||||
// and get rid of UpdatePluginsAsync()? Will have to change the installer a bit but that might be for the better API-wise.
|
||||
foreach (var plugin in updatablePlugins)
|
||||
|
||||
var progress = new Progress<PluginManager.PluginUpdateProgress>();
|
||||
progress.ProgressChanged += (_, progress) =>
|
||||
{
|
||||
try
|
||||
{
|
||||
notification.Content = $"Updating {plugin.InstalledPlugin.Manifest.Name}...";
|
||||
notification.Progress = (float)numDone / updatablePlugins.Count;
|
||||
|
||||
if (this.isDryRun.Value)
|
||||
{
|
||||
await Task.Delay(5000);
|
||||
}
|
||||
|
||||
var status = await this.pluginManager.UpdateSinglePluginAsync(plugin, true, this.isDryRun.Value);
|
||||
pluginStates.Add(status);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex, "Failed to auto-update plugin {PluginName}", plugin.InstalledPlugin.Manifest.Name);
|
||||
}
|
||||
|
||||
numDone++;
|
||||
}
|
||||
notification.Content = $"Updating {progress.CurrentPluginManifest.Name}...";
|
||||
notification.Progress = (float)progress.PluginsProcessed / progress.TotalPlugins;
|
||||
};
|
||||
|
||||
var pluginStates = await this.pluginManager.UpdatePluginsAsync(updatablePlugins, this.isDryRun.Value, true, progress);
|
||||
|
||||
notification.Progress = 1;
|
||||
notification.UserDismissable = true;
|
||||
notification.HardExpiry = DateTime.Now.AddSeconds(30);
|
||||
|
|
@ -318,7 +297,8 @@ internal class AutoUpdateManager : IServiceType
|
|||
};
|
||||
|
||||
// Update the notification to show the final state
|
||||
if (pluginStates.All(x => x.Status == PluginUpdateStatus.StatusKind.Success))
|
||||
var pluginUpdateStatusEnumerable = pluginStates as PluginUpdateStatus[] ?? pluginStates.ToArray();
|
||||
if (pluginUpdateStatusEnumerable.All(x => x.Status == PluginUpdateStatus.StatusKind.Success))
|
||||
{
|
||||
notification.Minimized = true;
|
||||
|
||||
|
|
@ -337,7 +317,7 @@ internal class AutoUpdateManager : IServiceType
|
|||
notification.Type = NotificationType.Error;
|
||||
notification.Content = "Some plugins failed to update. Please check the plugin installer for more information.";
|
||||
|
||||
var failedPlugins = pluginStates
|
||||
var failedPlugins = pluginUpdateStatusEnumerable
|
||||
.Where(x => x.Status != PluginUpdateStatus.StatusKind.Success)
|
||||
.Select(x => x.Name).ToList();
|
||||
|
||||
|
|
|
|||
|
|
@ -977,32 +977,39 @@ internal class PluginManager : IInternalDisposableService
|
|||
/// <summary>
|
||||
/// Update all non-dev plugins.
|
||||
/// </summary>
|
||||
/// <param name="ignoreDisabled">Ignore disabled plugins.</param>
|
||||
/// <param name="toUpdate">List of plugins to update.</param>
|
||||
/// <param name="dryRun">Perform a dry run, don't install anything.</param>
|
||||
/// <param name="autoUpdate">If this action was performed as part of an auto-update.</param>
|
||||
/// <param name="progress">An <see cref="IProgress{T}"/> implementation to receive progress updates about the installation status.</param>
|
||||
/// <returns>Success or failure and a list of updated plugin metadata.</returns>
|
||||
public async Task<IEnumerable<PluginUpdateStatus>> UpdatePluginsAsync(bool ignoreDisabled, bool dryRun, bool autoUpdate = false)
|
||||
public async Task<IEnumerable<PluginUpdateStatus>> UpdatePluginsAsync(
|
||||
ICollection<AvailablePluginUpdate> toUpdate,
|
||||
bool dryRun,
|
||||
bool autoUpdate = false,
|
||||
IProgress<PluginUpdateProgress>? progress = null)
|
||||
{
|
||||
Log.Information("Starting plugin update");
|
||||
|
||||
var updateTasks = new List<Task<PluginUpdateStatus>>();
|
||||
var totalPlugins = toUpdate.Count;
|
||||
var processedPlugins = 0;
|
||||
|
||||
// Prevent collection was modified errors
|
||||
lock (this.pluginListLock)
|
||||
{
|
||||
foreach (var plugin in this.updatablePluginsList)
|
||||
foreach (var plugin in toUpdate)
|
||||
{
|
||||
// Can't update that!
|
||||
if (plugin.InstalledPlugin.IsDev)
|
||||
continue;
|
||||
|
||||
if (!plugin.InstalledPlugin.IsWantedByAnyProfile && ignoreDisabled)
|
||||
if (!plugin.InstalledPlugin.IsWantedByAnyProfile)
|
||||
continue;
|
||||
|
||||
if (plugin.InstalledPlugin.Manifest.ScheduledForDeletion)
|
||||
continue;
|
||||
|
||||
updateTasks.Add(this.UpdateSinglePluginAsync(plugin, false, dryRun));
|
||||
updateTasks.Add(UpdateSinglePluginWithProgressAsync(plugin));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1013,9 +1020,26 @@ internal class PluginManager : IInternalDisposableService
|
|||
autoUpdate ? PluginListInvalidationKind.AutoUpdate : PluginListInvalidationKind.Update,
|
||||
updatedList.Select(x => x.InternalName));
|
||||
|
||||
Log.Information("Plugin update OK. {updateCount} plugins updated.", updatedList.Length);
|
||||
Log.Information("Plugin update OK. {UpdateCount} plugins updated", updatedList.Length);
|
||||
|
||||
return updatedList;
|
||||
|
||||
async Task<PluginUpdateStatus> UpdateSinglePluginWithProgressAsync(AvailablePluginUpdate plugin)
|
||||
{
|
||||
var result = await this.UpdateSinglePluginAsync(plugin, false, dryRun);
|
||||
|
||||
// Update the progress
|
||||
if (progress != null)
|
||||
{
|
||||
var newProcessedAmount = Interlocked.Increment(ref processedPlugins);
|
||||
progress.Report(new PluginUpdateProgress(
|
||||
newProcessedAmount,
|
||||
totalPlugins,
|
||||
plugin.InstalledPlugin.Manifest));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -1832,6 +1856,11 @@ internal class PluginManager : IInternalDisposableService
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Class representing progress of an update operation.
|
||||
/// </summary>
|
||||
public record PluginUpdateProgress(int PluginsProcessed, int TotalPlugins, IPluginManifest CurrentPluginManifest);
|
||||
|
||||
/// <summary>
|
||||
/// Simple class that tracks the internal names and public names of plugins that we are planning to load at startup,
|
||||
/// and are still actively loading.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue