From 3340a1a5adc024069a84738f435b72168208a23e Mon Sep 17 00:00:00 2001 From: amylizzle Date: Mon, 20 May 2024 13:08:49 +0100 Subject: [PATCH 1/6] fix loop in animate() --- OpenDreamClient/Rendering/DreamIcon.cs | 53 ++++++++++++++++++-------- 1 file changed, 38 insertions(+), 15 deletions(-) diff --git a/OpenDreamClient/Rendering/DreamIcon.cs b/OpenDreamClient/Rendering/DreamIcon.cs index 885804f281..f75938cdbc 100644 --- a/OpenDreamClient/Rendering/DreamIcon.cs +++ b/OpenDreamClient/Rendering/DreamIcon.cs @@ -2,6 +2,7 @@ using OpenDreamClient.Resources.ResourceTypes; using OpenDreamShared.Dream; using OpenDreamShared.Resources; +using Robust.Client.Animations; using Robust.Client.Graphics; using Robust.Shared.Timing; using System.Linq; @@ -47,6 +48,7 @@ private set { private int _animationFrame; private TimeSpan _animationFrameTime = gameTiming.CurTime; private List? _appearanceAnimations; + private int _appearanceAnimationsLoops = 0; private Box2? _cachedAABB; public DreamIcon(IGameTiming gameTiming, ClientAppearanceSystem appearanceSystem, int appearanceId, @@ -89,7 +91,17 @@ public void StartAppearanceAnimation(IconAppearance endingAppearance, TimeSpan d start = _appearanceAnimations[^1].Start + _appearanceAnimations[^1].Duration; //if it's not parallel, it's chained _appearanceAnimations ??= new List(); - _appearanceAnimations.Add(new AppearanceAnimation(start, duration, endingAppearance, easing, loops, flags, delay)); + if(_appearanceAnimations.Count == 0) //only valid on the first animation + _appearanceAnimationsLoops = loops; + + for(int i=_appearanceAnimations.Count-1; i>=0; i--) //there can be only one last-in-sequence, and it might not be the last element of the list because it could be added to mid-loop + if(_appearanceAnimations[i].LastInSequence) { + var lastAnim = _appearanceAnimations[i]; + lastAnim.LastInSequence = false; + _appearanceAnimations[i] = lastAnim; + break; + } + _appearanceAnimations.Add(new AppearanceAnimation(start, duration, endingAppearance, easing, flags, delay, true)); } /// @@ -155,10 +167,11 @@ private void UpdateAnimation() { return _appearance; IconAppearance appearance = new IconAppearance(_appearance); List? toRemove = null; + List? toReAdd = null; for(int i = 0; i < _appearanceAnimations.Count; i++) { AppearanceAnimation animation = _appearanceAnimations[i]; //if it's not the first one, and it's not parallel, break - if((animation.flags & AnimationFlags.AnimationParallel) == 0 && i != 0) + if((animation.Flags & AnimationFlags.AnimationParallel) == 0 && i != 0) break; float timeFactor = Math.Clamp((float)(DateTime.Now - animation.Start).Ticks / animation.Duration.Ticks, 0.0f, 1.0f); @@ -331,21 +344,31 @@ private void UpdateAnimation() { } if (timeFactor >= 1f) { - if (animation.loops > 0) { - var tempAnimation = _appearanceAnimations[i]; - tempAnimation.loops--; - _appearanceAnimations[i] = tempAnimation; - } - if (animation.loops == 0) { - toRemove ??= new(); - toRemove.Add(animation); + toRemove ??= new(); + toRemove.Add(animation); + if (_appearanceAnimationsLoops != 0) { //add it back to the list with the times updated + if(_appearanceAnimationsLoops != -1 && animation.LastInSequence) + _appearanceAnimationsLoops -= 1; + toReAdd ??= new(); + DateTime start; + if((animation.Flags & AnimationFlags.AnimationParallel) != 0) + start = _appearanceAnimations[^1].Start; //either that's also a parallel, or its one that this should be parallel with + else + start = _appearanceAnimations[^1].Start + _appearanceAnimations[^1].Duration; //if it's not parallel, it's chained + AppearanceAnimation repeatAnimation = new AppearanceAnimation(start, animation.Duration, animation.EndAppearance, animation.Easing, animation.Flags, animation.Delay, animation.LastInSequence); + toReAdd.Add(repeatAnimation); } + } } if(toRemove != null) - foreach (AppearanceAnimation animation in toRemove!) { + foreach (AppearanceAnimation animation in toRemove) { EndAppearanceAnimation(animation); } + if(toReAdd != null) + foreach (AppearanceAnimation animation in toReAdd) { + _appearanceAnimations.Add(animation); + } return appearance; } @@ -394,13 +417,13 @@ private void CheckSizeChange() { } } - private struct AppearanceAnimation(DateTime start, TimeSpan duration, IconAppearance endAppearance, AnimationEasing easing, int loops, AnimationFlags flags, int delay) { + private struct AppearanceAnimation(DateTime start, TimeSpan duration, IconAppearance endAppearance, AnimationEasing easing, AnimationFlags flags, int delay, bool lastInSequence) { public readonly DateTime Start = start; public readonly TimeSpan Duration = duration; public readonly IconAppearance EndAppearance = endAppearance; public readonly AnimationEasing Easing = easing; - public int loops = loops; - public readonly AnimationFlags flags = flags; - public int delay = delay; + public readonly AnimationFlags Flags = flags; + public readonly int Delay = delay; + public bool LastInSequence = lastInSequence; } } From 0cc4b0bdf469864a1d5edf14239095f45e38d971 Mon Sep 17 00:00:00 2001 From: amylizzle Date: Mon, 20 May 2024 13:30:41 +0100 Subject: [PATCH 2/6] bad using --- OpenDreamClient/Rendering/DreamIcon.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/OpenDreamClient/Rendering/DreamIcon.cs b/OpenDreamClient/Rendering/DreamIcon.cs index f75938cdbc..053171a48c 100644 --- a/OpenDreamClient/Rendering/DreamIcon.cs +++ b/OpenDreamClient/Rendering/DreamIcon.cs @@ -2,7 +2,6 @@ using OpenDreamClient.Resources.ResourceTypes; using OpenDreamShared.Dream; using OpenDreamShared.Resources; -using Robust.Client.Animations; using Robust.Client.Graphics; using Robust.Shared.Timing; using System.Linq; @@ -91,8 +90,10 @@ public void StartAppearanceAnimation(IconAppearance endingAppearance, TimeSpan d start = _appearanceAnimations[^1].Start + _appearanceAnimations[^1].Duration; //if it's not parallel, it's chained _appearanceAnimations ??= new List(); - if(_appearanceAnimations.Count == 0) //only valid on the first animation + if(_appearanceAnimations.Count == 0) {//only valid on the first animation + Logger.Debug("setting loops to {0}", loops); _appearanceAnimationsLoops = loops; + } for(int i=_appearanceAnimations.Count-1; i>=0; i--) //there can be only one last-in-sequence, and it might not be the last element of the list because it could be added to mid-loop if(_appearanceAnimations[i].LastInSequence) { From f17b6a9cc82bb3a1c56c29b44352d96cb2ad97e5 Mon Sep 17 00:00:00 2001 From: Amy <3855802+amylizzle@users.noreply.github.com> Date: Thu, 23 May 2024 14:02:48 +0100 Subject: [PATCH 3/6] Apply suggestions from code review --- OpenDreamClient/Rendering/DreamIcon.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/OpenDreamClient/Rendering/DreamIcon.cs b/OpenDreamClient/Rendering/DreamIcon.cs index 053171a48c..d8e2f89f5f 100644 --- a/OpenDreamClient/Rendering/DreamIcon.cs +++ b/OpenDreamClient/Rendering/DreamIcon.cs @@ -47,7 +47,7 @@ private set { private int _animationFrame; private TimeSpan _animationFrameTime = gameTiming.CurTime; private List? _appearanceAnimations; - private int _appearanceAnimationsLoops = 0; + private int _appearanceAnimationsLoops; private Box2? _cachedAABB; public DreamIcon(IGameTiming gameTiming, ClientAppearanceSystem appearanceSystem, int appearanceId, @@ -90,8 +90,6 @@ public void StartAppearanceAnimation(IconAppearance endingAppearance, TimeSpan d start = _appearanceAnimations[^1].Start + _appearanceAnimations[^1].Duration; //if it's not parallel, it's chained _appearanceAnimations ??= new List(); - if(_appearanceAnimations.Count == 0) {//only valid on the first animation - Logger.Debug("setting loops to {0}", loops); _appearanceAnimationsLoops = loops; } From 9e7e7c68913e2cdca709948616529401d0ad3bc6 Mon Sep 17 00:00:00 2001 From: amylizzle Date: Thu, 23 May 2024 14:11:38 +0100 Subject: [PATCH 4/6] oops --- OpenDreamClient/Rendering/DreamIcon.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/OpenDreamClient/Rendering/DreamIcon.cs b/OpenDreamClient/Rendering/DreamIcon.cs index d8e2f89f5f..6cd211cacf 100644 --- a/OpenDreamClient/Rendering/DreamIcon.cs +++ b/OpenDreamClient/Rendering/DreamIcon.cs @@ -90,6 +90,7 @@ public void StartAppearanceAnimation(IconAppearance endingAppearance, TimeSpan d start = _appearanceAnimations[^1].Start + _appearanceAnimations[^1].Duration; //if it's not parallel, it's chained _appearanceAnimations ??= new List(); + if(_appearanceAnimations.Count == 0) {//only valid on the first animation _appearanceAnimationsLoops = loops; } From 026870404c1bbf59718bb5f746b2771a27dcc932 Mon Sep 17 00:00:00 2001 From: amylizzle Date: Tue, 18 Jun 2024 15:50:35 +0100 Subject: [PATCH 5/6] lint --- OpenDreamClient/Rendering/DreamIcon.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/OpenDreamClient/Rendering/DreamIcon.cs b/OpenDreamClient/Rendering/DreamIcon.cs index ee059bda68..da84b750ba 100644 --- a/OpenDreamClient/Rendering/DreamIcon.cs +++ b/OpenDreamClient/Rendering/DreamIcon.cs @@ -189,6 +189,7 @@ public void GetWorldAABB(Vector2 worldPos, ref Box2? aabb) { private void UpdateAnimation() { if(DMI == null || Appearance == null) return; + DMIParser.ParsedDMIState? dmiState = DMI.Description.GetStateOrDefault(Appearance.IconState); if(dmiState == null) return; @@ -407,14 +408,17 @@ private void UpdateAnimation() { } } + if(toRemove != null) foreach (AppearanceAnimation animation in toRemove) { EndAppearanceAnimation(animation); } + if(toReAdd != null) foreach (AppearanceAnimation animation in toReAdd) { _appearanceAnimations.Add(animation); } + return appearance; } From 93ef03f4b5ea22f1358cdcdc9f31d2d2b691e29e Mon Sep 17 00:00:00 2001 From: Amy <3855802+amylizzle@users.noreply.github.com> Date: Tue, 18 Jun 2024 15:59:21 +0100 Subject: [PATCH 6/6] Update OpenDreamClient/Rendering/DreamIcon.cs --- OpenDreamClient/Rendering/DreamIcon.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/OpenDreamClient/Rendering/DreamIcon.cs b/OpenDreamClient/Rendering/DreamIcon.cs index da84b750ba..6a00e17eb4 100644 --- a/OpenDreamClient/Rendering/DreamIcon.cs +++ b/OpenDreamClient/Rendering/DreamIcon.cs @@ -145,6 +145,7 @@ public void StartAppearanceAnimation(IconAppearance endingAppearance, TimeSpan d _appearanceAnimations[i] = lastAnim; break; } + _appearanceAnimations.Add(new AppearanceAnimation(start, duration, endingAppearance, easing, flags, delay, true)); }