Merge pull request #7 from mackysoft/fix/subclassselector-drawing-overhead

Improve `SubclassSelectorDrawer` performance
This commit is contained in:
Makihiro 2022-03-28 23:06:54 +09:00 committed by GitHub
commit 55a071abe9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 51 additions and 34 deletions

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup> <PropertyGroup>
<LangVersion>8.0</LangVersion> <LangVersion>latest</LangVersion>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@ -52,11 +52,9 @@
<UnityBuildTarget>StandaloneWindows:5</UnityBuildTarget> <UnityBuildTarget>StandaloneWindows:5</UnityBuildTarget>
<UnityVersion>2020.3.24f1</UnityVersion> <UnityVersion>2020.3.24f1</UnityVersion>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<Analyzer Include="C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE\Extensions\Microsoft\Visual Studio Tools for Unity\Analyzers\Microsoft.Unity.Analyzers.dll" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="Assets\PackageTools\Editor\UnityPackageExporter.cs" /> <Compile Include="Assets\PackageTools\Editor\UnityPackageExporter.cs" />
<Compile Include="Assets\MackySoft\MackySoft.SerializeReferenceExtensions\Example\ExampleAssets\Scripts\Editor\ExampleEditor.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Reference Include="UnityEngine"> <Reference Include="UnityEngine">

View File

@ -6,36 +6,18 @@ using UnityEditor;
namespace MackySoft.SerializeReferenceExtensions.Editor { namespace MackySoft.SerializeReferenceExtensions.Editor {
public static class ManagedReferenceUtility { public static class ManagedReferenceUtility {
public static Type GetManagedReferenceFieldType (this SerializedProperty property) {
if (property.propertyType != SerializedPropertyType.ManagedReference) {
throw SerializedPropertyTypeMustBeManagedReference(nameof(property));
}
return GetType(property.managedReferenceFieldTypename);
}
public static Type GetManagedReferenceType (this SerializedProperty property) {
if (property.propertyType != SerializedPropertyType.ManagedReference) {
throw SerializedPropertyTypeMustBeManagedReference(nameof(property));
}
return GetType(property.managedReferenceFullTypename);
}
public static object SetManagedReference (this SerializedProperty property,Type type) { public static object SetManagedReference (this SerializedProperty property,Type type) {
object obj = (type != null) ? Activator.CreateInstance(type) : null; object obj = (type != null) ? Activator.CreateInstance(type) : null;
property.managedReferenceValue = obj; property.managedReferenceValue = obj;
return obj; return obj;
} }
static Type GetType (string typeName) { public static Type GetType (string typeName) {
int splitIndex = typeName.IndexOf(' '); int splitIndex = typeName.IndexOf(' ');
var assembly = Assembly.Load(typeName.Substring(0,splitIndex)); var assembly = Assembly.Load(typeName.Substring(0,splitIndex));
return assembly.GetType(typeName.Substring(splitIndex + 1)); return assembly.GetType(typeName.Substring(splitIndex + 1));
} }
static ArgumentException SerializedPropertyTypeMustBeManagedReference (string paramName) {
return new ArgumentException("The serialized property type must be SerializedPropertyType.ManagedReference.",paramName);
}
} }
} }
#endif #endif

View File

