Backlog/engine/backlog.zig

143 lines
4.6 KiB
Zig

pub const core = @import("core");
pub const platform = @import("platform");
pub const assets = @import("assets");
pub const rend = @import("rend");
pub const audio = @import("audio");
// pub const graphics = @import("graphics");
// pub const vkImgui = @import("vkImgui");
// pub const ui = @import("ui");
pub const papyrus = @import("papyrus");
pub const physics = @import("physics");
const modulelist = @import("modulelist.zig").list;
const std = @import("std");
pub const NwArgs = struct {
useGPA: bool = true, // slower zig based memory allocator, provides detailed tracking of leaks and memory violations
vulkanValidation: bool = true,
fastTest: bool = false,
dmt: bool = false, // detailed memory tracking, implements a timeline for tracking all memory allocations
fatDump: bool = false, // takes a full fat minidump on crash, very large files are produced
};
pub fn getArgs() !NwArgs {
const a = try core.ParseArgs(NwArgs);
return a;
}
// entry function for a backlog program
// when this function is called it will use the settings specified by the program spec
// to conditionally start up feature modules within the engine
var shutdownList: std.ArrayListUnmanaged(*const fn (std.mem.Allocator) void) = .{};
pub fn start_modules(comptime programSpec: anytype, maybeArgs: ?NwArgs, allocator: std.mem.Allocator) !void {
const Backlog = @This();
inline for (modulelist) |feature| {
if (@hasDecl(Backlog, feature)) {
const Struct = @field(Backlog, feature);
if (comptime core.isModuleEnabled(Struct.Module, programSpec)) {
if (maybeArgs) |args| {
try Struct.start_module(programSpec, args, allocator);
} else {
try Struct.start_module(programSpec, NwArgs{}, allocator);
}
try shutdownList.append(allocator, Struct.shutdown_module);
core.engine_logs("module started >>>> " ++ feature ++ " <<<<");
}
}
}
}
pub fn shutdown_modules(allocator: std.mem.Allocator) void {
var i: isize = @intCast(shutdownList.items.len - 1);
while (i >= 0) : (i -= 1) {
shutdownList.items[@intCast(i)](allocator);
}
shutdownList.deinit(allocator);
}
pub fn start_everything(comptime spec: anytype, allocator: std.mem.Allocator, maybeArgs: ?NwArgs) !void {
//if (maybeArgs) |args| {
// //if (args.vulkanValidation)
// // graphics.setStartupSettings("vulkanValidation", true);
//}
try start_modules(spec, maybeArgs, allocator);
}
pub fn shutdown_everything(allocator: std.mem.Allocator) void {
shutdown_modules(allocator);
}
pub fn run_everything(comptime GameContext: type) !void {
var canTick: bool = false;
if (@hasDecl(GameContext, "tick")) {
canTick = true;
}
var gameContext = try core.createObject(GameContext, .{ .can_tick = canTick });
if (@hasDecl(GameContext, "prepare_game")) {
gameContext.prepare_game() catch @panic("Unable to run base level prepare script");
} else if (@hasDecl(GameContext, "prepare")) {
gameContext.prepare() catch @panic("Unable to run base level prepare script");
}
try core.gEngine.run();
while (!core.gEngine.exitFinished()) {
const z = core.tracy.ZoneN(@src(), "shutdown poll");
platform.getInstance().pollEvents();
z.End();
}
}
pub fn initializeAndRunStandardProgram(comptime GameContext: type, comptime spec: anytype) !void {
const args = try getArgs();
var backingAllocator: std.mem.Allocator = std.heap.c_allocator;
var gpa: std.heap.GeneralPurposeAllocator(.{
.stack_trace_frames = 20,
}) = .{};
defer {
const cleanupStatus = gpa.deinit();
if (cleanupStatus == .leak) {
std.debug.print("gpa cleanup leaked memory\n", .{});
}
}
if (args.useGPA) {
backingAllocator = gpa.allocator();
}
const memory = core.MemoryTracker;
memory.MTSetup(backingAllocator, .{ .timeline = args.dmt });
defer memory.MTShutdown();
var tracker = memory.MTGet().?;
const allocator = tracker.allocator();
if (args.vulkanValidation) {
core.engine_logs("Using vulkan validation");
}
// graphics.setStartupSettings("vulkanValidation", args.vulkanValidation);
if (@hasField(@TypeOf(spec), "windowName")) {
platform.setWindowSettings(.{ .windowName = spec.windowName });
} else {
platform.setWindowSettings(.{ .windowName = spec.name });
}
try start_everything(spec, allocator, args);
defer shutdown_everything(allocator);
try run_everything(GameContext);
}