diff --git a/build/program.zig b/build/program.zig index bf3fa88..7d31285 100644 --- a/build/program.zig +++ b/build/program.zig @@ -44,7 +44,7 @@ pub const Program = struct { allocator: std.mem.Allocator, // just set this to the build allocator pub fn setModuleEnabled(self: *@This(), name: []const u8, enabled: bool) void { - const r = self.gameModulesMap.getOrPut(self.allocator, name); + const r = self.gameModulesMap.getOrPut(self.allocator, name) catch unreachable; r.value_ptr.* = enabled; } @@ -136,7 +136,7 @@ pub const Program = struct { // 1. generate the main launch codeset. const lib = b.addLibrary(.{ - .name = self.name, + .name = b.fmt("{s}-mod", .{self.name}), .linkage = if (opts.static_build) .static else .dynamic, .root_module = b.createModule(.{ .target = opts.target, @@ -145,8 +145,6 @@ pub const Program = struct { }), }); - lib.root_module.addImport("core", self.buildSystem.nwdep.module("core")); - if (opts.static_build) { // b.installArtifact(lib); } else { @@ -185,6 +183,11 @@ pub const Program = struct { const gameModule = self.makeGameModule(); const gameApi = self.makeGameApi(); gameModule.root_module.addImport("backlog", gameApi); + gameModule.root_module.addImport("gamespec", spec); + + if (self.opts.static_build) { + exe.root_module.addImport("backlog", gameApi); + } { const runArtifact = b.addRunArtifact(exe); diff --git a/buildgen/generateProgramSpec.zig b/buildgen/generateProgramSpec.zig index 6b841d7..94cee06 100644 --- a/buildgen/generateProgramSpec.zig +++ b/buildgen/generateProgramSpec.zig @@ -33,6 +33,7 @@ pub fn main() !void { ); try writer.print(allocator, ".name = \"{s}\",\n", .{programName}); + try writer.print(allocator, ".moduleName = \"{s}-mod\",\n", .{programName}); for (modules) |mod| { try writer.print(allocator, ".{s} = true,\n", .{mod}); diff --git a/engine/core/src/core.zig b/engine/core/src/core.zig index 1739f08..448258d 100644 --- a/engine/core/src/core.zig +++ b/engine/core/src/core.zig @@ -609,3 +609,7 @@ pub fn itof32(i: anytype) f32 { pub fn itof64(i: anytype) f32 { return @as(f32, @floatFromInt(i)); } + +pub fn setShutdownModule(shutdownFunction: *const fn () callconv(.c) void) void { + getEngine().shutdownModuleFunction = shutdownFunction; +} diff --git a/engine/core/src/engine.zig b/engine/core/src/engine.zig index a196955..01b0830 100644 --- a/engine/core/src/engine.zig +++ b/engine/core/src/engine.zig @@ -91,6 +91,8 @@ pub const Engine = struct { calibrationPeriod: f64 = 1.0, // in seconds first: bool = true, + shutdownModuleFunction: ?*const fn () callconv(.c) void = null, + pub fn init(allocator: std.mem.Allocator) !@This() { const rv = Engine{ .allocator = allocator, diff --git a/engine/main2.zig b/engine/main2.zig index 7f10412..99518fd 100644 --- a/engine/main2.zig +++ b/engine/main2.zig @@ -81,7 +81,7 @@ pub fn startEngine(spec: *core.SpecVariantMap) bool { _ = core.createNameRegistry(allocator) catch return false; core.maybeInitPackerFs(allocator) catch return false; - if (core.BuildOption("static_build")) { + if (comptime core.BuildOption("static_build")) { core.engine_log("static build, using embedded shaders", .{}); // const loader = @import("staticShaderLoader"); // loader.installStaticResources() catch return false; @@ -89,9 +89,16 @@ pub fn startEngine(spec: *core.SpecVariantMap) bool { core.start_module(spec, args, allocator) catch return false; - const programName = spec.get("name").?.string; + const moduleName = spec.get("moduleName").?.string; - core.loadModule(programName, true) catch return false; + if (comptime core.BuildOption("static_build")) { + const modlaunch = @import("modulelaunch.zig"); + var modargs = core.externModule.getModuleLoaderArgs(true); + var modalloc = allocator; + _ = modlaunch.startup_module(&modalloc, &modargs); + } else { + core.loadModule(moduleName, true) catch return false; + } // load the shared object and call startup() // core.beginLoading(""); @@ -101,6 +108,10 @@ pub fn startEngine(spec: *core.SpecVariantMap) bool { run() catch return false; + if (core.getEngine().shutdownModuleFunction) |f| { + f(); + } + core.shutdown_module(allocator); return true; diff --git a/engine/modulelaunch.zig b/engine/modulelaunch.zig index 245c4cc..c7a0d7c 100644 --- a/engine/modulelaunch.zig +++ b/engine/modulelaunch.zig @@ -1,16 +1,76 @@ +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; +} + +var shutdownList: std.ArrayListUnmanaged(*const fn (std.mem.Allocator) void) = .{}; +var shutdownModuleNames: std.ArrayListUnmanaged([]const u8) = .{}; + +var gAllocator: std.mem.Allocator = undefined; + pub export fn startup_module(p_allocator: *anyopaque, p_a: ?*anyopaque) bool { const allocator = core.modulePreamble(p_allocator, p_a) catch return false; - _ = allocator; + gAllocator = allocator; + core.engine_log("module started {s}", .{backlog.moduleName}); + const spec = gamespec.getSpec() catch return false; + for (backlog.moduleList) |li| { core.engine_log("mod: {s}", .{li}); } + const args = getArgs() catch NwArgs{}; + + inline for (backlog.moduleList) |feature| { + if (@hasDecl(backlog, feature) and !std.mem.eql(u8, "core", feature)) { + const Struct = @field(backlog, 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); + Struct.start_module(spec, args, allocator) catch return false; + + if (core.MemoryTracker.MTGet()) |_| { + core.MemoryTracker.MTPrintStatsDelta(); + } + + shutdownList.append(allocator, Struct.shutdown_module) catch return false; + shutdownModuleNames.append(allocator, feature) catch return false; + + core.engine_logs("module started >>>> " ++ feature ++ " <<<<"); + } + } + } + + core.setShutdownModule(shutdown_module); + return true; } -pub export fn shutdown_module() void {} +pub export fn shutdown_module() void { + var i: usize = shutdownList.items.len; + while (i > 0) { + const j = i - 1; + shutdownList.items[j](gAllocator); + i -= 1; + } + + shutdownList.deinit(gAllocator); + shutdownModuleNames.deinit(gAllocator); +} + +const gamespec = @import("gamespec"); const backlog = @import("backlog"); const core = backlog.core; +const std = @import("std"); diff --git a/projects/build.zig b/projects/build.zig index 646fffd..03b190e 100644 --- a/projects/build.zig +++ b/projects/build.zig @@ -15,5 +15,10 @@ pub fn build(b: *std.Build) void { "coreTest", ); coreTest.setIconPath("projects/content/icons/icon.ico"); + coreTest.setModuleEnabled("audio", true); + coreTest.setModuleEnabled("imgui", true); + coreTest.setModuleEnabled("net", true); + coreTest.setModuleEnabled("physics", true); + coreTest.setModuleEnabled("ui", true); _ = coreTest.compileInstall(); }