2025-02-07 16:04:12 +08:00
using AlicizaX ;
using System ;
using System.Collections.Generic ;
using System.IO ;
using System.Text ;
using AlicizaX.Runtime ;
using UnityEditor ;
using UnityEngine ;
namespace AlicizaX.Editor
{
2025-03-20 20:47:11 +08:00
[CustomEditor(typeof(MemoryPoolSetting))]
internal sealed class MemoryPoolComponentInspector : GameFrameworkInspector
2025-02-07 16:04:12 +08:00
{
2025-03-20 20:47:11 +08:00
private readonly Dictionary < string , List < MemoryPoolInfo > > m_ReferencePoolInfos = new Dictionary < string , List < MemoryPoolInfo > > ( StringComparer . Ordinal ) ;
2025-02-07 16:04:12 +08:00
private readonly HashSet < string > m_OpenedItems = new HashSet < string > ( ) ;
private SerializedProperty m_EnableStrictCheck = null ;
private bool m_ShowFullClassName = false ;
public override void OnInspectorGUI ( )
{
base . OnInspectorGUI ( ) ;
serializedObject . Update ( ) ;
2025-03-20 20:47:11 +08:00
MemoryPoolSetting t = ( MemoryPoolSetting ) target ;
2025-02-07 16:04:12 +08:00
if ( EditorApplication . isPlaying & & IsPrefabInHierarchy ( t . gameObject ) )
{
bool enableStrictCheck = EditorGUILayout . Toggle ( "Enable Strict Check" , t . EnableStrictCheck ) ;
if ( enableStrictCheck ! = t . EnableStrictCheck )
{
t . EnableStrictCheck = enableStrictCheck ;
}
2025-03-20 20:47:11 +08:00
EditorGUILayout . LabelField ( "Reference Pool Count" , MemoryPool . Count . ToString ( ) ) ;
2025-02-07 16:04:12 +08:00
m_ShowFullClassName = EditorGUILayout . Toggle ( "Show Full Class Name" , m_ShowFullClassName ) ;
m_ReferencePoolInfos . Clear ( ) ;
2025-03-20 20:47:11 +08:00
MemoryPoolInfo [ ] referencePoolInfos = MemoryPool . GetAllMemoryPoolInfos ( ) ;
foreach ( MemoryPoolInfo referencePoolInfo in referencePoolInfos )
2025-02-07 16:04:12 +08:00
{
string assemblyName = referencePoolInfo . Type . Assembly . GetName ( ) . Name ;
2025-03-20 20:47:11 +08:00
List < MemoryPoolInfo > results = null ;
2025-02-07 16:04:12 +08:00
if ( ! m_ReferencePoolInfos . TryGetValue ( assemblyName , out results ) )
{
2025-03-20 20:47:11 +08:00
results = new List < MemoryPoolInfo > ( ) ;
2025-02-07 16:04:12 +08:00
m_ReferencePoolInfos . Add ( assemblyName , results ) ;
}
results . Add ( referencePoolInfo ) ;
}
2025-03-20 20:47:11 +08:00
foreach ( KeyValuePair < string , List < MemoryPoolInfo > > assemblyReferencePoolInfo in m_ReferencePoolInfos )
2025-02-07 16:04:12 +08:00
{
bool lastState = m_OpenedItems . Contains ( assemblyReferencePoolInfo . Key ) ;
bool currentState = EditorGUILayout . Foldout ( lastState , assemblyReferencePoolInfo . Key ) ;
if ( currentState ! = lastState )
{
if ( currentState )
{
m_OpenedItems . Add ( assemblyReferencePoolInfo . Key ) ;
}
else
{
m_OpenedItems . Remove ( assemblyReferencePoolInfo . Key ) ;
}
}
if ( currentState )
{
EditorGUILayout . BeginVertical ( "box" ) ;
{
var label = "Unused\tUsing.\tAcquire\tRelease\tAdd\tRemove" ;
EditorGUILayout . LabelField ( m_ShowFullClassName ? "Full Class Name" : "Class Name" , label ) ;
assemblyReferencePoolInfo . Value . Sort ( Comparison ) ;
2025-03-20 20:47:11 +08:00
foreach ( MemoryPoolInfo referencePoolInfo in assemblyReferencePoolInfo . Value )
2025-02-07 16:04:12 +08:00
{
DrawReferencePoolInfo ( referencePoolInfo ) ;
}
if ( GUILayout . Button ( "Export CSV Data" ) )
{
string exportFileName = EditorUtility . SaveFilePanel ( "Export CSV Data" , string . Empty , Utility . Text . Format ( "Reference Pool Data - {0}.csv" , assemblyReferencePoolInfo . Key ) , string . Empty ) ;
if ( ! string . IsNullOrEmpty ( exportFileName ) )
{
try
{
int index = 0 ;
string [ ] data = new string [ assemblyReferencePoolInfo . Value . Count + 1 ] ;
data [ index + + ] = "Class Name,Full Class Name,Unused,Using,Acquire,Release,Add,Remove" ;
2025-03-20 20:47:11 +08:00
foreach ( MemoryPoolInfo referencePoolInfo in assemblyReferencePoolInfo . Value )
2025-02-07 16:04:12 +08:00
{
2025-03-20 20:47:11 +08:00
data [ index + + ] = Utility . Text . Format ( "{0},{1},{2},{3},{4},{5},{6},{7}" , referencePoolInfo . Type . Name , referencePoolInfo . Type . FullName , referencePoolInfo . UnusedMemoryCount , referencePoolInfo . UsingMemoryCount , referencePoolInfo . AcquireMemoryCount , referencePoolInfo . ReleaseMemoryCount , referencePoolInfo . AddMemoryCount , referencePoolInfo . RemoveMemoryCount ) ;
2025-02-07 16:04:12 +08:00
}
File . WriteAllLines ( exportFileName , data , Encoding . UTF8 ) ;
Debug . Log ( Utility . Text . Format ( "Export reference pool CSV data to '{0}' success." , exportFileName ) ) ;
}
catch ( Exception exception )
{
Debug . LogError ( Utility . Text . Format ( "Export reference pool CSV data to '{0}' failure, exception is '{1}'." , exportFileName , exception ) ) ;
}
}
}
}
EditorGUILayout . EndVertical ( ) ;
EditorGUILayout . Separator ( ) ;
}
}
}
else
{
EditorGUILayout . PropertyField ( m_EnableStrictCheck ) ;
}
serializedObject . ApplyModifiedProperties ( ) ;
Repaint ( ) ;
}
private void OnEnable ( )
{
m_EnableStrictCheck = serializedObject . FindProperty ( "m_EnableStrictCheck" ) ;
}
2025-03-20 20:47:11 +08:00
private void DrawReferencePoolInfo ( MemoryPoolInfo referencePoolInfo )
2025-02-07 16:04:12 +08:00
{
#if UNITY_6000_0_OR_NEWER
2025-03-20 20:47:11 +08:00
EditorGUILayout . LabelField ( m_ShowFullClassName ? referencePoolInfo . Type . FullName : referencePoolInfo . Type . Name , Utility . Text . Format ( "{0,-12}\t{1,-12}\t{2,-12}\t{3,-12}\t{4}\t{5}" , referencePoolInfo . UnusedMemoryCount , referencePoolInfo . UsingMemoryCount , referencePoolInfo . AcquireMemoryCount , referencePoolInfo . ReleaseMemoryCount , referencePoolInfo . AddMemoryCount , referencePoolInfo . RemoveMemoryCount ) ) ;
2025-02-07 16:04:12 +08:00
#else
2025-03-20 20:47:11 +08:00
EditorGUILayout . LabelField ( m_ShowFullClassName ? referencePoolInfo . Type . FullName :
referencePoolInfo . Type . Name , Utility . Text . Format ( "{0}\t{1}\t{2}\t{3}\t{4}\t{5}" , referencePoolInfo . UnusedMemoryCount , referencePoolInfo . UsingMemoryCount , referencePoolInfo . AcquireMemoryCount , referencePoolInfo . ReleaseMemoryCount , referencePoolInfo . AddMemoryCount , referencePoolInfo . RemoveMemoryCount ) ) ;
2025-02-07 16:04:12 +08:00
#endif
}
2025-03-20 20:47:11 +08:00
private int Comparison ( MemoryPoolInfo a , MemoryPoolInfo b )
2025-02-07 16:04:12 +08:00
{
if ( m_ShowFullClassName )
{
return a . Type . FullName . CompareTo ( b . Type . FullName ) ;
}
else
{
return a . Type . Name . CompareTo ( b . Type . Name ) ;
}
}
}
}