From 95d281283e0218df037d5117b6d7e89462aff539 Mon Sep 17 00:00:00 2001 From: Siyuan Chen Date: Thu, 18 Jan 2024 04:56:41 +0800 Subject: [PATCH 1/2] Fix the issue https://github.com/ivanperez-keera/SpaceInvaders/issues/44 Phenomenon: After executing spaceInvaders.exe,If you moving the mouse over the window, the game freezes! Root cause: When Yampa's sensing action takes window input, if the input is a `HGL.MouseMove` event, it calls `mmFilter` to consume all subsequent "redundant" `HGL.MouseMove` events. If there are several hundred `HGL.MouseMove` events, `mmFilter` will be recursively called several hundreds of times. The`mmFilter` further calls `gwi win` to take events, and `gwi win` calls `HGL.getWindowTick win` to yield the time slices to ensure that the thread acturally receiving WM events gets a chance to work. This leads to a problem: Since `HGL.getWindowTick win` is a blocking operation (i.e. waiting for a tickRate time), if there are 100 subsequent `HGL.MouseMove`, it will wait for "100 x tickRate time", which is unacceptable. Moreover, during this waiting period, there might be further mouse move events generated! This patch fixed the issue by placing `HGL.getWindowTick win` at the beginning of a frame, i.e. at the entry point of `getTimeInput`, rather than inside `gwi win`. --- src/Animate.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Animate.hs b/src/Animate.hs index f08b04c..fc16216 100644 --- a/src/Animate.hs +++ b/src/Animate.hs @@ -120,6 +120,7 @@ mkInitAndGetTimeInput win = do -- Next delta time and input let getTimeInput _ = do + HGL.getWindowTick win -- Get time tp <- readIORef tpRef t <- getElapsedTime `repeatUntil` (/= tp) -- Wrap around possible! @@ -186,7 +187,6 @@ getWinInput win weBufRef = do -- Maybe the process typically dies before the waiting time is up in -- the latter case? gwi win = do - HGL.getWindowTick win mwe <- HGL.maybeGetWindowEvent win return mwe From 430edb6aba05c24340496391821e389ff11d93f7 Mon Sep 17 00:00:00 2001 From: Siyuan Chen Date: Thu, 18 Jan 2024 05:23:38 +0800 Subject: [PATCH 2/2] Move the comments to be consistent with the patch https://github.com/ivanperez-keera/SpaceInvaders/pull/45 --- src/Animate.hs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/Animate.hs b/src/Animate.hs index fc16216..9f64691 100644 --- a/src/Animate.hs +++ b/src/Animate.hs @@ -120,6 +120,12 @@ mkInitAndGetTimeInput win = do -- Next delta time and input let getTimeInput _ = do + -- Seems as if we either have to yield or wait for a tick in order + -- to ensure that the thread receiving events gets a chance to + -- work. For some reason, yielding seems to result in window close + -- events getting through, wheras waiting often means they don't. + -- Maybe the process typically dies before the waiting time is up in + -- the latter case? HGL.getWindowTick win -- Get time tp <- readIORef tpRef @@ -179,13 +185,6 @@ getWinInput win weBufRef = do Just (HGL.MouseMove {}) -> mmFilter mwe' Just _ -> writeIORef weBufRef mwe' >> return jmme - - -- Seems as if we either have to yield or wait for a tick in order - -- to ensure that the thread receiving events gets a chance to - -- work. For some reason, yielding seems to result in window close - -- events getting through, wheras waiting often means they don't. - -- Maybe the process typically dies before the waiting time is up in - -- the latter case? gwi win = do mwe <- HGL.maybeGetWindowEvent win return mwe