com.alicizax.unity.framework/Runtime/Debugger/DebuggerComponent.TimerInformationWindow.cs

201 lines
8.1 KiB
C#
Raw Normal View History

using AlicizaX.Timer.Runtime;
using UnityEngine;
using UnityEngine.UIElements;
namespace AlicizaX.Debugger.Runtime
{
public sealed partial class DebuggerComponent
{
private sealed class TimerInformationWindow : ScrollableDebuggerWindowBase
{
private const int MAX_DISPLAY_COUNT = 50;
private struct RowView
{
public VisualElement Root;
public Label Title;
public Label Value;
}
private ITimerServiceDebugView m_TimerDebugView;
private TimerDebugInfo[] m_TimerInfos;
private Label m_SectionTitleLabel;
private Label m_ActiveCountLabel;
private Label m_PoolCapacityLabel;
private Label m_PeakCountLabel;
private Label m_FreeCountLabel;
private Label m_UsageLabel;
private Label m_WarningLabel;
private RowView m_EmptyRow;
private readonly RowView[] m_TimerRows = new RowView[MAX_DISPLAY_COUNT];
public override void Initialize(params object[] args)
{
m_TimerDebugView = AppServices.Require<ITimerService>() as ITimerServiceDebugView;
}
protected override void BuildWindow(VisualElement root)
{
if (m_TimerDebugView == null)
{
return;
}
root.Add(CreateActionButton("Refresh", RefreshContent, DebuggerTheme.ButtonSurfaceActive, DebuggerTheme.PrimaryText));
VisualElement overview = CreateSection("Timer Pool Overview", out VisualElement overviewCard);
m_ActiveCountLabel = AddTextRow(overviewCard, "Active Timer Count").Value;
m_PoolCapacityLabel = AddTextRow(overviewCard, "Pool Capacity").Value;
m_PeakCountLabel = AddTextRow(overviewCard, "Peak Active Count").Value;
m_FreeCountLabel = AddTextRow(overviewCard, "Free Count").Value;
m_UsageLabel = AddTextRow(overviewCard, "Pool Usage").Value;
root.Add(overview);
VisualElement section = CreateSection("Active Timers", out VisualElement timerCard);
m_SectionTitleLabel = section.ElementAt(0) as Label;
m_WarningLabel = new Label();
m_WarningLabel.style.color = new Color(1f, 0.5f, 0f);
m_WarningLabel.style.display = DisplayStyle.None;
m_WarningLabel.style.marginBottom = 4f;
timerCard.Add(m_WarningLabel);
m_EmptyRow = AddTextRow(timerCard, string.Empty);
m_EmptyRow.Root.style.display = DisplayStyle.None;
for (int i = 0; i < MAX_DISPLAY_COUNT; i++)
{
m_TimerRows[i] = AddTextRow(timerCard, string.Empty);
m_TimerRows[i].Root.style.display = DisplayStyle.None;
}
root.Add(section);
RefreshContent();
}
private void RefreshContent()
{
if (m_TimerDebugView == null)
{
return;
}
m_TimerDebugView.GetStatistics(out int activeCount, out int poolCapacity, out int peakActiveCount, out int freeCount);
float poolUsage = poolCapacity > 0 ? (float)activeCount / poolCapacity : 0f;
m_ActiveCountLabel.text = activeCount.ToString();
m_PoolCapacityLabel.text = poolCapacity.ToString();
m_PeakCountLabel.text = peakActiveCount.ToString();
m_FreeCountLabel.text = freeCount.ToString();
m_UsageLabel.text = Utility.Text.Format("{0:P1}", poolUsage);
if (activeCount <= 0)
{
m_SectionTitleLabel.text = "Active Timers";
m_WarningLabel.style.display = DisplayStyle.None;
m_EmptyRow.Root.style.display = DisplayStyle.Flex;
m_EmptyRow.Title.text = "Status";
m_EmptyRow.Value.text = "No active timers";
SetTimerRowsVisible(0);
return;
}
EnsureTimerInfoBuffer(activeCount);
int timerCount = m_TimerDebugView.GetAllTimers(m_TimerInfos);
int displayCount = timerCount > MAX_DISPLAY_COUNT ? MAX_DISPLAY_COUNT : timerCount;
m_SectionTitleLabel.text = Utility.Text.Format("Active Timers ({0})", timerCount);
m_EmptyRow.Root.style.display = DisplayStyle.None;
if (displayCount < timerCount)
{
m_WarningLabel.text = Utility.Text.Format("Showing first {0} timers of {1}.", displayCount, timerCount);
m_WarningLabel.style.display = DisplayStyle.Flex;
}
else
{
m_WarningLabel.style.display = DisplayStyle.None;
}
for (int i = 0; i < displayCount; i++)
{
ref RowView row = ref m_TimerRows[i];
TimerDebugInfo info = m_TimerInfos[i];
row.Title.text = Utility.Text.Format("Timer #{0}", info.TimerId);
row.Value.text = Utility.Text.Format(
"{0} | {1} | {2} | Remaining: {3:F2}s | Duration: {4:F2}s",
info.IsLoop ? "Loop" : "Once",
info.IsRunning ? "Running" : "Paused",
info.IsUnscaled ? "Unscaled" : "Scaled",
info.LeftTime,
info.Duration);
row.Root.style.display = DisplayStyle.Flex;
}
SetTimerRowsVisible(displayCount);
}
private void SetTimerRowsVisible(int visibleCount)
{
for (int i = 0; i < MAX_DISPLAY_COUNT; i++)
{
m_TimerRows[i].Root.style.display = i < visibleCount ? DisplayStyle.Flex : DisplayStyle.None;
}
}
private RowView AddTextRow(VisualElement parent, string title)
{
float scale = DebuggerComponent.Instance != null ? DebuggerComponent.Instance.GetUiScale() : 1f;
VisualElement row = new VisualElement();
row.style.flexDirection = FlexDirection.Row;
row.style.alignItems = Align.Center;
row.style.minHeight = 36f * scale;
row.style.marginBottom = 4f * scale;
Label titleLabel = new Label(title);
titleLabel.style.minWidth = 280f * scale;
titleLabel.style.maxWidth = 280f * scale;
titleLabel.style.color = DebuggerTheme.SecondaryText;
titleLabel.style.fontSize = 18f * scale;
titleLabel.style.unityFontStyleAndWeight = FontStyle.Bold;
titleLabel.style.flexShrink = 0f;
titleLabel.style.whiteSpace = WhiteSpace.Normal;
Label valueLabel = new Label();
valueLabel.style.flexGrow = 1f;
valueLabel.style.color = DebuggerTheme.PrimaryText;
valueLabel.style.fontSize = 18f * scale;
valueLabel.style.whiteSpace = WhiteSpace.Normal;
row.Add(titleLabel);
row.Add(valueLabel);
parent.Add(row);
RowView view;
view.Root = row;
view.Title = titleLabel;
view.Value = valueLabel;
return view;
}
private int EnsureTimerInfoBuffer(int count)
{
if (count <= 0)
{
if (m_TimerInfos == null || m_TimerInfos.Length == 0)
{
m_TimerInfos = new TimerDebugInfo[1];
}
return 0;
}
if (m_TimerInfos == null || m_TimerInfos.Length < count)
{
m_TimerInfos = new TimerDebugInfo[count];
}
return count;
}
}
}
}