From 6b302374a9835e4735fbab03c10af675d4b55280 Mon Sep 17 00:00:00 2001 From: Bob Polis Date: Mon, 26 Oct 2020 20:51:31 +0100 Subject: [PATCH] removed timer implementation, replaced with thread and nanosleep to drive frame rate --- Makefile | 2 +- main.cpp | 54 +++++++++++++++++++++++++----------------------------- 2 files changed, 26 insertions(+), 30 deletions(-) diff --git a/Makefile b/Makefile index 58f5e96..807570a 100644 --- a/Makefile +++ b/Makefile @@ -27,7 +27,7 @@ else CXXFLAGS += -D NDEBUG -O3 endif -LDLIBS := -lm -lpthread -lscgui -lSDL2 -lcairo -lscerror -lrt +LDLIBS := -lm -lpthread -lscgui -lSDL2 -lcairo -lscerror .PHONY: all clean install diff --git a/main.cpp b/main.cpp index ac24167..1f47603 100644 --- a/main.cpp +++ b/main.cpp @@ -14,17 +14,21 @@ #include #include #include -#include #include #include +#include +#include const int WIDTH {700}; const int HEIGHT {700}; +constexpr double FPS {50.0}; +constexpr int nanosecs {static_cast(round(1000000000.0 / FPS))}; sc::gui::Window* main_window {nullptr}; sc::gui::Image* main_image {nullptr}; cairo_t* cr {nullptr}; -bool timer_expired {true}; +bool expired {true}; +bool should_run {true}; void print_help() { std::cout << "usage: screensaver [-h|--version]\n"; @@ -36,9 +40,15 @@ void print_version() { std::cout << "screensaver version 1.0\n"; } -void timer_signal_handler(int /*sig*/, siginfo_t* /*si*/, void* /*uc*/) { - // timer_t* tmr {si->si_value.sival_ptr}; - timer_expired = true; +void update_frame() { + while (should_run) { + expired = true; + + struct timespec delay; + delay.tv_sec = 0; + delay.tv_nsec = nanosecs; + nanosleep(&delay, nullptr); + } } void draw() { @@ -49,8 +59,8 @@ void draw() { static double r = 0; static double dr = 0.01; - if (timer_expired) { - timer_expired = false; + if (expired) { + expired = false; sc::gui::ImageLock lock {*main_image}; // white background @@ -86,7 +96,8 @@ void draw() { if (x < 300) dx = 1; if (y < 300) dy = 1; r += dr; - if (r > 1) r = 0; + if (r > 1) dr = -0.01; + if (r < 0) dr = 0.01; } } @@ -128,27 +139,6 @@ int main(int argc, const char * argv[]) { // } // } - // install timer signal handler - struct sigaction sa; - sa.sa_flags = SA_SIGINFO; - sa.sa_sigaction = timer_signal_handler; - sigemptyset(&sa.sa_mask); - throw_if_min1(sigaction(SIGRTMAX, &sa, nullptr)); - - // setup repeating timer with 100 ms interval - timer_t timer; - struct sigevent sev; - sev.sigev_notify = SIGEV_SIGNAL; - sev.sigev_signo = SIGRTMAX; - sev.sigev_value.sival_ptr = &timer; - struct itimerspec ts; - ts.it_interval.tv_sec = 0; - ts.it_interval.tv_nsec = 25000000; - ts.it_value.tv_sec = 0; - ts.it_value.tv_nsec = 1; - throw_if_min1(timer_create(CLOCK_REALTIME, &sev, &timer)); - throw_if_min1(timer_settime(timer, 0, &ts, nullptr)); - // RAII instances sc::gui::SDLWrapper sdl2; sc::gui::SDLImageWrapper sdl_image; @@ -168,12 +158,18 @@ int main(int argc, const char * argv[]) { CAIRO_FORMAT_RGB24, s->w, s->h, s->pitch)}; cr = cairo_create(cs); + // setup thread which periodically sets 'expired' + std::thread frame_timer {update_frame}; + sc::gui::app().add_run_loop_action(draw); sc::gui::app().run(); cairo_surface_destroy(cs); cairo_destroy(cr); + should_run = false; + frame_timer.join(); + } catch (const std::exception& ex) { std::cerr << "screensaver: " << ex.what() << '\n'; return EXIT_FAILURE;