Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
bdunderscore committed Dec 15, 2024
1 parent 83192c8 commit abebecf
Show file tree
Hide file tree
Showing 9 changed files with 138 additions and 20 deletions.
39 changes: 27 additions & 12 deletions Editor/API/AnimatorServices/AnimationIndex.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace nadena.dev.ndmf.animator
{
public sealed class AnimationIndex
{
private readonly Func<IEnumerable<VirtualAnimatorController>> _getControllers;
private readonly Func<IEnumerable<VirtualNode>> _getRoots;
private readonly Func<long> _getInvalidationToken;

private long _lastInvalidationToken;
Expand All @@ -22,22 +22,21 @@ public sealed class AnimationIndex
private readonly Dictionary<string, HashSet<VirtualClip>> _objectPathToClip = new();
private readonly Dictionary<EditorCurveBinding, HashSet<VirtualClip>> _bindingToClip = new();
private readonly Dictionary<VirtualClip, HashSet<EditorCurveBinding>> _lastBindings = new();

internal AnimationIndex(
Func<IEnumerable<VirtualAnimatorController>> getControllers,
Func<IEnumerable<VirtualAnimatorController>> getRoots,
Func<long> getInvalidationToken)
{
_getControllers = getControllers;
_getRoots = getRoots;
_getInvalidationToken = getInvalidationToken;
_invalidateAction = () => _isValid = false;
}

// For testing
internal AnimationIndex(IEnumerable<VirtualAnimatorController> controllers)

public AnimationIndex(IEnumerable<VirtualNode> controllers)
{
_invalidateAction = () => _isValid = false;
var controllerList = new List<VirtualAnimatorController>(controllers);
_getControllers = () => controllerList;
var controllerList = new List<VirtualNode>(controllers);
_getRoots = () => controllerList;
_getInvalidationToken = () => _lastInvalidationToken;
}

Expand Down Expand Up @@ -65,11 +64,19 @@ public IEnumerable<VirtualClip> GetClipsForBinding(EditorCurveBinding binding)
return Enumerable.Empty<VirtualClip>();
}

public void RewritePaths(Dictionary<string, string?> rewriteRules)
public void RewritePaths(Func<string, string?> rewriteRules)
{
if (!IsValid) RebuildCache();

List<VirtualClip> recacheNeeded = new();
var rewriteSet = _objectPathToClip.Values.SelectMany(s => s).Distinct();

RewritePaths(rewriteSet, rewriteRules);
}

public void RewritePaths(Dictionary<string, string?> rewriteRules)
{
if (!IsValid) RebuildCache();

HashSet<VirtualClip> rewriteSet = new();

foreach (var key in rewriteRules.Keys)
Expand All @@ -85,6 +92,14 @@ public void RewritePaths(Dictionary<string, string?> rewriteRules)
if (rewriteRules.TryGetValue(k, out var v)) return v;
return k;
};

RewritePaths(rewriteSet, rewriteFunc);
}

