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

100 lines
2.7 KiB
C#

using System;
using System.Linq;
using Dalamud.Plugin;
using Dalamud.Plugin.Services;
using Microsoft.Extensions.Logging;
namespace Questionable.External;
internal sealed class WigglyNavAvailability : IDisposable
{
private const int SupportedMajorVersion = 1;
private const string WigglyNavInternalName = "WigglyNav";
private const long ReprobeIntervalMs = 5000L;
private readonly IDalamudPluginInterface _pluginInterface;
private readonly WigglyNavIpc _wigglyNavIpc;
private readonly IFramework _framework;
private readonly ILogger<WigglyNavAvailability> _logger;
private readonly object _verdictLock = new object();
private volatile bool _isCompatible;
private long _lastProbeTicks;
public bool IsCompatible => _isCompatible;
public event Action? CompatibilityChanged;
public WigglyNavAvailability(IDalamudPluginInterface pluginInterface, WigglyNavIpc wigglyNavIpc, IFramework framework, ILogger<WigglyNavAvailability> logger)
{
_pluginInterface = pluginInterface;
_wigglyNavIpc = wigglyNavIpc;
_framework = framework;
_logger = logger;
TryRefreshVerdict(respectThrottle: false);
_logger.LogInformation("WigglyNav native surface is {State} at startup", DescribeVerdict(_isCompatible));
_pluginInterface.ActivePluginsChanged += OnActivePluginsChanged;
_framework.Update += OnFrameworkUpdate;
}
public void Dispose()
{
_framework.Update -= OnFrameworkUpdate;
_pluginInterface.ActivePluginsChanged -= OnActivePluginsChanged;
}
private void OnActivePluginsChanged(IActivePluginsChangedEventArgs args)
{
if (args.AffectedInternalNames.Contains("WigglyNav") && TryRefreshVerdict(respectThrottle: false))
{
_logger.LogInformation("WigglyNav native surface is now {State} (plugin list change: {Kind})", DescribeVerdict(_isCompatible), args.Kind);
this.CompatibilityChanged?.Invoke();
}
}
private void OnFrameworkUpdate(IFramework framework)
{
if (!_isCompatible && TryRefreshVerdict(respectThrottle: true))
{
_logger.LogInformation("WigglyNav native surface is now {State} (periodic re-probe)", DescribeVerdict(_isCompatible));
this.CompatibilityChanged?.Invoke();
}
}
private bool TryRefreshVerdict(bool respectThrottle)
{
lock (_verdictLock)
{
long tickCount = Environment.TickCount64;
if (respectThrottle && tickCount - _lastProbeTicks < 5000)
{
return false;
}
_lastProbeTicks = tickCount;
(int, int)? tuple = _wigglyNavIpc.TryGetApiVersion();
bool flag = tuple.HasValue && tuple.GetValueOrDefault().Item1 == 1;
if (flag == _isCompatible)
{
return false;
}
_isCompatible = flag;
return true;
}
}
private static string DescribeVerdict(bool isCompatible)
{
if (!isCompatible)
{
return "unavailable or incompatible";
}
return "compatible";
}
}