diff --git a/src/GUI/MainWindow.cpp b/src/GUI/MainWindow.cpp index ef7c39a..9798312 100644 --- a/src/GUI/MainWindow.cpp +++ b/src/GUI/MainWindow.cpp @@ -20,7 +20,9 @@ f32 MainWindow::getDPI(){ return dpi; } -void MainWindow::init(const char* window_title){ +void MainWindow::open(const char* window_title, UpdatingFunc _update){ + update = _update; + SDL_TRY(SDL_Init(SDL_INIT_EVERYTHING)); SDL_version v; SDL_GetVersion(&v); @@ -76,9 +78,9 @@ void MainWindow::init(const char* window_title){ } // Wait, poll and handle events (inputs, window resize, etc.) -void MainWindow::poll_events(u16& frame_updates_requested, bool wait){ +void MainWindow::poll_events(bool waitForEvent){ SDL_Event event; - if(wait){ + if(waitForEvent){ // waits for first event in cpu-efficient way SDL_TRY(SDL_WaitEvent(&event) != 1); } @@ -87,8 +89,7 @@ void MainWindow::poll_events(u16& frame_updates_requested, bool wait){ return; do { - if(ImGui_ImplSDL2_ProcessEvent(&event)) - frame_updates_requested=2; + ImGui_ImplSDL2_ProcessEvent(&event); switch(event.type){ case SDL_QUIT: { close(); @@ -170,51 +171,34 @@ void MainWindow::draw_frame(){ SDL_RenderPresent(sdl_renderer); } -void MainWindow::startAndWait(){ +void MainWindow::startUpdateLoop(){ if(loop_running) - throw UsefulException("loop is already running"); + throw UsefulException("loop is running already"); - // draw first frame - draw_frame(); - - u16 frame_updates_requested=1; - u64 prev_update_time_ms=SDL_GetTicks64(); + nsec_t prev_update_time_ns = getMonotonicTimeNsec(); loop_running=true; // main loop while(loop_running){ - // waits for events - poll_events(frame_updates_requested, main_loop_wait_for_input); + poll_events(false); + + nsec_t update_time_ns = getMonotonicTimeNsec(); + if(update_time_ns < prev_update_time_ns) + throw UsefulException("monotonic clock returned unexpected value"); + f64 delta_time_s = (f64)(update_time_ns - prev_update_time_ns) / 1e9; + prev_update_time_ns = update_time_ns; - if(frame_updates_requested==0) - { - u64 update_time_ms=SDL_GetTicks64(); - if(update_time_ms >= prev_update_time_ms + 1000/fps_min){ - // if frame rate < fps_min then requests frame draw - // works only if main_loop_wait_for_input = false - frame_updates_requested=1; - prev_update_time_ms=update_time_ms; - } - else { - // skips frame rendering and waits to limit fps - u32 frame_delay_ms=1000/fps_max; - SDL_Delay(frame_delay_ms); - continue; - } - } + update(delta_time_s); + draw_frame(); - // deaws requested number of frames - while(frame_updates_requested>0) { - draw_frame(); - frame_updates_requested--; + nsec_t after_update_time_ns = getMonotonicTimeNsec(); + nsec_t frame_delay_ns = (nsec_t)1e9 / fps_max - (after_update_time_ns - update_time_ns); + if(frame_delay_ns > 0){ + std::cout<<"frameDelay: "< #include #include "../std.hpp" +#include "../time.hpp" /// converts hex color to float vector #define RGBAHexToF(R8,G8,B8,A8) ImVec4(((u8)35)/255.0f, ((u8)35)/255.0f, ((u8)50)/255.0f, ((u8)255)/255.0f) @@ -13,30 +14,32 @@ namespace ougge::GUI { #define default_font "DroidSans" +using UpdatingFunc = void (*)(f64 deltaTime); + class MainWindow { public: ImVec4 clear_color = RGBAHexToF(35,35,50,255); f32 default_font_size = 14.0f; - u8 fps_min = 30; - u8 fps_max = 60; + int fps_max = 30; + // called on each frame + UpdatingFunc update = nullptr; private: - bool loop_running=false; - bool main_loop_wait_for_input=true; + bool loop_running = false; bool show_demo_window = false; bool show_metrics_window = false; SDL_Window* sdl_window = nullptr; SDL_Renderer* sdl_renderer = nullptr; public: - void init(const char* window_title); - void startAndWait(); + void open(const char* window_title, UpdatingFunc update); + void startUpdateLoop(); void close(); - f32 getDPI(); private: void destroy(); - void poll_events(u16& frame_updates_requested, bool wait); + f32 getDPI(); + void poll_events(bool waitForEvent); void draw_frame(); void draw_ui(); void draw_debug_window(); diff --git a/src/main.cpp b/src/main.cpp index 540b7ea..1e862dd 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -8,15 +8,16 @@ using namespace ougge; -int main(int argc, const char** argv){ - if(setlocale(LC_CTYPE, "C.UTF-8")!=0) - std::cerr<<"\e[93msetlocale failed!\n"; +void update(f64 deltaTime){ + std::cout<<"deltaTime: "<= 199901L + #define _XOPEN_SOURCE 600 + #else + #define _XOPEN_SOURCE 500 + #endif +#endif + +#include "time.hpp" +#include +#include "UsefulException.hpp" + +nsec_t getMonotonicTimeNsec(){ + struct timespec t; + if(clock_gettime(CLOCK_MONOTONIC, &t) != 0) + throw UsefulException("clock_gettime(CLOCK_MONOTONIC) error"); + return (nsec_t)t.tv_sec * 1e9 + (nsec_t)t.tv_nsec; +} diff --git a/src/time.hpp b/src/time.hpp new file mode 100644 index 0000000..6c6bb6f --- /dev/null +++ b/src/time.hpp @@ -0,0 +1,10 @@ +#pragma once + +#include "std.hpp" + +/// nanoseconds +typedef i64 nsec_t; + +/// can be used to measure delta time +///@return time from some moment in nanoseconds. +nsec_t getMonotonicTimeNsec();