201 lines
8.1 KiB
C#
201 lines
8.1 KiB
C#
|
|
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;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|