2023-10-28 22:48:08 +02:00
|
|
|
const std = @import("std");
|
|
|
|
|
|
|
|
const options = @import("options.zig");
|
|
|
|
|
2024-04-19 13:16:00 +02:00
|
|
|
timerfd: std.posix.fd_t,
|
|
|
|
timerfd_active: bool = false,
|
2023-10-28 22:48:08 +02:00
|
|
|
|
|
|
|
/// Contains a bool for each output, true if needs redraw
|
|
|
|
should_redraw: []bool,
|
|
|
|
|
|
|
|
const DrawTimerHandler = @This();
|
|
|
|
|
2024-04-19 13:16:00 +02:00
|
|
|
pub const timerspec: std.os.linux.itimerspec = spec: {
|
|
|
|
const interval = 1000 / options.fps;
|
|
|
|
|
|
|
|
break :spec .{
|
|
|
|
.it_value = .{ .tv_sec = 0, .tv_nsec = 1 },
|
|
|
|
.it_interval = .{
|
|
|
|
.tv_sec = @divTrunc(interval, std.time.ms_per_s),
|
|
|
|
.tv_nsec = @mod(interval, std.time.ms_per_s) * std.time.ns_per_ms,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
pub fn shouldDisarm(self: *DrawTimerHandler) bool {
|
2023-10-28 22:48:08 +02:00
|
|
|
for (self.should_redraw) |ro|
|
2024-04-19 13:16:00 +02:00
|
|
|
if (ro) return false;
|
|
|
|
return true;
|
2023-10-28 22:48:08 +02:00
|
|
|
}
|
|
|
|
|
2024-04-19 13:16:00 +02:00
|
|
|
pub fn maybeWake(self: *DrawTimerHandler) !void {
|
|
|
|
if (!self.timerfd_active and !self.shouldDisarm()) {
|
|
|
|
try std.posix.timerfd_settime(self.timerfd, .{}, &timerspec, null);
|
|
|
|
self.timerfd_active = true;
|
2023-10-28 22:48:08 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-04-19 13:16:00 +02:00
|
|
|
pub fn damage(self: *DrawTimerHandler, idx: usize) !void {
|
2023-10-28 22:48:08 +02:00
|
|
|
self.should_redraw[idx] = true;
|
2024-04-19 13:16:00 +02:00
|
|
|
try self.maybeWake();
|
2023-10-28 22:48:08 +02:00
|
|
|
}
|
|
|
|
|
2024-04-19 13:16:00 +02:00
|
|
|
pub fn damageAll(self: *DrawTimerHandler) !void {
|
2023-10-28 23:06:24 +02:00
|
|
|
@memset(self.should_redraw, true);
|
2024-04-19 13:16:00 +02:00
|
|
|
try self.maybeWake();
|
2023-10-28 23:06:24 +02:00
|
|
|
}
|