Backlog/build/generateApi.zig

168 lines
6.7 KiB
Zig

const std = @import("std");
pub fn main() !void {
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
defer arena.deinit();
const allocator = arena.allocator();
// Get output filename from build system
const args = try std.process.argsAlloc(allocator);
if (args.len < 3) @panic("Missing output filename");
const out_path = args[1];
// Generate a startup module function that invokes
// startup module for each zig function
// and generates an api
var content = std.ArrayList(u8).init(allocator);
var writer = content.writer();
const moduleList = args[2..];
for (moduleList) |mod| {
try writer.print("pub const {s} = @import(\"{s}\").module;\n", .{ mod, mod });
}
try writer.print("pub const moduleList:[]const []const u8 = &.{{\n", .{});
for (moduleList) |mod| {
try writer.print("\"{s}\",\n", .{mod});
}
try writer.print("}};\n", .{});
try writer.print(
\\var shutdownList: std.ArrayListUnmanaged(*const fn (std.mem.Allocator) void) = .{{}};
\\var shutdownModuleNames: std.ArrayListUnmanaged([]const u8) = .{{}};
\\
\\ pub const NwArgs = struct {{
\\ useGPA: bool = false, // 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;
\\ }}
, .{});
try writer.print("pub fn start_modules_(spec: *core.SpecVariantMap, maybeArgs: ?NwArgs, allocator: std.mem.Allocator) !void {{", .{});
try writer.print(
\\
\\ var z = core.tracy.ZoneN(@src(), "Starting all Modules");
\\ defer z.End();
\\ inline for (moduleList) |feature| {{
\\ if (@hasDecl(@This(), feature)) {{
\\ const Struct = @field(@This(), feature);
\\ if (core.isModuleEnabled(Struct.Module, spec)) {{
\\ var z1 = core.tracy.ZoneN(@src(), @ptrCast("Initializing Module"));
\\ defer z1.End();
\\ core.tracy.Message(Struct.Module.name);
\\ if (maybeArgs) |args| {{
\\ try Struct.start_module(spec, args, allocator);
\\ }} else {{
\\ try Struct.start_module(spec, NwArgs{{}}, allocator);
\\ }}
\\ try shutdownList.append(allocator, Struct.shutdown_module);
\\ try shutdownModuleNames.append(allocator, feature);
\\ core.engine_logs("module started >>>> " ++ feature ++ " <<<<");
\\ }}
\\ }}
\\ }} }}
\\pub fn start_modules(spec: *core.SpecVariantMap, maybeArgs: ?NwArgs, allocator: std.mem.Allocator) bool {{ start_modules_(spec, maybeArgs, allocator) catch return false; return true;}}
\\
\\ pub fn shutdown_modules(allocator: std.mem.Allocator) void {{
\\ var i: isize = @intCast(shutdownList.items.len - 1);
\\ while (i >= 0) : (i -= 1) {{
\\ core.engine_log("module shutting down >>>> {{s}} <<<<", .{{shutdownModuleNames.items[@intCast(i)]}});
\\ shutdownList.items[@intCast(i)](allocator);
\\ }}
\\ shutdownList.deinit(allocator);
\\ shutdownModuleNames.deinit(allocator);
\\ }}
\\
, .{});
_ = try writer.write(
\\ pub fn startEngine(vtable: *core.EngineObjectVTable, spec: *core.SpecVariantMap) bool {
\\ const args = getArgs() catch return false;
\\
\\ 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 (spec.get("useGPA")) |arg| {
\\ if (arg.boolean == true) {
\\ 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 (!start_modules(spec, args, allocator)) return false;
\\ defer shutdown_modules(allocator);
\\
\\ run_everything_vtable(vtable) catch return false;
\\
\\ return true;
\\ }
\\
\\
\\ pub fn run_everything_vtable(gameVtable: *core.EngineObjectVTable) !void {
\\ core.engine_logs("creating Game context");
\\
\\ //_ = try core.createObject(GameContext, .{});
\\ _ = try core.createObjectVTable(gameVtable, .{});
\\
\\ core.engine_logs("calling gEngine.run");
\\
\\ try core.getEngine().run();
\\
\\ while (!core.getEngine().exitFinished()) {
\\ const z = core.tracy.ZoneN(@src(), "shutdown poll");
\\ z.End();
\\ }
\\ }
\\
\\ pub fn getSpec(comptime name:[]const u8) !core.SpecVariantMap {
\\ return try core.createSpecVariant(.{
\\ .name = name,
);
for (moduleList) |mod| {
try writer.print(".{s} = true,\n", .{mod});
}
try writer.print("}}, std.heap.c_allocator); }}\n", .{});
try writer.print("const std = @import(\"std\");\n", .{});
// Write to specified output file
// Open or create the file for writing (overwrites if it exists)
const file = try std.fs.cwd().createFile(out_path, .{});
defer file.close();
try content.append(0);
var ast = try std.zig.Ast.parse(allocator, @as([:0]const u8, @ptrCast(content.items[0 .. content.items.len - 1])), .zig);
std.debug.print("output={s}", .{content.items[0 .. content.items.len - 1]});
defer ast.deinit(allocator);
const out = try ast.render(allocator);
// Write the content to the file
try file.writeAll(out);
}