TH1/Unity/Assets/Scripts/TH1_UI/View/Common/UINetErrorAreaMono.cs
2026-05-28 15:52:40 +08:00

151 lines
3.2 KiB
C#

using System;
using System.Collections.Generic;
using System.Text;
using TH1_Logic.Net;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
namespace TH1_UI.View.Common
{
public class UINetErrorAreaMono : MonoBehaviour
{
[Header("Toggle")]
public Button ToggleButton;
public GameObject LogArea;
[Header("Log List")]
public RectTransform Content;
public GameObject LogItemPrefab;
public ScrollRect ScrollRect;
[Header("Config")]
public int MaxLogCount = 100;
private readonly Queue<GameObject> _logItems = new Queue<GameObject>();
private bool _initialized;
private bool _logAreaVisible;
private void OnDestroy()
{
Shutdown();
}
public void Init()
{
if (_initialized) return;
_initialized = true;
if (ToggleButton != null)
{
ToggleButton.gameObject.SetActive(true);
ToggleButton.onClick.RemoveListener(ToggleLogArea);
ToggleButton.onClick.AddListener(ToggleLogArea);
}
SetLogAreaVisible(false);
foreach (var payload in NetworkPlayerTipManager.Instance.GetRecentPayloads())
AddLog(payload, false);
RebuildLogLayout();
NetworkPlayerTipManager.Instance.OnTipRequested += OnNetworkPlayerTipRequested;
}
public void Shutdown()
{
if (!_initialized) return;
_initialized = false;
NetworkPlayerTipManager.Instance.OnTipRequested -= OnNetworkPlayerTipRequested;
if (ToggleButton != null)
ToggleButton.onClick.RemoveListener(ToggleLogArea);
ClearLogs();
}
private void OnNetworkPlayerTipRequested(NetworkPlayerTipPayload payload)
{
AddLog(payload, true);
}
private void ToggleLogArea()
{
SetLogAreaVisible(!_logAreaVisible);
}
private void SetLogAreaVisible(bool visible)
{
_logAreaVisible = visible;
if (LogArea != null)
LogArea.SetActive(visible);
}
private void AddLog(NetworkPlayerTipPayload payload, bool rebuildLayout)
{
if (Content == null || LogItemPrefab == null)
{
Debug.LogWarning("[NetErrorArea] Log prefab or content is not assigned.");
return;
}
while (_logItems.Count >= Mathf.Max(1, MaxLogCount))
{
var oldest = _logItems.Dequeue();
if (oldest != null)
Destroy(oldest);
}
var go = Instantiate(LogItemPrefab, Content);
go.SetActive(true);
var text = go.GetComponentInChildren<TMP_Text>();
if (text != null)
text.text = BuildLogText(payload);
_logItems.Enqueue(go);
if (rebuildLayout)
RebuildLogLayout();
}
private void RebuildLogLayout()
{
if (Content != null)
LayoutRebuilder.ForceRebuildLayoutImmediate(Content);
if (ScrollRect != null)
{
Canvas.ForceUpdateCanvases();
ScrollRect.verticalNormalizedPosition = 0f;
}
}
private static string BuildLogText(NetworkPlayerTipPayload payload)
{
var sb = new StringBuilder();
sb.Append('[').Append(DateTime.Now.ToString("HH:mm:ss")).Append("] ");
sb.Append(payload?.TipType.ToString() ?? "NetworkTip");
if (!string.IsNullOrEmpty(payload?.Title))
sb.Append(" | ").Append(payload.Title);
if (!string.IsNullOrEmpty(payload?.Message))
sb.Append('\n').Append(payload.Message);
return sb.ToString();
}
private void ClearLogs()
{
while (_logItems.Count > 0)
{
var go = _logItems.Dequeue();
if (go != null)
Destroy(go);
}
RebuildLogLayout();
}
}
}