Files
RobustToolbox/Robust.Shared/Configuration/ConfigurationManagerExtensions.cs
Fildrance 735ef09d42 Better unsubscription for multiple ConfigurationManager subscriptions (#6115)
* feat: new method or aggregating multiple config changed subscriptions into one disposable object or more slim unsubscribing code

* refactor: moved nested private class declaration to bottom of class

* refactor: reusing stateful object in tests is not smart

* fix: invalid code for forming new array during InvokeList.Remove call

* refactor: extracted new sub-multiple builder into configuration manager extensions

* refactor: remove unused code

* refactor: removed UnSubscribeActionsDelegates

* refactor: whitespaces and renaming

---------

Co-authored-by: pa.pecherskij <pa.pecherskij@interfax.ru>
2025-08-02 18:35:38 +02:00

92 lines
2.9 KiB
C#

using System;
using System.Collections.Generic;
namespace Robust.Shared.Configuration;
public static class ConfigurationManagerExtensions
{
/// <summary>
/// Subscribe to multiple cvar in succession and dispose object to unsubscribe from all of them when needed.
/// </summary>
public static ConfigurationMultiSubscriptionBuilder SubscribeMultiple(this IConfigurationManager manager)
{
return new ConfigurationMultiSubscriptionBuilder(manager);
}
}
/// <summary>
/// Container for batch-unsubscription of config changed events.
/// Call Dispose() when subscriptions are not needed anymore.
/// </summary>
public sealed class ConfigurationMultiSubscriptionBuilder(IConfigurationManager manager) : IDisposable
{
private readonly List<Action> _unsubscribeActions = [];
/// <inheritdoc cref="IConfigurationManager.OnValueChanged{T}(CVarDef{T},Action{T},bool)"/>>
public ConfigurationMultiSubscriptionBuilder OnValueChanged<T>(
CVarDef<T> cVar,
CVarChanged<T> onValueChanged,
bool invokeImmediately = false
)
where T : notnull
{
manager.OnValueChanged(cVar, onValueChanged, invokeImmediately);
_unsubscribeActions.Add(() => manager.UnsubValueChanged(cVar, onValueChanged));
return this;
}
/// <inheritdoc cref="IConfigurationManager.OnValueChanged{T}(string,Action{T},bool)"/>>
public ConfigurationMultiSubscriptionBuilder OnValueChanged<T>(
string name,
CVarChanged<T> onValueChanged,
bool invokeImmediately = false
)
where T : notnull
{
manager.OnValueChanged(name, onValueChanged, invokeImmediately);
_unsubscribeActions.Add(() => manager.UnsubValueChanged(name, onValueChanged));
return this;
}
/// <inheritdoc cref="IConfigurationManager.OnValueChanged{T}(CVarDef{T},CVarChanged{T},bool)"/>>
public ConfigurationMultiSubscriptionBuilder OnValueChanged<T>(
CVarDef<T> cVar,
Action<T> onValueChanged,
bool invokeImmediately = false
)
where T : notnull
{
manager.OnValueChanged(cVar, onValueChanged, invokeImmediately);
_unsubscribeActions.Add(() => manager.UnsubValueChanged(cVar, onValueChanged));
return this;
}
/// <inheritdoc cref="IConfigurationManager.OnValueChanged{T}(string,CVarChanged{T},bool)"/>>
public ConfigurationMultiSubscriptionBuilder OnValueChanged<T>(
string name,
Action<T> onValueChanged,
bool invokeImmediately = false
)
where T : notnull
{
manager.OnValueChanged(name, onValueChanged, invokeImmediately);
_unsubscribeActions.Add(() => manager.UnsubValueChanged(name, onValueChanged));
return this;
}
/// <inheritdoc />
public void Dispose()
{
foreach (var action in _unsubscribeActions)
{
action();
}
_unsubscribeActions.Clear();
}
}