DVUI

beginWait

Coordinates with Window.waitTime to run frames only when needed.

If on the previous frame you called Window.waitTime and waited with event interruption, then pass true if that wait was interrupted (by an event).

Typically called right before Window.begin.

See usage in the example folder for the backend of you choice.

Parameters

#
self:*Self
*Self
interrupted:bool
bool

Source

Implementation

#
pub fn beginWait(self: *Self, interrupted: bool) i128 {
    var new_time = @max(self.frame_time_ns, self.backend.nanoTime());

    if (self.loop_wait_target) |target| {
        if (self.loop_wait_target_can_interrupt and interrupted) {
            // interrupted by event, so don't adjust slop for target
            //std.debug.print("beginWait interrupted by event\n", .{});
            return new_time;
        }

        //std.debug.print("beginWait adjusting slop\n", .{});
        // we were trying to sleep for a specific amount of time, adjust slop to
        // compensate if we didn't hit our target
        if (new_time > target) {
            // woke up later than expected
            self.loop_target_slop_frames = math.clamp(self.loop_target_slop_frames * 2, 1, 1000);
            self.loop_target_slop += self.loop_target_slop_frames;
        } else if (new_time < target) {
            // woke up sooner than expected
            self.loop_target_slop_frames = math.clamp(self.loop_target_slop_frames * 2, -1000, -1);
            self.loop_target_slop += self.loop_target_slop_frames;

            const max_behind = std.time.ns_per_ms;
            if (new_time > target - max_behind) {
                // we are early (but not too early), so spin a bit to try and hit target
                //var i: usize = 0;
                //var first_time = new_time;
                while (new_time < target) {
                    //i += 1;
                    self.backend.sleep(0);
                    new_time = @max(self.frame_time_ns, self.backend.nanoTime());
                }

                //if (i > 0) {
                //  std.debug.print("    begin {d} spun {d} {d}us\n", .{self.loop_target_slop, i, @divFloor(new_time - first_time, 1000)});
                //}
            }
        }

        // make sure this never gets too crazy -1ms to 100ms
        self.loop_target_slop = math.clamp(self.loop_target_slop, -1_000, 100_000);
    }

    //std.debug.print("beginWait {d:6} {d}\n", .{ self.loop_target_slop, self.loop_target_slop_frames });
    return new_time;
}