From c3ce7171b749a21179ce24bee2648d78693d3106 Mon Sep 17 00:00:00 2001 From: Anton Tarasenko Date: Mon, 11 Jul 2022 02:08:47 +0700 Subject: [PATCH] Fix `Timer` not restarting during signal handling --- sources/Time/Timer.uc | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/sources/Time/Timer.uc b/sources/Time/Timer.uc index 6a3e730..f6b1c5e 100644 --- a/sources/Time/Timer.uc +++ b/sources/Time/Timer.uc @@ -222,6 +222,8 @@ public final function float GetElapsedTime() private final function Tick(float delta, float dilationCoefficient) { + local int lifeVersion; + if (onElapsedSignal == none || eventInterval <= 0.0) { StopMe(); @@ -234,10 +236,18 @@ private final function Tick(float delta, float dilationCoefficient) // It is important to modify _before_ the signal call in case `Timer` // is reset there and already has a zeroed `totalElapsedTime` totalElapsedTime -= eventInterval; - onElapsedSignal.Emit(self); - if (!isTimerAutoReset && IsAllocated()) - { + // Stop `Timer` before emitting a signal, to allow user to potentially + // restart it + if (!isTimerAutoReset) { StopMe(); + } + // During signal emission caller `Timer` can get reallocated and + // used to perform a completely different role. + // In such a case we need to bail from this method as soom as + // possible. + lifeVersion = GetLifeVersion(); + onElapsedSignal.Emit(self); + if (!isTimerEnabled || lifeVersion != GetLifeVersion()) { return; } }