Add "loading dialog" for service init, unify blocking logic (#1779)

* wip

* hacky fix for overlapping event text in profiler

* move IsResumeGameAfterPluginLoad logic to PluginManager

* fix some warnings

* handle exceptions properly

* remove ability to cancel, rename button to "hide" instead

* undo Dalamud.Service refactor for now

* warnings

* add explainer, show which plugins are still loading

* add some text if loading takes more than 3 minutes

* undo wrong CS merge
This commit is contained in:
goat 2024-04-21 17:28:37 +02:00 committed by GitHub
parent 93adea0ac9
commit 448b0d16ea
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
294 changed files with 560 additions and 506 deletions

View file

@ -33,8 +33,9 @@ internal sealed class Dalamud : IServiceType
{
#region Internals
private static int shownServiceError = 0;
private readonly ManualResetEvent unloadSignal;
#endregion
/// <summary>
@ -68,54 +69,47 @@ internal sealed class Dalamud : IServiceType
// Set up FFXIVClientStructs
this.SetupClientStructsResolver(cacheDir);
if (!configuration.IsResumeGameAfterPluginLoad)
void KickoffGameThread()
{
Log.Verbose("=============== GAME THREAD KICKOFF ===============");
Timings.Event("Game thread kickoff");
NativeFunctions.SetEvent(mainThreadContinueEvent);
ServiceManager.InitializeEarlyLoadableServices()
.ContinueWith(t =>
}
void HandleServiceInitFailure(Task t)
{
Log.Error(t.Exception!, "Service initialization failure");
if (Interlocked.CompareExchange(ref shownServiceError, 1, 0) != 0)
return;
Util.Fatal(
"Dalamud failed to load all necessary services.\n\nThe game will continue, but you may not be able to use plugins.",
"Dalamud", false);
}
ServiceManager.InitializeEarlyLoadableServices()
.ContinueWith(
t =>
{
if (t.IsCompletedSuccessfully)
return;
Log.Error(t.Exception!, "Service initialization failure");
Util.Fatal(
"Dalamud failed to load all necessary services.\n\nThe game will continue, but you may not be able to use plugins.",
"Dalamud", false);
HandleServiceInitFailure(t);
});
}
else
{
Task.Run(async () =>
ServiceManager.BlockingResolved.ContinueWith(
t =>
{
try
if (t.IsCompletedSuccessfully)
{
var tasks = new[]
{
ServiceManager.InitializeEarlyLoadableServices(),
ServiceManager.BlockingResolved,
};
await Task.WhenAny(tasks);
var faultedTasks = tasks.Where(x => x.IsFaulted).Select(x => (Exception)x.Exception!).ToArray();
if (faultedTasks.Any())
throw new AggregateException(faultedTasks);
NativeFunctions.SetEvent(mainThreadContinueEvent);
await Task.WhenAll(tasks);
}
catch (Exception e)
{
Log.Error(e, "Service initialization failure");
Util.Fatal("Dalamud could not initialize correctly. Please report this error. \n\nThe game will continue, but you may not be able to use plugins.", "Dalamud", false);
}
finally
{
NativeFunctions.SetEvent(mainThreadContinueEvent);
KickoffGameThread();
return;
}
HandleServiceInitFailure(t);
});
}
this.DefaultExceptionFilter = NativeFunctions.SetUnhandledExceptionFilter(nint.Zero);
NativeFunctions.SetUnhandledExceptionFilter(this.DefaultExceptionFilter);