Co-authored-by: m0_75251201 <m0_75251201@noreply.gitcode.com> Reviewed-on: Roguelite-Game-Developing-Team/Gen_Hack-and-Slash-Roguelite#55
131 lines
4.0 KiB
C#
131 lines
4.0 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using UnityEngine;
|
||
|
||
namespace Logging
|
||
{
|
||
public static class LogCapturer
|
||
{
|
||
// 日志条目结构
|
||
public struct LogEntry
|
||
{
|
||
public DateTime Timestamp;
|
||
public LogType Type;
|
||
public string Message;
|
||
public string StackTrace;
|
||
|
||
public override string ToString()
|
||
{
|
||
// 逻辑修改:扩展条件,使LogType.Error和LogType.Assert也能显示堆栈信息
|
||
if (Type == LogType.Exception || Type == LogType.Error || Type == LogType.Assert)
|
||
{
|
||
return $"[{Timestamp:HH:mm:ss}] [{Type}] {Message}\n{StackTrace}";
|
||
}
|
||
return $"[{Timestamp:HH:mm:ss}] [{Type}] {Message}";
|
||
}
|
||
}
|
||
|
||
private static readonly Queue<LogEntry> _logs = new Queue<LogEntry>();
|
||
private static readonly object _lock = new object(); // 线程锁
|
||
private static int _maxLogs = 1000; // 默认容量
|
||
private static bool _isInitialized = false; // 逻辑修改:添加一个私有标志来跟踪是否已初始化
|
||
|
||
// 最大日志容量属性
|
||
public static int MaxLogs
|
||
{
|
||
get => _maxLogs;
|
||
set
|
||
{
|
||
lock (_lock)
|
||
{
|
||
_maxLogs = Mathf.Max(value, 1); // 最小值为1
|
||
TrimExcess();
|
||
}
|
||
}
|
||
}
|
||
|
||
// 逻辑修改:添加 [RuntimeInitializeOnLoadMethod] 特性,确保 Init() 方法在 Unity 启动时自动执行
|
||
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterAssembliesLoaded)]
|
||
public static void Init()
|
||
{
|
||
// 确保线程安全地检查和设置初始化状态
|
||
lock (_lock)
|
||
{
|
||
if (_isInitialized)
|
||
{
|
||
Debug.LogWarning("[LogCapturer] Init() called multiple times. LogCapturer is already initialized.");
|
||
return;
|
||
}
|
||
|
||
Application.logMessageReceivedThreaded += HandleLog;
|
||
_isInitialized = true;
|
||
}
|
||
}
|
||
|
||
// 逻辑修改:添加一个 Shutdown 方法来解除事件注册和清理
|
||
public static void Shutdown()
|
||
{
|
||
// 确保线程安全地检查和解除注册
|
||
lock (_lock)
|
||
{
|
||
if (!_isInitialized)
|
||
{
|
||
Debug.LogWarning("[LogCapturer] Shutdown() called but LogCapturer was not initialized.");
|
||
return;
|
||
}
|
||
|
||
Application.logMessageReceivedThreaded -= HandleLog;
|
||
_isInitialized = false;
|
||
_logs.Clear(); // 逻辑修改:在关闭时清空所有捕获的日志,确保下次启用时是全新状态。
|
||
}
|
||
}
|
||
|
||
// 日志处理回调
|
||
private static void HandleLog(string message, string stackTrace, LogType type)
|
||
{
|
||
lock (_lock)
|
||
{
|
||
var entry = new LogEntry
|
||
{
|
||
Timestamp = DateTime.Now,
|
||
Type = type,
|
||
Message = message,
|
||
StackTrace = stackTrace
|
||
};
|
||
|
||
_logs.Enqueue(entry);
|
||
TrimExcess();
|
||
}
|
||
}
|
||
|
||
// 日志队列修剪
|
||
private static void TrimExcess()
|
||
{
|
||
while (_logs.Count > _maxLogs)
|
||
{
|
||
_logs.Dequeue();
|
||
}
|
||
}
|
||
|
||
// 获取当前所有日志(倒序:最新在前)
|
||
public static List<LogEntry> GetLogs(bool reverseOrder = true)
|
||
{
|
||
lock (_lock)
|
||
{
|
||
var list = new List<LogEntry>(_logs);
|
||
if (reverseOrder) list.Reverse();
|
||
return list;
|
||
}
|
||
}
|
||
|
||
// 清空日志
|
||
public static void Clear()
|
||
{
|
||
lock (_lock)
|
||
{
|
||
_logs.Clear();
|
||
}
|
||
}
|
||
}
|
||
}
|