Fix quadratic time behavior on exception

Previously, processing would abort before clearing AvatarTagComponents when an exception
is thrown. This would result in unprocessed AvatarTagComponents re-triggering processing
as part of their Awake callback, causing O(n^2) behavior.
This commit is contained in:
bd_ 2022-11-24 17:19:37 -08:00
parent 7ed1593bda
commit d2f8c22ac8

View File

@ -109,20 +109,27 @@ namespace nadena.dev.modular_avatar.core.editor
BoneDatabase.ResetBones();
PathMappings.Clear();
new RenameParametersHook().OnPreprocessAvatar(avatarGameObject);
new MenuInstallHook().OnPreprocessAvatar(avatarGameObject);
new MergeArmatureHook().OnPreprocessAvatar(avatarGameObject);
new RetargetMeshes().OnPreprocessAvatar(avatarGameObject);
new BoneProxyProcessor().OnPreprocessAvatar(avatarGameObject);
new VisibleHeadAccessoryProcessor(avatarGameObject.GetComponent<VRCAvatarDescriptor>()).Process();
new MergeAnimatorProcessor().OnPreprocessAvatar(avatarGameObject);
new BlendshapeSyncAnimationProcessor().OnPreprocessAvatar(avatarGameObject);
AfterProcessing?.Invoke(avatarGameObject);
foreach (var component in avatarGameObject.GetComponentsInChildren<AvatarTagComponent>(true))
try
{
UnityEngine.Object.DestroyImmediate(component);
new RenameParametersHook().OnPreprocessAvatar(avatarGameObject);
new MenuInstallHook().OnPreprocessAvatar(avatarGameObject);
new MergeArmatureHook().OnPreprocessAvatar(avatarGameObject);
new RetargetMeshes().OnPreprocessAvatar(avatarGameObject);
new BoneProxyProcessor().OnPreprocessAvatar(avatarGameObject);
new VisibleHeadAccessoryProcessor(avatarGameObject.GetComponent<VRCAvatarDescriptor>()).Process();
new MergeAnimatorProcessor().OnPreprocessAvatar(avatarGameObject);
new BlendshapeSyncAnimationProcessor().OnPreprocessAvatar(avatarGameObject);
AfterProcessing?.Invoke(avatarGameObject);
}
finally
{
// Ensure that we clean up AvatarTagComponents after failed processing. This ensures we don't re-enter
// processing from the Awake method on the unprocessed AvatarTagComponents
foreach (var component in avatarGameObject.GetComponentsInChildren<AvatarTagComponent>(true))
{
UnityEngine.Object.DestroyImmediate(component);
}
}
// The VRCSDK captures some debug information about animators as part of the build process, prior to invoking