Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions src/store/capture_store.zig
Original file line number Diff line number Diff line change
Expand Up @@ -167,14 +167,15 @@ pub const CaptureStore = struct {
};
}

pub fn duration_seconds(self: *const @This(), io: std.Io) ?u64 {
pub fn duration(self: *const @This(), io: std.Io) ?f64 {
if (self.start_time) |start| {
const now = std.Io.Timestamp.now(io, .awake).nanoseconds;
const elapsed_ns = now - start.nanoseconds;
const elapsed_ns: f64 = @floatFromInt(now - start.nanoseconds);
if (elapsed_ns < 0) {
return 0;
}
return @intCast(@divTrunc(elapsed_ns, std.time.ns_per_s));

return elapsed_ns / @as(f64, @floatFromInt(std.time.ns_per_s));
}
return null;
}
Expand Down
9 changes: 7 additions & 2 deletions src/ui/draw_bottom_panel.zig
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,10 @@ pub fn draw_bottom_panel(allocator: Allocator, store: *Store, state: *Store.Stat
if (c.ImGui_CollapsingHeader("Video", c.ImGuiTreeNodeFlags_DefaultOpen)) {
const replay_buffer_duration_label = try util.format_duration_label(
allocator,
@intCast(state.capture.replay_buffer_metrics.duration_seconds(store.io) orelse 0),
.{
.seconds = state.capture.replay_buffer_metrics.duration(store.io) orelse 0,
.max = state.user_settings.user_settings.replay_seconds,
},
);
defer allocator.free(replay_buffer_duration_label);

Expand Down Expand Up @@ -132,7 +135,9 @@ pub fn draw_bottom_panel(allocator: Allocator, store: *Store, state: *Store.Stat

_ = c.ImGui_TableNextColumn();
if (state.capture.recording_to_disk) {
const recording_duration_label = try util.format_duration_label(allocator, @intCast(state.capture.recording_metrics.duration_seconds(store.io) orelse 0));
const recording_duration_label = try util.format_duration_label(allocator, .{
.seconds = state.capture.recording_metrics.duration(store.io) orelse 0,
});
defer allocator.free(recording_duration_label);
c.ImGui_TextUnformatted(recording_duration_label);
} else {
Expand Down
4 changes: 3 additions & 1 deletion src/ui/draw_left_column.zig
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,9 @@ fn draw_capture_settings(allocator: std.mem.Allocator, store: *Store, state: *St
replay_seconds_local = null;
}

const replay_duration_label = try util.format_duration_label(allocator, @intCast(replay_seconds));
const replay_duration_label = try util.format_duration_label(allocator, .{
.seconds = @floatFromInt(replay_seconds),
});
defer allocator.free(replay_duration_label);
c.ImGui_PushTextWrapPos(0);
c.ImGui_TextDisabled("Duration: %s", replay_duration_label.ptr);
Expand Down
39 changes: 37 additions & 2 deletions src/util.zig
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,22 @@ pub fn print_elapsed(io: std.Io, start_time: i128, prefix: []const u8) void {
log.debug("[{s}] time elapsed {}ms\n", .{ prefix, total_time });
}

pub fn format_duration_label(allocator: std.mem.Allocator, total_seconds: u32) ![:0]u8 {
pub fn format_duration_label(allocator: std.mem.Allocator, args: struct {
seconds: f64,
max: ?u32 = null,
}) ![:0]u8 {
const input_seconds = @max(args.seconds, 0.0);
// If max is provided, round seconds up and then take
// the min of the two. This prevents any flicker on the UI
// when a number changes from 9.9 to 10.0 for example.
const total_seconds: u64 = if (args.max) |max_seconds|
@min(
@as(u64, @intFromFloat(@ceil(input_seconds))),
max_seconds,
)
else
@intFromFloat(@trunc(input_seconds));

const hours = total_seconds / 3600;
const minutes = (total_seconds % 3600) / 60;
const seconds = total_seconds % 60;
Expand Down Expand Up @@ -281,7 +296,27 @@ test "Util - format_duration_label formats compact duration strings" {
};

for (cases) |case| {
const label = try format_duration_label(allocator, case.seconds);
const label = try format_duration_label(allocator, .{ .seconds = @floatFromInt(case.seconds) });
defer allocator.free(label);

try std.testing.expectEqualStrings(case.expected, label);
}

const replay_cases = [_]struct {
seconds: f64,
max: u32,
expected: []const u8,
}{
.{ .seconds = 8.9, .max = 10, .expected = "9s" },
.{ .seconds = 9.1, .max = 10, .expected = "10s" },
.{ .seconds = 10.2, .max = 10, .expected = "10s" },
};

for (replay_cases) |case| {
const label = try format_duration_label(allocator, .{
.seconds = case.seconds,
.max = case.max,
});
defer allocator.free(label);

try std.testing.expectEqualStrings(case.expected, label);
Expand Down
Loading