Skip to content

Commit

Permalink
refactor: add ObjectReferenceProperties to utils and use it
Browse files Browse the repository at this point in the history
  • Loading branch information
anatawa12 committed Sep 28, 2023
1 parent 1126f84 commit a973168
Show file tree
Hide file tree
Showing 6 changed files with 128 additions and 170 deletions.
90 changes: 19 additions & 71 deletions Editor/Processors/ApplyObjectMapping.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,65 +24,26 @@ protected override void Execute(BuildContext context)
var serialized = new SerializedObject(component);
AnimatorControllerMapper mapper = null;
SpecialMappingApplier.Apply(component.GetType(), serialized, mapping, ref mapper);
var p = serialized.GetIterator();
var enterChildren = true;
while (p.Next(enterChildren))
{
if (p.propertyType == SerializedPropertyType.ObjectReference)
{
if (mapping.MapComponentInstance(p.objectReferenceInstanceIDValue, out var mappedComponent))
p.objectReferenceValue = mappedComponent;

if (p.objectReferenceValue is AnimatorController controller)
{
if (mapper == null)
mapper = new AnimatorControllerMapper(mapping.CreateAnimationMapper(component.gameObject));

// ReSharper disable once AccessToModifiedClosure
var mapped = BuildReport.ReportingObject(controller,
() => mapper.MapAnimatorController(controller));
if (mapped != null)
p.objectReferenceValue = mapped;
}
}
foreach (var p in serialized.ObjectReferenceProperties())
{
if (mapping.MapComponentInstance(p.objectReferenceInstanceIDValue, out var mappedComponent))
p.objectReferenceValue = mappedComponent;

switch (p.propertyType)
if (p.objectReferenceValue is AnimatorController controller)
{
case SerializedPropertyType.String:
case SerializedPropertyType.Integer:
case SerializedPropertyType.Boolean:
case SerializedPropertyType.Float:
case SerializedPropertyType.Color:
case SerializedPropertyType.ObjectReference:
case SerializedPropertyType.LayerMask:
case SerializedPropertyType.Enum:
case SerializedPropertyType.Vector2:
case SerializedPropertyType.Vector3:
case SerializedPropertyType.Vector4:
case SerializedPropertyType.Rect:
case SerializedPropertyType.ArraySize:
case SerializedPropertyType.Character:
case SerializedPropertyType.AnimationCurve:
case SerializedPropertyType.Bounds:
case SerializedPropertyType.Gradient:
case SerializedPropertyType.Quaternion:
case SerializedPropertyType.FixedBufferSize:
case SerializedPropertyType.Vector2Int:
case SerializedPropertyType.Vector3Int:
case SerializedPropertyType.RectInt:
case SerializedPropertyType.BoundsInt:
enterChildren = false;
break;
case SerializedPropertyType.Generic:
case SerializedPropertyType.ExposedReference:
case SerializedPropertyType.ManagedReference:
default:
enterChildren = true;
break;
if (mapper == null)
mapper = new AnimatorControllerMapper(mapping.CreateAnimationMapper(component.gameObject));

// ReSharper disable once AccessToModifiedClosure
var mapped = BuildReport.ReportingObject(controller,
() => mapper.MapAnimatorController(controller));
if (mapped != null)
p.objectReferenceValue = mapped;
}
}

serialized.ApplyModifiedProperties();
serialized.ApplyModifiedPropertiesWithoutUndo();
});
}
}
Expand Down Expand Up @@ -295,26 +256,13 @@ private T DeepClone<T>(T original, Func<Object, Object> visitor) where T : Objec

_cache[original] = obj;

SerializedObject so = new SerializedObject(obj);
SerializedProperty prop = so.GetIterator();

bool enterChildren = true;
while (prop.Next(enterChildren))
using (var so = new SerializedObject(obj))
{
enterChildren = true;
switch (prop.propertyType)
{
case SerializedPropertyType.ObjectReference:
prop.objectReferenceValue = DeepClone(prop.objectReferenceValue, visitor);
break;
// Iterating strings can get super slow...
case SerializedPropertyType.String:
enterChildren = false;
break;
}
}
foreach (var prop in so.ObjectReferenceProperties())
prop.objectReferenceValue = DeepClone(prop.objectReferenceValue, visitor);

so.ApplyModifiedPropertiesWithoutUndo();
so.ApplyModifiedPropertiesWithoutUndo();
}

return (T)obj;
}
Expand Down
17 changes: 7 additions & 10 deletions Editor/Processors/SkinnedMeshes/MergeSkinnedMeshProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -228,20 +228,17 @@ private bool CheckAnimateSubMeshIndex(OptimizerSession session, MeshInfo2[] mesh
{
if (component is Transform) continue;

var serialized = new SerializedObject(component);
var prop = serialized.GetIterator();
var enterChildren = true;
while (prop.Next(enterChildren))
using (var serialized = new SerializedObject(component))
{
enterChildren = prop.propertyType == SerializedPropertyType.Generic;

if (prop.propertyType == SerializedPropertyType.ObjectReference &&
prop.objectReferenceValue is AnimatorController controller &&
controller.animationClips
foreach (var prop in serialized.ObjectReferenceProperties())
{
if (!(prop.objectReferenceValue is AnimatorController controller)) continue;
if (controller.animationClips
.SelectMany(x => AnimationUtility.GetObjectReferenceCurveBindings(x))
.Select(x => (AnimationUtility.GetAnimatedObject(component.gameObject, x), x.propertyName))
.Any(targetProperties.Contains))
return true;
return true;
}
}
}
return false;
Expand Down
50 changes: 5 additions & 45 deletions Editor/Processors/TraceAndOptimize/ComponentDependencyCollector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -136,52 +136,12 @@ private void FallbackDependenciesParser(Component component)
dependencies.EntrypointComponent = true;
using (var serialized = new SerializedObject(component))
{
var iterator = serialized.GetIterator();
var enterChildren = true;
while (iterator.Next(enterChildren))
foreach (var property in serialized.ObjectReferenceProperties())
{
if (iterator.propertyType == SerializedPropertyType.ObjectReference)
{
if (iterator.objectReferenceValue is GameObject go)
dependencies.AddAlwaysDependency(go.transform);
else if (iterator.objectReferenceValue is Component com)
dependencies.AddAlwaysDependency(com);
}

switch (iterator.propertyType)
{
case SerializedPropertyType.String:
case SerializedPropertyType.Integer:
case SerializedPropertyType.Boolean:
case SerializedPropertyType.Float:
case SerializedPropertyType.Color:
case SerializedPropertyType.ObjectReference:
case SerializedPropertyType.LayerMask:
case SerializedPropertyType.Enum:
case SerializedPropertyType.Vector2:
case SerializedPropertyType.Vector3:
case SerializedPropertyType.Vector4:
case SerializedPropertyType.Rect:
case SerializedPropertyType.ArraySize:
case SerializedPropertyType.Character:
case SerializedPropertyType.AnimationCurve:
case SerializedPropertyType.Bounds:
case SerializedPropertyType.Gradient:
case SerializedPropertyType.Quaternion:
case SerializedPropertyType.FixedBufferSize:
case SerializedPropertyType.Vector2Int:
case SerializedPropertyType.Vector3Int:
case SerializedPropertyType.RectInt:
case SerializedPropertyType.BoundsInt:
enterChildren = false;
break;
case SerializedPropertyType.Generic:
case SerializedPropertyType.ExposedReference:
case SerializedPropertyType.ManagedReference:
default:
enterChildren = true;
break;
}
if (property.objectReferenceValue is GameObject go)
dependencies.AddAlwaysDependency(go.transform);
else if (property.objectReferenceValue is Component com)
dependencies.AddAlwaysDependency(com);
}
}
}
Expand Down
48 changes: 4 additions & 44 deletions Editor/Processors/TraceAndOptimize/FindUnusedObjectsProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -458,51 +458,11 @@ void AddGameObject(GameObject gameObject)

using (var serialized = new SerializedObject(component))
{
var iter = serialized.GetIterator();
var enterChildren = true;
while (iter.Next(enterChildren))
foreach (var iter in serialized.ObjectReferenceProperties())
{
if (iter.propertyType == SerializedPropertyType.ObjectReference)
{
var value = iter.objectReferenceValue;
if (value is Component c && !EditorUtility.IsPersistent(value))
AddGameObject(c.gameObject);
}

switch (iter.propertyType)
{
case SerializedPropertyType.Integer:
case SerializedPropertyType.Boolean:
case SerializedPropertyType.Float:
case SerializedPropertyType.String:
case SerializedPropertyType.Color:
case SerializedPropertyType.ObjectReference:
case SerializedPropertyType.Enum:
case SerializedPropertyType.Vector2:
case SerializedPropertyType.Vector3:
case SerializedPropertyType.Vector4:
case SerializedPropertyType.Rect:
case SerializedPropertyType.ArraySize:
case SerializedPropertyType.Character:
case SerializedPropertyType.Bounds:
case SerializedPropertyType.Quaternion:
case SerializedPropertyType.FixedBufferSize:
case SerializedPropertyType.Vector2Int:
case SerializedPropertyType.Vector3Int:
case SerializedPropertyType.RectInt:
case SerializedPropertyType.BoundsInt:
enterChildren = false;
break;
case SerializedPropertyType.Generic:
case SerializedPropertyType.LayerMask:
case SerializedPropertyType.AnimationCurve:
case SerializedPropertyType.Gradient:
case SerializedPropertyType.ExposedReference:
case SerializedPropertyType.ManagedReference:
default:
enterChildren = true;
break;
}
var value = iter.objectReferenceValue;
if (value is Component c && !EditorUtility.IsPersistent(value))
AddGameObject(c.gameObject);
}
}
}
Expand Down
90 changes: 90 additions & 0 deletions Editor/Utils/Utils.ObjectReferencePropertiesEnumerable.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
using System.Collections;
using System.Collections.Generic;
using UnityEditor;

namespace Anatawa12.AvatarOptimizer
{
internal partial class Utils
{
public static ObjectReferencePropertiesEnumerable ObjectReferenceProperties(this SerializedObject obj)
=> new ObjectReferencePropertiesEnumerable(obj);

public readonly struct ObjectReferencePropertiesEnumerable : IEnumerable<SerializedProperty>
{
private readonly SerializedObject _obj;

public ObjectReferencePropertiesEnumerable(SerializedObject obj) => _obj = obj;

public Enumerator GetEnumerator() => new Enumerator(_obj);
IEnumerator<SerializedProperty> IEnumerable<SerializedProperty>.GetEnumerator() => GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();

public struct Enumerator : IEnumerator<SerializedProperty>
{
private readonly SerializedProperty _iterator;

public Enumerator(SerializedObject obj) => _iterator = obj.GetIterator();

public bool MoveNext()
{
while (true)
{
bool enterChildren;
switch (_iterator.propertyType)
{
case SerializedPropertyType.String:
case SerializedPropertyType.Integer:
case SerializedPropertyType.Boolean:
case SerializedPropertyType.Float:
case SerializedPropertyType.Color:
case SerializedPropertyType.ObjectReference:
case SerializedPropertyType.LayerMask:
case SerializedPropertyType.Enum:
case SerializedPropertyType.Vector2:
case SerializedPropertyType.Vector3:
case SerializedPropertyType.Vector4:
case SerializedPropertyType.Rect:
case SerializedPropertyType.ArraySize:
case SerializedPropertyType.Character:
case SerializedPropertyType.AnimationCurve:
case SerializedPropertyType.Bounds:
case SerializedPropertyType.Gradient:
case SerializedPropertyType.Quaternion:
case SerializedPropertyType.FixedBufferSize:
case SerializedPropertyType.Vector2Int:
case SerializedPropertyType.Vector3Int:
case SerializedPropertyType.RectInt:
case SerializedPropertyType.BoundsInt:
enterChildren = false;
break;
case SerializedPropertyType.Generic:
case SerializedPropertyType.ExposedReference:
case SerializedPropertyType.ManagedReference:
default:
enterChildren = true;
break;
}

if (!_iterator.Next(enterChildren)) return false;
if (_iterator.propertyType == SerializedPropertyType.ObjectReference)
return true;
}
}

public void Reset()
{
var obj = _iterator.serializedObject;
Dispose();
this = new Enumerator(obj);
}

public SerializedProperty Current => _iterator;
object IEnumerator.Current => Current;

public void Dispose()
{
}
}
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit a973168

Please sign in to comment.