mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-12 10:17:22 +01:00
Add GameConfigPluginScoped (#1383)
* Add GameConfigPluginScoped * Proposed Resolution to sub-object events * Nullify delegates to prevent memory leaks
This commit is contained in:
parent
b742abe77f
commit
43abb12710
3 changed files with 235 additions and 8 deletions
|
|
@ -12,11 +12,7 @@ namespace Dalamud.Game.Config;
|
||||||
/// This class represents the game's configuration.
|
/// This class represents the game's configuration.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[InterfaceVersion("1.0")]
|
[InterfaceVersion("1.0")]
|
||||||
[PluginInterface]
|
|
||||||
[ServiceManager.EarlyLoadedService]
|
[ServiceManager.EarlyLoadedService]
|
||||||
#pragma warning disable SA1015
|
|
||||||
[ResolveVia<IGameConfig>]
|
|
||||||
#pragma warning restore SA1015
|
|
||||||
internal sealed class GameConfig : IServiceType, IGameConfig, IDisposable
|
internal sealed class GameConfig : IServiceType, IGameConfig, IDisposable
|
||||||
{
|
{
|
||||||
private readonly GameConfigAddressResolver address = new();
|
private readonly GameConfigAddressResolver address = new();
|
||||||
|
|
@ -36,15 +32,30 @@ internal sealed class GameConfig : IServiceType, IGameConfig, IDisposable
|
||||||
|
|
||||||
this.address.Setup(sigScanner);
|
this.address.Setup(sigScanner);
|
||||||
this.configChangeHook = Hook<ConfigChangeDelegate>.FromAddress(this.address.ConfigChangeAddress, this.OnConfigChanged);
|
this.configChangeHook = Hook<ConfigChangeDelegate>.FromAddress(this.address.ConfigChangeAddress, this.OnConfigChanged);
|
||||||
this.configChangeHook?.Enable();
|
this.configChangeHook.Enable();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private unsafe delegate nint ConfigChangeDelegate(ConfigBase* configBase, ConfigEntry* configEntry);
|
private unsafe delegate nint ConfigChangeDelegate(ConfigBase* configBase, ConfigEntry* configEntry);
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public event EventHandler<ConfigChangeEvent> Changed;
|
public event EventHandler<ConfigChangeEvent>? Changed;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Unused internally, used as a proxy for System.Changed via GameConfigPluginScoped
|
||||||
|
/// </summary>
|
||||||
|
public event EventHandler<ConfigChangeEvent>? SystemChanged;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Unused internally, used as a proxy for UiConfig.Changed via GameConfigPluginScoped
|
||||||
|
/// </summary>
|
||||||
|
public event EventHandler<ConfigChangeEvent>? UiConfigChanged;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Unused internally, used as a proxy for UiControl.Changed via GameConfigPluginScoped
|
||||||
|
/// </summary>
|
||||||
|
public event EventHandler<ConfigChangeEvent>? UiControlChanged;
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public GameConfigSection System { get; private set; }
|
public GameConfigSection System { get; private set; }
|
||||||
|
|
||||||
|
|
@ -192,3 +203,204 @@ internal sealed class GameConfig : IServiceType, IGameConfig, IDisposable
|
||||||
return returnValue;
|
return returnValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Plugin-scoped version of a GameConfig service.
|
||||||
|
/// </summary>
|
||||||
|
[PluginInterface]
|
||||||
|
[InterfaceVersion("1.0")]
|
||||||
|
[ServiceManager.ScopedService]
|
||||||
|
#pragma warning disable SA1015
|
||||||
|
[ResolveVia<IGameConfig>]
|
||||||
|
#pragma warning restore SA1015
|
||||||
|
internal class GameConfigPluginScoped : IDisposable, IServiceType, IGameConfig
|
||||||
|
{
|
||||||
|
[ServiceManager.ServiceDependency]
|
||||||
|
private readonly GameConfig gameConfigService = Service<GameConfig>.Get();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="GameConfigPluginScoped"/> class.
|
||||||
|
/// </summary>
|
||||||
|
internal GameConfigPluginScoped()
|
||||||
|
{
|
||||||
|
this.gameConfigService.Changed += this.ConfigChangedForward;
|
||||||
|
this.gameConfigService.System.Changed += this.SystemConfigChangedForward;
|
||||||
|
this.gameConfigService.UiConfig.Changed += this.UiConfigConfigChangedForward;
|
||||||
|
this.gameConfigService.UiControl.Changed += this.UiControlConfigChangedForward;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public event EventHandler<ConfigChangeEvent>? Changed;
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public event EventHandler<ConfigChangeEvent>? SystemChanged;
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public event EventHandler<ConfigChangeEvent>? UiConfigChanged;
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public event EventHandler<ConfigChangeEvent>? UiControlChanged;
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public GameConfigSection System => this.gameConfigService.System;
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public GameConfigSection UiConfig => this.gameConfigService.UiConfig;
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public GameConfigSection UiControl => this.gameConfigService.UiControl;
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
this.gameConfigService.Changed -= this.ConfigChangedForward;
|
||||||
|
this.gameConfigService.System.Changed -= this.SystemConfigChangedForward;
|
||||||
|
this.gameConfigService.UiConfig.Changed -= this.UiConfigConfigChangedForward;
|
||||||
|
this.gameConfigService.UiControl.Changed -= this.UiControlConfigChangedForward;
|
||||||
|
|
||||||
|
this.Changed = null;
|
||||||
|
this.SystemChanged = null;
|
||||||
|
this.UiConfigChanged = null;
|
||||||
|
this.UiControlChanged = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public bool TryGet(SystemConfigOption option, out bool value)
|
||||||
|
=> this.gameConfigService.TryGet(option, out value);
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public bool TryGet(SystemConfigOption option, out uint value)
|
||||||
|
=> this.gameConfigService.TryGet(option, out value);
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public bool TryGet(SystemConfigOption option, out float value)
|
||||||
|
=> this.gameConfigService.TryGet(option, out value);
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public bool TryGet(SystemConfigOption option, out string value)
|
||||||
|
=> this.gameConfigService.TryGet(option, out value);
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public bool TryGet(SystemConfigOption option, out UIntConfigProperties? properties)
|
||||||
|
=> this.gameConfigService.TryGet(option, out properties);
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public bool TryGet(SystemConfigOption option, out FloatConfigProperties? properties)
|
||||||
|
=> this.gameConfigService.TryGet(option, out properties);
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public bool TryGet(SystemConfigOption option, out StringConfigProperties? properties)
|
||||||
|
=> this.gameConfigService.TryGet(option, out properties);
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public bool TryGet(UiConfigOption option, out bool value)
|
||||||
|
=> this.gameConfigService.TryGet(option, out value);
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public bool TryGet(UiConfigOption option, out uint value)
|
||||||
|
=> this.gameConfigService.TryGet(option, out value);
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public bool TryGet(UiConfigOption option, out float value)
|
||||||
|
=> this.gameConfigService.TryGet(option, out value);
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public bool TryGet(UiConfigOption option, out string value)
|
||||||
|
=> this.gameConfigService.TryGet(option, out value);
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public bool TryGet(UiConfigOption option, out UIntConfigProperties? properties)
|
||||||
|
=> this.gameConfigService.TryGet(option, out properties);
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public bool TryGet(UiConfigOption option, out FloatConfigProperties? properties)
|
||||||
|
=> this.gameConfigService.TryGet(option, out properties);
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public bool TryGet(UiConfigOption option, out StringConfigProperties? properties)
|
||||||
|
=> this.gameConfigService.TryGet(option, out properties);
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public bool TryGet(UiControlOption option, out bool value)
|
||||||
|
=> this.gameConfigService.TryGet(option, out value);
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public bool TryGet(UiControlOption option, out uint value)
|
||||||
|
=> this.gameConfigService.TryGet(option, out value);
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public bool TryGet(UiControlOption option, out float value)
|
||||||
|
=> this.gameConfigService.TryGet(option, out value);
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public bool TryGet(UiControlOption option, out string value)
|
||||||
|
=> this.gameConfigService.TryGet(option, out value);
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public bool TryGet(UiControlOption option, out UIntConfigProperties? properties)
|
||||||
|
=> this.gameConfigService.TryGet(option, out properties);
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public bool TryGet(UiControlOption option, out FloatConfigProperties? properties)
|
||||||
|
=> this.gameConfigService.TryGet(option, out properties);
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public bool TryGet(UiControlOption option, out StringConfigProperties? properties)
|
||||||
|
=> this.gameConfigService.TryGet(option, out properties);
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public void Set(SystemConfigOption option, bool value)
|
||||||
|
=> this.gameConfigService.Set(option, value);
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public void Set(SystemConfigOption option, uint value)
|
||||||
|
=> this.gameConfigService.Set(option, value);
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public void Set(SystemConfigOption option, float value)
|
||||||
|
=> this.gameConfigService.Set(option, value);
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public void Set(SystemConfigOption option, string value)
|
||||||
|
=> this.gameConfigService.Set(option, value);
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public void Set(UiConfigOption option, bool value)
|
||||||
|
=> this.gameConfigService.Set(option, value);
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public void Set(UiConfigOption option, uint value)
|
||||||
|
=> this.gameConfigService.Set(option, value);
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public void Set(UiConfigOption option, float value)
|
||||||
|
=> this.gameConfigService.Set(option, value);
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public void Set(UiConfigOption option, string value)
|
||||||
|
=> this.gameConfigService.Set(option, value);
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public void Set(UiControlOption option, bool value)
|
||||||
|
=> this.gameConfigService.Set(option, value);
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public void Set(UiControlOption option, uint value)
|
||||||
|
=> this.gameConfigService.Set(option, value);
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public void Set(UiControlOption option, float value)
|
||||||
|
=> this.gameConfigService.Set(option, value);
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public void Set(UiControlOption option, string value)
|
||||||
|
=> this.gameConfigService.Set(option, value);
|
||||||
|
|
||||||
|
private void ConfigChangedForward(object sender, ConfigChangeEvent data) => this.Changed?.Invoke(sender, data);
|
||||||
|
|
||||||
|
private void SystemConfigChangedForward(object sender, ConfigChangeEvent data) => this.SystemChanged?.Invoke(sender, data);
|
||||||
|
|
||||||
|
private void UiConfigConfigChangedForward(object sender, ConfigChangeEvent data) => this.UiConfigChanged?.Invoke(sender, data);
|
||||||
|
|
||||||
|
private void UiControlConfigChangedForward(object sender, ConfigChangeEvent data) => this.UiControlChanged?.Invoke(sender, data);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ public class GameConfigSection
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event which is fired when a game config option is changed within the section.
|
/// Event which is fired when a game config option is changed within the section.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public event EventHandler<ConfigChangeEvent>? Changed;
|
internal event EventHandler<ConfigChangeEvent>? Changed;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the number of config entries contained within the section.
|
/// Gets the number of config entries contained within the section.
|
||||||
|
|
|
||||||
|
|
@ -12,10 +12,25 @@ namespace Dalamud.Plugin.Services;
|
||||||
public interface IGameConfig
|
public interface IGameConfig
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event which is fired when a game config option is changed.
|
/// Event which is fired when any game config option is changed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public event EventHandler<ConfigChangeEvent> Changed;
|
public event EventHandler<ConfigChangeEvent> Changed;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Event which is fired when a system config option is changed.
|
||||||
|
/// </summary>
|
||||||
|
public event EventHandler<ConfigChangeEvent> SystemChanged;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Event which is fired when a UiConfig option is changed.
|
||||||
|
/// </summary>
|
||||||
|
public event EventHandler<ConfigChangeEvent> UiConfigChanged;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Event which is fired when a UiControl config option is changed.
|
||||||
|
/// </summary>
|
||||||
|
public event EventHandler<ConfigChangeEvent> UiControlChanged;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the collection of config options that persist between characters.
|
/// Gets the collection of config options that persist between characters.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue