aboutsummaryrefslogtreecommitdiff
path: root/src/sys.zig
blob: 6cb0864fa6b37d1d8bfbad65f3a8afcb161c81e4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
const std = @import("std");
const windows = std.os.windows;

const interface = @import("interface.zig");
const northstar = @import("northstar.zig");

const Class = @import("class.zig").Class;

const CSys = Class(.{}, .{
    .log = .{ .type = *const fn (*anyopaque, ?windows.HMODULE, LogLevel, [*:0]const u8) callconv(.C) void, .virtual = true },
    .unload = .{ .type = *const fn (*anyopaque, ?windows.HMODULE) callconv(.C) void, .virtual = true },
    .reload = .{ .type = *const fn (*anyopaque, ?windows.HMODULE) callconv(.C) void, .virtual = true },
});

var sys: ?*CSys = null;

pub const LogLevel = enum(c_int) { LOG_INFO, LOG_WARN, LOG_ERR };

pub fn init() void {
    if (northstar.create_interface) |create_interface| {
        var status: interface.InterfaceStatus = .IFACE_OK;
        sys = @ptrCast(@alignCast(create_interface("NSSys001", &status)));

        if (status != .IFACE_OK) {
            std.log.err("Failed to create NSSys001 interface: {}", .{status});
        }
    } else {
        std.log.err("Failed to create NSSys001 interface: {s}", .{"Failed to resolve CreateInterface"});
    }
}

pub fn log(
    comptime level: std.log.Level,
    comptime scope: @TypeOf(.EnumLiteral),
    comptime format: []const u8,
    args: anytype,
) void {
    const scope_prefix = switch (scope) {
        std.log.default_log_scope => "",
        else => "(" ++ @tagName(scope) ++ ") ",
    };

    var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
    defer arena.deinit();

    const allocator = arena.allocator();

    const log_level: LogLevel = switch (level) {
        .err => LogLevel.LOG_ERR,
        .warn => LogLevel.LOG_WARN,
        .info => LogLevel.LOG_INFO,
        .debug => LogLevel.LOG_INFO,
    };

    const msg = std.fmt.allocPrintZ(allocator, scope_prefix ++ format, args) catch unreachable;

    if (sys) |s| {
        if (s.vtable) |vtable| {
            vtable.log(s, northstar.plugin_handle, log_level, msg);
            return;
        }
    }

    std.log.defaultLog(level, scope, format, args);
}