removed timer implementation, replaced with thread and nanosleep to drive frame rate
This commit is contained in:
parent
0a41b25368
commit
6b302374a9
2
Makefile
2
Makefile
@ -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
|
||||||
|
|
||||||
|
54
main.cpp
54
main.cpp
@ -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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user