1

I have this timeHandler function that is executed each frame and for which the time passed since the application started is passed as a floating argument:

timeHandler :: Float -> World -> World
timeHandler time = ... my funcs ...

Now I have one function that doesn't need to be executed EACH frame but, for example, each 10 frames. So I figured I'd use the mod function for this but that's not working:

timeHandler time = if (((floor time) `mod` 10) == 0) then myFunc else id

I figured I'd execute the function only when the time divided by 10 leaves no rest value, or in other words: execute it each 10 seconds (at least that's what I thought). But (obviously) it's not working, it seems the condition is always true.

If someone could help me out on this it'd be much appreciated!

Best regards, Skyfe.

1
  • Your function works the way you expect it to - it will apply myFunc every 10 seconds for 1 second. If you need to be assured of this - map (\time -> ((floor time) mod` 10) == 0) [9.95, 10.00 .. 11.05]`. Your error is almost certainly elsewhere. Commented Oct 30, 2014 at 6:39

2 Answers 2

2

The 'problem' is that time doesn't change. It's misleading because of its name, but time is the current POSIXtime when the game runs. It's not a bug, it is used only for the initialisation (of the RndGen for example). If you want to use a changing time value you will have to implement it by hand.

time <- round <$> getPOSIXTime

The main method is the only place where the time value is set.

1
  • Aah I got it! Hadn't noticed that before, thank you for pointing it out. I'll try implementing my own timer for its purpose. Commented Oct 30, 2014 at 17:23
1

Some thoughts on how to debug this....

First of all, is t time in seconds, or frame number? Because if it is time in seconds, note that you will fire for every frame that starts with a multiple of 10 (ie- if you have 20 frames per second, it will fire 20 times between 20s and 21s).

Otherwise, the code you showed here looks correct to me.... In that it will evaluate to True for each t=10*n.

To find the problem, I would use Debug.Trace.trace in the call, like this

timeHandler t = trace (show t) $
                if (((floor time) `mod` 10) == 0) then myFunc else id

and watch what is coming in. trace is a function (that you should only use for debugging, since it is impure) that will allow you to see values in real time. Seeing what values of t are being sent in can really help you understand what is happening.

You could also trace the values of

((floor time `mod` 10) == 0)

etc, to see if it really is getting triggered.

If, after doing this, you are still confused, show us what you have learned here, and we can help.

1
  • Thank you! Somehow it constantly shows 1.66666668e-2 as value for time, I'm not sure how this is possible but that must've been the bug. Commented Oct 30, 2014 at 11:34

Not the answer you're looking for? Browse other questions tagged or ask your own question.