deepfire/reflex-glfw

Input event processing limited at one per frame

Closed this issue · 6 comments

As can be seen at

This causes an unfortunate over-queuing of events, that can get quite visible sometimes.

@ryantrinkle, do you have any suggestions on how to better handle this?

@deepfire Are you coupling the OpenGL frames to reflex frames? You probably will want to run more than one reflex frame per GL frame - possibly an unlimited number, terminated by some kind of signal, or possibly just time-bounded.

@ryantrinkle, have you seen Reflex.GLFW.host, particularly at https://github.com/deepfire/reflex-glfw/blob/master/src/Reflex/GLFW.hs#L380 ?

It can be seen there, that the window frame event is fired every host frame, which is at least as often as the input event, since:

  1. both fire at most as often as one host frame is processed
  2. the input event may skip firing (which is of little, unrelated consolation)

The problem is, I'm not sure how to untie them -- the host.hs example doesn't provide any clue how to do this.. and I haven't been able to figure it out on my own..

@deepfire Just do something approximately like this:

let processInput = do
      mInput <- readInput queue
      case mInput of
        Nothing -> return ()
        Just input -> do
          mTrig'' ← liftIO $ readIORef iTriggerRef
          case mTrig'' of
            Nothing -> return ()
            Just trig -> threadedFire [trig :=> Identity input] $ pure ()
          processInput

I.e.: as long as it can ingest input, it does. Then, it exits, and presumably lets the window render at that time. You could also do something more advanced, like setting a deadline and stopping input processing if the deadline is hit.

@ryantrinkle, and thanks to your suggestion, the issue is solved -- the demo is smooth now!

I had no clue the host can fire these events at random.

That comes from rushing ahead and not thinking enough.. : -)

@deepfire I'm glad to hear that fixed it!