removed timer implementation, replaced with thread and nanosleep to drive frame rate

This commit is contained in:
Bob Polis 2020-10-26 20:51:31 +01:00
parent 0a41b25368
commit 6b302374a9
2 changed files with 26 additions and 30 deletions

View File

@ -27,7 +27,7 @@ else
CXXFLAGS += -D NDEBUG -O3 CXXFLAGS += -D NDEBUG -O3
endif endif
LDLIBS := -lm -lpthread -lscgui -lSDL2 -lcairo -lscerror -lrt LDLIBS := -lm -lpthread -lscgui -lSDL2 -lcairo -lscerror
.PHONY: all clean install .PHONY: all clean install

View File

@ -14,17 +14,21 @@
#include <libscgui.hpp> #include <libscgui.hpp>
#include <unistd.h> #include <unistd.h>
#include <cairo/cairo.h> #include <cairo/cairo.h>
#include <signal.h>
#include <time.h> #include <time.h>
#include <libscerror.hpp> #include <libscerror.hpp>
#include <cmath>
#include <thread>
const int WIDTH {700}; const int WIDTH {700};
const int HEIGHT {700}; const int HEIGHT {700};
constexpr double FPS {50.0};
constexpr int nanosecs {static_cast<int>(round(1000000000.0 / FPS))};
sc::gui::Window* main_window {nullptr}; sc::gui::Window* main_window {nullptr};
sc::gui::Image* main_image {nullptr}; sc::gui::Image* main_image {nullptr};
cairo_t* cr {nullptr}; cairo_t* cr {nullptr};
bool timer_expired {true}; bool expired {true};
bool should_run {true};
void print_help() { void print_help() {
std::cout << "usage: screensaver [-h|--version]\n"; std::cout << "usage: screensaver [-h|--version]\n";
@ -36,9 +40,15 @@ void print_version() {
std::cout << "screensaver version 1.0\n"; std::cout << "screensaver version 1.0\n";
} }
void timer_signal_handler(int /*sig*/, siginfo_t* /*si*/, void* /*uc*/) { void update_frame() {
// timer_t* tmr {si->si_value.sival_ptr}; while (should_run) {
timer_expired = true; expired = true;
struct timespec delay;
delay.tv_sec = 0;
delay.tv_nsec = nanosecs;
nanosleep(&delay, nullptr);
}
} }
void draw() { void draw() {
@ -49,8 +59,8 @@ void draw() {
static double r = 0; static double r = 0;
static double dr = 0.01; static double dr = 0.01;
if (timer_expired) { if (expired) {
timer_expired = false; expired = false;
sc::gui::ImageLock lock {*main_image}; sc::gui::ImageLock lock {*main_image};
// white background // white background
@ -86,7 +96,8 @@ void draw() {
if (x < 300) dx = 1; if (x < 300) dx = 1;
if (y < 300) dy = 1; if (y < 300) dy = 1;
r += dr; 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 // RAII instances
sc::gui::SDLWrapper sdl2; sc::gui::SDLWrapper sdl2;
sc::gui::SDLImageWrapper sdl_image; 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)}; CAIRO_FORMAT_RGB24, s->w, s->h, s->pitch)};
cr = cairo_create(cs); 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().add_run_loop_action(draw);
sc::gui::app().run(); sc::gui::app().run();
cairo_surface_destroy(cs); cairo_surface_destroy(cs);
cairo_destroy(cr); cairo_destroy(cr);
should_run = false;
frame_timer.join();
} catch (const std::exception& ex) { } catch (const std::exception& ex) {
std::cerr << "screensaver: " << ex.what() << '\n'; std::cerr << "screensaver: " << ex.what() << '\n';
return EXIT_FAILURE; return EXIT_FAILURE;