lib & contrib: update users of Clock
[nit.git] / lib / gamnit / limit_fps.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 # Frame-rate control for applications
16 module limit_fps
17
18 import gamnit
19 private import realtime
20
21 redef class App
22 # Limit the frame-rate to a given frequency
23 #
24 # This basically limits how much `frame_core` is called per second.
25 # Zero (or a negative value) means no limit.
26 #
27 # Applications can modify this value even during the main-loop.
28 var maximum_fps = 60.0 is writable
29
30 # Current frame-rate
31 #
32 # Updated each 5 seconds, initialized at the value of `maximum_fps`.
33 var current_fps: Float = maximum_fps is lazy
34
35 redef fun frame_full
36 do
37 super
38 limit_fps
39 end
40
41 # The clock for limit_fps
42 private var clock = new Clock
43
44 # Number of frames since the last deadline
45 #
46 # Used to compute `current_fps`.
47 private var frame_count = 0
48
49 # Deadline used to compute `current_fps`
50 private var frame_count_deadline = 5.0
51
52 # Check and sleep to maintain a frame-rate bellow `maximum_fps`
53 #
54 # Also periodically update `current_fps`
55 # Is automatically called at the end of `full_frame`.
56 fun limit_fps
57 do
58 var t = clock.total
59 if t >= frame_count_deadline then
60 var cfps = frame_count.to_f / 5.0
61 self.current_fps = cfps
62 frame_count = 0
63 frame_count_deadline = t + 5.0
64 end
65 frame_count += 1
66
67 var mfps = maximum_fps
68 if mfps <= 0.0 then return
69 var lapse = clock.lapse
70 var dt = lapse.to_f
71 var target_dt = 1.0 / mfps
72 if dt < target_dt then
73 var sleep_t = target_dt - dt
74 sleep_t.sleep
75 clock.lapse
76 end
77 end
78 end