private void RewritePaths(IEnumerable<VirtualClip> rewriteSet, Func<string, string?> rewriteFunc)
{
List<VirtualClip> recacheNeeded = new();

foreach (var clip in rewriteSet)
{
clip.EditPaths(rewriteFunc);
Expand Down Expand Up @@ -185,7 +200,7 @@ private IEnumerable<VirtualClip> EnumerateClips()
Queue<VirtualNode> queue = new();

_lastInvalidationToken = _getInvalidationToken();
foreach (var controller in _getControllers())
foreach (var controller in _getRoots())
{
queue.Enqueue(controller);
}
Expand Down
7 changes: 4 additions & 3 deletions Editor/API/AnimatorServices/ObjectPathRemapper.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#nullable enable

using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using JetBrains.Annotations;
using nadena.dev.ndmf.runtime;
using UnityEngine;
Expand Down Expand Up @@ -119,7 +120,7 @@ public void RecordObjectTree(Transform subtree)
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public string? GetVirtualPathForObject(GameObject obj)
public string GetVirtualPathForObject(GameObject obj)
{
return GetVirtualPathForObject(obj.transform);
}
Expand All @@ -131,15 +132,15 @@ public void RecordObjectTree(Transform subtree)
/// </summary>
/// <param name="t"></param>
/// <returns></returns>
public string? GetVirtualPathForObject(Transform t)
public string GetVirtualPathForObject(Transform t)
{
if (_objectToOriginalPaths.TryGetValue(t, out var paths))
{
return paths[0];
}

var path = RuntimeUtil.RelativePath(_root, t);
if (path == null) return null;
if (path == null) path = t.gameObject.name + "###UNROOTED_" + t.GetInstanceID();

if (_pathToObject.ContainsKey(path))
{
Expand Down
2 changes: 1 addition & 1 deletion Editor/API/AnimatorServices/VirtualControllerContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ public void OnDeactivate(BuildContext context)
commitContext.ActiveInnateLayerKey = kv.Key;
return (RuntimeAnimatorController)commitContext.CommitObject(kv.Value.VirtualController!);
});

_platformBindings!.CommitControllers(root, controllers);
}

Expand Down
5 changes: 3 additions & 2 deletions Editor/API/AnimatorServices/VirtualObjects/VirtualClip.cs
Original file line number Diff line number Diff line change
Expand Up @@ -267,9 +267,10 @@ Dictionary<EditorCurveBinding, CachedCurve<T>> Transform<T>(
var newBinding = binding;
newBinding.path = pathEditor(binding.path);

if (ECBComparator.Instance.Equals(binding, newBinding))
if (ECBComparator.Instance.Equals(binding, newBinding)
|| (binding.type == typeof(Animator) && binding.path == ""))
{
newCache[newBinding] = kvp.Value;
newCache[binding] = kvp.Value;
continue;
}

Expand Down
2 changes: 2 additions & 0 deletions Editor/API/AnimatorServices/VirtualObjects/VirtualMotion.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#nullable enable

using System;
using System.Collections;
using System.Collections.Generic;
using JetBrains.Annotations;
using UnityEditor.Animations;
using UnityEngine;
Expand Down
25 changes: 24 additions & 1 deletion Editor/API/AnimatorServices/VirtualObjects/VirtualNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,30 @@ internal void RegisterCacheObserver(Action? observer)
_lastCacheObserver = observer;
}

internal IEnumerable<VirtualNode> EnumerateChildren()
public IEnumerable<VirtualNode> AllReachableNodes()
{
var visited = new HashSet<VirtualNode>();
var queue = new Queue<VirtualNode>();

queue.Enqueue(this);
visited.Add(this);

while (queue.Count > 0)
{
var node = queue.Dequeue();
yield return node;

foreach (var child in node.EnumerateChildren())
{
if (visited.Add(child))
{
queue.Enqueue(child);
}
}
}
}

public IEnumerable<VirtualNode> EnumerateChildren()
{
return _EnumerateChildren();
}
Expand Down
1 change: 1 addition & 0 deletions Editor/API/AnimatorServices/VirtualObjects/VirtualState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ void ICommitable<AnimatorState>.Commit(CommitContext context, AnimatorState obj)
{
obj.behaviours = Behaviours.Select(context.CommitBehaviour).ToArray();
obj.transitions = Transitions.Select(t => (AnimatorStateTransition)context.CommitObject(t)).ToArray();
obj.motion = context.CommitObject(Motion);
}

public override string ToString()
Expand Down
28 changes: 28 additions & 0 deletions Editor/API/AnimatorServices/VirtualObjects/VirtualStateMachine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -282,5 +282,33 @@ public VirtualState AddState(string name, VirtualMotion? motion = null, Vector3?

return state;
}

/// <summary>
/// Returns an enumerator of all states reachable from this state machine (including sub-state machines)
/// </summary>
/// <returns></returns>
public IEnumerable<VirtualState> AllStates()
{
foreach (var state in Walk(this, new())) yield return state;

IEnumerable<VirtualState> Walk(VirtualStateMachine sm, HashSet<VirtualStateMachine> visited)
{
if (!visited.Add(sm)) yield break;

foreach (var state in States)
{
yield return state.State;
}

foreach (var ssm in StateMachines)
{
foreach (var state in Walk(ssm.StateMachine, visited))
{
yield return state;
}
}
}

}
}
}
49 changes: 48 additions & 1 deletion Editor/API/BuildContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -346,11 +346,58 @@ internal void RunPass(ConcretePass pass)
}
}

public void DeactivateAllExtensionContexts()
{
Dictionary<Type, List<Type>> depIndex = new();
foreach (var ty in _activeExtensions.Keys)
{
foreach (var dep in ty.ContextDependencies())
{
if (!depIndex.ContainsKey(dep))
{
depIndex[dep] = new List<Type>();
}

depIndex[dep].Add(ty);
}
}

while (_activeExtensions.Keys.Count > 0)
{
Type next = _activeExtensions.Keys.First();
Type candidate;
do
{
candidate = next;
var revDeps = depIndex.GetValueOrDefault(next) as IEnumerable<Type>
?? Array.Empty<Type>();
next = revDeps.FirstOrDefault(t => _activeExtensions.ContainsKey(t));
} while (next != null);

DeactivateExtensionContext(candidate);
}
}

public T ActivateExtensionContextRecurse<T>() where T : IExtensionContext
{
return (T) ActivateExtensionContextRecurse(typeof(T));
}

public IExtensionContext ActivateExtensionContextRecurse(Type ty)
{
foreach (var dependency in ty.ContextDependencies())
{
ActivateExtensionContextRecurse(dependency);
}

return ActivateExtensionContext(ty);
}

public T ActivateExtensionContext<T>() where T : IExtensionContext
{
return (T)ActivateExtensionContext(typeof(T));
}

public IExtensionContext ActivateExtensionContext(Type ty)
{
using (new ExecutionScope(this))
Expand Down

0 comments on commit abebecf

Please sign in to comment.