Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion contrib/crazy_moles/src/moles.nit
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ redef class App
do
super

maximum_fps = 50
maximum_fps = 50.0
end

redef fun frame_core(display)
Expand Down
4 changes: 2 additions & 2 deletions contrib/tinks/src/client/client.nit
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ redef class App
redef fun on_create
do
super
maximum_fps = 60
maximum_fps = 60.0
assets.assign_images_to_story context.game.story
end

Expand Down Expand Up @@ -127,7 +127,7 @@ redef class App
return new LocalServerContext
else
print "Connecting to:{address}:{port}"
maximum_fps = 0
maximum_fps = 0.0

# Args are: tinks server_address {port}
#var address = "riph" # args[0]
Expand Down
2 changes: 1 addition & 1 deletion examples/mnit_ballz/src/ballz_android.nit
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ redef class App
gyroscope.enabled = true
light.enabled = true
proximity.enabled = true
maximum_fps = 50
maximum_fps = 50.0
sensors_support_enabled = true
super
end
Expand Down
2 changes: 1 addition & 1 deletion examples/mnit_ballz/src/ballz_linux.nit
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ redef class App

redef fun run
do
maximum_fps = 50
maximum_fps = 50.0
super
end

Expand Down
2 changes: 1 addition & 1 deletion examples/mnit_dino/src/dino.nit
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ redef class App
do
super

maximum_fps = 80
maximum_fps = 80.0

var display = display
assert display != null
Expand Down
10 changes: 10 additions & 0 deletions lib/core/time.nit
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,16 @@ redef class Sys
`}
end

redef class Float
# Sleep approximately `self` seconds
fun sleep `{
time_t s = self;
long ns = (self-s) * 1000000000.0;
const struct timespec req = {s, ns};
nanosleep(&req, NULL);
`}
end

# Time since epoch
extern class TimeT `{time_t`}

Expand Down
78 changes: 78 additions & 0 deletions lib/gamnit/limit_fps.nit
Original file line number Diff line number Diff line change
@@ -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
21 changes: 10 additions & 11 deletions lib/mnit/mnit_fps.nit
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ redef class App
# Zero (or a negative value) means no limit.
#
# Applications can modify this value even during the main-loop.
var maximum_fps = 60 is writable
var maximum_fps = 60.0 is writable

# Current frame-rate
# Updated each 5 seconds.
Expand Down Expand Up @@ -53,23 +53,22 @@ redef class App
do
var t = clock.total.sec
if t >= frame_count_deadline then
var cfps = frame_count_deadline.to_f / 5.0
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 then return
var dt = clock.lapse
var target_dt = 1000000000 / mfps
var sec = dt.sec
var nanosec = dt.nanosec
if sec == 0 and nanosec < target_dt then
var sleep_t = target_dt - nanosec
sys.nanosleep(0, sleep_t)
dt = clock.lapse
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