112 lines
3.8 KiB
Zig
112 lines
3.8 KiB
Zig
const std = @import("std");
|
|
const rl = @import("raylib");
|
|
const Assets = @import("./assets.zig");
|
|
const Allocator = std.mem.Allocator;
|
|
const assert = std.debug.assert;
|
|
const FontId = Assets.FontId;
|
|
|
|
const srcery = @import("./srcery.zig");
|
|
const rect_utils = @import("./rect-utils.zig");
|
|
|
|
allocator: Allocator,
|
|
history: []u128,
|
|
history_size: usize,
|
|
history_head: usize,
|
|
|
|
started_at: i128,
|
|
ns_budget: u128,
|
|
font: FontId,
|
|
|
|
pub fn init(allocator: Allocator, data_points: usize, ns_budget: u128, font: FontId) !@This() {
|
|
return @This(){
|
|
.allocator = allocator,
|
|
.history = try allocator.alloc(u128, data_points),
|
|
.history_size = 0,
|
|
.history_head = 0,
|
|
.started_at = 0,
|
|
.ns_budget = ns_budget,
|
|
.font = font,
|
|
};
|
|
}
|
|
|
|
pub fn deinit(self: @This()) void {
|
|
self.allocator.free(self.history);
|
|
}
|
|
|
|
pub fn start(self: *@This()) void {
|
|
self.started_at = std.time.nanoTimestamp();
|
|
}
|
|
|
|
pub fn stop(self: *@This()) void {
|
|
const stopped_at = std.time.nanoTimestamp();
|
|
assert(stopped_at >= self.started_at);
|
|
|
|
const duration: u128 = @intCast(stopped_at - self.started_at);
|
|
|
|
if (self.history_size < self.history.len) {
|
|
self.history[self.history_size] = duration;
|
|
self.history_size += 1;
|
|
} else {
|
|
self.history_head = @mod(self.history_head + 1, self.history.len);
|
|
self.history[self.history_head] = duration;
|
|
}
|
|
}
|
|
|
|
pub fn showResults(self: *const @This()) !void {
|
|
const screen_width: f32 = @floatFromInt(rl.getScreenWidth());
|
|
const screen_height: f32 = @floatFromInt(rl.getScreenHeight());
|
|
|
|
const profile_height = 200;
|
|
const profile_box = rl.Rectangle.init(0, screen_height - profile_height, screen_width, profile_height);
|
|
const color = srcery.bright_white;
|
|
rl.drawRectangleLinesEx(profile_box, 1, color);
|
|
|
|
const ns_budget: f32 = @floatFromInt(self.ns_budget);
|
|
|
|
const measurement_width = profile_box.width / @as(f32, @floatFromInt(self.history.len));
|
|
for (0..self.history_size) |i| {
|
|
const measurement = self.history[@mod(self.history_head + i, self.history.len)];
|
|
const measurement_height = @as(f32, @floatFromInt(measurement)) / ns_budget * profile_box.height;
|
|
rl.drawRectangleV(
|
|
.{
|
|
.x = profile_box.x + measurement_width * @as(f32, @floatFromInt(i + self.history.len - self.history_size)),
|
|
.y = profile_box.y + profile_box.height - measurement_height
|
|
},
|
|
.{ .x = measurement_width, .y = measurement_height },
|
|
color
|
|
);
|
|
}
|
|
|
|
var min_time_taken = self.history[0];
|
|
var max_time_taken = self.history[0];
|
|
var sum_time_taken: u128 = 0;
|
|
for (self.history[0..self.history_size]) |measurement| {
|
|
min_time_taken = @min(min_time_taken, measurement);
|
|
max_time_taken = @max(max_time_taken, measurement);
|
|
sum_time_taken += measurement;
|
|
}
|
|
const avg_time_taken = @as(f32, @floatFromInt(sum_time_taken)) / @as(f32, @floatFromInt(self.history_size));
|
|
|
|
const content_rect = rect_utils.shrink(profile_box, 10);
|
|
var layout_offset: f32 = 0;
|
|
|
|
const allocator = self.allocator;
|
|
const font_face = Assets.font(self.font);
|
|
const font_size = font_face.getSize();
|
|
|
|
const labels = .{
|
|
.{ "Min", @as(f32, @floatFromInt(min_time_taken)) },
|
|
.{ "Max", @as(f32, @floatFromInt(max_time_taken)) },
|
|
.{ "Avg", avg_time_taken }
|
|
};
|
|
|
|
inline for (labels) |label| {
|
|
const label_name = label[0];
|
|
const time_taken = label[1];
|
|
const min_time_str = try std.fmt.allocPrintZ(allocator, "{s}: {d:10.0}us ({d:.3}%)", .{ label_name, time_taken / std.time.ns_per_us, time_taken / ns_budget * 100 });
|
|
defer allocator.free(min_time_str);
|
|
|
|
font_face.drawText(min_time_str, .{ .x = content_rect.x, .y = content_rect.y + layout_offset }, color);
|
|
layout_offset += font_size;
|
|
}
|
|
} |