mirror of
https://github.com/goatcorp/Dalamud.git
synced 2026-02-20 14:57:45 +01:00
Merge pull request #1699 from Soreepeong/fix/ime-perf
Fix Chinese IME lagging
This commit is contained in:
commit
7ee20272de
6 changed files with 620 additions and 531 deletions
|
|
@ -96,12 +96,6 @@ internal class DalamudCommands : IServiceType
|
||||||
ShowInHelp = false,
|
ShowInHelp = false,
|
||||||
});
|
});
|
||||||
|
|
||||||
commandManager.AddHandler("/xlime", new CommandInfo(this.OnDebugDrawIMEPanel)
|
|
||||||
{
|
|
||||||
HelpMessage = Loc.Localize("DalamudIMEPanelHelp", "Draw IME panel"),
|
|
||||||
ShowInHelp = false,
|
|
||||||
});
|
|
||||||
|
|
||||||
commandManager.AddHandler("/xllog", new CommandInfo(this.OnOpenLog)
|
commandManager.AddHandler("/xllog", new CommandInfo(this.OnOpenLog)
|
||||||
{
|
{
|
||||||
HelpMessage = Loc.Localize("DalamudDevLogHelp", "Open dev log DEBUG"),
|
HelpMessage = Loc.Localize("DalamudDevLogHelp", "Open dev log DEBUG"),
|
||||||
|
|
@ -308,11 +302,6 @@ internal class DalamudCommands : IServiceType
|
||||||
dalamudInterface.ToggleDataWindow(arguments);
|
dalamudInterface.ToggleDataWindow(arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnDebugDrawIMEPanel(string command, string arguments)
|
|
||||||
{
|
|
||||||
Service<DalamudInterface>.Get().OpenImeWindow();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnOpenLog(string command, string arguments)
|
private void OnOpenLog(string command, string arguments)
|
||||||
{
|
{
|
||||||
Service<DalamudInterface>.Get().ToggleLogWindow();
|
Service<DalamudInterface>.Get().ToggleLogWindow();
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -61,7 +61,6 @@ internal class DalamudInterface : IDisposable, IServiceType
|
||||||
private readonly ComponentDemoWindow componentDemoWindow;
|
private readonly ComponentDemoWindow componentDemoWindow;
|
||||||
private readonly DataWindow dataWindow;
|
private readonly DataWindow dataWindow;
|
||||||
private readonly GamepadModeNotifierWindow gamepadModeNotifierWindow;
|
private readonly GamepadModeNotifierWindow gamepadModeNotifierWindow;
|
||||||
private readonly DalamudImeWindow imeWindow;
|
|
||||||
private readonly ConsoleWindow consoleWindow;
|
private readonly ConsoleWindow consoleWindow;
|
||||||
private readonly PluginStatWindow pluginStatWindow;
|
private readonly PluginStatWindow pluginStatWindow;
|
||||||
private readonly PluginInstallerWindow pluginWindow;
|
private readonly PluginInstallerWindow pluginWindow;
|
||||||
|
|
@ -114,7 +113,6 @@ internal class DalamudInterface : IDisposable, IServiceType
|
||||||
this.componentDemoWindow = new ComponentDemoWindow() { IsOpen = false };
|
this.componentDemoWindow = new ComponentDemoWindow() { IsOpen = false };
|
||||||
this.dataWindow = new DataWindow() { IsOpen = false };
|
this.dataWindow = new DataWindow() { IsOpen = false };
|
||||||
this.gamepadModeNotifierWindow = new GamepadModeNotifierWindow() { IsOpen = false };
|
this.gamepadModeNotifierWindow = new GamepadModeNotifierWindow() { IsOpen = false };
|
||||||
this.imeWindow = new DalamudImeWindow() { IsOpen = false };
|
|
||||||
this.consoleWindow = new ConsoleWindow(configuration) { IsOpen = configuration.LogOpenAtStartup };
|
this.consoleWindow = new ConsoleWindow(configuration) { IsOpen = configuration.LogOpenAtStartup };
|
||||||
this.pluginStatWindow = new PluginStatWindow() { IsOpen = false };
|
this.pluginStatWindow = new PluginStatWindow() { IsOpen = false };
|
||||||
this.pluginWindow = new PluginInstallerWindow(pluginImageCache, configuration) { IsOpen = false };
|
this.pluginWindow = new PluginInstallerWindow(pluginImageCache, configuration) { IsOpen = false };
|
||||||
|
|
@ -142,7 +140,6 @@ internal class DalamudInterface : IDisposable, IServiceType
|
||||||
this.WindowSystem.AddWindow(this.componentDemoWindow);
|
this.WindowSystem.AddWindow(this.componentDemoWindow);
|
||||||
this.WindowSystem.AddWindow(this.dataWindow);
|
this.WindowSystem.AddWindow(this.dataWindow);
|
||||||
this.WindowSystem.AddWindow(this.gamepadModeNotifierWindow);
|
this.WindowSystem.AddWindow(this.gamepadModeNotifierWindow);
|
||||||
this.WindowSystem.AddWindow(this.imeWindow);
|
|
||||||
this.WindowSystem.AddWindow(this.consoleWindow);
|
this.WindowSystem.AddWindow(this.consoleWindow);
|
||||||
this.WindowSystem.AddWindow(this.pluginStatWindow);
|
this.WindowSystem.AddWindow(this.pluginStatWindow);
|
||||||
this.WindowSystem.AddWindow(this.pluginWindow);
|
this.WindowSystem.AddWindow(this.pluginWindow);
|
||||||
|
|
@ -265,11 +262,6 @@ internal class DalamudInterface : IDisposable, IServiceType
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void OpenGamepadModeNotifierWindow() => this.gamepadModeNotifierWindow.IsOpen = true;
|
public void OpenGamepadModeNotifierWindow() => this.gamepadModeNotifierWindow.IsOpen = true;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Opens the <see cref="DalamudImeWindow"/>.
|
|
||||||
/// </summary>
|
|
||||||
public void OpenImeWindow() => this.imeWindow.IsOpen = true;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Opens the <see cref="ConsoleWindow"/>.
|
/// Opens the <see cref="ConsoleWindow"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -365,11 +357,6 @@ internal class DalamudInterface : IDisposable, IServiceType
|
||||||
|
|
||||||
#region Close
|
#region Close
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Closes the <see cref="DalamudImeWindow"/>.
|
|
||||||
/// </summary>
|
|
||||||
public void CloseImeWindow() => this.imeWindow.IsOpen = false;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Closes the <see cref="GamepadModeNotifierWindow"/>.
|
/// Closes the <see cref="GamepadModeNotifierWindow"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -417,11 +404,6 @@ internal class DalamudInterface : IDisposable, IServiceType
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void ToggleGamepadModeNotifierWindow() => this.gamepadModeNotifierWindow.Toggle();
|
public void ToggleGamepadModeNotifierWindow() => this.gamepadModeNotifierWindow.Toggle();
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Toggles the <see cref="DalamudImeWindow"/>.
|
|
||||||
/// </summary>
|
|
||||||
public void ToggleImeWindow() => this.imeWindow.Toggle();
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Toggles the <see cref="ConsoleWindow"/>.
|
/// Toggles the <see cref="ConsoleWindow"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
||||||
|
|
@ -68,9 +68,6 @@ internal class InterfaceManager : IDisposable, IServiceType
|
||||||
[ServiceManager.ServiceDependency]
|
[ServiceManager.ServiceDependency]
|
||||||
private readonly WndProcHookManager wndProcHookManager = Service<WndProcHookManager>.Get();
|
private readonly WndProcHookManager wndProcHookManager = Service<WndProcHookManager>.Get();
|
||||||
|
|
||||||
[ServiceManager.ServiceDependency]
|
|
||||||
private readonly DalamudIme dalamudIme = Service<DalamudIme>.Get();
|
|
||||||
|
|
||||||
private readonly SwapChainVtableResolver address = new();
|
private readonly SwapChainVtableResolver address = new();
|
||||||
private readonly Hook<SetCursorDelegate> setCursorHook;
|
private readonly Hook<SetCursorDelegate> setCursorHook;
|
||||||
private RawDX11Scene? scene;
|
private RawDX11Scene? scene;
|
||||||
|
|
@ -627,8 +624,6 @@ internal class InterfaceManager : IDisposable, IServiceType
|
||||||
var r = this.scene?.ProcessWndProcW(args.Hwnd, (User32.WindowMessage)args.Message, args.WParam, args.LParam);
|
var r = this.scene?.ProcessWndProcW(args.Hwnd, (User32.WindowMessage)args.Message, args.WParam, args.LParam);
|
||||||
if (r is not null)
|
if (r is not null)
|
||||||
args.SuppressWithValue(r.Value);
|
args.SuppressWithValue(r.Value);
|
||||||
|
|
||||||
this.dalamudIme.ProcessImeMessage(args);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -1,266 +0,0 @@
|
||||||
using System.Numerics;
|
|
||||||
|
|
||||||
using Dalamud.Interface.Windowing;
|
|
||||||
|
|
||||||
using ImGuiNET;
|
|
||||||
|
|
||||||
namespace Dalamud.Interface.Internal.Windows;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A window for displaying IME details.
|
|
||||||
/// </summary>
|
|
||||||
internal unsafe class DalamudImeWindow : Window
|
|
||||||
{
|
|
||||||
private const int ImePageSize = 9;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of the <see cref="DalamudImeWindow"/> class.
|
|
||||||
/// </summary>
|
|
||||||
public DalamudImeWindow()
|
|
||||||
: base(
|
|
||||||
"Dalamud IME",
|
|
||||||
ImGuiWindowFlags.NoTitleBar | ImGuiWindowFlags.NoFocusOnAppearing | ImGuiWindowFlags.NoResize | ImGuiWindowFlags.NoBackground)
|
|
||||||
{
|
|
||||||
this.Size = default(Vector2);
|
|
||||||
|
|
||||||
this.RespectCloseHotkey = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc/>
|
|
||||||
public override void Draw()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc/>
|
|
||||||
public override void PostDraw()
|
|
||||||
{
|
|
||||||
if (Service<DalamudIme>.GetNullable() is not { } ime)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var viewport = ime.AssociatedViewport;
|
|
||||||
if (viewport.NativePtr is null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var drawCand = ime.ImmCand.Count != 0;
|
|
||||||
var drawConv = drawCand || ime.ShowPartialConversion;
|
|
||||||
var drawIme = ime.InputModeIcon != 0;
|
|
||||||
var imeIconFont = InterfaceManager.DefaultFont;
|
|
||||||
|
|
||||||
var pad = ImGui.GetStyle().WindowPadding;
|
|
||||||
var candTextSize = ImGui.CalcTextSize(ime.ImmComp == string.Empty ? " " : ime.ImmComp);
|
|
||||||
|
|
||||||
var native = ime.ImmCandNative;
|
|
||||||
var totalIndex = native.dwSelection + 1;
|
|
||||||
var totalSize = native.dwCount;
|
|
||||||
|
|
||||||
var pageStart = native.dwPageStart;
|
|
||||||
var pageIndex = (pageStart / ImePageSize) + 1;
|
|
||||||
var pageCount = (totalSize / ImePageSize) + 1;
|
|
||||||
var pageInfo = $"{totalIndex}/{totalSize} ({pageIndex}/{pageCount})";
|
|
||||||
|
|
||||||
// Calc the window size.
|
|
||||||
var maxTextWidth = 0f;
|
|
||||||
for (var i = 0; i < ime.ImmCand.Count; i++)
|
|
||||||
{
|
|
||||||
var textSize = ImGui.CalcTextSize($"{i + 1}. {ime.ImmCand[i]}");
|
|
||||||
maxTextWidth = maxTextWidth > textSize.X ? maxTextWidth : textSize.X;
|
|
||||||
}
|
|
||||||
|
|
||||||
maxTextWidth = maxTextWidth > ImGui.CalcTextSize(pageInfo).X ? maxTextWidth : ImGui.CalcTextSize(pageInfo).X;
|
|
||||||
maxTextWidth = maxTextWidth > ImGui.CalcTextSize(ime.ImmComp).X
|
|
||||||
? maxTextWidth
|
|
||||||
: ImGui.CalcTextSize(ime.ImmComp).X;
|
|
||||||
|
|
||||||
var numEntries = (drawCand ? ime.ImmCand.Count + 1 : 0) + 1 + (drawIme ? 1 : 0);
|
|
||||||
var spaceY = ImGui.GetStyle().ItemSpacing.Y;
|
|
||||||
var imeWindowHeight = (spaceY * (numEntries - 1)) + (candTextSize.Y * numEntries);
|
|
||||||
var windowSize = new Vector2(maxTextWidth, imeWindowHeight) + (pad * 2);
|
|
||||||
|
|
||||||
// 1. Figure out the expanding direction.
|
|
||||||
var expandUpward = ime.CursorPos.Y + windowSize.Y > viewport.WorkPos.Y + viewport.WorkSize.Y;
|
|
||||||
var windowPos = ime.CursorPos - pad;
|
|
||||||
if (expandUpward)
|
|
||||||
{
|
|
||||||
windowPos.Y -= windowSize.Y - candTextSize.Y - (pad.Y * 2);
|
|
||||||
if (drawIme)
|
|
||||||
windowPos.Y += candTextSize.Y + spaceY;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (drawIme)
|
|
||||||
windowPos.Y -= candTextSize.Y + spaceY;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. Contain within the viewport. Do not use clamp, as the target window might be too small.
|
|
||||||
if (windowPos.X < viewport.WorkPos.X)
|
|
||||||
windowPos.X = viewport.WorkPos.X;
|
|
||||||
else if (windowPos.X + windowSize.X > viewport.WorkPos.X + viewport.WorkSize.X)
|
|
||||||
windowPos.X = (viewport.WorkPos.X + viewport.WorkSize.X) - windowSize.X;
|
|
||||||
if (windowPos.Y < viewport.WorkPos.Y)
|
|
||||||
windowPos.Y = viewport.WorkPos.Y;
|
|
||||||
else if (windowPos.Y + windowSize.Y > viewport.WorkPos.Y + viewport.WorkSize.Y)
|
|
||||||
windowPos.Y = (viewport.WorkPos.Y + viewport.WorkSize.Y) - windowSize.Y;
|
|
||||||
|
|
||||||
var cursor = windowPos + pad;
|
|
||||||
|
|
||||||
// Draw the ime window.
|
|
||||||
var drawList = ImGui.GetForegroundDrawList(viewport);
|
|
||||||
|
|
||||||
// Draw the background rect for candidates.
|
|
||||||
if (drawCand)
|
|
||||||
{
|
|
||||||
Vector2 candRectLt, candRectRb;
|
|
||||||
if (!expandUpward)
|
|
||||||
{
|
|
||||||
candRectLt = windowPos + candTextSize with { X = 0 } + pad with { X = 0 };
|
|
||||||
candRectRb = windowPos + windowSize;
|
|
||||||
if (drawIme)
|
|
||||||
candRectLt.Y += spaceY + candTextSize.Y;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
candRectLt = windowPos;
|
|
||||||
candRectRb = windowPos + (windowSize - candTextSize with { X = 0 } - pad with { X = 0 });
|
|
||||||
if (drawIme)
|
|
||||||
candRectRb.Y -= spaceY + candTextSize.Y;
|
|
||||||
}
|
|
||||||
|
|
||||||
drawList.AddRectFilled(
|
|
||||||
candRectLt,
|
|
||||||
candRectRb,
|
|
||||||
ImGui.GetColorU32(ImGuiCol.WindowBg),
|
|
||||||
ImGui.GetStyle().WindowRounding);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!expandUpward && drawIme)
|
|
||||||
{
|
|
||||||
for (var dx = -2; dx <= 2; dx++)
|
|
||||||
{
|
|
||||||
for (var dy = -2; dy <= 2; dy++)
|
|
||||||
{
|
|
||||||
if (dx != 0 || dy != 0)
|
|
||||||
{
|
|
||||||
imeIconFont.RenderChar(
|
|
||||||
drawList,
|
|
||||||
imeIconFont.FontSize,
|
|
||||||
cursor + new Vector2(dx, dy),
|
|
||||||
ImGui.GetColorU32(ImGuiCol.WindowBg),
|
|
||||||
ime.InputModeIcon);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
imeIconFont.RenderChar(
|
|
||||||
drawList,
|
|
||||||
imeIconFont.FontSize,
|
|
||||||
cursor,
|
|
||||||
ImGui.GetColorU32(ImGuiCol.Text),
|
|
||||||
ime.InputModeIcon);
|
|
||||||
cursor.Y += candTextSize.Y + spaceY;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!expandUpward && drawConv)
|
|
||||||
{
|
|
||||||
DrawTextBeingConverted();
|
|
||||||
cursor.Y += candTextSize.Y + spaceY;
|
|
||||||
|
|
||||||
// Add a separator.
|
|
||||||
drawList.AddLine(cursor, cursor + new Vector2(maxTextWidth, 0), ImGui.GetColorU32(ImGuiCol.Separator));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (drawCand)
|
|
||||||
{
|
|
||||||
// Add the candidate words.
|
|
||||||
for (var i = 0; i < ime.ImmCand.Count; i++)
|
|
||||||
{
|
|
||||||
var selected = i == (native.dwSelection % ImePageSize);
|
|
||||||
var color = ImGui.GetColorU32(ImGuiCol.Text);
|
|
||||||
if (selected)
|
|
||||||
color = ImGui.GetColorU32(ImGuiCol.NavHighlight);
|
|
||||||
|
|
||||||
drawList.AddText(cursor, color, $"{i + 1}. {ime.ImmCand[i]}");
|
|
||||||
cursor.Y += candTextSize.Y + spaceY;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add a separator
|
|
||||||
drawList.AddLine(cursor, cursor + new Vector2(maxTextWidth, 0), ImGui.GetColorU32(ImGuiCol.Separator));
|
|
||||||
|
|
||||||
// Add the pages infomation.
|
|
||||||
drawList.AddText(cursor, ImGui.GetColorU32(ImGuiCol.Text), pageInfo);
|
|
||||||
cursor.Y += candTextSize.Y + spaceY;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (expandUpward && drawConv)
|
|
||||||
{
|
|
||||||
// Add a separator.
|
|
||||||
drawList.AddLine(cursor, cursor + new Vector2(maxTextWidth, 0), ImGui.GetColorU32(ImGuiCol.Separator));
|
|
||||||
|
|
||||||
DrawTextBeingConverted();
|
|
||||||
cursor.Y += candTextSize.Y + spaceY;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (expandUpward && drawIme)
|
|
||||||
{
|
|
||||||
for (var dx = -2; dx <= 2; dx++)
|
|
||||||
{
|
|
||||||
for (var dy = -2; dy <= 2; dy++)
|
|
||||||
{
|
|
||||||
if (dx != 0 || dy != 0)
|
|
||||||
{
|
|
||||||
imeIconFont.RenderChar(
|
|
||||||
drawList,
|
|
||||||
imeIconFont.FontSize,
|
|
||||||
cursor + new Vector2(dx, dy),
|
|
||||||
ImGui.GetColorU32(ImGuiCol.WindowBg),
|
|
||||||
ime.InputModeIcon);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
imeIconFont.RenderChar(
|
|
||||||
drawList,
|
|
||||||
imeIconFont.FontSize,
|
|
||||||
cursor,
|
|
||||||
ImGui.GetColorU32(ImGuiCol.Text),
|
|
||||||
ime.InputModeIcon);
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
|
|
||||||
void DrawTextBeingConverted()
|
|
||||||
{
|
|
||||||
// Draw the text background.
|
|
||||||
drawList.AddRectFilled(
|
|
||||||
cursor - (pad / 2),
|
|
||||||
cursor + candTextSize + (pad / 2),
|
|
||||||
ImGui.GetColorU32(ImGuiCol.WindowBg));
|
|
||||||
|
|
||||||
// If only a part of the full text is marked for conversion, then draw background for the part being edited.
|
|
||||||
if (ime.PartialConversionFrom != 0 || ime.PartialConversionTo != ime.ImmComp.Length)
|
|
||||||
{
|
|
||||||
var part1 = ime.ImmComp[..ime.PartialConversionFrom];
|
|
||||||
var part2 = ime.ImmComp[..ime.PartialConversionTo];
|
|
||||||
var size1 = ImGui.CalcTextSize(part1);
|
|
||||||
var size2 = ImGui.CalcTextSize(part2);
|
|
||||||
drawList.AddRectFilled(
|
|
||||||
cursor + size1 with { Y = 0 },
|
|
||||||
cursor + size2,
|
|
||||||
ImGui.GetColorU32(ImGuiCol.TextSelectedBg));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add the text being converted.
|
|
||||||
drawList.AddText(cursor, ImGui.GetColorU32(ImGuiCol.Text), ime.ImmComp);
|
|
||||||
|
|
||||||
// Draw the caret inside the composition string.
|
|
||||||
if (DalamudIme.ShowCursorInInputText)
|
|
||||||
{
|
|
||||||
var partBeforeCaret = ime.ImmComp[..ime.CompositionCursorOffset];
|
|
||||||
var sizeBeforeCaret = ImGui.CalcTextSize(partBeforeCaret);
|
|
||||||
drawList.AddLine(
|
|
||||||
cursor + sizeBeforeCaret with { Y = 0 },
|
|
||||||
cursor + sizeBeforeCaret,
|
|
||||||
ImGui.GetColorU32(ImGuiCol.Text));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -165,6 +165,7 @@ internal static class ServiceManager
|
||||||
|
|
||||||
var earlyLoadingServices = new HashSet<Type>();
|
var earlyLoadingServices = new HashSet<Type>();
|
||||||
var blockingEarlyLoadingServices = new HashSet<Type>();
|
var blockingEarlyLoadingServices = new HashSet<Type>();
|
||||||
|
var providedServices = new HashSet<Type>();
|
||||||
|
|
||||||
var dependencyServicesMap = new Dictionary<Type, List<Type>>();
|
var dependencyServicesMap = new Dictionary<Type, List<Type>>();
|
||||||
var getAsyncTaskMap = new Dictionary<Type, Task>();
|
var getAsyncTaskMap = new Dictionary<Type, Task>();
|
||||||
|
|
@ -197,7 +198,10 @@ internal static class ServiceManager
|
||||||
|
|
||||||
// We don't actually need to load provided services, something else does
|
// We don't actually need to load provided services, something else does
|
||||||
if (serviceKind.HasFlag(ServiceKind.ProvidedService))
|
if (serviceKind.HasFlag(ServiceKind.ProvidedService))
|
||||||
|
{
|
||||||
|
providedServices.Add(serviceType);
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
Debug.Assert(
|
Debug.Assert(
|
||||||
serviceKind.HasFlag(ServiceKind.EarlyLoadedService) ||
|
serviceKind.HasFlag(ServiceKind.EarlyLoadedService) ||
|
||||||
|
|
@ -340,7 +344,16 @@ internal static class ServiceManager
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!tasks.Any())
|
if (!tasks.Any())
|
||||||
throw new InvalidOperationException("Unresolvable dependency cycle detected");
|
{
|
||||||
|
// No more services we can start loading for now.
|
||||||
|
// Either we're waiting for provided services, or there's a dependency cycle.
|
||||||
|
providedServices.RemoveWhere(x => getAsyncTaskMap[x].IsCompleted);
|
||||||
|
if (providedServices.Any())
|
||||||
|
await Task.WhenAny(providedServices.Select(x => getAsyncTaskMap[x]));
|
||||||
|
else
|
||||||
|
throw new InvalidOperationException("Unresolvable dependency cycle detected");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (servicesToLoad.Any())
|
if (servicesToLoad.Any())
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue