181 lines
7.9 KiB
C#
181 lines
7.9 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using UnityEditor;
|
|
using UnityEngine;
|
|
|
|
namespace AlicizaX
|
|
{
|
|
[CustomEditor(typeof(GameObjectPoolManager))]
|
|
public sealed class GameObjectPoolEditor : UnityEditor.Editor
|
|
{
|
|
private readonly Dictionary<string, bool> _foldoutState = new Dictionary<string, bool>(StringComparer.Ordinal);
|
|
|
|
public override void OnInspectorGUI()
|
|
{
|
|
serializedObject.Update();
|
|
DrawDefaultInspector();
|
|
serializedObject.ApplyModifiedProperties();
|
|
|
|
var poolManager = (GameObjectPoolManager)target;
|
|
if (!Application.isPlaying)
|
|
{
|
|
EditorGUILayout.HelpBox("Enter Play Mode to inspect the runtime pool.", MessageType.Info);
|
|
return;
|
|
}
|
|
|
|
if (!poolManager.showDetailedInfo)
|
|
{
|
|
return;
|
|
}
|
|
|
|
EditorGUILayout.Space();
|
|
DrawRuntimeState(poolManager);
|
|
}
|
|
|
|
public override bool RequiresConstantRepaint()
|
|
{
|
|
var poolManager = target as GameObjectPoolManager;
|
|
return poolManager != null && Application.isPlaying && poolManager.showDetailedInfo;
|
|
}
|
|
|
|
private void DrawRuntimeState(GameObjectPoolManager poolManager)
|
|
{
|
|
GameObjectPoolSummarySnapshot summary = poolManager.GetDebugSummary();
|
|
DrawSummary(summary);
|
|
|
|
if (summary.WaitingForBootstrap)
|
|
{
|
|
EditorGUILayout.HelpBox("Waiting for YooAssets bootstrap before pool catalog build.", MessageType.Info);
|
|
return;
|
|
}
|
|
|
|
if (!summary.IsReady)
|
|
{
|
|
EditorGUILayout.HelpBox("Pool manager is not ready.", MessageType.Warning);
|
|
return;
|
|
}
|
|
|
|
List<GameObjectPoolSnapshot> snapshots = poolManager.GetDebugSnapshots();
|
|
if (snapshots.Count == 0)
|
|
{
|
|
EditorGUILayout.HelpBox("No pooled runtime instances exist yet.", MessageType.Info);
|
|
return;
|
|
}
|
|
|
|
for (int i = 0; i < snapshots.Count; i++)
|
|
{
|
|
DrawSnapshot(snapshots[i]);
|
|
}
|
|
}
|
|
|
|
private static void DrawSummary(in GameObjectPoolSummarySnapshot summary)
|
|
{
|
|
EditorGUILayout.BeginVertical("box");
|
|
EditorGUILayout.LabelField("Runtime Summary", EditorStyles.boldLabel);
|
|
EditorGUILayout.LabelField("Ready", summary.IsReady ? "Yes" : "No");
|
|
EditorGUILayout.LabelField("Waiting Bootstrap", summary.WaitingForBootstrap ? "Yes" : "No");
|
|
EditorGUILayout.LabelField("Pools", summary.PoolCount.ToString());
|
|
EditorGUILayout.LabelField("Loaded Prefabs", summary.LoadedPrefabCount.ToString());
|
|
EditorGUILayout.LabelField("Instances", summary.TotalInstanceCount.ToString());
|
|
EditorGUILayout.LabelField("Active", summary.ActiveInstanceCount.ToString());
|
|
EditorGUILayout.LabelField("Inactive", summary.InactiveInstanceCount.ToString());
|
|
EditorGUILayout.LabelField("Pending Maintenance", summary.PendingMaintenanceCount.ToString());
|
|
EditorGUILayout.EndVertical();
|
|
EditorGUILayout.Space();
|
|
}
|
|
|
|
private void DrawSnapshot(GameObjectPoolSnapshot snapshot)
|
|
{
|
|
if (snapshot == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
string entryLabel = string.IsNullOrWhiteSpace(snapshot.entryName) ? snapshot.assetPath : snapshot.entryName;
|
|
string foldoutKey = string.Concat(entryLabel, "|", snapshot.assetPath);
|
|
if (!_foldoutState.ContainsKey(foldoutKey))
|
|
{
|
|
_foldoutState[foldoutKey] = false;
|
|
}
|
|
|
|
string foldoutLabel = string.Format(
|
|
"{0} [{1}/{2}] Hit:{3}/{4}",
|
|
entryLabel,
|
|
snapshot.activeCount,
|
|
snapshot.totalCount,
|
|
snapshot.hitCount,
|
|
snapshot.acquireCount);
|
|
|
|
EditorGUILayout.BeginVertical("box");
|
|
_foldoutState[foldoutKey] = EditorGUILayout.Foldout(_foldoutState[foldoutKey], foldoutLabel, true);
|
|
if (_foldoutState[foldoutKey])
|
|
{
|
|
EditorGUILayout.LabelField("Rule", entryLabel);
|
|
EditorGUILayout.LabelField("Asset Path", snapshot.assetPath);
|
|
EditorGUILayout.LabelField("Loader", snapshot.loaderType.ToString());
|
|
EditorGUILayout.LabelField("Retain Target", snapshot.retainTarget.ToString());
|
|
EditorGUILayout.LabelField("Soft Capacity", snapshot.softCapacity.ToString());
|
|
EditorGUILayout.LabelField("Capacity", snapshot.hardCapacity.ToString());
|
|
EditorGUILayout.LabelField("Runtime Capacity", snapshot.runtimeHardCapacity.ToString());
|
|
EditorGUILayout.LabelField("Inactive", snapshot.inactiveCount.ToString());
|
|
EditorGUILayout.LabelField("Prefab Loaded", snapshot.prefabLoaded ? "Yes" : "No");
|
|
EditorGUILayout.LabelField("Prefab Cold", FormatSeconds(snapshot.prefabIdleDuration));
|
|
EditorGUILayout.LabelField("Wake Count", snapshot.prefabWakeCount.ToString());
|
|
EditorGUILayout.LabelField("Wake Gap", snapshot.prefabWakeGap < 0f ? "N/A" : FormatSeconds(snapshot.prefabWakeGap));
|
|
EditorGUILayout.LabelField("Unload Delay", snapshot.prefabUnloadDelay < 0f ? "N/A" : FormatSeconds(snapshot.prefabUnloadDelay));
|
|
EditorGUILayout.LabelField("Next Maintenance", snapshot.nextMaintenanceIn < 0f ? "None" : FormatSeconds(snapshot.nextMaintenanceIn));
|
|
EditorGUILayout.Space();
|
|
EditorGUILayout.LabelField("Acquire", snapshot.acquireCount.ToString());
|
|
EditorGUILayout.LabelField("Release", snapshot.releaseCount.ToString());
|
|
EditorGUILayout.LabelField("Hit", snapshot.hitCount.ToString());
|
|
EditorGUILayout.LabelField("Miss", snapshot.missCount.ToString());
|
|
EditorGUILayout.LabelField("Expand", snapshot.expandCount.ToString());
|
|
EditorGUILayout.LabelField("Destroy", snapshot.destroyCount.ToString());
|
|
EditorGUILayout.LabelField("Peak Active", snapshot.peakActive.ToString());
|
|
EditorGUILayout.LabelField("Peak Active Short", snapshot.peakActiveShort.ToString());
|
|
EditorGUILayout.LabelField("Peak Active Long", snapshot.peakActiveLong.ToString());
|
|
|
|
if (snapshot.instances.Count > 0)
|
|
{
|
|
EditorGUILayout.Space();
|
|
EditorGUILayout.LabelField("Instances", EditorStyles.boldLabel);
|
|
for (int i = 0; i < snapshot.instances.Count; i++)
|
|
{
|
|
DrawInstance(snapshot.instances[i]);
|
|
}
|
|
}
|
|
}
|
|
|
|
EditorGUILayout.EndVertical();
|
|
EditorGUILayout.Space();
|
|
}
|
|
|
|
private static void DrawInstance(GameObjectPoolInstanceSnapshot snapshot)
|
|
{
|
|
if (snapshot == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
EditorGUILayout.BeginHorizontal("box");
|
|
EditorGUILayout.BeginVertical();
|
|
EditorGUILayout.LabelField(snapshot.instanceName, EditorStyles.boldLabel);
|
|
EditorGUILayout.LabelField("State", snapshot.isActive ? "Active" : "Inactive");
|
|
EditorGUILayout.LabelField("Life", FormatSeconds(snapshot.lifeDuration));
|
|
if (!snapshot.isActive)
|
|
{
|
|
EditorGUILayout.LabelField("Idle", FormatSeconds(snapshot.idleDuration));
|
|
}
|
|
|
|
EditorGUILayout.EndVertical();
|
|
EditorGUILayout.ObjectField(snapshot.gameObject, typeof(GameObject), true, GUILayout.Width(140f));
|
|
EditorGUILayout.EndHorizontal();
|
|
}
|
|
|
|
private static string FormatSeconds(float seconds)
|
|
{
|
|
return seconds.ToString("F2") + "s";
|
|
}
|
|
}
|
|
}
|