artificer/gui/main.zig

128 lines
4.0 KiB
Zig

// zig fmt: off
const std = @import("std");
const Lib = @import("lib");
const rl = @import("raylib");
const raylib_h = @cImport({
@cInclude("stdio.h");
@cInclude("raylib.h");
});
const App = @import("./app.zig");
const Api = Lib.Api;
pub const std_options = .{
.log_scope_levels = &[_]std.log.ScopeLevel{
.{ .scope = .api, .level = .warn },
.{ .scope = .raylib, .level = .warn },
}
};
fn toRaylibTraceLogLevel(log_level: std.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) ?std.log.Level {
return switch (log_type) {
@intFromEnum(rl.TraceLogLevel.log_trace) => std.log.Level.debug,
@intFromEnum(rl.TraceLogLevel.log_debug) => std.log.Level.debug,
@intFromEnum(rl.TraceLogLevel.log_info) => std.log.Level.info,
@intFromEnum(rl.TraceLogLevel.log_warning) => std.log.Level.warn,
@intFromEnum(rl.TraceLogLevel.log_error) => std.log.Level.err,
@intFromEnum(rl.TraceLogLevel.log_fatal) => std.log.Level.err,
else => null,
};
}
fn raylibTraceLogCallback(logType: c_int, text: [*c]const u8, args: [*c]raylib_h.struct___va_list_tag_1) 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} });
}
}
}
fn getAPITokenFromArgs(allocator: std.mem.Allocator) !?[]u8 {
const args = try std.process.argsAlloc(allocator);
defer std.process.argsFree(allocator, args);
if (args.len < 2) {
return null;
}
const filename = args[1];
const cwd = std.fs.cwd();
var token_buffer: [256]u8 = undefined;
const token = try cwd.readFile(filename, &token_buffer);
return try allocator.dupe(u8, std.mem.trim(u8, token, "\n\t "));
}
pub fn main() anyerror!void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const allocator = gpa.allocator();
raylib_h.SetTraceLogCallback(raylibTraceLogCallback);
rl.setTraceLogLevel(toRaylibTraceLogLevel(std.log.default_level));
const token = (try getAPITokenFromArgs(allocator)) orelse return error.MissingToken;
defer allocator.free(token);
var store = try Api.Store.init(allocator);
defer store.deinit(allocator);
var server = try Api.Server.init(allocator, &store);
defer server.deinit();
try server.setToken(token);
std.log.info("Prefetching server data", .{});
{
const cwd_path = try std.fs.cwd().realpathAlloc(allocator, ".");
defer allocator.free(cwd_path);
const cache_path = try std.fs.path.resolve(allocator, &.{ cwd_path, "./api-store-gui.bin" });
defer allocator.free(cache_path);
try server.prefetchCached(allocator, cache_path, .{ .images = true });
}
const characters = try server.getMyCharacters(allocator);
characters.deinit();
rl.initWindow(800, 450, "Artificer");
defer rl.closeWindow();
rl.setWindowMinSize(200, 200);
rl.setWindowState(.{
.vsync_hint = true,
.window_resizable = true
});
var app = try App.init(allocator, &store, &server);
defer app.deinit();
while (!rl.windowShouldClose()) {
try app.tick();
}
}