mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-13 12:14:16 +01:00
fix: wait for font rebuild when initially setting up ImGui
This is to work around changed behaviour with ImGui >1.78 wherein a race condition during font rebuild together with plugin loads would cause the remote CLR thread to end
This commit is contained in:
parent
2c66ecc84e
commit
d949734fe9
2 changed files with 83 additions and 67 deletions
|
|
@ -178,91 +178,94 @@ namespace Dalamud {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Start() {
|
public void Start() {
|
||||||
Configuration = DalamudConfiguration.Load(StartInfo.ConfigurationPath);
|
try {
|
||||||
|
Configuration = DalamudConfiguration.Load(StartInfo.ConfigurationPath);
|
||||||
|
|
||||||
// Initialize the process information.
|
// Initialize the process information.
|
||||||
TargetModule = Process.GetCurrentProcess().MainModule;
|
TargetModule = Process.GetCurrentProcess().MainModule;
|
||||||
SigScanner = new SigScanner(TargetModule, true);
|
SigScanner = new SigScanner(TargetModule, true);
|
||||||
|
|
||||||
AntiDebug = new AntiDebug(SigScanner);
|
AntiDebug = new AntiDebug(SigScanner);
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
AntiDebug.Enable();
|
AntiDebug.Enable();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Initialize game subsystem
|
// Initialize game subsystem
|
||||||
Framework = new Framework(SigScanner, this);
|
Framework = new Framework(SigScanner, this);
|
||||||
|
|
||||||
WinSock2 = new WinSockHandlers();
|
WinSock2 = new WinSockHandlers();
|
||||||
|
|
||||||
NetworkHandlers = new NetworkHandlers(this, StartInfo.OptOutMbCollection);
|
NetworkHandlers = new NetworkHandlers(this, StartInfo.OptOutMbCollection);
|
||||||
|
|
||||||
ClientState = new ClientState(this, StartInfo, SigScanner);
|
ClientState = new ClientState(this, StartInfo, SigScanner);
|
||||||
|
|
||||||
LocalizationManager = new Localization(AssetDirectory.FullName);
|
LocalizationManager = new Localization(AssetDirectory.FullName);
|
||||||
if (!string.IsNullOrEmpty(Configuration.LanguageOverride))
|
if (!string.IsNullOrEmpty(Configuration.LanguageOverride))
|
||||||
LocalizationManager.SetupWithLangCode(Configuration.LanguageOverride);
|
LocalizationManager.SetupWithLangCode(Configuration.LanguageOverride);
|
||||||
else
|
else
|
||||||
LocalizationManager.SetupWithUiCulture();
|
LocalizationManager.SetupWithUiCulture();
|
||||||
|
|
||||||
PluginRepository = new PluginRepository(this, StartInfo.PluginDirectory, StartInfo.GameVersion);
|
PluginRepository = new PluginRepository(this, StartInfo.PluginDirectory, StartInfo.GameVersion);
|
||||||
|
|
||||||
DalamudUi = new DalamudInterface(this);
|
DalamudUi = new DalamudInterface(this);
|
||||||
|
|
||||||
var isInterfaceLoaded = false;
|
var isInterfaceLoaded = false;
|
||||||
if (!bool.Parse(Environment.GetEnvironmentVariable("DALAMUD_NOT_HAVE_INTERFACE") ?? "false")) {
|
if (!bool.Parse(Environment.GetEnvironmentVariable("DALAMUD_NOT_HAVE_INTERFACE") ?? "false")) {
|
||||||
|
try {
|
||||||
|
InterfaceManager = new InterfaceManager(this, SigScanner);
|
||||||
|
InterfaceManager.OnDraw += DalamudUi.Draw;
|
||||||
|
|
||||||
|
InterfaceManager.Enable();
|
||||||
|
isInterfaceLoaded = true;
|
||||||
|
|
||||||
|
InterfaceManager.WaitForFontRebuild();
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.Information(e, "Could not init interface.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Data = new DataManager(StartInfo.Language);
|
||||||
try {
|
try {
|
||||||
InterfaceManager = new InterfaceManager(this, SigScanner);
|
Data.Initialize(AssetDirectory.FullName);
|
||||||
InterfaceManager.OnDraw += DalamudUi.Draw;
|
|
||||||
|
|
||||||
InterfaceManager.Enable();
|
|
||||||
isInterfaceLoaded = true;
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.Information(e, "Could not init interface.");
|
Log.Error(e, "Could not initialize DataManager.");
|
||||||
|
Unload();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Data = new DataManager(StartInfo.Language);
|
SeStringManager = new SeStringManager(Data);
|
||||||
try {
|
|
||||||
Data.Initialize(AssetDirectory.FullName);
|
// Initialize managers. Basically handlers for the logic
|
||||||
} catch (Exception e) {
|
CommandManager = new CommandManager(this, StartInfo.Language);
|
||||||
Log.Error(e, "Could not initialize DataManager.");
|
DalamudCommands = new DalamudCommands(this);
|
||||||
|
DalamudCommands.SetupCommands();
|
||||||
|
|
||||||
|
ChatHandlers = new ChatHandlers(this);
|
||||||
|
|
||||||
|
if (!bool.Parse(Environment.GetEnvironmentVariable("DALAMUD_NOT_HAVE_PLUGINS") ?? "false")) {
|
||||||
|
try {
|
||||||
|
PluginRepository.CleanupPlugins();
|
||||||
|
|
||||||
|
PluginManager =
|
||||||
|
new PluginManager(this, StartInfo.PluginDirectory, StartInfo.DefaultPluginDirectory);
|
||||||
|
PluginManager.LoadPlugins();
|
||||||
|
} catch (Exception ex) {
|
||||||
|
Log.Error(ex, "Plugin load failed.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Framework.Enable();
|
||||||
|
ClientState.Enable();
|
||||||
|
|
||||||
|
IsReady = true;
|
||||||
|
|
||||||
|
Troubleshooting.LogTroubleshooting(this, isInterfaceLoaded);
|
||||||
|
|
||||||
|
Log.Information("Dalamud is ready.");
|
||||||
|
} catch (Exception ex) {
|
||||||
|
Log.Error(ex, "Oh no! Dalamud::Start() failed.");
|
||||||
Unload();
|
Unload();
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SeStringManager = new SeStringManager(Data);
|
|
||||||
|
|
||||||
// Initialize managers. Basically handlers for the logic
|
|
||||||
CommandManager = new CommandManager(this, StartInfo.Language);
|
|
||||||
DalamudCommands = new DalamudCommands(this);
|
|
||||||
DalamudCommands.SetupCommands();
|
|
||||||
|
|
||||||
ChatHandlers = new ChatHandlers(this);
|
|
||||||
|
|
||||||
if (!bool.Parse(Environment.GetEnvironmentVariable("DALAMUD_NOT_HAVE_PLUGINS") ?? "false"))
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
PluginRepository.CleanupPlugins();
|
|
||||||
|
|
||||||
PluginManager =
|
|
||||||
new PluginManager(this, StartInfo.PluginDirectory, StartInfo.DefaultPluginDirectory);
|
|
||||||
PluginManager.LoadPlugins();
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Log.Error(ex, "Plugin load failed.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Framework.Enable();
|
|
||||||
ClientState.Enable();
|
|
||||||
|
|
||||||
IsReady = true;
|
|
||||||
|
|
||||||
Troubleshooting.LogTroubleshooting(this, isInterfaceLoaded);
|
|
||||||
|
|
||||||
Log.Information("Dalamud is ready.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Unload() {
|
public void Unload() {
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ using System.IO;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
using Dalamud.Game;
|
using Dalamud.Game;
|
||||||
using Dalamud.Game.Internal.DXGI;
|
using Dalamud.Game.Internal.DXGI;
|
||||||
using Dalamud.Hooking;
|
using Dalamud.Hooking;
|
||||||
|
|
@ -42,6 +43,8 @@ namespace Dalamud.Interface
|
||||||
[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
|
[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
|
||||||
private delegate IntPtr SetCursorDelegate(IntPtr hCursor);
|
private delegate IntPtr SetCursorDelegate(IntPtr hCursor);
|
||||||
|
|
||||||
|
private ManualResetEvent fontBuildSignal;
|
||||||
|
|
||||||
private ISwapChainAddressResolver Address { get; }
|
private ISwapChainAddressResolver Address { get; }
|
||||||
|
|
||||||
private Dalamud dalamud;
|
private Dalamud dalamud;
|
||||||
|
|
@ -68,6 +71,8 @@ namespace Dalamud.Interface
|
||||||
{
|
{
|
||||||
this.dalamud = dalamud;
|
this.dalamud = dalamud;
|
||||||
|
|
||||||
|
this.fontBuildSignal = new ManualResetEvent(false);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
var sigResolver = new SwapChainSigResolver();
|
var sigResolver = new SwapChainSigResolver();
|
||||||
sigResolver.Setup(scanner);
|
sigResolver.Setup(scanner);
|
||||||
|
|
@ -272,6 +277,8 @@ namespace Dalamud.Interface
|
||||||
|
|
||||||
private unsafe void SetupFonts()
|
private unsafe void SetupFonts()
|
||||||
{
|
{
|
||||||
|
this.fontBuildSignal.Reset();
|
||||||
|
|
||||||
ImGui.GetIO().Fonts.Clear();
|
ImGui.GetIO().Fonts.Clear();
|
||||||
|
|
||||||
ImFontConfigPtr fontConfig = ImGuiNative.ImFontConfig_ImFontConfig();
|
ImFontConfigPtr fontConfig = ImGuiNative.ImFontConfig_ImFontConfig();
|
||||||
|
|
@ -317,12 +324,18 @@ namespace Dalamud.Interface
|
||||||
|
|
||||||
Log.Verbose("[FONT] Fonts built!");
|
Log.Verbose("[FONT] Fonts built!");
|
||||||
|
|
||||||
|
this.fontBuildSignal.Set();
|
||||||
|
|
||||||
fontConfig.Destroy();
|
fontConfig.Destroy();
|
||||||
japaneseRangeHandle.Free();
|
japaneseRangeHandle.Free();
|
||||||
gameRangeHandle.Free();
|
gameRangeHandle.Free();
|
||||||
iconRangeHandle.Free();
|
iconRangeHandle.Free();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void WaitForFontRebuild() {
|
||||||
|
this.fontBuildSignal.WaitOne();
|
||||||
|
}
|
||||||
|
|
||||||
// This is intended to only be called as a handler attached to scene.OnNewRenderFrame
|
// This is intended to only be called as a handler attached to scene.OnNewRenderFrame
|
||||||
private void RebuildFontsInternal()
|
private void RebuildFontsInternal()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue