mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 10:17:22 +01:00
115 lines
3.4 KiB
C#
115 lines
3.4 KiB
C#
using Dalamud.Plugin;
|
|
using OtterGui.Services;
|
|
using OtterGui.Text;
|
|
using Penumbra.Api.Enums;
|
|
|
|
namespace Penumbra.UI.Integration;
|
|
|
|
public sealed class IntegrationSettingsRegistry : IService, IDisposable
|
|
{
|
|
private readonly IDalamudPluginInterface _pluginInterface;
|
|
|
|
private readonly List<(string InternalName, string Name, Action Draw)> _sections = [];
|
|
|
|
private bool _disposed = false;
|
|
|
|
public IntegrationSettingsRegistry(IDalamudPluginInterface pluginInterface)
|
|
{
|
|
_pluginInterface = pluginInterface;
|
|
|
|
_pluginInterface.ActivePluginsChanged += OnActivePluginsChanged;
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
_disposed = true;
|
|
|
|
_pluginInterface.ActivePluginsChanged -= OnActivePluginsChanged;
|
|
|
|
_sections.Clear();
|
|
}
|
|
|
|
public void Draw()
|
|
{
|
|
foreach (var (internalName, name, draw) in _sections)
|
|
{
|
|
if (!ImUtf8.CollapsingHeader($"Integration with {name}###IntegrationSettingsHeader.{internalName}"))
|
|
continue;
|
|
|
|
using var id = ImUtf8.PushId($"IntegrationSettings.{internalName}");
|
|
try
|
|
{
|
|
draw();
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Penumbra.Log.Error($"Error while drawing {internalName} integration settings: {e}");
|
|
}
|
|
}
|
|
}
|
|
|
|
public PenumbraApiEc RegisterSection(Action draw)
|
|
{
|
|
if (_disposed)
|
|
return PenumbraApiEc.SystemDisposed;
|
|
|
|
var plugin = GetPlugin(draw);
|
|
if (plugin is null)
|
|
return PenumbraApiEc.InvalidArgument;
|
|
|
|
var section = (plugin.InternalName, plugin.Name, draw);
|
|
|
|
var index = FindSectionIndex(plugin.InternalName);
|
|
if (index >= 0)
|
|
{
|
|
if (_sections[index] == section)
|
|
return PenumbraApiEc.NothingChanged;
|
|
_sections[index] = section;
|
|
}
|
|
else
|
|
_sections.Add(section);
|
|
_sections.Sort((lhs, rhs) => string.Compare(lhs.Name, rhs.Name, StringComparison.CurrentCultureIgnoreCase));
|
|
|
|
return PenumbraApiEc.Success;
|
|
}
|
|
|
|
public bool UnregisterSection(Action draw)
|
|
{
|
|
var index = FindSectionIndex(draw);
|
|
if (index < 0)
|
|
return false;
|
|
|
|
_sections.RemoveAt(index);
|
|
return true;
|
|
}
|
|
|
|
private void OnActivePluginsChanged(IActivePluginsChangedEventArgs args)
|
|
{
|
|
if (args.Kind is PluginListInvalidationKind.Loaded)
|
|
return;
|
|
|
|
foreach (var internalName in args.AffectedInternalNames)
|
|
{
|
|
var index = FindSectionIndex(internalName);
|
|
if (index >= 0 && GetPlugin(_sections[index].Draw) is null)
|
|
{
|
|
_sections.RemoveAt(index);
|
|
Penumbra.Log.Warning($"Removed stale integration setting section of {internalName} (reason: {args.Kind})");
|
|
}
|
|
}
|
|
}
|
|
|
|
private IExposedPlugin? GetPlugin(Delegate @delegate)
|
|
=> @delegate.Method.DeclaringType
|
|
switch
|
|
{
|
|
null => null,
|
|
var type => _pluginInterface.GetPlugin(type.Assembly),
|
|
};
|
|
|
|
private int FindSectionIndex(string internalName)
|
|
=> _sections.FindIndex(section => section.InternalName.Equals(internalName, StringComparison.Ordinal));
|
|
|
|
private int FindSectionIndex(Action draw)
|
|
=> _sections.FindIndex(section => section.Draw == draw);
|
|
}
|