using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using UnityEngine; namespace VRMShaders { public class AnimationClipFactory : IResponsibilityForDestroyObjects { private readonly IReadOnlyDictionary _externalClips; private readonly Dictionary _runtimeClips = new Dictionary(); private readonly List _loadedClipKeys = new List(); /// /// 外部アセットとして渡された AnimationClip /// public IReadOnlyDictionary ExternalClips => _externalClips; /// /// ImporterContext によって Runtime に生成された AnimationClip /// public IReadOnlyDictionary RuntimeGeneratedClips => _runtimeClips; /// /// ImporterContext によって必要とされた AnimationClip の SubAssetKey. /// 必ずしも ExternalClips と RuntimeGeneratedClips の集合とは限らない. /// public IReadOnlyList LoadedClipKeys => _loadedClipKeys; public AnimationClipFactory(IReadOnlyDictionary externalClips) { _externalClips = externalClips; } public void Dispose() { foreach (var kv in _runtimeClips) { UnityObjectDestroyer.DestroyRuntimeOrEditor(kv.Value); } _runtimeClips.Clear(); } public void TransferOwnership(TakeResponsibilityForDestroyObjectFunc take) { foreach (var (key, o) in _runtimeClips.ToArray()) { take(key, o); _runtimeClips.Remove(key); } } public AnimationClip GetAnimationClip(SubAssetKey key) { if (_externalClips.TryGetValue(key, out var clip)) { return clip; } if (_runtimeClips.TryGetValue(key, out clip)) { return clip; } return null; } public async Task LoadAnimationClipAsync(SubAssetKey key, Func> loadAnimationClip) { if (!_loadedClipKeys.Contains(key)) { _loadedClipKeys.Add(key); } var clip = GetAnimationClip(key); if (clip != null) { return clip; } clip = await loadAnimationClip(); _runtimeClips.Add(key, clip); return clip; } } }