Load services asynchronously whenever possible (#893)

This commit is contained in:
kizer 2022-06-25 05:12:51 +09:00 committed by GitHub
parent fba8c7163c
commit 8e7f370ddd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
66 changed files with 959 additions and 899 deletions

View file

@ -378,7 +378,7 @@ namespace Dalamud.Plugin
realScopedObjects[0] = this;
Array.Copy(scopedObjects, 0, realScopedObjects, 1, scopedObjects.Length);
return svcContainer.InjectProperties(instance, realScopedObjects);
return svcContainer.InjectProperties(instance, realScopedObjects).GetAwaiter().GetResult();
}
#endregion

View file

@ -27,6 +27,7 @@ namespace Dalamud.Plugin.Internal;
/// <summary>
/// Class responsible for loading and unloading plugins.
/// </summary>
[ServiceManager.EarlyLoadedService]
internal partial class PluginManager : IDisposable
{
/// <summary>
@ -40,16 +41,17 @@ internal partial class PluginManager : IDisposable
private readonly DirectoryInfo devPluginDirectory;
private readonly BannedPlugin[] bannedPlugins;
/// <summary>
/// Initializes a new instance of the <see cref="PluginManager"/> class.
/// </summary>
public PluginManager()
{
var startInfo = Service<DalamudStartInfo>.Get();
var configuration = Service<DalamudConfiguration>.Get();
[ServiceManager.ServiceDependency]
private readonly DalamudConfiguration configuration = Service<DalamudConfiguration>.Get();
this.pluginDirectory = new DirectoryInfo(startInfo.PluginDirectory);
this.devPluginDirectory = new DirectoryInfo(startInfo.DefaultPluginDirectory);
[ServiceManager.ServiceDependency]
private readonly DalamudStartInfo startInfo = Service<DalamudStartInfo>.Get();
[ServiceManager.ServiceConstructor]
private PluginManager()
{
this.pluginDirectory = new DirectoryInfo(this.startInfo.PluginDirectory!);
this.devPluginDirectory = new DirectoryInfo(this.startInfo.DefaultPluginDirectory!);
if (!this.pluginDirectory.Exists)
this.pluginDirectory.Create();
@ -57,16 +59,16 @@ internal partial class PluginManager : IDisposable
if (!this.devPluginDirectory.Exists)
this.devPluginDirectory.Create();
this.SafeMode = EnvironmentConfiguration.DalamudNoPlugins || configuration.PluginSafeMode;
this.SafeMode = EnvironmentConfiguration.DalamudNoPlugins || this.configuration.PluginSafeMode;
if (this.SafeMode)
{
configuration.PluginSafeMode = false;
configuration.Save();
this.configuration.PluginSafeMode = false;
this.configuration.Save();
}
this.PluginConfigs = new PluginConfigurations(Path.Combine(Path.GetDirectoryName(startInfo.ConfigurationPath) ?? string.Empty, "pluginConfigs"));
this.PluginConfigs = new PluginConfigurations(Path.Combine(Path.GetDirectoryName(this.startInfo.ConfigurationPath) ?? string.Empty, "pluginConfigs"));
var bannedPluginsJson = File.ReadAllText(Path.Combine(startInfo.AssetDirectory, "UIRes", "bannedplugin.json"));
var bannedPluginsJson = File.ReadAllText(Path.Combine(this.startInfo.AssetDirectory!, "UIRes", "bannedplugin.json"));
this.bannedPlugins = JsonConvert.DeserializeObject<BannedPlugin[]>(bannedPluginsJson) ?? Array.Empty<BannedPlugin>();
this.ApplyPatches();
@ -225,12 +227,10 @@ internal partial class PluginManager : IDisposable
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
public async Task SetPluginReposFromConfigAsync(bool notify)
{
var configuration = Service<DalamudConfiguration>.Get();
var repos = new List<PluginRepository>() { PluginRepository.MainRepo };
repos.AddRange(configuration.ThirdRepoList
.Where(repo => repo.IsEnabled)
.Select(repo => new PluginRepository(repo.Url, repo.IsEnabled)));
repos.AddRange(this.configuration.ThirdRepoList
.Where(repo => repo.IsEnabled)
.Select(repo => new PluginRepository(repo.Url, repo.IsEnabled)));
this.Repos = repos;
await this.ReloadPluginMastersAsync(notify);
@ -251,8 +251,6 @@ internal partial class PluginManager : IDisposable
return;
}
var configuration = Service<DalamudConfiguration>.Get();
var pluginDefs = new List<PluginDef>();
var devPluginDefs = new List<PluginDef>();
@ -282,7 +280,7 @@ internal partial class PluginManager : IDisposable
// devPlugins are more freeform. Look for any dll and hope to get lucky.
var devDllFiles = this.devPluginDirectory.GetFiles("*.dll", SearchOption.AllDirectories).ToList();
foreach (var setting in configuration.DevPluginLoadLocations)
foreach (var setting in this.configuration.DevPluginLoadLocations)
{
if (!setting.IsEnabled)
continue;
@ -420,15 +418,13 @@ internal partial class PluginManager : IDisposable
return;
}
var configuration = Service<DalamudConfiguration>.Get();
if (!this.devPluginDirectory.Exists)
this.devPluginDirectory.Create();
// devPlugins are more freeform. Look for any dll and hope to get lucky.
var devDllFiles = this.devPluginDirectory.GetFiles("*.dll", SearchOption.AllDirectories).ToList();
foreach (var setting in configuration.DevPluginLoadLocations)
foreach (var setting in this.configuration.DevPluginLoadLocations)
{
if (!setting.IsEnabled)
continue;
@ -682,9 +678,6 @@ internal partial class PluginManager : IDisposable
/// </summary>
public void CleanupPlugins()
{
var configuration = Service<DalamudConfiguration>.Get();
var startInfo = Service<DalamudStartInfo>.Get();
foreach (var pluginDir in this.pluginDirectory.GetDirectories())
{
try
@ -748,7 +741,7 @@ internal partial class PluginManager : IDisposable
continue;
}
if (manifest.ApplicableVersion < startInfo.GameVersion)
if (manifest.ApplicableVersion <this.startInfo.GameVersion)
{
Log.Information($"Inapplicable version: cleaning up {versionDir.FullName}");
versionDir.Delete(true);
@ -919,15 +912,12 @@ internal partial class PluginManager : IDisposable
/// <returns>If the manifest is eligible.</returns>
public bool IsManifestEligible(PluginManifest manifest)
{
var configuration = Service<DalamudConfiguration>.Get();
var startInfo = Service<DalamudStartInfo>.Get();
// Testing exclusive
if (manifest.IsTestingExclusive && !configuration.DoPluginTest)
return false;
// Applicable version
if (manifest.ApplicableVersion < startInfo.GameVersion)
if (manifest.ApplicableVersion <this.startInfo.GameVersion)
return false;
// API level
@ -945,7 +935,6 @@ internal partial class PluginManager : IDisposable
/// <returns>A value indicating whether the plugin/manifest has been banned.</returns>
public bool IsManifestBanned(PluginManifest manifest)
{
var configuration = Service<DalamudConfiguration>.Get();
return !configuration.LoadBannedPlugins && this.bannedPlugins.Any(ban => (ban.Name == manifest.InternalName || ban.Name == Hash.GetStringSha256Hash(manifest.InternalName))
&& ban.AssemblyVersion >= manifest.AssemblyVersion);
}

View file

@ -0,0 +1,49 @@
using System;
using System.Threading.Tasks;
using Dalamud.Logging.Internal;
using Dalamud.Support;
using Dalamud.Utility.Timing;
namespace Dalamud.Plugin.Internal;
/// <summary>
/// Class responsible for loading plugins on startup.
/// </summary>
[ServiceManager.BlockingEarlyLoadedService]
public class StartupPluginLoader
{
private static readonly ModuleLog Log = new("SPL");
[ServiceManager.ServiceConstructor]
private StartupPluginLoader(PluginManager pluginManager)
{
try
{
using (Timings.Start("PM Load Plugin Repos"))
{
_ = pluginManager.SetPluginReposFromConfigAsync(false);
pluginManager.OnInstalledPluginsChanged += () => Task.Run(Troubleshooting.LogTroubleshooting);
Log.Information("[T3] PM repos OK!");
}
using (Timings.Start("PM Cleanup Plugins"))
{
pluginManager.CleanupPlugins();
Log.Information("[T3] PMC OK!");
}
using (Timings.Start("PM Load Sync Plugins"))
{
pluginManager.LoadAllPlugins();
Log.Information("[T3] PML OK!");
}
Task.Run(Troubleshooting.LogTroubleshooting);
}
catch (Exception ex)
{
Log.Error(ex, "Plugin load failed");
}
}
}

View file

@ -334,7 +334,7 @@ internal class LocalPlugin : IDisposable
this.DalamudInterface = new DalamudPluginInterface(this.pluginAssembly.GetName().Name!, this.DllFile, reason, this.IsDev);
var ioc = Service<ServiceContainer>.Get();
this.instance = ioc.Create(this.pluginType, this.DalamudInterface) as IDalamudPlugin;
this.instance = ioc.Create(this.pluginType, this.DalamudInterface).GetAwaiter().GetResult() as IDalamudPlugin;
if (this.instance == null)
{
this.State = PluginState.LoadError;

View file

@ -5,14 +5,13 @@ namespace Dalamud.Plugin.Ipc.Internal
/// <summary>
/// This class facilitates inter-plugin communication.
/// </summary>
[ServiceManager.EarlyLoadedService]
internal class CallGate
{
private readonly Dictionary<string, CallGateChannel> gates = new();
/// <summary>
/// Initializes a new instance of the <see cref="CallGate"/> class.
/// </summary>
internal CallGate()
[ServiceManager.ServiceConstructor]
private CallGate()
{
}