From 75a9ae1b3967edbd091100769e2e5a3b500f09f2 Mon Sep 17 00:00:00 2001 From: Peter Li Date: Sat, 27 Dec 2025 22:51:40 -0800 Subject: [PATCH] spec generation complete --- build.zig | 6 ++- build/engineDeps.zig | 8 ++-- build/program.zig | 27 ++++++++++- buildgen/{ => archive}/generateApi.zig | 0 buildgen/generateProgramSpec.zig | 64 +++++++++++++++++++++++++ buildgen/templates/launcher-templ.zig | 11 +++++ buildgen/templates/launcher.zig | 26 ++++++++++ buildgen/templates/trampoline-templ.zig | 0 engine/main2.zig | 21 +------- todo.txt | 7 +-- 10 files changed, 138 insertions(+), 32 deletions(-) rename buildgen/{ => archive}/generateApi.zig (100%) create mode 100644 buildgen/generateProgramSpec.zig create mode 100644 buildgen/templates/launcher-templ.zig create mode 100644 buildgen/templates/launcher.zig create mode 100644 buildgen/templates/trampoline-templ.zig diff --git a/build.zig b/build.zig index 3efa854..c78d3c8 100644 --- a/build.zig +++ b/build.zig @@ -14,10 +14,11 @@ backlogRoot: []const u8, reflectShaderPathList: [][]u8 = undefined, nwdep: *std.Build.Dependency, -apigen: *std.Build.Step.Compile, +// apigen: *std.Build.Step.Compile, shaderEmbedGen: *std.Build.Step.Compile, loadDynamicsGen: *std.Build.Step.Compile, rcGen: *std.Build.Step.Compile, +specGen: *std.Build.Step.Compile, generatedApis: std.StringHashMapUnmanaged(*std.Build.Module) = .{}, pub const BuildSystem = @This(); @@ -68,8 +69,9 @@ pub fn init(b: *std.Build, initOptions: InitOptions) BuildSystem { .cookShaders = b.option(bool, "cookShaders", "generates shaders and updates .json files before running the build. (needs to be done whenever shaders are updated, this just runs tools/scripts/cook-shaders.py)") orelse false, .nwdep = nwdep, - .apigen = nwdep.artifact("backlog-apigen"), + // .apigen = nwdep.artifact("backlog-apigen"), .loadDynamicsGen = nwdep.artifact("backlog-generate-loadDynamics"), + .specGen = nwdep.artifact("backlog-generate-spec"), .rcGen = nwdep.artifact("backlog-generate-rc"), .shaderEmbedGen = nwdep.artifact("backlog-shaderEmbedGen"), }; diff --git a/build/engineDeps.zig b/build/engineDeps.zig index 83f32c9..c506ddd 100644 --- a/build/engineDeps.zig +++ b/build/engineDeps.zig @@ -30,12 +30,12 @@ pub fn buildGenerators(b: *std.Build, opts: bh.Options) void { }), }); - const generateExe = b.addExecutable(.{ - .name = "backlog-apigen", + const generateProgramSpecExe = b.addExecutable(.{ + .name = "backlog-generate-spec", .root_module = b.createModule(.{ .target = b.graph.host, .optimize = .Debug, - .root_source_file = b.path("buildgen/generateApi.zig"), + .root_source_file = b.path("buildgen/generateProgramSpec.zig"), }), }); @@ -68,7 +68,7 @@ pub fn buildGenerators(b: *std.Build, opts: bh.Options) void { b.installArtifact(fwdGeneratorExe); b.installArtifact(generateLoadDynamicsExe); - b.installArtifact(generateExe); + b.installArtifact(generateProgramSpecExe); b.installArtifact(generateShaders); b.installArtifact(generateRcExe); diff --git a/build/program.zig b/build/program.zig index f340486..6a50f81 100644 --- a/build/program.zig +++ b/build/program.zig @@ -28,6 +28,28 @@ pub const Program = struct { self.iconPath = self.buildSystem.generateRc(self.name, path) catch return; } + pub fn makeSpec(self: *@This()) *std.Build.Module { + const b = self.buildSystem.b; + const run = b.addRunArtifact(self.buildSystem.specGen); + const pfile = run.addOutputFileArg(b.fmt("{s}-spec.zig", .{self.name})); + run.addArg(self.name); + for (self.gameModules.items) |mod| { + if (mod.enabled) + run.addArg(mod.name); + } + + const mod = b.createModule(.{ + .target = self.opts.target, + .optimize = self.opts.optimize, + .root_source_file = pfile, + }); + + const core = self.buildSystem.nwdep.module("core"); + mod.addImport("core", core); + + return mod; + } + pub fn compileInstall(self: *@This()) *std.Build.Step.Compile { const bEngine = self.buildSystem.bEngine; const b = self.buildSystem.b; @@ -50,6 +72,9 @@ pub const Program = struct { }), }); + // link core + const spec = self.makeSpec(); + exe.root_module.addImport("gamespec", spec); exe.root_module.addImport("core", core); exe.root_module.addImport("trampoline", trampoline); exe.root_module.addOptions("BacklogOptions", self.buildSystem.options); @@ -64,8 +89,6 @@ pub const Program = struct { run_exe.dependOn(&runArtifact.step); } - // link core - // 2. create the actual library that the loader will try to load // 3. set up linking, if static then we will link against the loader diff --git a/buildgen/generateApi.zig b/buildgen/archive/generateApi.zig similarity index 100% rename from buildgen/generateApi.zig rename to buildgen/archive/generateApi.zig diff --git a/buildgen/generateProgramSpec.zig b/buildgen/generateProgramSpec.zig new file mode 100644 index 0000000..6db72f2 --- /dev/null +++ b/buildgen/generateProgramSpec.zig @@ -0,0 +1,64 @@ +const std = @import("std"); + +pub fn usage() void { + std.debug.print("generate-program-spec \n", .{}); +} + +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) { + usage(); + @panic("Missing output filename\n"); + } + const out_path = args[1]; + + const programName = args[2]; + const modules = args[3..]; + + // Generate Zig code content + var writer = std.ArrayList(u8){}; + _ = try writer.appendSlice(allocator, + \\const core = @import("core").module; + \\ + \\ const std = @import("std"); + \\ pub fn getSpec() !*core.SpecVariantMap { + \\ const spec = try std.heap.smp_allocator.create(core.SpecVariantMap); + \\ spec.* = try core.createSpecVariant(.{ + \\ .useGPA = true, + ); + + try writer.print(allocator, ".name = \"{s}\",\n", .{programName}); + + for (modules) |mod| { + try writer.print(allocator, ".{s} = true,\n", .{mod}); + } + + _ = try writer.appendSlice(allocator, + \\ }, std.heap.smp_allocator); + \\ + \\ return spec; + \\ } + \\ + ); + + try writer.append(allocator, 0); + + // 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(); + + var ast = try std.zig.Ast.parse(allocator, @as([:0]const u8, @ptrCast(writer.items[0 .. writer.items.len - 1])), .zig); + + // std.debug.print("output=\n{s}", .{content.items[0 .. content.items.len - 1]}); + defer ast.deinit(allocator); + const out = try ast.renderAlloc(allocator); + + // Write the content to the file + try file.writeAll(out); +} diff --git a/buildgen/templates/launcher-templ.zig b/buildgen/templates/launcher-templ.zig new file mode 100644 index 0000000..a53e84d --- /dev/null +++ b/buildgen/templates/launcher-templ.zig @@ -0,0 +1,11 @@ +// templated file +// +// should still be a formattable zig file +// even if it is not compile-able +// +// definitions marked with // TEMPLATE_DEFINITION +// are removed during the templating step + +const programName = "__program_name"; // TEMPLATE_DEFINITION + +export fn loadModule() void {} diff --git a/buildgen/templates/launcher.zig b/buildgen/templates/launcher.zig new file mode 100644 index 0000000..0f6759e --- /dev/null +++ b/buildgen/templates/launcher.zig @@ -0,0 +1,26 @@ +// templated file +// +// should still be a formattable zig file +// even if it is not compile-able +// +// definitions marked with // TEMPLATE_DEFINITION +// are removed during the templating step + +const core = @import("core"); + +const programName = "__program_name"; // TEMPLATE_DEFINITION + +pub export fn startup_module(p_allocator: *anyopaque, p_a: ?*anyopaque) bool { + const allocator = core.modulePreamble(p_allocator, p_a) catch return false; + _ = allocator; + // imgui.setupFromModule(); + // platform.setupFromModule(); + // sys.setupFromModule(); + // rend.setupFromModule(); + // backlog.physics.setupFromModule(); + + core.engine_logs("creating externgame"); + // start_module(core.startup_getArgs(p_a.?)) catch return false; + + return true; +} diff --git a/buildgen/templates/trampoline-templ.zig b/buildgen/templates/trampoline-templ.zig new file mode 100644 index 0000000..e69de29 diff --git a/engine/main2.zig b/engine/main2.zig index 834c1a4..19da20f 100644 --- a/engine/main2.zig +++ b/engine/main2.zig @@ -4,9 +4,7 @@ const panickers = core.panickers; // const realMain = @import("main"); -// pub const gametree = @import("gametree"); - -pub const trampoline = @import("trampoline"); +pub const gamespec = @import("gamespec"); pub const options = @import("BacklogOptions"); pub const std_options = std.Options{ .enable_segfault_handler = true, @@ -40,21 +38,6 @@ fn fileExists(path: []const u8) bool { return true; } -// this should be provided by gametree, -pub fn getSpec(comptime name: []const u8) !*core.SpecVariantMap { - const spec = try std.heap.smp_allocator.create(core.SpecVariantMap); - spec.* = try core.createSpecVariant(.{ - .useGPA = true, - .name = name, - // placeholder module list. - .core = true, - .platform = true, - .assets = true, - }, std.heap.smp_allocator); - - return spec; -} - pub fn run() !void { core.engine_logs("calling gEngine.run"); @@ -144,7 +127,7 @@ pub fn main() !void { core.engine_log("Working Dir set: {s}", .{try std.fs.cwd().realpath(".", &BUFFER)}); } - const spec = try getSpec("sampleGame"); + const spec = try gamespec.getSpec(); _ = startEngine(spec); // panickers.attachSegfaultHandler(); diff --git a/todo.txt b/todo.txt index 11ac402..3db98e6 100644 --- a/todo.txt +++ b/todo.txt @@ -1,7 +1,4 @@ -What is thisthis -this is going to be an exercise in craftsmanship - -1. start with a simple main program that starts the core's loop. - +1. create generate-launcher.zig +2. create generate-landing.zig