Refactor and enhance graphics and audio systems
Updated target frameworks to .NET 10.0 across multiple projects for compatibility with the latest features. Refactored namespaces and introduced new classes for shader descriptors, FMOD integration, and DirectX 12 utilities using TerraFX. Replaced `Win32` bindings with TerraFX equivalents for DirectX 12. Added a C# wrapper for FMOD Studio API, including DSP and error handling. Enhanced entity queries, component storage, and query filters for better performance and type safety. Introduced new test projects and updated the solution structure. Added `meshoptimizer` bindings and integrated `meshoptimizer_native.dll`. Improved code readability, maintainability, and performance.
This commit is contained in:
110
Ghost.Graphics.Test/Services/LoggingService.cs
Normal file
110
Ghost.Graphics.Test/Services/LoggingService.cs
Normal file
@@ -0,0 +1,110 @@
|
||||
using Ghost.UnitTest.Models;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Ghost.UnitTest.Services;
|
||||
|
||||
internal class LoggingService
|
||||
{
|
||||
private const int MAX_LOGS = 4096;
|
||||
private static readonly Lazy<LoggingService> _instance = new(() => new LoggingService());
|
||||
|
||||
private readonly List<LogItem> _logs = [];
|
||||
private readonly object _lockObject = new();
|
||||
|
||||
public static LoggingService Instance => _instance.Value;
|
||||
|
||||
public IReadOnlyList<LogItem> Logs
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (_lockObject)
|
||||
{
|
||||
return _logs.AsReadOnly();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool CaptureStackTrace { get; set; } = false;
|
||||
|
||||
public event Action<LogItem>? LogAdded;
|
||||
public event Action? LogsCleared;
|
||||
|
||||
private LoggingService()
|
||||
{
|
||||
}
|
||||
|
||||
private void AddLog(LogItem logItem)
|
||||
{
|
||||
lock (_lockObject)
|
||||
{
|
||||
if (_logs.Count >= MAX_LOGS)
|
||||
{
|
||||
_logs.RemoveAt(0);
|
||||
}
|
||||
|
||||
_logs.Add(logItem);
|
||||
}
|
||||
|
||||
// Invoke event outside of lock to prevent deadlock
|
||||
LogAdded?.Invoke(logItem);
|
||||
}
|
||||
|
||||
private string? CaptureCurrentStackTrace()
|
||||
{
|
||||
if (!CaptureStackTrace)
|
||||
return null;
|
||||
|
||||
var stackTrace = new StackTrace(skipFrames: 2, fNeedFileInfo: true);
|
||||
return stackTrace.ToString();
|
||||
}
|
||||
|
||||
public void Log(LogLevel level, object? message)
|
||||
{
|
||||
var stackTrace = CaptureCurrentStackTrace();
|
||||
var logItem = new LogItem(level, message?.ToString() ?? string.Empty, stackTrace);
|
||||
AddLog(logItem);
|
||||
}
|
||||
|
||||
public void LogInfo(object? message)
|
||||
{
|
||||
Log(LogLevel.Info, message);
|
||||
}
|
||||
|
||||
public void LogWarning(object? message)
|
||||
{
|
||||
Log(LogLevel.Warning, message);
|
||||
}
|
||||
|
||||
public void LogError(object? message)
|
||||
{
|
||||
Log(LogLevel.Error, message);
|
||||
}
|
||||
|
||||
public void LogError(Exception exception)
|
||||
{
|
||||
var logItem = new LogItem(LogLevel.Error, exception.Message, exception.StackTrace);
|
||||
AddLog(logItem);
|
||||
}
|
||||
|
||||
public void LogDebug(object? message)
|
||||
{
|
||||
Log(LogLevel.Debug, message);
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
lock (_lockObject)
|
||||
{
|
||||
_logs.Clear();
|
||||
}
|
||||
|
||||
LogsCleared?.Invoke();
|
||||
}
|
||||
|
||||
// Static methods for easier usage throughout the test project
|
||||
public static void Info(object? message) => Instance.LogInfo(message);
|
||||
public static void Warning(object? message) => Instance.LogWarning(message);
|
||||
public static void Error(object? message) => Instance.LogError(message);
|
||||
public static void Error(Exception exception) => Instance.LogError(exception);
|
||||
public static void Debug(object? message) => Instance.LogDebug(message);
|
||||
}
|
||||
Reference in New Issue
Block a user