Skip to content

Commit fd153a9

Browse files
committed
Fix event polling
pollEvents was apparently broken by a recent-ish [patch](libsdl-org/SDL#4794) to SDL. This should fix that. As an aside, this attempts to make polling events a bit more efficient; We just statically allocate a single buffer for events (AFAIK you can only call Poll from the main thread anyway, so the fact that this isn't thread safe shouldn't be an issue).
1 parent 5934e81 commit fd153a9

File tree

4 files changed

+35
-6
lines changed

4 files changed

+35
-6
lines changed

cbits/sdlhelper.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,17 @@
11
#include <string.h>
2+
#include <stdlib.h>
23
#include "sdlhelper.h"
34

5+
int SDLHelper_GetEventBufferSize() { return 64; }
6+
SDL_Event *SDLHelper_GetEventBuffer() {
7+
static SDL_Event *buffer = NULL;
8+
if(buffer == NULL) {
9+
/* leak an inconsequental amount of memory */
10+
buffer = calloc(SDLHelper_GetEventBufferSize(), sizeof(SDL_Event));
11+
}
12+
return buffer;
13+
}
14+
415
void SDLHelper_JoystickGetDeviceGUID (int device_index, SDL_JoystickGUID *guid)
516
{
617
SDL_JoystickGUID t = SDL_JoystickGetDeviceGUID (device_index);

include/sdlhelper.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
#include <stddef.h>
55
#include "SDL.h"
66

7+
int SDLHelper_GetEventBufferSize(void);
8+
SDL_Event *SDLHelper_GetEventBuffer(void);
79
void SDLHelper_JoystickGetDeviceGUID (int device_index, SDL_JoystickGUID *guid);
810
void SDLHelper_JoystickGetGUID (SDL_Joystick *joystick, SDL_JoystickGUID *guid);
911
void SDLHelper_JoystickGetGUIDFromString (const char *pchGUID, SDL_JoystickGUID *guid);

src/SDL/Event.hs

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ import Data.Text (Text)
9292
import Data.Typeable
9393
import Foreign hiding (throwIfNeg_)
9494
import Foreign.C
95+
import Foreign.Marshal.Array
9596
import GHC.Generics (Generic)
9697
import SDL.Vect
9798
import SDL.Input.Joystick
@@ -104,6 +105,7 @@ import SDL.Internal.Types (Window(Window))
104105
import qualified Data.ByteString.Char8 as BSC8
105106
import qualified Data.Text.Encoding as Text
106107
import qualified SDL.Raw as Raw
108+
import Text.Printf
107109

108110
#if !MIN_VERSION_base(4,8,0)
109111
import Control.Applicative
@@ -765,11 +767,20 @@ pollEvent =
765767
-- Like 'pollEvent' this function should only be called in the OS thread which
766768
-- set the video mode.
767769
pollEvents :: MonadIO m => m [Event]
768-
pollEvents =
769-
do e <- pollEvent
770-
case e of
771-
Nothing -> return []
772-
Just e' -> (e' :) <$> pollEvents
770+
pollEvents = liftIO $ do
771+
Raw.pumpEvents
772+
peepAllEvents >>= mapM convertRaw where
773+
peepAllEvents = do
774+
numPeeped <- Raw.peepEvents
775+
Raw.eventBuffer
776+
Raw.eventBufferSize
777+
Raw.SDL_GETEVENT
778+
Raw.SDL_FIRSTEVENT
779+
Raw.SDL_LASTEVENT
780+
peeped <- peekArray (fromIntegral numPeeped) Raw.eventBuffer
781+
if numPeeped == Raw.eventBufferSize -- are there more events to peep?
782+
then (peeped ++) <$> peepAllEvnets
783+
else return peeped
773784

774785
-- | Run a monadic computation, accumulating over all known 'Event's.
775786
--

src/SDL/Raw/Event.hs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,9 @@ module SDL.Raw.Event (
112112
gameControllerNameForIndex,
113113
gameControllerOpen,
114114
gameControllerUpdate,
115-
isGameController
115+
isGameController,
116+
eventBuffer,
117+
eventBufferSize
116118
) where
117119

118120
import Control.Monad.IO.Class
@@ -235,6 +237,9 @@ foreign import ccall "SDL.h SDL_GameControllerOpen" gameControllerOpenFFI :: CIn
235237
foreign import ccall "SDL.h SDL_GameControllerUpdate" gameControllerUpdateFFI :: IO ()
236238
foreign import ccall "SDL.h SDL_IsGameController" isGameControllerFFI :: CInt -> IO Bool
237239

240+
foreign import ccall "sdlhelper.c SDLHelper_GetEventBufferSize" eventBufferSize :: CInt
241+
foreign import ccall "sdlhelper.c SDLHelper_GetEventBuffer" eventBuffer :: Ptr Event
242+
238243
addEventWatch :: MonadIO m => EventFilter -> Ptr () -> m ()
239244
addEventWatch v1 v2 = liftIO $ addEventWatchFFI v1 v2
240245
{-# INLINE addEventWatch #-}

0 commit comments

Comments
 (0)