I have a game written using Silk.NET, the framework has an equivalent of OpenTK's GameWindow with Update
and Render
methods, etc.
I do log messages using ILogger
and I've written an ILogger
that redirects message to imgui which is an immediate mode GUI library.
This is the constructor of my game class:
public Game(ILogger<IGame> logger, ILoggerFactory loggerFactory)
{
Logger = logger;
ImGuiLogger.Action = s => LoggerQueue.Add(s); // s is a string
loggerFactory.AddProvider(new ImGuiLoggerProvider());
}
As you can see, I assign an action to a static property in the logger class.
This is what allows me to read the logged messages in my update loop and display them.
So basically, there's a direct dependency and furthermore, I'm assigning a static property which is far from ideal.
This just works as I only have one GUI controller but still, it's not really clean.
This is the logger in question for reference:
using Microsoft.Extensions.Logging;
namespace TestDI.Silk.Logging;
internal sealed class ImGuiLogger : ILogger
{
public ImGuiLogger(string categoryName, IExternalScopeProvider? scopeProvider)
{
CategoryName = categoryName;
ScopeProvider = scopeProvider;
}
private string CategoryName { get; }
private IExternalScopeProvider? ScopeProvider { get; }
public static Action<string>? Action { get; set; }
#region ILogger Members
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func<TState, Exception?, string> formatter)
{
if (Action is null)
{
return;
}
var message = formatter(state, exception);
message = $"{DateTime.Now:HH:mm:ss.fff} [{logLevel.ToString()[..4]}] {CategoryName} {message}";
Action.Invoke(message);
}
public bool IsEnabled(LogLevel logLevel)
{
return logLevel != LogLevel.None;
}
public IDisposable BeginScope<TState>(TState state)
{
return ScopeProvider?.Push(state) ?? NullScope.Instance;
}
#endregion
#region Nested type: NullScope
private sealed class NullScope : IDisposable
{
private NullScope()
{
}
public static NullScope Instance { get; } = new();
#region IDisposable Members
public void Dispose()
{
}
#endregion
}
#endregion
}
Question:
How can I get this logger, to query for an action to execute when it logs a message?
I guess you get the point, i.e. remove that strong reference to a static property.
Aucun commentaire:
Enregistrer un commentaire