qstbak/Questionable/Questionable.Data/NpcPositionCacheWarmer.cs
2026-08-17 20:29:32 +10:00

75 lines
2.2 KiB
C#

using System;
using System.Threading;
using Dalamud.Plugin;
using Dalamud.Plugin.Services;
using LLib.Shop;
using Microsoft.Extensions.Logging;
using SmartNav;
using SmartNav.Data;
namespace Questionable.Data;
internal sealed class NpcPositionCacheWarmer : IDisposable
{
private readonly CancellationTokenSource _cts = new CancellationTokenSource();
private readonly Thread? _thread;
public NpcPositionCacheWarmer(NpcPositionCache npcPositionCache, WarpDataService warpDataService, NavRouter navRouter, LgbWorkerSupervisor workerSupervisor, IDalamudPluginInterface pluginInterface, IDataManager dataManager, NpcPositionCacheOptions cacheOptions, ILogger<NpcPositionCacheWarmer> logger)
{
NpcPositionCacheWarmer npcPositionCacheWarmer = this;
if (npcPositionCache.IsBuilt)
{
return;
}
_thread = new Thread((ThreadStart)delegate
{
try
{
bool flag = false;
string fullName = dataManager.GameData.DataPath.FullName;
string gameVersion = cacheOptions.GameVersion;
string cacheDirectory = cacheOptions.CacheDirectory;
string directoryName = pluginInterface.AssemblyLocation.DirectoryName;
if (fullName != null && gameVersion != null && cacheDirectory != null && directoryName != null)
{
flag = workerSupervisor.RunWorker(fullName, gameVersion, cacheDirectory, directoryName, npcPositionCacheWarmer._cts.Token);
if (flag)
{
npcPositionCache.TryLoadFromDisk();
}
}
if (!flag)
{
logger.LogInformation("Falling back to in-process LGB scan");
npcPositionCache.WarmUp(npcPositionCacheWarmer._cts.Token);
}
if (warpDataService.ApplyDerivedSources())
{
navRouter.InvalidateStaticGraph();
logger.LogInformation("Applied derived warp sources after NPC position warm-up");
}
}
catch (OperationCanceledException)
{
}
catch (Exception exception)
{
logger.LogError(exception, "NPC position cache warm-up failed");
}
})
{
IsBackground = true,
Priority = ThreadPriority.BelowNormal,
Name = "Questionable.NpcPositionCacheWarmer"
};
_thread.Start();
}
public void Dispose()
{
_cts.Cancel();
_thread?.Join(TimeSpan.FromSeconds(1L));
_cts.Dispose();
}
}