Yampa icon indicating copy to clipboard operation
Yampa copied to clipboard

Sampling frequency of mouse motion events

Open madjestic opened this issue 4 years ago • 5 comments

Hey guys, is there a way to control the frequency at which mouse motion is being sampled in Yampa or Bear River?

It feels like the event stream is too dense, when I move the mouse and I could easily have less events, as the app is reacting to the relative mouse motion.

Just to clarify: when I rotate the camera with the keyboard cursor keys, it behaves as expected, but when I move the mouse, it almost feels like the app is trying to react too detailed to every position change of the mouse motion, it feels like it's lagging trying to process too many samples.

Does it sound familiar? Can I fix it by controlling the sampling frequency?

Cheers, Vlad

madjestic avatar Nov 25 '20 00:11 madjestic

Yampa/bearriver provides no native way to set the frequency at which the network or branches of the network is run as far as I know, unless you just make the thread running reactimate sleep. My solution to this problem of having different update rates at different parts of the application would be to simply have a set network update rate (200 FPS usually) using the thread sleep method (sleep $ timePassed - frameDelta) and then creating a switch that recursively switches into something like iPre noEvent >>> myFun so that every second input gets ignored. However this is pretty ugly since it wont work the same if the update rate changes because then the updates would be happening less often so to skip 2 updates then would take a different amount of time than before. Maybe there is a better solution to this in yampa/BR? The real solution to this problem however is what rhine is doing with clocks

But I think the better alternative in your specific case is to just outside of the FRP network accumulate the mouse events and then eventually send them in as a single event containing the accumulated mouse events every 0.0166 milliseconds or so.

walseb avatar Nov 25 '20 00:11 walseb

Thanks for the reply, @walseb . Do you, maybe, have an example that does something similar for a reference?

Here's how I get the relative mouse motion events:

nextAppInput :: AppInput -> SDL.EventPayload -> AppInput
-- | mouse movement/position
nextAppInput inp (SDL.MouseMotionEvent ev) =
  inp { ...
      , inpMousePos     = (fromIntegral x, fromIntegral y)
      , inpMouseRelPos  = (fromIntegral x', fromIntegral y') }
  where (P (V2 x  y ))  = SDL.mouseMotionEventPos ev
        (  (V2 x' y'))  = SDL.mouseMotionEventRelMotion ev

The AppInput is passed along to the Game inside the topmost SF as

parseWinInput :: SF WinInput AppInput
parseWinInput = accumHoldBy nextAppInput initAppInput
  animate
    window
    (parseWinInput >>> (mainGame game &&& handleExit))

madjestic avatar Nov 25 '20 09:11 madjestic

It looks like iPre f >>>... does the trick though:

mouseRelPos :: SF AppInput (Double,Double)
mouseRelPos = iPre initAppInput >>> arr inpMouseRelPos  -- <- this seems to fix it

Thanks!

madjestic avatar Nov 25 '20 11:11 madjestic

Using iPre like that should only delay it by the initial tick though, not every other tick Try this mess I made instead:

runSFEveryOtherTick :: SF a (Event b) -> SF a (Event b)
runSFEveryOtherTick sf =
  dSwitch
    (constant noEvent &&& constant (Event ()))
    (const $ dSwitch
         (sf &&& constant (Event ()))
         (const $ runSFEveryOther sf))

Maybe it will just hang, I haven't tried it myself, but it does compile so there is hope

walseb avatar Nov 25 '20 19:11 walseb

I was thinking about this today and my solution wont work if the SF you pass in stores data because the argument SF isn't actually modified. For that to work you would probably have to unMSF the SF, so that it's run forcefully and then pass the new SF back again to runSFEveryOtherTick. But since you are just using a normal function that you lift into a SF that shouldn't be a problem

walseb avatar Nov 26 '20 16:11 walseb

There seems to be a solution in the comments with iPre, and there's been no activity in this issue for years. Closing.

ivanperez-keera avatar Mar 06 '23 13:03 ivanperez-keera