daq-view/src/main.zig

193 lines
5.7 KiB
Zig

const std = @import("std");
const rl = @import("raylib");
const builtin = @import("builtin");
const Application = @import("./app.zig");
const Assets = @import("./assets.zig");
const Profiler = @import("./my-profiler.zig");
const Platform = @import("./platform/root.zig");
const raylib_h = @cImport({
@cInclude("stdio.h");
@cInclude("raylib.h");
});
const log = std.log;
const profiler_enabled = builtin.mode == .Debug;
// TODO: Maybe move this to a config.zig or options.zig file.
// Have all of the contstants in a single file.
pub const version = std.SemanticVersion{
.major = 0,
.minor = 1,
.patch = 0
};
fn toRaylibLogLevel(log_level: log.Level) rl.TraceLogLevel {
return switch (log_level) {
.err => rl.TraceLogLevel.log_error,
.warn => rl.TraceLogLevel.log_warning,
.info => rl.TraceLogLevel.log_info,
.debug => rl.TraceLogLevel.log_trace,
};
}
fn toZigLogLevel(log_type: c_int) ?log.Level {
return switch (log_type) {
@intFromEnum(rl.TraceLogLevel.log_trace) => log.Level.debug,
@intFromEnum(rl.TraceLogLevel.log_debug) => log.Level.debug,
@intFromEnum(rl.TraceLogLevel.log_info) => log.Level.info,
@intFromEnum(rl.TraceLogLevel.log_warning) => log.Level.warn,
@intFromEnum(rl.TraceLogLevel.log_error) => log.Level.err,
@intFromEnum(rl.TraceLogLevel.log_fatal) => log.Level.err,
else => null
};
}
fn raylibTraceLogCallback(logType: c_int, text: [*c]const u8, args: raylib_h.va_list) callconv(.C) void {
const log_level = toZigLogLevel(logType) orelse return;
const scope = .raylib;
const raylib_log = std.log.scoped(scope);
const max_tracelog_msg_length = 256; // from utils.c in raylib
var buffer: [max_tracelog_msg_length:0]u8 = undefined;
inline for (std.meta.fields(std.log.Level)) |field| {
const message_level: std.log.Level = @enumFromInt(field.value);
if (std.log.logEnabled(message_level, scope) and log_level == message_level) {
@memset(&buffer, 0);
const text_length = raylib_h.vsnprintf(&buffer, buffer.len, text, args);
const formatted_text = buffer[0..@intCast(text_length)];
const log_function = @field(raylib_log, field.name);
@call(.auto, log_function, .{ "{s}", .{formatted_text} });
}
}
}
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{
.thread_safe = true
}){};
const allocator = gpa.allocator();
defer _ = gpa.deinit();
Platform.init(allocator);
defer Platform.deinit(allocator);
// TODO: Setup logging to a file
raylib_h.SetTraceLogCallback(raylibTraceLogCallback);
rl.setTraceLogLevel(toRaylibLogLevel(std.options.log_level));
const icon_png = @embedFile("./assets/icon.png");
var icon_image = rl.loadImageFromMemory(".png", icon_png);
defer icon_image.unload();
rl.initWindow(800, 600, "DAQ view");
defer rl.closeWindow();
rl.setWindowState(.{ .window_resizable = true, .vsync_hint = true });
rl.setWindowMinSize(256, 256);
rl.setWindowIcon(icon_image);
const target_fps = 60;
rl.setTargetFPS(target_fps);
if (builtin.mode != .Debug) {
rl.setExitKey(.key_null);
}
try Assets.init(allocator);
defer Assets.deinit(allocator);
var app: Application = undefined;
try Application.init(&app, allocator);
defer app.deinit();
if (builtin.mode == .Debug) {
var cwd_realpath_buff: [std.fs.MAX_PATH_BYTES]u8 = undefined;
const cwd_realpath = try std.fs.cwd().realpath(".", &cwd_realpath_buff);
const save_location = try std.fs.path.join(allocator, &.{ cwd_realpath, "project.proj" });
errdefer allocator.free(save_location);
app.project.save_location = save_location;
app.project.sample_rate = 5000;
// _ = try app.addView(.{
// .channel = try app.addChannel("Dev1/ai0")
// });
// _ = try app.addView(.{
// .file = try app.addFile("./samples-5k.bin")
// });
// _ = try app.addView(.{
// .file = try app.addFile("./samples-50k.bin")
// });
// _ = try app.addView(.{
// .file = try app.addFile("./samples-300k.bin")
// });
// _ = try app.addView(.{
// .file = try app.addFile("./samples-9m.bin")
// });
// _ = try app.addView(.{
// .file = try app.addFile("./samples-18m.bin")
// });
}
var profiler: ?Profiler = null;
defer if (profiler) |p| p.deinit();
var profiler_shown = false;
if (profiler_enabled) {
profiler = try Profiler.init(
allocator,
10 * target_fps,
@divFloor(std.time.ns_per_s, target_fps),
Assets.FontId{ .variant = .regular, .size = 16 }
);
}
rl.setExitKey(rl.KeyboardKey.key_null);
var last_font_cleanup_at = rl.getTime();
while (!rl.windowShouldClose() and !app.should_close) {
rl.beginDrawing();
{
if (profiler) |*p| {
p.start();
}
try app.tick();
if (profiler) |*p| {
p.stop();
if (rl.isKeyPressed(.key_p) and rl.isKeyDown(.key_left_control)) {
profiler_shown = !profiler_shown;
}
if (profiler_shown) {
try p.showResults();
}
}
const now = rl.getTime();
if (now - last_font_cleanup_at > 10) {
Assets.deinitUnusedFonts();
last_font_cleanup_at = now;
}
}
rl.endDrawing();
}
}
test {
_ = @import("./ni-daq/root.zig");
_ = @import("./range.zig");
_ = @import("./graph.zig");
}