mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-19 15:14:18 +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
|
|
@ -712,7 +712,11 @@ internal class PluginInstallerWindow : Window, IDisposable
|
||||||
this.updateStatus = OperationStatus.InProgress;
|
this.updateStatus = OperationStatus.InProgress;
|
||||||
this.loadingIndicatorKind = LoadingIndicatorKind.UpdatingAll;
|
this.loadingIndicatorKind = LoadingIndicatorKind.UpdatingAll;
|
||||||
|
|
||||||
Task.Run(() => pluginManager.UpdatePluginsAsync(true, false))
|
var toUpdate = this.pluginListUpdatable
|
||||||
|
.Where(x => x.InstalledPlugin.IsLoaded)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
Task.Run(() => pluginManager.UpdatePluginsAsync(toUpdate, false))
|
||||||
.ContinueWith(task =>
|
.ContinueWith(task =>
|
||||||
{
|
{
|
||||||
this.updateStatus = OperationStatus.Complete;
|
this.updateStatus = OperationStatus.Complete;
|
||||||
|
|
|
||||||
|
|
@ -255,8 +255,6 @@ internal class AutoUpdateManager : IServiceType
|
||||||
|
|
||||||
private async Task RunAutoUpdates(ICollection<AvailablePluginUpdate> updatablePlugins)
|
private async Task RunAutoUpdates(ICollection<AvailablePluginUpdate> updatablePlugins)
|
||||||
{
|
{
|
||||||
var pluginStates = new List<PluginUpdateStatus>();
|
|
||||||
|
|
||||||
Log.Information("Found {UpdatablePluginsCount} plugins to update", updatablePlugins.Count);
|
Log.Information("Found {UpdatablePluginsCount} plugins to update", updatablePlugins.Count);
|
||||||
|
|
||||||
if (updatablePlugins.Count == 0)
|
if (updatablePlugins.Count == 0)
|
||||||
|
|
@ -275,33 +273,14 @@ internal class AutoUpdateManager : IServiceType
|
||||||
Minimized = false,
|
Minimized = false,
|
||||||
});
|
});
|
||||||
|
|
||||||
var numDone = 0;
|
var progress = new Progress<PluginManager.PluginUpdateProgress>();
|
||||||
// TODO: This is NOT correct, we need to do this inside PM to be able to avoid notifying for each of these and avoid
|
progress.ProgressChanged += (_, progress) =>
|
||||||
// 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)
|
|
||||||
{
|
{
|
||||||
try
|
notification.Content = $"Updating {progress.CurrentPluginManifest.Name}...";
|
||||||
{
|
notification.Progress = (float)progress.PluginsProcessed / progress.TotalPlugins;
|
||||||
notification.Content = $"Updating {plugin.InstalledPlugin.Manifest.Name}...";
|
};
|
||||||
notification.Progress = (float)numDone / updatablePlugins.Count;
|
|
||||||
|
|
||||||
if (this.isDryRun.Value)
|
var pluginStates = await this.pluginManager.UpdatePluginsAsync(updatablePlugins, this.isDryRun.Value, true, progress);
|
||||||
{
|
|
||||||
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.Progress = 1;
|
notification.Progress = 1;
|
||||||
notification.UserDismissable = true;
|
notification.UserDismissable = true;
|
||||||
|
|
@ -318,7 +297,8 @@ internal class AutoUpdateManager : IServiceType
|
||||||
};
|
};
|
||||||
|
|
||||||
// Update the notification to show the final state
|
// 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;
|
notification.Minimized = true;
|
||||||
|
|
||||||
|
|
@ -337,7 +317,7 @@ internal class AutoUpdateManager : IServiceType
|
||||||
notification.Type = NotificationType.Error;
|
notification.Type = NotificationType.Error;
|
||||||
notification.Content = "Some plugins failed to update. Please check the plugin installer for more information.";
|
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)
|
.Where(x => x.Status != PluginUpdateStatus.StatusKind.Success)
|
||||||
.Select(x => x.Name).ToList();
|
.Select(x => x.Name).ToList();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -977,32 +977,39 @@ internal class PluginManager : IInternalDisposableService
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Update all non-dev plugins.
|
/// Update all non-dev plugins.
|
||||||
/// </summary>
|
/// </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="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="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>
|
/// <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");
|
Log.Information("Starting plugin update");
|
||||||
|
|
||||||
var updateTasks = new List<Task<PluginUpdateStatus>>();
|
var updateTasks = new List<Task<PluginUpdateStatus>>();
|
||||||
|
var totalPlugins = toUpdate.Count;
|
||||||
|
var processedPlugins = 0;
|
||||||
|
|
||||||
// Prevent collection was modified errors
|
// Prevent collection was modified errors
|
||||||
lock (this.pluginListLock)
|
lock (this.pluginListLock)
|
||||||
{
|
{
|
||||||
foreach (var plugin in this.updatablePluginsList)
|
foreach (var plugin in toUpdate)
|
||||||
{
|
{
|
||||||
// Can't update that!
|
// Can't update that!
|
||||||
if (plugin.InstalledPlugin.IsDev)
|
if (plugin.InstalledPlugin.IsDev)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!plugin.InstalledPlugin.IsWantedByAnyProfile && ignoreDisabled)
|
if (!plugin.InstalledPlugin.IsWantedByAnyProfile)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (plugin.InstalledPlugin.Manifest.ScheduledForDeletion)
|
if (plugin.InstalledPlugin.Manifest.ScheduledForDeletion)
|
||||||
continue;
|
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,
|
autoUpdate ? PluginListInvalidationKind.AutoUpdate : PluginListInvalidationKind.Update,
|
||||||
updatedList.Select(x => x.InternalName));
|
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;
|
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>
|
/// <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>
|
/// <summary>
|
||||||
/// Simple class that tracks the internal names and public names of plugins that we are planning to load at startup,
|
/// 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.
|
/// and are still actively loading.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue