mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-12 18:27:23 +01:00
Completion: Don't create Utf8String before the game has initialized
This commit is contained in:
parent
84d121c7bc
commit
bf0dbde55f
2 changed files with 34 additions and 12 deletions
|
|
@ -241,12 +241,12 @@ internal sealed unsafe class CommandManager : IInternalDisposableService, IComma
|
||||||
public class CommandEventArgs : EventArgs
|
public class CommandEventArgs : EventArgs
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the command string
|
/// Gets the command string.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Command { get; init; }
|
public string Command { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the command info
|
/// Gets the command info.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IReadOnlyCommandInfo CommandInfo { get; init; }
|
public IReadOnlyCommandInfo CommandInfo { get; init; }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,10 +31,11 @@ internal sealed unsafe class Completion : IInternalDisposableService
|
||||||
[ServiceManager.ServiceDependency]
|
[ServiceManager.ServiceDependency]
|
||||||
private readonly Framework framework = Service<Framework>.Get();
|
private readonly Framework framework = Service<Framework>.Get();
|
||||||
|
|
||||||
private readonly EntryStrings dalamudCategory = new("【Dalamud】");
|
|
||||||
private readonly Dictionary<string, EntryStrings> cachedCommands = [];
|
private readonly Dictionary<string, EntryStrings> cachedCommands = [];
|
||||||
private readonly ConcurrentQueue<string> addedCommands = [];
|
private readonly ConcurrentQueue<string> addedCommands = [];
|
||||||
|
|
||||||
|
private EntryStrings? dalamudCategory;
|
||||||
|
|
||||||
private Hook<CompletionModule.Delegates.GetSelection>? getSelection;
|
private Hook<CompletionModule.Delegates.GetSelection>? getSelection;
|
||||||
|
|
||||||
// This is marked volatile since we set and check it from different threads. Instead of using a synchronization
|
// This is marked volatile since we set and check it from different threads. Instead of using a synchronization
|
||||||
|
|
@ -148,6 +149,9 @@ internal sealed unsafe class Completion : IInternalDisposableService
|
||||||
this.framework.Update -= this.OnUpdate;
|
this.framework.Update -= this.OnUpdate;
|
||||||
this.commandManager.CommandAdded -= this.OnCommandAdded;
|
this.commandManager.CommandAdded -= this.OnCommandAdded;
|
||||||
this.commandManager.CommandRemoved -= this.OnCommandRemoved;
|
this.commandManager.CommandRemoved -= this.OnCommandRemoved;
|
||||||
|
|
||||||
|
this.dalamudCategory?.Dispose();
|
||||||
|
this.ClearCachedCommands();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.disposed = true;
|
this.disposed = true;
|
||||||
|
|
@ -176,6 +180,11 @@ internal sealed unsafe class Completion : IInternalDisposableService
|
||||||
// but that's the same as making a typo, really
|
// but that's the same as making a typo, really
|
||||||
if (textInput->CompletionDepth > 0) return;
|
if (textInput->CompletionDepth > 0) return;
|
||||||
|
|
||||||
|
// Create the category for Dalamud commands.
|
||||||
|
// This needs to be done here, since we cannot create Utf8Strings before the game
|
||||||
|
// has initialized (no allocator set up yet).
|
||||||
|
this.dalamudCategory ??= new EntryStrings("【Dalamud】");
|
||||||
|
|
||||||
this.LoadCommands(textInput->CompletionModule);
|
this.LoadCommands(textInput->CompletionModule);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -202,12 +211,25 @@ internal sealed unsafe class Completion : IInternalDisposableService
|
||||||
// Create the category since we don't have one
|
// Create the category since we don't have one
|
||||||
var categoryData = (CategoryData*)Memory.MemoryHelper.GameAllocateDefault((ulong)sizeof(CategoryData));
|
var categoryData = (CategoryData*)Memory.MemoryHelper.GameAllocateDefault((ulong)sizeof(CategoryData));
|
||||||
categoryData->Ctor(GroupNumber, 0xFF);
|
categoryData->Ctor(GroupNumber, 0xFF);
|
||||||
module->AddCategoryData(GroupNumber, this.dalamudCategory.Display->StringPtr,
|
module->AddCategoryData(GroupNumber, this.dalamudCategory!.Display->StringPtr,
|
||||||
this.dalamudCategory.Match->StringPtr, categoryData);
|
this.dalamudCategory.Match->StringPtr, categoryData);
|
||||||
|
|
||||||
return categoryData;
|
return categoryData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void ClearCachedCommands()
|
||||||
|
{
|
||||||
|
if (this.cachedCommands.Count == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
foreach (var entry in this.cachedCommands.Values)
|
||||||
|
{
|
||||||
|
entry.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.cachedCommands.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
private void LoadCommands(CompletionModule* completionModule)
|
private void LoadCommands(CompletionModule* completionModule)
|
||||||
{
|
{
|
||||||
if (completionModule == null) return;
|
if (completionModule == null) return;
|
||||||
|
|
@ -217,7 +239,7 @@ internal sealed unsafe class Completion : IInternalDisposableService
|
||||||
{
|
{
|
||||||
this.needsClear = false;
|
this.needsClear = false;
|
||||||
completionModule->ClearCompletionData();
|
completionModule->ClearCompletionData();
|
||||||
this.cachedCommands.Clear();
|
this.ClearCachedCommands();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -277,17 +299,17 @@ internal sealed unsafe class Completion : IInternalDisposableService
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
private class EntryStrings(string command)
|
private class EntryStrings(string command) : IDisposable
|
||||||
{
|
{
|
||||||
~EntryStrings()
|
|
||||||
{
|
|
||||||
this.Display->Dtor(true);
|
|
||||||
this.Match->Dtor(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Utf8String* Display { get; } =
|
public Utf8String* Display { get; } =
|
||||||
Utf8String.FromSequence(new SeStringBuilder().AddUiForeground(command, 539).Encode());
|
Utf8String.FromSequence(new SeStringBuilder().AddUiForeground(command, 539).Encode());
|
||||||
|
|
||||||
public Utf8String* Match { get; } = Utf8String.FromString(command);
|
public Utf8String* Match { get; } = Utf8String.FromString(command);
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
this.Display->Dtor(true);
|
||||||
|
this.Match->Dtor(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue