mirror of
https://github.com/bdunderscore/modular-avatar.git
synced 2025-01-31 02:32:53 +08:00
fix: performance issues with MAMenuItem (#1170)
Cache parameter introspection results (using PropCache) to avoid excessive recomputation. Closes: #1165
This commit is contained in:
parent
c2b6766a40
commit
a98ef213ff
@ -2,10 +2,12 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.Immutable;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Runtime.Serialization;
|
using System.Runtime.Serialization;
|
||||||
using nadena.dev.modular_avatar.core.menu;
|
using nadena.dev.modular_avatar.core.menu;
|
||||||
using nadena.dev.ndmf;
|
using nadena.dev.ndmf;
|
||||||
|
using nadena.dev.ndmf.preview;
|
||||||
using UnityEditor;
|
using UnityEditor;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using VRC.SDK3.Avatars.Components;
|
using VRC.SDK3.Avatars.Components;
|
||||||
@ -21,6 +23,39 @@ namespace nadena.dev.modular_avatar.core.editor
|
|||||||
protected override string localizationPrefix => "submenu_source";
|
protected override string localizationPrefix => "submenu_source";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal static class ParameterIntrospectionCache
|
||||||
|
{
|
||||||
|
internal static PropCache<GameObject, ImmutableList<ProvidedParameter>> ProvidedParameterCache = new (GetParametersForObject_miss);
|
||||||
|
|
||||||
|
internal static PropCache<GameObject, ImmutableDictionary<(ParameterNamespace, string), ParameterMapping>>
|
||||||
|
ParameterRemappingCache = new(GetParameterRemappingsAt_miss);
|
||||||
|
|
||||||
|
private static ImmutableList<ProvidedParameter> GetParametersForObject_miss(ComputeContext ctx, GameObject obj)
|
||||||
|
{
|
||||||
|
if (obj == null) return ImmutableList<ProvidedParameter>.Empty;
|
||||||
|
|
||||||
|
return ParameterInfo.ForPreview(ctx).GetParametersForObject(obj).ToImmutableList();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ImmutableDictionary<(ParameterNamespace, string), ParameterMapping>
|
||||||
|
GetParameterRemappingsAt_miss(ComputeContext ctx, GameObject obj)
|
||||||
|
{
|
||||||
|
if (obj == null) return ImmutableDictionary<(ParameterNamespace, string), ParameterMapping>.Empty;
|
||||||
|
|
||||||
|
return ParameterInfo.ForPreview(ctx).GetParameterRemappingsAt(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static ImmutableList<ProvidedParameter> GetParametersForObject(GameObject avatar)
|
||||||
|
{
|
||||||
|
return ProvidedParameterCache.Get(ComputeContext.NullContext, avatar);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static ImmutableDictionary<(ParameterNamespace, string), ParameterMapping> GetParameterRemappingsAt(GameObject avatar)
|
||||||
|
{
|
||||||
|
return ParameterRemappingCache.Get(ComputeContext.NullContext, avatar);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
internal class MenuItemCoreGUI
|
internal class MenuItemCoreGUI
|
||||||
{
|
{
|
||||||
private static readonly ObjectIDGenerator IdGenerator = new ObjectIDGenerator();
|
private static readonly ObjectIDGenerator IdGenerator = new ObjectIDGenerator();
|
||||||
@ -134,12 +169,12 @@ namespace nadena.dev.modular_avatar.core.editor
|
|||||||
|
|
||||||
Dictionary<string, ProvidedParameter> rootParameters = new();
|
Dictionary<string, ProvidedParameter> rootParameters = new();
|
||||||
|
|
||||||
foreach (var param in ParameterInfo.ForUI.GetParametersForObject(parentAvatar.gameObject)
|
foreach (var param in ParameterIntrospectionCache.GetParametersForObject(parentAvatar.gameObject)
|
||||||
.Where(p => p.Namespace == ParameterNamespace.Animator)
|
.Where(p => p.Namespace == ParameterNamespace.Animator)
|
||||||
)
|
)
|
||||||
rootParameters[param.EffectiveName] = param;
|
rootParameters[param.EffectiveName] = param;
|
||||||
|
|
||||||
var remaps = ParameterInfo.ForUI.GetParameterRemappingsAt(paramRef);
|
var remaps = ParameterIntrospectionCache.GetParameterRemappingsAt(paramRef);
|
||||||
foreach (var remap in remaps)
|
foreach (var remap in remaps)
|
||||||
{
|
{
|
||||||
if (remap.Key.Item1 != ParameterNamespace.Animator) continue;
|
if (remap.Key.Item1 != ParameterNamespace.Animator) continue;
|
||||||
@ -613,7 +648,7 @@ namespace nadena.dev.modular_avatar.core.editor
|
|||||||
var myParameterName = myMenuItem.Control.parameter.name;
|
var myParameterName = myMenuItem.Control.parameter.name;
|
||||||
if (string.IsNullOrEmpty(myParameterName)) return new List<ModularAvatarMenuItem>();
|
if (string.IsNullOrEmpty(myParameterName)) return new List<ModularAvatarMenuItem>();
|
||||||
|
|
||||||
var myMappings = ParameterInfo.ForUI.GetParameterRemappingsAt(myMenuItem.gameObject);
|
var myMappings = ParameterIntrospectionCache.GetParameterRemappingsAt(myMenuItem.gameObject);
|
||||||
if (myMappings.TryGetValue((ParameterNamespace.Animator, myParameterName), out var myReplacement))
|
if (myMappings.TryGetValue((ParameterNamespace.Animator, myParameterName), out var myReplacement))
|
||||||
myParameterName = myReplacement.ParameterName;
|
myParameterName = myReplacement.ParameterName;
|
||||||
|
|
||||||
@ -627,7 +662,7 @@ namespace nadena.dev.modular_avatar.core.editor
|
|||||||
var otherParameterName = otherMenuItem.Control.parameter.name;
|
var otherParameterName = otherMenuItem.Control.parameter.name;
|
||||||
if (string.IsNullOrEmpty(otherParameterName)) continue;
|
if (string.IsNullOrEmpty(otherParameterName)) continue;
|
||||||
|
|
||||||
var otherMappings = ParameterInfo.ForUI.GetParameterRemappingsAt(otherMenuItem.gameObject);
|
var otherMappings = ParameterIntrospectionCache.GetParameterRemappingsAt(otherMenuItem.gameObject);
|
||||||
if (otherMappings.TryGetValue((ParameterNamespace.Animator, otherParameterName),
|
if (otherMappings.TryGetValue((ParameterNamespace.Animator, otherParameterName),
|
||||||
out var otherReplacement))
|
out var otherReplacement))
|
||||||
otherParameterName = otherReplacement.ParameterName;
|
otherParameterName = otherReplacement.ParameterName;
|
||||||
|
Loading…
Reference in New Issue
Block a user