using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Spine.SpineWrappers; using SpineRuntime37; namespace Spine.Implementations.SpineWrappers.V37 { internal sealed class AnimationState37(AnimationState innerObject, SpineObjectData37 data) : IAnimationState { private readonly AnimationState _o = innerObject; private readonly SpineObjectData37 _data = data; private readonly Dictionary _trackEntryPool = []; private readonly Dictionary _eventMapping = []; private readonly Dictionary _eventCount = []; public AnimationState InnerObject => _o; public event IAnimationState.TrackEntryDelegate? Start { add { if (value is null) return; if (!_eventMapping.TryGetValue(value, out var f)) { _eventMapping[value] = f = (TrackEntry t) => value(GetTrackEntry(t)); _eventCount[value] = 0; } _o.Start += f; _eventCount[value]++; } remove { if (value is null) return; if (_eventMapping.TryGetValue(value, out var f)) { _o.Start -= f; _eventCount[value]--; if (_eventCount[value] <= 0) { _eventMapping.Remove(value); _eventCount.Remove(value); } } } } public event IAnimationState.TrackEntryDelegate? Interrupt { add { if (value is null) return; if (!_eventMapping.TryGetValue(value, out var f)) { _eventMapping[value] = f = (TrackEntry t) => value(GetTrackEntry(t)); _eventCount[value] = 0; } _o.Interrupt += f; _eventCount[value]++; } remove { if (value is null) return; if (_eventMapping.TryGetValue(value, out var f)) { _o.Interrupt -= f; _eventCount[value]--; if (_eventCount[value] <= 0) { _eventMapping.Remove(value); _eventCount.Remove(value); } } } } public event IAnimationState.TrackEntryDelegate? End { add { if (value is null) return; if (!_eventMapping.TryGetValue(value, out var f)) { _eventMapping[value] = f = (TrackEntry t) => value(GetTrackEntry(t)); _eventCount[value] = 0; } _o.End += f; _eventCount[value]++; } remove { if (value is null) return; if (_eventMapping.TryGetValue(value, out var f)) { _o.End -= f; _eventCount[value]--; if (_eventCount[value] <= 0) { _eventMapping.Remove(value); _eventCount.Remove(value); } } } } public event IAnimationState.TrackEntryDelegate? Complete { add { if (value is null) return; if (!_eventMapping.TryGetValue(value, out var f)) { _eventMapping[value] = f = (TrackEntry t) => value(GetTrackEntry(t)); _eventCount[value] = 0; } _o.Complete += f; _eventCount[value]++; } remove { if (value is null) return; if (_eventMapping.TryGetValue(value, out var f)) { _o.Complete -= f; _eventCount[value]--; if (_eventCount[value] <= 0) { _eventMapping.Remove(value); _eventCount.Remove(value); } } } } public event IAnimationState.TrackEntryDelegate? Dispose { add { if (value is null) return; if (!_eventMapping.TryGetValue(value, out var f)) { _eventMapping[value] = f = (TrackEntry t) => value(GetTrackEntry(t)); _eventCount[value] = 0; } _o.Dispose += f; _eventCount[value]++; } remove { if (value is null) return; if (_eventMapping.TryGetValue(value, out var f)) { _o.Dispose -= f; _eventCount[value]--; if (_eventCount[value] <= 0) { _eventMapping.Remove(value); _eventCount.Remove(value); } } } } public float TimeScale { get => _o.TimeScale; set => _o.TimeScale = value; } public void Update(float delta) => _o.Update(delta); public void Apply(ISkeleton skeleton) { if (skeleton is Skeleton37 skel) { _o.Apply(skel.InnerObject); return; } throw new ArgumentException($"Received {skeleton.GetType().Name}", nameof(skeleton)); } /// /// 获取 对象, 不存在则创建 /// public ITrackEntry GetTrackEntry(TrackEntry trackEntry) { if (!_trackEntryPool.TryGetValue(trackEntry, out var tr)) _trackEntryPool[trackEntry] = tr = new(trackEntry, this, _data); return tr; } public IEnumerable IterTracks() => _o.Tracks.Select(t => t is null ? null : GetTrackEntry(t)); public ITrackEntry? GetCurrent(int index) { var t = _o.GetCurrent(index); return t is null ? null : GetTrackEntry(t); } public void ClearTrack(int index) => _o.ClearTrack(index); public void ClearTracks() => _o.ClearTracks(); public ITrackEntry SetAnimation(int trackIndex, string animationName, bool loop) => GetTrackEntry(_o.SetAnimation(trackIndex, animationName, loop)); public ITrackEntry SetAnimation(int trackIndex, IAnimation animation, bool loop) { if (animation is Animation37 anime) return GetTrackEntry(_o.SetAnimation(trackIndex, anime.InnerObject, loop)); throw new ArgumentException($"Received {animation.GetType().Name}", nameof(animation)); } public ITrackEntry SetEmptyAnimation(int trackIndex, float mixDuration) => GetTrackEntry(_o.SetEmptyAnimation(trackIndex, mixDuration)); public void SetEmptyAnimations(float mixDuration) => _o.SetEmptyAnimations(mixDuration); public ITrackEntry AddAnimation(int trackIndex, string animationName, bool loop, float delay) => GetTrackEntry(_o.AddAnimation(trackIndex, animationName, loop, delay)); public ITrackEntry AddAnimation(int trackIndex, IAnimation animation, bool loop, float delay) { if (animation is Animation37 anime) return GetTrackEntry(_o.AddAnimation(trackIndex, anime.InnerObject, loop, delay)); throw new ArgumentException($"Received {animation.GetType().Name}", nameof(animation)); } public ITrackEntry AddEmptyAnimation(int trackIndex, float mixDuration, float delay) => GetTrackEntry(_o.AddEmptyAnimation(trackIndex, mixDuration, delay)); public override string ToString() => _o.ToString(); } }