lib/gamnit: copy and update `mnit::mnit_fps` as `gamnit::limit_fps`
authorAlexis Laferrière <alexis.laf@xymus.net>
Sun, 6 Dec 2015 22:47:37 +0000 (17:47 -0500)
committerAlexis Laferrière <alexis.laf@xymus.net>
Tue, 8 Dec 2015 16:11:17 +0000 (11:11 -0500)
This duplication could probably be avoided as only the name of the method
`frame_full` changes. But the doal is also to fully replace `mnit` so
the old module should be removed soon...

Signed-off-by: Alexis Laferrière <alexis.laf@xymus.net>

lib/gamnit/limit_fps.nit [new file with mode: 0644]

diff --git a/lib/gamnit/limit_fps.nit b/lib/gamnit/limit_fps.nit
new file mode 100644 (file)
index 0000000..a300b54
--- /dev/null
@@ -0,0 +1,78 @@
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Frame-rate control for applications
+module limit_fps
+
+import gamnit
+private import realtime
+
+redef class App
+       # Limit the frame-rate to a given frequency
+       #
+       # This basically limits how much `frame_core` is called per second.
+       # Zero (or a negative value) means no limit.
+       #
+       # Applications can modify this value even during the main-loop.
+       var maximum_fps = 60.0 is writable
+
+       # Current frame-rate
+       #
+       # Updated each 5 seconds.
+       var current_fps = 0.0
+
+       redef fun frame_full
+       do
+               super
+               limit_fps
+       end
+
+       # The clock for limit_fps
+       private var clock = new Clock
+
+       # Number of frames since the last deadline
+       #
+       # Used to compute `current_fps`.
+       private var frame_count = 0
+
+       # Deadline used to compute `current_fps`
+       private var frame_count_deadline = 0
+
+       # Check and sleep to maintain a frame-rate bellow `maximum_fps`
+       #
+       # Also periodically update `current_fps`
+       # Is automatically called at the end of `full_frame`.
+       fun limit_fps
+       do
+               var t = clock.total.sec
+               if t >= frame_count_deadline then
+                       var cfps = frame_count.to_f / 5.0
+                       self.current_fps = cfps
+                       frame_count = 0
+                       frame_count_deadline = t + 5
+               end
+               frame_count += 1
+
+               var mfps = maximum_fps
+               if mfps <= 0.0 then return
+               var lapse = clock.lapse
+               var dt = lapse.to_f
+               var target_dt = 1.0 / mfps
+               if dt < target_dt then
+                       var sleep_t = target_dt - dt
+                       sleep_t.sleep
+                       clock.lapse
+               end
+       end
+end