@ -29,13 +29,11 @@ namespace MackySoft.SerializeReferenceExtensions.Editor {
readonly Dictionary<string,GUIContent> m_TypeNameCaches = new Dictionary<string,GUIContent>(); readonly Dictionary<string,GUIContent> m_TypeNameCaches = new Dictionary<string,GUIContent>();
SerializedProperty m_TargetProperty; SerializedProperty m_TargetProperty;
public override void OnGUI (Rect position,SerializedProperty property,GUIContent label) { public override void OnGUI (Rect position,SerializedProperty property,GUIContent label) {
EditorGUI.BeginProperty(position,label,property); EditorGUI.BeginProperty(position,label,property);
if (property.propertyType == SerializedPropertyType.ManagedReference) { if (property.propertyType == SerializedPropertyType.ManagedReference) {
TypePopupCache popup = GetTypePopup(property);
// Draw the subclass selector popup. // Draw the subclass selector popup.
Rect popupPosition = new Rect(position); Rect popupPosition = new Rect(position);
popupPosition.width -= EditorGUIUtility.labelWidth; popupPosition.width -= EditorGUIUtility.labelWidth;
@ -43,6 +41,7 @@ namespace MackySoft.SerializeReferenceExtensions.Editor {
popupPosition.height = EditorGUIUtility.singleLineHeight; popupPosition.height = EditorGUIUtility.singleLineHeight;
if (EditorGUI.DropdownButton(popupPosition,GetTypeName(property),FocusType.Keyboard)) { if (EditorGUI.DropdownButton(popupPosition,GetTypeName(property),FocusType.Keyboard)) {
TypePopupCache popup = GetTypePopup(property);
m_TargetProperty = property; m_TargetProperty = property;
popup.TypePopup.Show(popupPosition); popup.TypePopup.Show(popupPosition);
} }
@ -57,10 +56,13 @@ namespace MackySoft.SerializeReferenceExtensions.Editor {
} }
TypePopupCache GetTypePopup (SerializedProperty property) { TypePopupCache GetTypePopup (SerializedProperty property) {
if (!m_TypePopups.TryGetValue(property.managedReferenceFieldTypename,out TypePopupCache result)) { // Cache this string. This property internally call Assembly.GetName, which result in a large allocation.
var state = new AdvancedDropdownState(); string managedReferenceFieldTypename = property.managedReferenceFieldTypename;
Type baseType = property.GetManagedReferenceFieldType(); if (!m_TypePopups.TryGetValue(managedReferenceFieldTypename,out TypePopupCache result)) {
var state = new AdvancedDropdownState();
Type baseType = ManagedReferenceUtility.GetType(managedReferenceFieldTypename);
var popup = new AdvancedTypePopup( var popup = new AdvancedTypePopup(
TypeCache.GetTypesDerivedFrom(baseType).Where(p => TypeCache.GetTypesDerivedFrom(baseType).Where(p =>
(p.IsPublic || p.IsNestedPublic) && (p.IsPublic || p.IsNestedPublic) &&
@ -79,20 +81,23 @@ namespace MackySoft.SerializeReferenceExtensions.Editor {
m_TargetProperty.serializedObject.ApplyModifiedProperties(); m_TargetProperty.serializedObject.ApplyModifiedProperties();
}; };
m_TypePopups.Add(property.managedReferenceFieldTypename,new TypePopupCache(popup,state)); m_TypePopups.Add(managedReferenceFieldTypename,new TypePopupCache(popup,state));
} }
return result; return result;
} }
GUIContent GetTypeName (SerializedProperty property) { GUIContent GetTypeName (SerializedProperty property) {
if (string.IsNullOrEmpty(property.managedReferenceFullTypename)) { // Cache this string.
string managedReferenceFullTypename = property.managedReferenceFullTypename;
if (string.IsNullOrEmpty(managedReferenceFullTypename)) {
return k_NullDisplayName; return k_NullDisplayName;
} }
if (m_TypeNameCaches.TryGetValue(property.managedReferenceFullTypename,out GUIContent cachedTypeName)) { if (m_TypeNameCaches.TryGetValue(managedReferenceFullTypename,out GUIContent cachedTypeName)) {
return cachedTypeName; return cachedTypeName;
} }
Type type = property.GetManagedReferenceType(); Type type = ManagedReferenceUtility.GetType(managedReferenceFullTypename);
string typeName = null; string typeName = null;
AddTypeMenuAttribute typeMenu = TypeMenuUtility.GetAttribute(type); AddTypeMenuAttribute typeMenu = TypeMenuUtility.GetAttribute(type);
@ -108,7 +113,7 @@ namespace MackySoft.SerializeReferenceExtensions.Editor {
} }
GUIContent result = new GUIContent(typeName); GUIContent result = new GUIContent(typeName);
m_TypeNameCaches.Add(property.managedReferenceFullTypename,result); m_TypeNameCaches.Add(managedReferenceFullTypename,result);
return result; return result;
} }

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 9a6c0659b60e6c44f998f2d392bb5af6
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,13 @@
using UnityEditor;
namespace MackySoft.SerializeReferenceExtensions.Example.Editor {
// Enabling the custom editor slowdown rendering performance.
//[CustomEditor(typeof(Example))]
public class ExampleEditor : UnityEditor.Editor {
public override void OnInspectorGUI () {
base.OnInspectorGUI();
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: cfc194a2f8ebd084b9a5e0be5ec30589
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: