#include "app/app.h" namespace app { void App::exit() { running = false; } void App::switch_to_scene(uint64_t scene_id) { scene_pool.release(current_scene_id); scene_pool.use(scene_id); current_scene_id = scene_id; } App::App(Vec2 size, const char *title) { window.update(size, title); Scene *loading_scene = new Scene{}; current_scene_id = scene_pool.acquire(loading_scene); } void App::set_fps(float fps) { this->fps = fps; target_frame_time = 1e9 / fps; } uint64_t App::get_fps() const { return fps; } void App::loop() { uint64_t frame_start = window.get_time(); uint64_t frame_end = window.get_time(); uint64_t previous_frame_end = 0; while (running) { frame_start = window.get_time(); uint64_t frame_time = frame_start - frame_end; if (frame_time <= target_frame_time) { struct timespec req; req.tv_sec = 0; req.tv_nsec = target_frame_time - frame_time; nanosleep(&req, nullptr); } previous_frame_end = frame_end; frame_end = window.get_time(); float dt = frame_end - previous_frame_end; Scene *scene = scene_pool[current_scene_id]; pressed_keys.clear(); released_keys.clear(); scroll = {0, 0}; text = ""; Event e; while (window.poll(e)) { switch (e.type) { case Event::QUIT: running = false; break; case Event::MOUSE_BUTTON_DOWN: scene->click(e.mouse_button.position); down_keys[e.mouse_button.button] = true; pressed_keys.push_back(e.mouse_button.button); break; case Event::MOUSE_BUTTON_UP: down_keys[e.mouse_button.button] = false; released_keys.push_back(e.mouse_button.button); break; case Event::MOUSE_MOVE: mouse_position = e.mouse_move.position; break; case Event::MOUSE_LEAVE: mouse_position = {-1, -1}; break; case Event::KEY_DOWN: down_keys[e.key.key] = true; pressed_keys.push_back(e.key.key); break; case Event::KEY_UP: down_keys[e.key.key] = false; released_keys.push_back(e.key.key); break; case Event::SCROLL: scroll = e.scroll; break; case Event::TEXT_INPUT: text += *e.text_input; delete e.text_input; break; default: break; } } int ai = mrb_gc_arena_save(Ruby::mrb); mrb_value dt_val = mrb_float_value(Ruby::mrb, dt / 1e9); update.call(1, &dt_val); scene->update_scene(dt_val); mrb_gc_arena_restore(Ruby::mrb, ai); scene->render(window.get_time()); window.render(); window.clear(); } } } // namespace app