CI / build-test (push) Failing after 1m8s
Add MrGameEng.AI utility-AI module; format codebase with CSharpier New MrGameEng.AI module (ResponseCurve, Consideration, UtilityAction, UtilityAi selector, Blackboard) plus CSharpier formatting applied across the whole engine. Documents the CSharpier convention in CLAUDE.md. @
64 lines
2.1 KiB
C#
64 lines
2.1 KiB
C#
namespace MrGameEng.Core;
|
|
|
|
/// <summary>
|
|
/// Minimal service locator used by engine modules to expose their services
|
|
/// (input, audio, assets, …) to scenes and systems without coupling modules to each other.
|
|
/// </summary>
|
|
public sealed class ServiceRegistry
|
|
{
|
|
private readonly Dictionary<Type, object> _services = new();
|
|
|
|
/// <summary>Registers a service instance under type <typeparamref name="T"/>. Throws if already registered.</summary>
|
|
public void Add<T>(T service)
|
|
where T : class
|
|
{
|
|
if (!_services.TryAdd(typeof(T), service))
|
|
{
|
|
throw new InvalidOperationException(
|
|
$"Service of type {typeof(T)} is already registered."
|
|
);
|
|
}
|
|
}
|
|
|
|
/// <summary>Returns the registered service of type <typeparamref name="T"/>. Throws if missing.</summary>
|
|
public T Get<T>()
|
|
where T : class
|
|
{
|
|
return _services.TryGetValue(typeof(T), out var service)
|
|
? (T)service
|
|
: throw new InvalidOperationException(
|
|
$"Service of type {typeof(T)} is not registered."
|
|
);
|
|
}
|
|
|
|
/// <summary>Returns the registered service of type <typeparamref name="T"/> or null.</summary>
|
|
public T? GetOrDefault<T>()
|
|
where T : class
|
|
{
|
|
return _services.TryGetValue(typeof(T), out var service) ? (T)service : null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Disposes every registered <see cref="IDisposable"/> service (each instance once, even
|
|
/// when registered under several types) and clears the registry. <paramref name="except"/>
|
|
/// is skipped. Called on host shutdown.
|
|
/// </summary>
|
|
internal void DisposeServices(object? except = null)
|
|
{
|
|
var disposed = new HashSet<object>(ReferenceEqualityComparer.Instance);
|
|
foreach (var service in _services.Values)
|
|
{
|
|
if (
|
|
!ReferenceEquals(service, except)
|
|
&& service is IDisposable disposable
|
|
&& disposed.Add(service)
|
|
)
|
|
{
|
|
disposable.Dispose();
|
|
}
|
|
}
|
|
|
|
_services.Clear();
|
|
}
|
|
}
|