Add logging functionality with ILogger interface and implementations
This commit is contained in:
@@ -34,6 +34,7 @@ public class WeaponSystem : ISystem
|
|||||||
if (!cost.CanAfford(context))
|
if (!cost.CanAfford(context))
|
||||||
{
|
{
|
||||||
canFire = false;
|
canFire = false;
|
||||||
|
world.Logger.Warn("Weapon fire failed due to insufficient resources.");
|
||||||
world.PublishEvent(new WeaponFireFailedEvent());
|
world.PublishEvent(new WeaponFireFailedEvent());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,4 +3,5 @@ namespace GameCore.Config;
|
|||||||
public class SimulationConfig
|
public class SimulationConfig
|
||||||
{
|
{
|
||||||
public float GravityStrength { get; set; } = 9.81f;
|
public float GravityStrength { get; set; } = 9.81f;
|
||||||
|
public bool LoggingEnabled { get; set; } = true;
|
||||||
}
|
}
|
||||||
@@ -3,6 +3,7 @@ using GameCore.ECS.Interfaces;
|
|||||||
using GameCore.Events;
|
using GameCore.Events;
|
||||||
using GameCore.Events.Interfaces;
|
using GameCore.Events.Interfaces;
|
||||||
using GameCore.Input.Interfaces;
|
using GameCore.Input.Interfaces;
|
||||||
|
using GameCore.Logging.Interfaces;
|
||||||
|
|
||||||
namespace GameCore.ECS;
|
namespace GameCore.ECS;
|
||||||
|
|
||||||
@@ -11,7 +12,7 @@ namespace GameCore.ECS;
|
|||||||
/// It manages all entities, components, and systems, and orchestrates the main game loop.
|
/// It manages all entities, components, and systems, and orchestrates the main game loop.
|
||||||
/// This class is the primary point of interaction for the Engine/Presentation layer.
|
/// This class is the primary point of interaction for the Engine/Presentation layer.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class World(IInputService inputService, IWorldQuery worldQuery, SimulationConfig config)
|
public class World(IInputService inputService, IWorldQuery worldQuery, SimulationConfig config, ILogger logger)
|
||||||
{
|
{
|
||||||
private readonly Dictionary<int, List<IComponent>> _componentsByEntityId = new();
|
private readonly Dictionary<int, List<IComponent>> _componentsByEntityId = new();
|
||||||
private readonly EventBus _eventBus = new();
|
private readonly EventBus _eventBus = new();
|
||||||
@@ -19,6 +20,7 @@ public class World(IInputService inputService, IWorldQuery worldQuery, Simulatio
|
|||||||
|
|
||||||
public readonly SimulationConfig Config = config;
|
public readonly SimulationConfig Config = config;
|
||||||
public readonly IInputService InputService = inputService;
|
public readonly IInputService InputService = inputService;
|
||||||
|
public readonly ILogger Logger = logger;
|
||||||
public readonly IWorldQuery WorldQuery = worldQuery;
|
public readonly IWorldQuery WorldQuery = worldQuery;
|
||||||
private int _nextEntityId;
|
private int _nextEntityId;
|
||||||
|
|
||||||
|
|||||||
33
GameCore/Logging/CompositeLogger.cs
Normal file
33
GameCore/Logging/CompositeLogger.cs
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
using GameCore.Logging.Interfaces;
|
||||||
|
|
||||||
|
namespace GameCore.Logging;
|
||||||
|
|
||||||
|
public class CompositeLogger : ILogger
|
||||||
|
{
|
||||||
|
private readonly List<ILogger> _loggers = [];
|
||||||
|
|
||||||
|
public CompositeLogger(params ILogger[] loggers)
|
||||||
|
{
|
||||||
|
_loggers.AddRange(loggers);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Debug(string message)
|
||||||
|
{
|
||||||
|
foreach (var logger in _loggers) logger.Debug(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Info(string message)
|
||||||
|
{
|
||||||
|
foreach (var logger in _loggers) logger.Info(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Warn(string message)
|
||||||
|
{
|
||||||
|
foreach (var logger in _loggers) logger.Warn(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Error(string message, Exception ex = null)
|
||||||
|
{
|
||||||
|
foreach (var logger in _loggers) logger.Error(message, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
73
GameCore/Logging/FileLogger.cs
Normal file
73
GameCore/Logging/FileLogger.cs
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
using System.Text;
|
||||||
|
using GameCore.Logging.Interfaces;
|
||||||
|
|
||||||
|
namespace GameCore.Logging;
|
||||||
|
|
||||||
|
public class FileLogger : ILogger, IDisposable
|
||||||
|
{
|
||||||
|
private readonly object _lock = new();
|
||||||
|
private readonly LogLevel _minLogLevel = LogLevel.Debug;
|
||||||
|
private readonly StreamWriter _streamWriter;
|
||||||
|
|
||||||
|
public FileLogger(string filePath, LogLevel minLogLevel = LogLevel.Debug)
|
||||||
|
{
|
||||||
|
_minLogLevel = minLogLevel;
|
||||||
|
|
||||||
|
var stream = new FileStream(filePath, FileMode.Append, FileAccess.Write, FileShare.Read);
|
||||||
|
_streamWriter = new StreamWriter(stream, Encoding.UTF8);
|
||||||
|
_streamWriter.AutoFlush = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
Dispose(true);
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Debug(string message)
|
||||||
|
{
|
||||||
|
Log(LogLevel.Debug, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Info(string message)
|
||||||
|
{
|
||||||
|
Log(LogLevel.Info, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Warn(string message)
|
||||||
|
{
|
||||||
|
Log(LogLevel.Warn, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Error(string message, Exception? ex = null)
|
||||||
|
{
|
||||||
|
Log(LogLevel.Error, message, ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing)
|
||||||
|
lock (_lock)
|
||||||
|
{
|
||||||
|
_streamWriter?.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
~FileLogger()
|
||||||
|
{
|
||||||
|
Dispose(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Log(LogLevel level, string message, Exception? ex = null)
|
||||||
|
{
|
||||||
|
if (level < _minLogLevel) return;
|
||||||
|
|
||||||
|
var logMessage = $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss.ffff}] [{level.ToString().ToUpper()}] {message}";
|
||||||
|
|
||||||
|
lock (_lock)
|
||||||
|
{
|
||||||
|
_streamWriter.WriteLine(logMessage);
|
||||||
|
if (ex != null) _streamWriter.WriteLine(ex.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
9
GameCore/Logging/Interfaces/ILogger.cs
Normal file
9
GameCore/Logging/Interfaces/ILogger.cs
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
namespace GameCore.Logging.Interfaces;
|
||||||
|
|
||||||
|
public interface ILogger
|
||||||
|
{
|
||||||
|
void Debug(string message);
|
||||||
|
void Info(string message);
|
||||||
|
void Warn(string message);
|
||||||
|
void Error(string message, Exception? ex = null);
|
||||||
|
}
|
||||||
9
GameCore/Logging/LogLevel.cs
Normal file
9
GameCore/Logging/LogLevel.cs
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
namespace GameCore.Logging;
|
||||||
|
|
||||||
|
public enum LogLevel
|
||||||
|
{
|
||||||
|
Debug,
|
||||||
|
Info,
|
||||||
|
Warn,
|
||||||
|
Error
|
||||||
|
}
|
||||||
22
GameCore/Logging/NullLogger.cs
Normal file
22
GameCore/Logging/NullLogger.cs
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
using GameCore.Logging.Interfaces;
|
||||||
|
|
||||||
|
namespace GameCore.Logging;
|
||||||
|
|
||||||
|
public class NullLogger : ILogger
|
||||||
|
{
|
||||||
|
public void Debug(string message)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Info(string message)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Warn(string message)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Error(string message, Exception ex = null)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user