Improve loop with fps control

This commit is contained in:
2026-05-20 21:47:25 +01:00
parent 6ff16e3db4
commit 2bff3eb93f
5 changed files with 54 additions and 29 deletions
+23 -10
View File
@@ -252,26 +252,35 @@ struct App {
current_scene_id = scene_pool.acquire(loading_scene);
}
void loop() {
const uint64_t TARGET_NS = 1e9 / 60;
void set_fps(float fps) {
this->fps = fps;
target_frame_time = 1e9 / fps;
}
uint64_t time_a = window.get_time();
uint64_t time_b = window.get_time();
uint64_t get_fps() const {
return fps;
}
void loop() {
uint64_t frame_start = window.get_time();
uint64_t frame_end = window.get_time();
uint64_t previous_frame_end = 0;
while (running) {
time_a = window.get_time();
uint64_t frame_time = time_a - time_b;
frame_start = window.get_time();
uint64_t frame_time = frame_start - frame_end;
if (frame_time <= TARGET_NS) {
if (frame_time <= target_frame_time) {
struct timespec req;
req.tv_sec = 0;
req.tv_nsec = TARGET_NS - frame_time;
req.tv_nsec = target_frame_time - frame_time;
nanosleep(&req, nullptr);
}
time_b = window.get_time();
previous_frame_end = frame_end;
frame_end = window.get_time();
uint64_t dt = window.delta_time();
float dt = frame_end - previous_frame_end;
Scene *scene = scene_pool[current_scene_id];
@@ -329,6 +338,10 @@ struct App {
window.clear();
}
}
private:
uint64_t fps = 60;
uint64_t target_frame_time = 1e9 / fps;
};
} // namespace app
+22 -2
View File
@@ -1487,11 +1487,29 @@ static mrb_value scene_hash(mrb_state *mrb, mrb_value self) {
static mrb_value app_run(mrb_state *mrb, mrb_value) {
mrb_int width, height;
mrb_value options_hash;
char *title = nullptr;
mrb_get_args(mrb, "iiz", &width, &height, &title);
mrb_get_args(mrb, "iiz|H", &width, &height, &title, &options_hash);
app_ = new app::App({(float)width, (float)height}, title);
float fps = 60;
if (!mrb_nil_p(options_hash))
HASH_FLOAT(options_hash, fps, fps);
app_->set_fps(fps);
return mrb_nil_value();
}
static mrb_value app_fps_get(mrb_state *mrb, mrb_value) {
return mrb_float_value(mrb, app_->get_fps());
}
static mrb_value app_fps_set(mrb_state *mrb, mrb_value) {
mrb_float fps;
mrb_get_args(mrb, "f", &fps);
app_->set_fps(fps);
return mrb_nil_value();
}
@@ -1750,9 +1768,11 @@ inline void setup() {
ADD_METHOD(Scene, "elements", scene_elements, MRB_ARGS_NONE());
DEF_MODULE(App);
ADD_MODULE_METHOD(App, "run", app_run, MRB_ARGS_REQ(3));
ADD_MODULE_METHOD(App, "run", app_run, MRB_ARGS_REQ(3) | MRB_ARGS_OPT(1));
ADD_MODULE_METHOD(App, "start", app_start, MRB_ARGS_REQ(1));
ADD_MODULE_METHOD(App, "switch_to", app_switch_to, MRB_ARGS_REQ(1));
ADD_MODULE_METHOD(App, "fps=", app_fps_set, MRB_ARGS_REQ(1));
ADD_MODULE_METHOD(App, "fps", app_fps_get, MRB_ARGS_NONE());
ADD_MODULE_METHOD(App, "localize", app_localize, MRB_ARGS_REQ(3));
ADD_MODULE_METHOD(App, "language=", app_language_set, MRB_ARGS_REQ(1));
ADD_MODULE_METHOD(App, "language", app_language_get, MRB_ARGS_NONE());
+1 -2
View File
@@ -341,8 +341,7 @@ public:
// Time
uint64_t get_time(); // returns the time in nanoseconds since the window was created
uint64_t delta_time(); // returns the time in nanoseconds since the last render call
uint64_t get_time(); // returns the time in nanoseconds since the window was created
private:
// internal data and functions