From b5bee0facb870875a148f6a4536c692b54ae5e34 Mon Sep 17 00:00:00 2001 From: Ellpeck Date: Tue, 21 Dec 2021 21:17:45 +0100 Subject: [PATCH] improved SpriteAnimationGroup performance --- MLEM/Animations/SpriteAnimationGroup.cs | 68 ++++++++++++++----------- 1 file changed, 38 insertions(+), 30 deletions(-) diff --git a/MLEM/Animations/SpriteAnimationGroup.cs b/MLEM/Animations/SpriteAnimationGroup.cs index ac62c1a..2551fec 100644 --- a/MLEM/Animations/SpriteAnimationGroup.cs +++ b/MLEM/Animations/SpriteAnimationGroup.cs @@ -11,23 +11,15 @@ namespace MLEM.Animations { /// public class SpriteAnimationGroup : GenericDataHolder { - private readonly List animations = new List(); - private ConditionedAnimation currAnimation; - private ConditionedAnimation CurrAnimation { - get { - if (this.isDirty) { - this.isDirty = false; - this.animations.Sort((a1, a2) => a2.Priority.CompareTo(a1.Priority)); - this.FindAnimationToPlay(); - } - return this.currAnimation; - } - set => this.currAnimation = value; - } /// /// Returns the animation that is currently playing. /// - public SpriteAnimation CurrentAnimation => this.CurrAnimation?.Animation; + public SpriteAnimation CurrentAnimation { + get { + this.SortAnimationsIfDirty(true); + return this.currentAnimation?.Animation; + } + } /// /// Returns the frame that is displaying. /// @@ -40,11 +32,6 @@ namespace MLEM.Animations { /// Returns the 's . /// public IList CurrentRegions => this.CurrentAnimation?.CurrentRegions; - /// - /// A callback for when the currently displaying animation has changed due to a condition with a higher priority being met. - /// - public event AnimationChanged OnAnimationChanged; - private bool isDirty; /// public float SpeedMultiplier { set { @@ -53,6 +40,15 @@ namespace MLEM.Animations { } } + /// + /// A callback for when the currently displaying animation has changed due to a condition with a higher priority being met. + /// + public event AnimationChanged OnAnimationChanged; + + private readonly List animations = new List(); + private ConditionedAnimation currentAnimation; + private bool animationsDirty; + /// /// Adds a to this group. /// @@ -62,7 +58,7 @@ namespace MLEM.Animations { /// This group, for chaining public SpriteAnimationGroup Add(SpriteAnimation anim, Func condition, int priority = 0) { this.animations.Add(new ConditionedAnimation(anim, condition, priority)); - this.isDirty = true; + this.animationsDirty = true; return this; } @@ -74,8 +70,8 @@ namespace MLEM.Animations { /// public void Update(TimeSpan elapsed) { this.FindAnimationToPlay(); - if (this.CurrAnimation != null) - this.CurrAnimation.Animation.Update(elapsed); + if (this.CurrentAnimation != null) + this.CurrentAnimation.Update(elapsed); } /// @@ -88,25 +84,37 @@ namespace MLEM.Animations { } private void FindAnimationToPlay() { + this.SortAnimationsIfDirty(false); + ConditionedAnimation animToPlay = null; - if (this.CurrAnimation != null && this.CurrAnimation.ShouldPlay()) - animToPlay = this.CurrAnimation; + if (this.currentAnimation != null && this.currentAnimation.ShouldPlay()) + animToPlay = this.currentAnimation; + foreach (var anim in this.animations) { - // if we find an animation with a lower priority then it means we can break - // because the list is sorted by priority - if (animToPlay != null && anim.Priority < animToPlay.Priority) + // if we find an animation with a lower priority then it means we can break since the list is sorted by priority + if (animToPlay != null && anim.Priority <= animToPlay.Priority) break; if (anim.ShouldPlay()) animToPlay = anim; } - if (animToPlay != this.CurrAnimation) { - this.OnAnimationChanged?.Invoke(this.CurrAnimation?.Animation, animToPlay?.Animation); - this.CurrAnimation = animToPlay; + + if (animToPlay != this.currentAnimation) { + this.OnAnimationChanged?.Invoke(this.currentAnimation?.Animation, animToPlay?.Animation); + this.currentAnimation = animToPlay; if (animToPlay != null) animToPlay.Animation.Restart(); } } + private void SortAnimationsIfDirty(bool findAnimationToPlay) { + if (this.animationsDirty) { + this.animationsDirty = false; + this.animations.Sort((a1, a2) => a2.Priority.CompareTo(a1.Priority)); + if (findAnimationToPlay) + this.FindAnimationToPlay(); + } + } + /// /// A callback delegate for when a 's current animation changed. ///