Compare commits
21 Commits
dev/parall
...
dev/varian
| Author | SHA1 | Date |
|---|---|---|
|
|
2d59109994 | |
|
|
bae150305d | |
|
|
6300ef0e35 | |
|
|
a518a89798 | |
|
|
e69a8d13ec | |
|
|
ef91c4599b | |
|
|
9f9f40abd9 | |
|
|
81aaaa81b7 | |
|
|
c36cae7db9 | |
|
|
a06b0e6394 | |
|
|
17b3a4c23d | |
|
|
81132ac97b | |
|
|
97c8de24b9 | |
|
|
bb99e9025e | |
|
|
b4fa25106a | |
|
|
75a9ae1b39 | |
|
|
18b5537826 | |
|
|
b248573930 | |
|
|
3648615829 | |
|
|
8a30c78260 | |
|
|
cc00fb076e |
31
CLAUDE.md
31
CLAUDE.md
|
|
@ -96,37 +96,6 @@ The shader compilation system automatically discovers `.hlsl` files in `engine/*
|
|||
- The build system generates API wrappers automatically for enabled modules
|
||||
- Content directory location is determined by `content.txt` file pointing to `projects/content/`
|
||||
|
||||
### MakeModLib Build Helper
|
||||
|
||||
The project uses a custom `MakeModLib` helper function (defined in `lib/bh/build.zig`) to create library modules with consistent patterns:
|
||||
|
||||
```zig
|
||||
const mylib = bh.MakeModLib(b, .{
|
||||
.name = "mylib",
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.static_build = static_build,
|
||||
.root = b.path("src/mylib.zig"),
|
||||
});
|
||||
```
|
||||
|
||||
**What MakeModLib creates:**
|
||||
- A Zig module (`.mod`) for compile-time imports
|
||||
- A library artifact (`.lib`) for linking (static or dynamic based on `static_build` flag)
|
||||
- The library uses an empty stub source file and is intended to carry C dependencies
|
||||
|
||||
**Usage pattern:**
|
||||
All libraries using `MakeModLib` follow this pattern in their test executables:
|
||||
```zig
|
||||
tests.root_module.addImport("mylib", mylib.mod); // Import the module
|
||||
tests.root_module.linkLibrary(mylib.lib); // Link the library
|
||||
```
|
||||
|
||||
**Libraries using MakeModLib:**
|
||||
- `bh`, `cimgui`, `enet`, `lua`, `miniaudio`, `nfd`, `objLoader`, `p2`, `packer`, `spng`, `tracy`, `watcher`, `zgltf`, `zmath`
|
||||
|
||||
This pattern separates Zig code (in the module) from C/C++ dependencies (in the library), allowing for flexible static/dynamic linking while maintaining consistent module interfaces.
|
||||
|
||||
## Common Development Tasks
|
||||
|
||||
- Adding new engine modules: Create in `engine/` with `build.zig` and add to `engineDepList`
|
||||
|
|
|
|||
|
|
@ -97,11 +97,4 @@ git bug bug comment abc123
|
|||
- Issues sync with `git bug pull/push`
|
||||
- Keep descriptions factual and clear
|
||||
|
||||
---
|
||||
|
||||
/// --------------------------------------------------------
|
||||
void* malloc(size_t size); // gives you a pointer to a memory buffer of size
|
||||
void free(void* ptr); // releases a pointer to memory
|
||||
/// --------------------------------------------------------
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,662 @@
|
|||
// MVK_CONFIG_USE_METAL_ARGUMENT_BUFFERS=1 -- use this if you're getting that odd crash on mac
|
||||
b: *std.Build,
|
||||
nw_builder: *std.Build,
|
||||
target: std.Build.ResolvedTarget,
|
||||
optimize: std.builtin.OptimizeMode,
|
||||
nw_mod: *std.Build.Module,
|
||||
gltf2ozz: ozz.GltfToOzz,
|
||||
options: *std.Build.Step.Options,
|
||||
cookShaders: bool,
|
||||
|
||||
backlogRoot: []const u8,
|
||||
// list of all shaders discovered under
|
||||
// content/_shaders/def
|
||||
reflectShaderPathList: [][]u8 = undefined,
|
||||
|
||||
staticBuild: bool = false,
|
||||
|
||||
nwdep: *std.Build.Dependency,
|
||||
apigen: *std.Build.Step.Compile,
|
||||
shaderEmbedGen: *std.Build.Step.Compile,
|
||||
loadDynamicsGen: *std.Build.Step.Compile,
|
||||
rcGen: *std.Build.Step.Compile,
|
||||
generatedApis: std.StringHashMapUnmanaged(*std.Build.Module) = .{},
|
||||
|
||||
const engineDepList = [_][]const u8{
|
||||
"assets",
|
||||
"audio",
|
||||
"core",
|
||||
"net",
|
||||
"papyrus",
|
||||
"platform",
|
||||
"rend",
|
||||
"ui",
|
||||
"imgui",
|
||||
"physics",
|
||||
"sys",
|
||||
};
|
||||
|
||||
const BuildSystem = @This();
|
||||
const std = @import("std");
|
||||
const Build = std.Build;
|
||||
const LazyPath = Build.LazyPath;
|
||||
|
||||
const ozz = @import("ozz");
|
||||
|
||||
pub const InitOptions = struct {
|
||||
import_name: []const u8 = "Backlog",
|
||||
backlogRoot: []const u8 = "./BacklogEngine",
|
||||
staticBuild: bool = false,
|
||||
target: Build.ResolvedTarget,
|
||||
optimize: std.builtin.OptimizeMode,
|
||||
};
|
||||
|
||||
pub fn init(b: *std.Build, opts: InitOptions) BuildSystem {
|
||||
var buildOpts = declareBuildOptions(b);
|
||||
|
||||
if (opts.target.result.os.tag == .linux) {
|
||||
// using a static build for linux... object loading hell is not fun
|
||||
std.debug.print("Important! only supporting static builds for linux", .{});
|
||||
buildOpts.static_build = true;
|
||||
}
|
||||
|
||||
const nwdep = b.dependency(opts.import_name, .{
|
||||
.target = opts.target,
|
||||
.optimize = opts.optimize,
|
||||
.static_build = buildOpts.static_build,
|
||||
});
|
||||
|
||||
var self = BuildSystem{
|
||||
.b = b,
|
||||
.nw_builder = nwdep.builder,
|
||||
.target = opts.target,
|
||||
.optimize = opts.optimize,
|
||||
.nw_mod = nwdep.module("Backlog"),
|
||||
.backlogRoot = opts.backlogRoot,
|
||||
.options = createGameOptions(b, buildOpts),
|
||||
.gltf2ozz = ozz.GltfToOzz.init(nwdep.builder, .{}),
|
||||
.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,
|
||||
|
||||
.staticBuild = buildOpts.static_build,
|
||||
.nwdep = nwdep,
|
||||
.apigen = nwdep.artifact("backlog-apigen"),
|
||||
.loadDynamicsGen = nwdep.artifact("backlog-generate-loadDynamics"),
|
||||
.rcGen = nwdep.artifact("backlog-generate-rc"),
|
||||
.shaderEmbedGen = nwdep.artifact("backlog-shaderEmbedGen"),
|
||||
};
|
||||
|
||||
const exeList = [1]*std.Build.Step.Compile{self.gltf2ozz.exe};
|
||||
const install_tools = b.step("tools", "installs tools needed to generate outputs for the engine");
|
||||
for (exeList) |exe| {
|
||||
const toolsInstall = b.addInstallArtifact(exe, .{
|
||||
.dest_dir = .{ .override = .{ .custom = "tools" } },
|
||||
});
|
||||
|
||||
install_tools.dependOn(&toolsInstall.step);
|
||||
}
|
||||
|
||||
{
|
||||
const runArtifact = b.addRunArtifact(self.gltf2ozz.exe);
|
||||
if (b.args) |args| {
|
||||
runArtifact.addArgs(args);
|
||||
}
|
||||
|
||||
const run_exe = b.step("gltf2ozz", "runs the gltf animation converter.");
|
||||
run_exe.dependOn(&runArtifact.step);
|
||||
}
|
||||
|
||||
self.addDependencyInstalls(self.b, .ReleaseFast);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
pub const AddProgramOptions = struct {
|
||||
name: []const u8,
|
||||
desc: []const u8,
|
||||
root_source_file: LazyPath,
|
||||
imports: []const Build.Module.Import = &.{},
|
||||
};
|
||||
|
||||
pub fn addProgram(self: *BuildSystem, opts: AddProgramOptions) *std.Build.Module {
|
||||
const b = self.b;
|
||||
|
||||
const exe = self.nw_builder.addExecutable(.{
|
||||
.name = opts.name,
|
||||
.root_module = b.createModule(.{
|
||||
.target = self.target,
|
||||
.optimize = self.optimize,
|
||||
.root_source_file = self.nw_builder.path("engine/main.zig"),
|
||||
}),
|
||||
});
|
||||
|
||||
b.installArtifact(exe);
|
||||
const runArtifact = b.addRunArtifact(exe);
|
||||
if (b.args) |args| {
|
||||
runArtifact.addArgs(args);
|
||||
}
|
||||
const run_exe = b.step(self.b.fmt("run-{s}", .{opts.name}), opts.desc);
|
||||
run_exe.dependOn(&runArtifact.step);
|
||||
|
||||
// main path = name/main.zig
|
||||
const mod = b.addModule(opts.name, .{
|
||||
.target = self.target,
|
||||
.optimize = self.optimize,
|
||||
.root_source_file = opts.root_source_file,
|
||||
.imports = opts.imports,
|
||||
});
|
||||
|
||||
exe.root_module.addImport("main", mod);
|
||||
// todo.. remove this one and see what happens
|
||||
exe.root_module.addImport("core", self.nwdep.module("core"));
|
||||
// mod.addImport("Backlog", self.nw_mod);
|
||||
exe.root_module.addOptions("BacklogOptions", self.options);
|
||||
|
||||
if (self.cookShaders) {
|
||||
const cookShadersScript = b.fmt("{s}/tools/scripts/cookShaders.py", .{self.backlogRoot});
|
||||
const cookShadersCommand = b.addSystemCommand(&[_][]const u8{"python"});
|
||||
cookShadersCommand.addArg(cookShadersScript);
|
||||
|
||||
run_exe.dependOn(&cookShadersCommand.step);
|
||||
}
|
||||
|
||||
b.getInstallStep().dependOn(self.nw_builder.getInstallStep());
|
||||
|
||||
// run_exe.dependOn(b.getInstallStep());
|
||||
|
||||
return mod;
|
||||
}
|
||||
|
||||
pub const BuildOptions = struct {
|
||||
mutex_job_queue: bool,
|
||||
static_build: bool,
|
||||
zero_logging: bool,
|
||||
slow_logging: bool,
|
||||
force_mailbox: bool,
|
||||
};
|
||||
|
||||
pub fn declareBuildOptions(b: *std.Build) BuildOptions {
|
||||
return .{
|
||||
.mutex_job_queue = b.option(bool, "mutex_job_queue", "temporary test, reverts to old mutex based queue behaviour in jobs.zig:JobManager") orelse false,
|
||||
.static_build = b.option(bool, "static_build", "builds the entire game as a single executable") orelse false,
|
||||
.zero_logging = b.option(bool, "zero_logging", "disables all logging, only intended for use on job dispatch testing") orelse false,
|
||||
.slow_logging = b.option(bool, "slow_logging", "Disables buffered logging, takes a hit to performance but gain timing information on logging") orelse false,
|
||||
.force_mailbox = b.option(bool, "force_mailbox", "forces mailbox mode for present mode. unlocks framerate to irresponsible levels") orelse false,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn createGameOptions(b: *std.Build, options: BuildOptions) *std.Build.Step.Options {
|
||||
const opts = b.addOptions();
|
||||
|
||||
inline for (@typeInfo(BuildOptions).@"struct".fields) |field| {
|
||||
opts.addOption(bool, field.name, @field(options, field.name));
|
||||
}
|
||||
|
||||
return opts;
|
||||
}
|
||||
|
||||
pub fn addExtraModule(self: *BuildSystem, mod: *std.Build.Module, moduleName: []const u8) void {
|
||||
const dep = self.b.dependency(moduleName, .{ .target = self.target, .optimize = self.optimize, .static_build = self.staticBuild });
|
||||
mod.addImport(moduleName, dep.module(moduleName));
|
||||
}
|
||||
|
||||
pub fn addDependencyInstalls(self: *BuildSystem, b: *std.Build, optimize: std.builtin.OptimizeMode) void {
|
||||
//if (self.staticBuild) {
|
||||
//return;
|
||||
// }
|
||||
|
||||
inline for (DynamicDepList) |d| {
|
||||
b.installArtifact(b.dependency(
|
||||
d.dep,
|
||||
.{ .target = self.target, .optimize = optimize, .static_build = self.staticBuild },
|
||||
).artifact(d.artifact));
|
||||
}
|
||||
|
||||
// b.installArtifact(b.dependency(
|
||||
// "sdl3",
|
||||
// .{ .target = self.target, .optimize = optimize, .static_build = self.staticBuild },
|
||||
// ).artifact("SDL3"));
|
||||
}
|
||||
|
||||
const DynamicDepList: []const struct { dep: []const u8, artifact: []const u8 } = &.{
|
||||
.{ .dep = "sdl3", .artifact = "SDL3" },
|
||||
.{ .dep = "spng", .artifact = "spng_c" },
|
||||
.{ .dep = "lua", .artifact = "luac" },
|
||||
.{ .dep = "miniaudio", .artifact = "miniaudio_c" },
|
||||
.{ .dep = "zphysics", .artifact = "joltc" },
|
||||
// .{ .dep = "enet", .artifact = "enet_c" },
|
||||
.{ .dep = "ozz", .artifact = "ozz_cpp" },
|
||||
};
|
||||
|
||||
// all other modules are disabled by default
|
||||
pub const defaultEnabledModules: []const []const u8 = &.{
|
||||
"core",
|
||||
"assets",
|
||||
"platform",
|
||||
"rend",
|
||||
};
|
||||
|
||||
pub const moduleOrder: []const []const u8 = &.{
|
||||
"core",
|
||||
"sys",
|
||||
"assets",
|
||||
"platform",
|
||||
"net",
|
||||
"physics",
|
||||
"audio",
|
||||
"rend",
|
||||
"ui",
|
||||
"imgui",
|
||||
"papyrus",
|
||||
};
|
||||
|
||||
pub const DynamicModule = struct {
|
||||
name: []const u8,
|
||||
allocator: std.mem.Allocator,
|
||||
buildSystem: *BuildSystem,
|
||||
programName: []const u8,
|
||||
opts: AddProgramOptions,
|
||||
|
||||
extras: std.ArrayListUnmanaged(GameModule) = .{},
|
||||
gameModules: std.ArrayListUnmanaged(GameModule) = .{},
|
||||
|
||||
library: ?*std.Build.Step.Compile = null,
|
||||
|
||||
pub fn addExtraModule(self: *@This(), module: []const u8) void {
|
||||
self.extras.append(self.allocator, .{ .name = module, .enabled = true }) catch @panic("out of memory");
|
||||
}
|
||||
|
||||
pub fn init(name: []const u8, p: *Program) *@This() {
|
||||
var self: *@This() = p.allocator.create(@This()) catch @panic("out of memory");
|
||||
|
||||
self.* = .{
|
||||
.opts = p.opts,
|
||||
.programName = p.opts.name,
|
||||
.buildSystem = p.buildSystem,
|
||||
.allocator = p.allocator,
|
||||
.name = name,
|
||||
};
|
||||
|
||||
for (p.gameModules.items) |module| {
|
||||
self.gameModules.append(self.allocator, module) catch @panic("out of memory");
|
||||
}
|
||||
|
||||
for (p.extras.items) |module| {
|
||||
self.extras.append(self.allocator, module) catch @panic("out of memory");
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
pub fn compileInstall(self: *@This()) *std.Build.Step.Compile {
|
||||
if (self.library) |lib| {
|
||||
return lib;
|
||||
}
|
||||
|
||||
const b = self.buildSystem.b;
|
||||
const static = self.buildSystem.staticBuild;
|
||||
const lib = b.addLibrary(.{
|
||||
.name = self.name,
|
||||
.linkage = if (static) .static else .dynamic,
|
||||
.root_module = b.createModule(.{
|
||||
.root_source_file = self.opts.root_source_file,
|
||||
.link_libc = true,
|
||||
.optimize = self.buildSystem.optimize,
|
||||
.target = self.buildSystem.target,
|
||||
}),
|
||||
});
|
||||
|
||||
const allocator = self.buildSystem.b.allocator;
|
||||
|
||||
var modlist = std.ArrayList([]const u8){};
|
||||
|
||||
for (self.gameModules.items) |mod| {
|
||||
if (mod.enabled) {
|
||||
modlist.append(allocator, mod.name) catch @panic("out of memory");
|
||||
}
|
||||
}
|
||||
|
||||
for (self.extras.items) |extra| {
|
||||
self.buildSystem.addExtraModule(lib.root_module, extra.name);
|
||||
}
|
||||
|
||||
lib.root_module.addImport("backlog", self.buildSystem.generateApi(self.name, modlist.items, null));
|
||||
lib.root_module.addOptions("BacklogOptions", self.buildSystem.options);
|
||||
|
||||
if (static) {
|
||||
// generateApi should create static callers for the main program
|
||||
} else {
|
||||
const installExtern = b.addInstallArtifact(lib, .{
|
||||
.dest_dir = .{ .override = .{ .custom = "modules" } },
|
||||
});
|
||||
b.getInstallStep().dependOn(&installExtern.step);
|
||||
}
|
||||
|
||||
return lib;
|
||||
}
|
||||
};
|
||||
|
||||
pub const GameModule = struct {
|
||||
name: []const u8,
|
||||
enabled: bool = true,
|
||||
};
|
||||
|
||||
pub const Program = struct {
|
||||
allocator: std.mem.Allocator,
|
||||
opts: AddProgramOptions,
|
||||
gameModules: std.ArrayListUnmanaged(GameModule) = .{},
|
||||
extras: std.ArrayListUnmanaged(GameModule) = .{},
|
||||
dynamicModules: std.ArrayListUnmanaged(*DynamicModule) = .{},
|
||||
buildSystem: *BuildSystem,
|
||||
|
||||
iconPath: ?std.Build.LazyPath = null,
|
||||
|
||||
pub fn setIconPath(self: *@This(), path: []const u8) void {
|
||||
if (self.iconPath != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
self.iconPath = self.buildSystem.generateRc(self.opts.name, path) catch return;
|
||||
}
|
||||
|
||||
pub fn setModuleEnabled(self: *@This(), module: []const u8, enable: bool) void {
|
||||
for (self.gameModules.items) |*m| {
|
||||
if (std.mem.eql(u8, m.name, module)) {
|
||||
m.enabled = enable;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// module not found, add it here.
|
||||
self.gameModules.append(self.allocator, .{ .name = module, .enabled = enable }) catch @panic("out of memory");
|
||||
}
|
||||
|
||||
pub fn addExtraModule(self: *@This(), module: []const u8) void {
|
||||
self.extras.append(self.allocator, .{ .name = module, .enabled = true }) catch @panic("out of memory");
|
||||
}
|
||||
|
||||
pub fn addDynamicModule(self: *@This(), module: []const u8, root_source_file: std.Build.LazyPath) *DynamicModule {
|
||||
const dynamicModule = DynamicModule.init(module, self);
|
||||
dynamicModule.opts.root_source_file = root_source_file;
|
||||
self.dynamicModules.append(self.allocator, dynamicModule) catch @panic("out of memory");
|
||||
|
||||
return dynamicModule;
|
||||
}
|
||||
|
||||
pub fn compileInstall(self: *@This()) *std.Build.Module {
|
||||
const exe = self.buildSystem.addProgram(self.opts);
|
||||
const allocator = self.buildSystem.b.allocator;
|
||||
|
||||
var modlist = std.ArrayList([]const u8){};
|
||||
|
||||
for (self.gameModules.items) |mod| {
|
||||
if (mod.enabled) {
|
||||
modlist.append(allocator, mod.name) catch @panic("out of memory");
|
||||
}
|
||||
}
|
||||
|
||||
for (self.extras.items) |extra| {
|
||||
self.buildSystem.addExtraModule(exe, extra.name);
|
||||
}
|
||||
|
||||
exe.addImport("backlog", self.buildSystem.generateApi(self.opts.name, modlist.items, self.dynamicModules.items));
|
||||
|
||||
if (self.buildSystem.target.result.os.tag == .windows) {
|
||||
if (self.iconPath) |ip| {
|
||||
exe.addWin32ResourceFile(.{
|
||||
.file = ip,
|
||||
.flags = &.{},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return exe;
|
||||
}
|
||||
};
|
||||
|
||||
pub fn program(self: *BuildSystem, opts: AddProgramOptions) *Program {
|
||||
const prog = self.b.allocator.create(Program) catch unreachable;
|
||||
|
||||
prog.* = .{
|
||||
.allocator = self.b.allocator,
|
||||
.opts = opts,
|
||||
.buildSystem = self,
|
||||
};
|
||||
|
||||
for (moduleOrder) |module| {
|
||||
prog.setModuleEnabled(module, false);
|
||||
}
|
||||
|
||||
for (defaultEnabledModules) |module| {
|
||||
prog.setModuleEnabled(module, true);
|
||||
}
|
||||
|
||||
return prog;
|
||||
}
|
||||
|
||||
// ========= standalone build instance =======
|
||||
// maybe the default should be like an engine launcher/project launcher or something
|
||||
pub fn build(b: *std.Build) void {
|
||||
const target = b.standardTargetOptions(.{});
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
const static_build = b.option(bool, "static_build", "builds backlog dependencies for static linking") orelse false;
|
||||
|
||||
const fwdGeneratorExe = b.addExecutable(.{
|
||||
.name = "backlog-generate-fwd",
|
||||
.root_module = b.createModule(.{
|
||||
.target = b.graph.host,
|
||||
.optimize = .Debug,
|
||||
.root_source_file = b.path("build/generateFwd.zig"),
|
||||
}),
|
||||
});
|
||||
|
||||
const generateExe = b.addExecutable(.{
|
||||
.name = "backlog-apigen",
|
||||
.root_module = b.createModule(.{
|
||||
.target = b.graph.host,
|
||||
.optimize = .Debug,
|
||||
.root_source_file = b.path("build/generateApi.zig"),
|
||||
}),
|
||||
});
|
||||
|
||||
const generateShaders = b.addExecutable(.{
|
||||
.name = "backlog-shaderEmbedGen",
|
||||
.root_module = b.createModule(.{
|
||||
.target = b.graph.host,
|
||||
.optimize = .Debug,
|
||||
.root_source_file = b.path("build/generateEmbeddedShaders.zig"),
|
||||
}),
|
||||
});
|
||||
|
||||
const generateRcExe = b.addExecutable(.{
|
||||
.name = "backlog-generate-rc",
|
||||
.root_module = b.createModule(.{
|
||||
.target = b.graph.host,
|
||||
.optimize = .Debug,
|
||||
.root_source_file = b.path("build/generateRc.zig"),
|
||||
}),
|
||||
});
|
||||
|
||||
const generateLoadDynamicsExe = b.addExecutable(.{
|
||||
.name = "backlog-generate-loadDynamics",
|
||||
.root_module = b.createModule(.{
|
||||
.target = b.graph.host,
|
||||
.optimize = .Debug,
|
||||
.root_source_file = b.path("build/generateLoadDynamics.zig"),
|
||||
}),
|
||||
});
|
||||
|
||||
b.installArtifact(generateLoadDynamicsExe);
|
||||
b.installArtifact(generateExe);
|
||||
b.installArtifact(generateShaders);
|
||||
b.installArtifact(generateRcExe);
|
||||
|
||||
{
|
||||
const loadDynamicsStub = b.addModule("loadDynamicsStub", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.root_source_file = b.path("engine/loadDynamicsStub.zig"),
|
||||
});
|
||||
|
||||
_ = loadDynamicsStub;
|
||||
|
||||
const mod = b.addModule("Backlog", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.root_source_file = b.path("engine/backlog.zig"),
|
||||
});
|
||||
|
||||
for (engineDepList) |depName| {
|
||||
const dep = b.dependency(
|
||||
depName,
|
||||
.{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.static_build = static_build,
|
||||
},
|
||||
);
|
||||
|
||||
const run = b.addRunArtifact(fwdGeneratorExe);
|
||||
const output = run.addOutputFileArg(b.fmt("{s}_fwd.zig", .{depName}));
|
||||
|
||||
const modFwd = b.addModule(depName, .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.root_source_file = output,
|
||||
});
|
||||
|
||||
mod.addImport(b.fmt("{s}", .{depName}), modFwd);
|
||||
modFwd.addImport("module", dep.module(depName));
|
||||
|
||||
// mod.addImport(depName, dep.module(depName));
|
||||
}
|
||||
|
||||
// link in large platform support functions... special case.
|
||||
{
|
||||
const dep = b.dependency("sdl3", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.static_build = static_build,
|
||||
});
|
||||
const lib = dep.module("SDL3");
|
||||
|
||||
mod.addImport("sdl3_fwd", lib);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn generateApi(self: *@This(), programName: []const u8, moduleList: []const []const u8, dynamicModules: ?[]const *DynamicModule) *std.Build.Module {
|
||||
// std.debug.print("GENERATE API:: {s}\n", .{programName});
|
||||
|
||||
for (moduleList) |mod| {
|
||||
_ = mod;
|
||||
// std.debug.print("{s}\n", .{mod});
|
||||
}
|
||||
//
|
||||
if (self.generatedApis.get(programName)) |m| {
|
||||
return m;
|
||||
}
|
||||
|
||||
const run = self.b.addRunArtifact(self.apigen);
|
||||
const pfile = self.b.fmt("{s}Api.zig", .{programName});
|
||||
const output = run.addOutputFileArg(pfile);
|
||||
for (moduleList) |modName| {
|
||||
run.addArg(modName);
|
||||
}
|
||||
|
||||
const mod = self.b.addModule(pfile, .{
|
||||
.target = self.target,
|
||||
.optimize = self.optimize,
|
||||
.root_source_file = output,
|
||||
});
|
||||
for (moduleList) |modName| {
|
||||
mod.addImport(modName, self.nwdep.module(modName));
|
||||
}
|
||||
|
||||
const loadStatics = self.generateInstallStaticResources(programName, "content/_shaders") catch unreachable;
|
||||
mod.addImport("staticShaderLoader", loadStatics);
|
||||
|
||||
// deal with dynamics
|
||||
if (dynamicModules) |dynamics| {
|
||||
const loadDynamics = self.generateLoadDynamics(programName, dynamics) catch @panic("unknown");
|
||||
mod.addImport("loadDynamics", loadDynamics);
|
||||
} else {
|
||||
mod.addImport("loadDynamics", self.nwdep.module("loadDynamicsStub"));
|
||||
}
|
||||
|
||||
self.generatedApis.put(self.b.allocator, programName, mod) catch @panic("out of memory");
|
||||
|
||||
return mod;
|
||||
}
|
||||
|
||||
pub fn generateRc(self: *@This(), programName: []const u8, iconPath: []const u8) !std.Build.LazyPath {
|
||||
const run = self.b.addRunArtifact(self.rcGen);
|
||||
const pfile = self.b.fmt("{s}.rc", .{programName});
|
||||
const output = run.addOutputFileArg(pfile);
|
||||
run.addArg(iconPath);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
pub fn generateLoadDynamics(self: *@This(), programName: []const u8, dynamics: []const *DynamicModule) !*std.Build.Module {
|
||||
const run = self.b.addRunArtifact(self.loadDynamicsGen);
|
||||
const pfile = self.b.fmt("{s}LoadDynamics.zig", .{programName});
|
||||
const output = run.addOutputFileArg(pfile);
|
||||
if (self.staticBuild) {
|
||||
run.addArg("static");
|
||||
} else {
|
||||
run.addArg("dynamic");
|
||||
}
|
||||
|
||||
for (dynamics) |dyn| {
|
||||
run.addArg(dyn.name);
|
||||
}
|
||||
|
||||
const mod = self.b.addModule(pfile, .{
|
||||
.target = self.target,
|
||||
.optimize = self.optimize,
|
||||
.root_source_file = output,
|
||||
});
|
||||
|
||||
mod.addImport("core", self.nwdep.module("core"));
|
||||
for (dynamics) |dyn| {
|
||||
const dynmod = dyn.compileInstall();
|
||||
mod.addImport(dyn.name, dynmod.root_module);
|
||||
}
|
||||
|
||||
return mod;
|
||||
}
|
||||
|
||||
pub fn generateInstallStaticResources(self: *@This(), programName: []const u8, shadersPath: []const u8) !*std.Build.Module {
|
||||
const run = self.b.addRunArtifact(self.shaderEmbedGen);
|
||||
const pfile = self.b.fmt("{s}ShaderGen.zig", .{programName});
|
||||
const output = run.addOutputFileArg(pfile);
|
||||
run.addArg(shadersPath);
|
||||
|
||||
const b = self.b;
|
||||
const mod = self.b.addModule(pfile, .{
|
||||
.target = self.target,
|
||||
.optimize = self.optimize,
|
||||
.root_source_file = output,
|
||||
});
|
||||
mod.addImport("core", self.nwdep.module("core"));
|
||||
|
||||
var dir = try std.fs.cwd().openDir("content/_shaders", .{ .iterate = true });
|
||||
defer dir.close();
|
||||
|
||||
var walker = dir.iterate();
|
||||
while (try walker.next()) |shaderType| {
|
||||
if (shaderType.kind == .directory) {
|
||||
var d2 = try dir.openDir(shaderType.name, .{ .iterate = true });
|
||||
defer d2.close();
|
||||
var w2 = d2.iterate();
|
||||
while (try w2.next()) |shaderName| {
|
||||
const shaderPath = b.fmt("content/_shaders/{s}/{s}", .{ shaderType.name, shaderName.name });
|
||||
mod.addAnonymousImport(shaderName.name, .{
|
||||
.root_source_file = b.path(shaderPath),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return mod;
|
||||
}
|
||||
|
|
@ -0,0 +1,696 @@
|
|||
// MVK_CONFIG_USE_METAL_ARGUMENT_BUFFERS=1 -- use this if you're getting that odd crash on mac
|
||||
b: *std.Build,
|
||||
nw_builder: *std.Build,
|
||||
target: std.Build.ResolvedTarget,
|
||||
optimize: std.builtin.Mode,
|
||||
nw_mod: *std.Build.Module,
|
||||
spirvReflect: SpirvReflect.SpirvGenerator2,
|
||||
gltf2ozz: ozz.GltfToOzz,
|
||||
options: *std.Build.Step.Options,
|
||||
cookShaders: bool,
|
||||
|
||||
backlogRoot: []const u8,
|
||||
// list of all shaders discovered under
|
||||
// content/_shaders/def
|
||||
reflectShaderPathList: [][]u8 = undefined,
|
||||
|
||||
staticBuild: bool = false,
|
||||
|
||||
nwdep: *std.Build.Dependency,
|
||||
apigen: *std.Build.Step.Compile,
|
||||
shaderEmbedGen: *std.Build.Step.Compile,
|
||||
loadDynamicsGen: *std.Build.Step.Compile,
|
||||
rcGen: *std.Build.Step.Compile,
|
||||
generatedApis: std.StringHashMapUnmanaged(*std.Build.Module) = .{},
|
||||
|
||||
const engineDepList = [_][]const u8{
|
||||
"assets",
|
||||
"audio",
|
||||
"core",
|
||||
"net",
|
||||
"papyrus",
|
||||
"platform",
|
||||
"rend",
|
||||
"ui",
|
||||
"imgui",
|
||||
"physics",
|
||||
"sys",
|
||||
};
|
||||
|
||||
const BuildSystem = @This();
|
||||
const std = @import("std");
|
||||
const Build = std.Build;
|
||||
const LazyPath = Build.LazyPath;
|
||||
|
||||
const SpirvReflect = @import("SpirvReflect");
|
||||
const ozz = @import("ozz");
|
||||
|
||||
pub const InitOptions = struct {
|
||||
import_name: []const u8 = "Backlog",
|
||||
backlogRoot: []const u8 = "./BacklogEngine",
|
||||
staticBuild: bool = false,
|
||||
target: Build.ResolvedTarget,
|
||||
optimize: std.builtin.OptimizeMode,
|
||||
};
|
||||
|
||||
pub fn init(b: *std.Build, opts: InitOptions) BuildSystem {
|
||||
var buildOpts = declareBuildOptions(b);
|
||||
|
||||
if (opts.target.result.os.tag == .linux) {
|
||||
// using a static build for linux... object loading hell is not fun
|
||||
std.debug.print("Important! only supporting static builds for linux", .{});
|
||||
buildOpts.static_build = true;
|
||||
}
|
||||
|
||||
const nwdep = b.dependency(opts.import_name, .{
|
||||
.target = opts.target,
|
||||
.optimize = opts.optimize,
|
||||
.static_build = buildOpts.static_build,
|
||||
});
|
||||
|
||||
var self = BuildSystem{
|
||||
.b = b,
|
||||
.nw_builder = nwdep.builder,
|
||||
.target = opts.target,
|
||||
.optimize = opts.optimize,
|
||||
.nw_mod = nwdep.module("Backlog"),
|
||||
.backlogRoot = opts.backlogRoot,
|
||||
.spirvReflect = SpirvReflect.SpirvGenerator2.init(nwdep.builder, .{}),
|
||||
.options = createGameOptions(b, buildOpts),
|
||||
.gltf2ozz = ozz.GltfToOzz.init(nwdep.builder, .{}),
|
||||
.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,
|
||||
|
||||
.staticBuild = buildOpts.static_build,
|
||||
.nwdep = nwdep,
|
||||
.apigen = nwdep.artifact("backlog-apigen"),
|
||||
.loadDynamicsGen = nwdep.artifact("backlog-generate-loadDynamics"),
|
||||
.rcGen = nwdep.artifact("backlog-generate-rc"),
|
||||
.shaderEmbedGen = nwdep.artifact("backlog-shaderEmbedGen"),
|
||||
};
|
||||
|
||||
const exeList = [2]*std.Build.Step.Compile{ self.gltf2ozz.exe, self.spirvReflect.reflect };
|
||||
const install_tools = b.step("tools", "installs tools needed to generate outputs for the engine");
|
||||
for (exeList) |exe| {
|
||||
const toolsInstall = b.addInstallArtifact(exe, .{
|
||||
.dest_dir = .{ .override = .{ .custom = "tools" } },
|
||||
});
|
||||
|
||||
install_tools.dependOn(&toolsInstall.step);
|
||||
}
|
||||
|
||||
{
|
||||
const runArtifact = b.addRunArtifact(self.gltf2ozz.exe);
|
||||
if (b.args) |args| {
|
||||
runArtifact.addArgs(args);
|
||||
}
|
||||
|
||||
const run_exe = b.step("gltf2ozz", "runs the gltf animation converter.");
|
||||
run_exe.dependOn(&runArtifact.step);
|
||||
}
|
||||
|
||||
{
|
||||
const runArtifact = b.addRunArtifact(self.spirvReflect.reflect);
|
||||
if (b.args) |args| {
|
||||
runArtifact.addArgs(args);
|
||||
}
|
||||
|
||||
const run_exe = b.step("spv-reflect", "runs the gltf animation converter.");
|
||||
run_exe.dependOn(&runArtifact.step);
|
||||
}
|
||||
|
||||
self.addDependencyInstalls(self.b, .ReleaseFast);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
pub const AddProgramOptions = struct {
|
||||
name: []const u8,
|
||||
desc: []const u8,
|
||||
root_source_file: LazyPath,
|
||||
imports: []const Build.Module.Import = &.{},
|
||||
};
|
||||
|
||||
pub fn addProgram(self: *BuildSystem, opts: AddProgramOptions) *std.Build.Module {
|
||||
const b = self.b;
|
||||
|
||||
const exe = self.nw_builder.addExecutable(.{
|
||||
.name = opts.name,
|
||||
.target = self.target,
|
||||
.optimize = self.optimize,
|
||||
.root_source_file = self.nw_builder.path("engine/main.zig"),
|
||||
});
|
||||
|
||||
b.installArtifact(exe);
|
||||
const runArtifact = b.addRunArtifact(exe);
|
||||
if (b.args) |args| {
|
||||
runArtifact.addArgs(args);
|
||||
}
|
||||
const run_exe = b.step(self.b.fmt("run-{s}", .{opts.name}), opts.desc);
|
||||
run_exe.dependOn(&runArtifact.step);
|
||||
|
||||
// main path = name/main.zig
|
||||
const mod = b.addModule(opts.name, .{
|
||||
.target = self.target,
|
||||
.optimize = self.optimize,
|
||||
.root_source_file = opts.root_source_file,
|
||||
.imports = opts.imports,
|
||||
});
|
||||
|
||||
exe.root_module.addImport("main", mod);
|
||||
// todo.. remove this one and see what happens
|
||||
exe.root_module.addImport("core", self.nwdep.module("core"));
|
||||
// mod.addImport("Backlog", self.nw_mod);
|
||||
exe.root_module.addOptions("BacklogOptions", self.options);
|
||||
|
||||
if (self.cookShaders) {
|
||||
const cookShadersScript = b.fmt("{s}/tools/scripts/cookShaders.py", .{self.backlogRoot});
|
||||
const cookShadersCommand = b.addSystemCommand(&[_][]const u8{"python"});
|
||||
cookShadersCommand.addArg(cookShadersScript);
|
||||
|
||||
run_exe.dependOn(&cookShadersCommand.step);
|
||||
}
|
||||
|
||||
b.getInstallStep().dependOn(self.nw_builder.getInstallStep());
|
||||
|
||||
// run_exe.dependOn(b.getInstallStep());
|
||||
|
||||
return mod;
|
||||
}
|
||||
|
||||
pub const BuildOptions = struct {
|
||||
mutex_job_queue: bool,
|
||||
static_build: bool,
|
||||
zero_logging: bool,
|
||||
slow_logging: bool,
|
||||
force_mailbox: bool,
|
||||
};
|
||||
|
||||
pub fn declareBuildOptions(b: *std.Build) BuildOptions {
|
||||
return .{
|
||||
.mutex_job_queue = b.option(bool, "mutex_job_queue", "temporary test, reverts to old mutex based queue behaviour in jobs.zig:JobManager") orelse false,
|
||||
.static_build = b.option(bool, "static_build", "builds the entire game as a single executable") orelse false,
|
||||
.zero_logging = b.option(bool, "zero_logging", "disables all logging, only intended for use on job dispatch testing") orelse false,
|
||||
.slow_logging = b.option(bool, "slow_logging", "Disables buffered logging, takes a hit to performance but gain timing information on logging") orelse false,
|
||||
.force_mailbox = b.option(bool, "force_mailbox", "forces mailbox mode for present mode. unlocks framerate to irresponsible levels") orelse false,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn createGameOptions(b: *std.Build, options: BuildOptions) *std.Build.Step.Options {
|
||||
const opts = b.addOptions();
|
||||
|
||||
inline for (@typeInfo(BuildOptions).@"struct".fields) |field| {
|
||||
opts.addOption(bool, field.name, @field(options, field.name));
|
||||
}
|
||||
|
||||
// build options for core.zig
|
||||
// opts.addOption(
|
||||
// bool,
|
||||
// "mutex_job_queue",
|
||||
// );
|
||||
|
||||
// opts.addOption(
|
||||
// bool,
|
||||
// "static_build",
|
||||
// );
|
||||
|
||||
// opts.addOption(
|
||||
// bool,
|
||||
// "zero_logging",
|
||||
// );
|
||||
// opts.addOption(
|
||||
// bool,
|
||||
// "slow_logging",
|
||||
// );
|
||||
// opts.addOption(
|
||||
// bool,
|
||||
// "force_mailbox",
|
||||
// );
|
||||
|
||||
return opts;
|
||||
}
|
||||
|
||||
pub fn addExtraModule(self: *BuildSystem, mod: *std.Build.Module, moduleName: []const u8) void {
|
||||
const dep = self.b.dependency(moduleName, .{ .target = self.target, .optimize = self.optimize, .static_build = self.staticBuild });
|
||||
mod.addImport(moduleName, dep.module(moduleName));
|
||||
}
|
||||
|
||||
pub fn addDependencyInstalls(self: *BuildSystem, b: *std.Build, optimize: std.builtin.OptimizeMode) void {
|
||||
//if (self.staticBuild) {
|
||||
//return;
|
||||
// }
|
||||
|
||||
inline for (DynamicDepList) |d| {
|
||||
b.installArtifact(b.dependency(
|
||||
d.dep,
|
||||
.{ .target = self.target, .optimize = optimize, .static_build = self.staticBuild },
|
||||
).artifact(d.artifact));
|
||||
}
|
||||
|
||||
// b.installArtifact(b.dependency(
|
||||
// "sdl3",
|
||||
// .{ .target = self.target, .optimize = optimize, .static_build = self.staticBuild },
|
||||
// ).artifact("SDL3"));
|
||||
}
|
||||
|
||||
const DynamicDepList: []const struct { dep: []const u8, artifact: []const u8 } = &.{
|
||||
.{ .dep = "sdl3", .artifact = "SDL3" },
|
||||
.{ .dep = "spng", .artifact = "spng_c" },
|
||||
.{ .dep = "lua", .artifact = "luac" },
|
||||
// .{ .dep = "miniaudio", .artifact = "miniaudio_c" },
|
||||
.{ .dep = "zphysics", .artifact = "joltc" },
|
||||
// .{ .dep = "enet", .artifact = "enet_c" },
|
||||
.{ .dep = "ozz", .artifact = "ozz_cpp" },
|
||||
};
|
||||
|
||||
// all other modules are disabled by default
|
||||
pub const defaultEnabledModules: []const []const u8 = &.{
|
||||
"core",
|
||||
"assets",
|
||||
"platform",
|
||||
"rend",
|
||||
};
|
||||
|
||||
pub const moduleOrder: []const []const u8 = &.{
|
||||
"core",
|
||||
"sys",
|
||||
"assets",
|
||||
"platform",
|
||||
"net",
|
||||
"physics",
|
||||
"audio",
|
||||
"rend",
|
||||
"ui",
|
||||
"imgui",
|
||||
"papyrus",
|
||||
};
|
||||
|
||||
pub const DynamicModule = struct {
|
||||
name: []const u8,
|
||||
allocator: std.mem.Allocator,
|
||||
buildSystem: *BuildSystem,
|
||||
programName: []const u8,
|
||||
opts: AddProgramOptions,
|
||||
|
||||
extras: std.ArrayListUnmanaged(GameModule) = .{},
|
||||
gameModules: std.ArrayListUnmanaged(GameModule) = .{},
|
||||
|
||||
library: ?*std.Build.Step.Compile = null,
|
||||
|
||||
pub fn addExtraModule(self: *@This(), module: []const u8) void {
|
||||
self.extras.append(self.allocator, .{ .name = module, .enabled = true }) catch @panic("out of memory");
|
||||
}
|
||||
|
||||
pub fn init(name: []const u8, p: *Program) *@This() {
|
||||
var self: *@This() = p.allocator.create(@This()) catch @panic("out of memory");
|
||||
|
||||
self.* = .{
|
||||
.opts = p.opts,
|
||||
.programName = p.opts.name,
|
||||
.buildSystem = p.buildSystem,
|
||||
.allocator = p.allocator,
|
||||
.name = name,
|
||||
};
|
||||
|
||||
for (p.gameModules.items) |module| {
|
||||
self.gameModules.append(self.allocator, module) catch @panic("out of memory");
|
||||
}
|
||||
|
||||
for (p.extras.items) |module| {
|
||||
self.extras.append(self.allocator, module) catch @panic("out of memory");
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
pub fn compileInstall(self: *@This()) *std.Build.Step.Compile {
|
||||
if (self.library) |lib| {
|
||||
return lib;
|
||||
}
|
||||
|
||||
const b = self.buildSystem.b;
|
||||
const static = self.buildSystem.staticBuild;
|
||||
const lib = if (static)
|
||||
b.addStaticLibrary(.{
|
||||
.root_source_file = self.opts.root_source_file,
|
||||
.link_libc = true,
|
||||
.optimize = self.buildSystem.optimize,
|
||||
.target = self.buildSystem.target,
|
||||
.name = self.name,
|
||||
})
|
||||
else
|
||||
b.addSharedLibrary(.{
|
||||
.root_source_file = self.opts.root_source_file,
|
||||
.link_libc = true,
|
||||
.optimize = self.buildSystem.optimize,
|
||||
.target = self.buildSystem.target,
|
||||
.name = self.name,
|
||||
});
|
||||
|
||||
var modlist = std.ArrayList([]const u8).init(self.buildSystem.b.allocator);
|
||||
|
||||
for (self.gameModules.items) |mod| {
|
||||
if (mod.enabled) {
|
||||
modlist.append(mod.name) catch @panic("out of memory");
|
||||
}
|
||||
}
|
||||
|
||||
for (self.extras.items) |extra| {
|
||||
self.buildSystem.addExtraModule(lib.root_module, extra.name);
|
||||
}
|
||||
|
||||
lib.root_module.addImport("backlog", self.buildSystem.generateApi(self.name, modlist.items, null));
|
||||
lib.root_module.addOptions("BacklogOptions", self.buildSystem.options);
|
||||
|
||||
if (static) {
|
||||
// generateApi should create static callers for the main program
|
||||
} else {
|
||||
const installExtern = b.addInstallArtifact(lib, .{
|
||||
.dest_dir = .{ .override = .{ .custom = "modules" } },
|
||||
});
|
||||
b.getInstallStep().dependOn(&installExtern.step);
|
||||
}
|
||||
|
||||
return lib;
|
||||
}
|
||||
};
|
||||
|
||||
pub const GameModule = struct {
|
||||
name: []const u8,
|
||||
enabled: bool = true,
|
||||
};
|
||||
|
||||
pub const Program = struct {
|
||||
allocator: std.mem.Allocator,
|
||||
opts: AddProgramOptions,
|
||||
gameModules: std.ArrayListUnmanaged(GameModule) = .{},
|
||||
extras: std.ArrayListUnmanaged(GameModule) = .{},
|
||||
dynamicModules: std.ArrayListUnmanaged(*DynamicModule) = .{},
|
||||
buildSystem: *BuildSystem,
|
||||
|
||||
iconPath: ?std.Build.LazyPath = null,
|
||||
|
||||
pub fn setIconPath(self: *@This(), path: []const u8) void {
|
||||
if (self.iconPath != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
self.iconPath = self.buildSystem.generateRc(self.opts.name, path) catch return;
|
||||
}
|
||||
|
||||
pub fn setModuleEnabled(self: *@This(), module: []const u8, enable: bool) void {
|
||||
for (self.gameModules.items) |*m| {
|
||||
if (std.mem.eql(u8, m.name, module)) {
|
||||
m.enabled = enable;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// module not found, add it here.
|
||||
self.gameModules.append(self.allocator, .{ .name = module, .enabled = enable }) catch @panic("out of memory");
|
||||
}
|
||||
|
||||
pub fn addExtraModule(self: *@This(), module: []const u8) void {
|
||||
self.extras.append(self.allocator, .{ .name = module, .enabled = true }) catch @panic("out of memory");
|
||||
}
|
||||
|
||||
pub fn addDynamicModule(self: *@This(), module: []const u8, root_source_file: std.Build.LazyPath) *DynamicModule {
|
||||
const dynamicModule = DynamicModule.init(module, self);
|
||||
dynamicModule.opts.root_source_file = root_source_file;
|
||||
self.dynamicModules.append(self.allocator, dynamicModule) catch @panic("out of memory");
|
||||
|
||||
return dynamicModule;
|
||||
}
|
||||
|
||||
pub fn compileInstall(self: *@This()) *std.Build.Module {
|
||||
const exe = self.buildSystem.addProgram(self.opts);
|
||||
var modlist = std.ArrayList([]const u8).init(self.buildSystem.b.allocator);
|
||||
|
||||
for (self.gameModules.items) |mod| {
|
||||
if (mod.enabled) {
|
||||
modlist.append(mod.name) catch @panic("out of memory");
|
||||
}
|
||||
}
|
||||
|
||||
for (self.extras.items) |extra| {
|
||||
self.buildSystem.addExtraModule(exe, extra.name);
|
||||
}
|
||||
|
||||
exe.addImport("backlog", self.buildSystem.generateApi(self.opts.name, modlist.items, self.dynamicModules.items));
|
||||
|
||||
if (self.buildSystem.target.result.os.tag == .windows) {
|
||||
if (self.iconPath) |ip| {
|
||||
exe.addWin32ResourceFile(.{
|
||||
.file = ip,
|
||||
.flags = &.{},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return exe;
|
||||
}
|
||||
};
|
||||
|
||||
pub fn program(self: *BuildSystem, opts: AddProgramOptions) *Program {
|
||||
const prog = self.b.allocator.create(Program) catch unreachable;
|
||||
|
||||
prog.* = .{
|
||||
.allocator = self.b.allocator,
|
||||
.opts = opts,
|
||||
.buildSystem = self,
|
||||
};
|
||||
|
||||
for (moduleOrder) |module| {
|
||||
prog.setModuleEnabled(module, false);
|
||||
}
|
||||
|
||||
for (defaultEnabledModules) |module| {
|
||||
prog.setModuleEnabled(module, true);
|
||||
}
|
||||
|
||||
return prog;
|
||||
}
|
||||
|
||||
// ========= standalone build instance =======
|
||||
// maybe the default should be like an engine launcher/project launcher or something
|
||||
pub fn build(b: *std.Build) void {
|
||||
const target = b.standardTargetOptions(.{});
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
const static_build = b.option(bool, "static_build", "builds backlog dependencies for static linking") orelse false;
|
||||
|
||||
const spirvDep = b.dependency("SpirvReflect", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.static_build = static_build,
|
||||
});
|
||||
_ = spirvDep;
|
||||
|
||||
const fwdGeneratorExe = b.addExecutable(.{
|
||||
.name = "backlog-generate-fwd",
|
||||
.target = b.graph.host,
|
||||
.optimize = .Debug,
|
||||
.root_source_file = b.path("build/generateFwd.zig"),
|
||||
});
|
||||
|
||||
const generateExe = b.addExecutable(.{
|
||||
.name = "backlog-apigen",
|
||||
.target = b.graph.host,
|
||||
.optimize = .Debug,
|
||||
.root_source_file = b.path("build/generateApi.zig"),
|
||||
});
|
||||
|
||||
const generateShaders = b.addExecutable(.{
|
||||
.name = "backlog-shaderEmbedGen",
|
||||
.target = b.graph.host,
|
||||
.optimize = .Debug,
|
||||
.root_source_file = b.path("build/generateEmbeddedShaders.zig"),
|
||||
});
|
||||
|
||||
const generateRcExe = b.addExecutable(.{
|
||||
.name = "backlog-generate-rc",
|
||||
.target = b.graph.host,
|
||||
.optimize = .Debug,
|
||||
.root_source_file = b.path("build/generateRc.zig"),
|
||||
});
|
||||
|
||||
const generateLoadDynamicsExe = b.addExecutable(.{
|
||||
.name = "backlog-generate-loadDynamics",
|
||||
.target = b.graph.host,
|
||||
.optimize = .Debug,
|
||||
.root_source_file = b.path("build/generateLoadDynamics.zig"),
|
||||
});
|
||||
|
||||
b.installArtifact(generateLoadDynamicsExe);
|
||||
b.installArtifact(generateExe);
|
||||
b.installArtifact(generateShaders);
|
||||
b.installArtifact(generateRcExe);
|
||||
|
||||
{
|
||||
const loadDynamicsStub = b.addModule("loadDynamicsStub", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.root_source_file = b.path("engine/loadDynamicsStub.zig"),
|
||||
});
|
||||
|
||||
_ = loadDynamicsStub;
|
||||
|
||||
const mod = b.addModule("Backlog", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.root_source_file = b.path("engine/backlog.zig"),
|
||||
});
|
||||
|
||||
for (engineDepList) |depName| {
|
||||
const dep = b.dependency(
|
||||
depName,
|
||||
.{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.static_build = static_build,
|
||||
},
|
||||
);
|
||||
|
||||
const run = b.addRunArtifact(fwdGeneratorExe);
|
||||
const output = run.addOutputFileArg(b.fmt("{s}_fwd.zig", .{depName}));
|
||||
|
||||
const modFwd = b.addModule(depName, .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.root_source_file = output,
|
||||
});
|
||||
|
||||
mod.addImport(b.fmt("{s}", .{depName}), modFwd);
|
||||
modFwd.addImport("module", dep.module(depName));
|
||||
|
||||
// mod.addImport(depName, dep.module(depName));
|
||||
}
|
||||
|
||||
// link in large platform support functions... special case.
|
||||
{
|
||||
const dep = b.dependency("sdl3", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.static_build = static_build,
|
||||
});
|
||||
const lib = dep.module("SDL3");
|
||||
|
||||
mod.addImport("sdl3_fwd", lib);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn generateApi(self: *@This(), programName: []const u8, moduleList: []const []const u8, dynamicModules: ?[]const *DynamicModule) *std.Build.Module {
|
||||
// std.debug.print("GENERATE API:: {s}\n", .{programName});
|
||||
|
||||
for (moduleList) |mod| {
|
||||
_ = mod;
|
||||
// std.debug.print("{s}\n", .{mod});
|
||||
}
|
||||
//
|
||||
if (self.generatedApis.get(programName)) |m| {
|
||||
return m;
|
||||
}
|
||||
|
||||
const run = self.b.addRunArtifact(self.apigen);
|
||||
const pfile = self.b.fmt("{s}Api.zig", .{programName});
|
||||
const output = run.addOutputFileArg(pfile);
|
||||
for (moduleList) |modName| {
|
||||
run.addArg(modName);
|
||||
}
|
||||
|
||||
const mod = self.b.addModule(pfile, .{
|
||||
.target = self.target,
|
||||
.optimize = self.optimize,
|
||||
.root_source_file = output,
|
||||
});
|
||||
for (moduleList) |modName| {
|
||||
mod.addImport(modName, self.nwdep.module(modName));
|
||||
}
|
||||
|
||||
const loadStatics = self.generateInstallStaticResources(programName, "content/_shaders") catch unreachable;
|
||||
mod.addImport("staticShaderLoader", loadStatics);
|
||||
|
||||
// deal with dynamics
|
||||
if (dynamicModules) |dynamics| {
|
||||
const loadDynamics = self.generateLoadDynamics(programName, dynamics) catch @panic("unknown");
|
||||
mod.addImport("loadDynamics", loadDynamics);
|
||||
} else {
|
||||
mod.addImport("loadDynamics", self.nwdep.module("loadDynamicsStub"));
|
||||
}
|
||||
|
||||
self.generatedApis.put(self.b.allocator, programName, mod) catch @panic("out of memory");
|
||||
|
||||
return mod;
|
||||
}
|
||||
|
||||
pub fn generateRc(self: *@This(), programName: []const u8, iconPath: []const u8) !std.Build.LazyPath {
|
||||
const run = self.b.addRunArtifact(self.rcGen);
|
||||
const pfile = self.b.fmt("{s}.rc", .{programName});
|
||||
const output = run.addOutputFileArg(pfile);
|
||||
run.addArg(iconPath);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
pub fn generateLoadDynamics(self: *@This(), programName: []const u8, dynamics: []const *DynamicModule) !*std.Build.Module {
|
||||
const run = self.b.addRunArtifact(self.loadDynamicsGen);
|
||||
const pfile = self.b.fmt("{s}LoadDynamics.zig", .{programName});
|
||||
const output = run.addOutputFileArg(pfile);
|
||||
if (self.staticBuild) {
|
||||
run.addArg("static");
|
||||
} else {
|
||||
run.addArg("dynamic");
|
||||
}
|
||||
|
||||
for (dynamics) |dyn| {
|
||||
run.addArg(dyn.name);
|
||||
}
|
||||
|
||||
const mod = self.b.addModule(pfile, .{
|
||||
.target = self.target,
|
||||
.optimize = self.optimize,
|
||||
.root_source_file = output,
|
||||
});
|
||||
|
||||
mod.addImport("core", self.nwdep.module("core"));
|
||||
for (dynamics) |dyn| {
|
||||
const dynmod = dyn.compileInstall();
|
||||
mod.addImport(dyn.name, dynmod.root_module);
|
||||
}
|
||||
|
||||
return mod;
|
||||
}
|
||||
|
||||
pub fn generateInstallStaticResources(self: *@This(), programName: []const u8, shadersPath: []const u8) !*std.Build.Module {
|
||||
const run = self.b.addRunArtifact(self.shaderEmbedGen);
|
||||
const pfile = self.b.fmt("{s}ShaderGen.zig", .{programName});
|
||||
const output = run.addOutputFileArg(pfile);
|
||||
run.addArg(shadersPath);
|
||||
|
||||
const b = self.b;
|
||||
const mod = self.b.addModule(pfile, .{
|
||||
.target = self.target,
|
||||
.optimize = self.optimize,
|
||||
.root_source_file = output,
|
||||
});
|
||||
mod.addImport("core", self.nwdep.module("core"));
|
||||
|
||||
var dir = try std.fs.cwd().openDir("content/_shaders", .{ .iterate = true });
|
||||
defer dir.close();
|
||||
|
||||
var walker = dir.iterate();
|
||||
while (try walker.next()) |shaderType| {
|
||||
if (shaderType.kind == .directory) {
|
||||
var d2 = try dir.openDir(shaderType.name, .{ .iterate = true });
|
||||
defer d2.close();
|
||||
var w2 = d2.iterate();
|
||||
while (try w2.next()) |shaderName| {
|
||||
const shaderPath = b.fmt("content/_shaders/{s}/{s}", .{ shaderType.name, shaderName.name });
|
||||
mod.addAnonymousImport(shaderName.name, .{
|
||||
.root_source_file = b.path(shaderPath),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return mod;
|
||||
}
|
||||
597
build.zig
597
build.zig
|
|
@ -1,42 +1,27 @@
|
|||
// MVK_CONFIG_USE_METAL_ARGUMENT_BUFFERS=1 -- use this if you're getting that odd crash on mac
|
||||
b: *std.Build,
|
||||
nw_builder: *std.Build,
|
||||
target: std.Build.ResolvedTarget,
|
||||
optimize: std.builtin.OptimizeMode,
|
||||
bEngine: *std.Build, // used to resolve executable paths from within the engine's root directory
|
||||
opts: bh.Options,
|
||||
nw_mod: *std.Build.Module,
|
||||
gltf2ozz: ozz.GltfToOzz,
|
||||
options: *std.Build.Step.Options,
|
||||
cookShaders: bool,
|
||||
|
||||
backlogRoot: []const u8,
|
||||
|
||||
// list of all shaders discovered under
|
||||
// content/_shaders/def
|
||||
reflectShaderPathList: [][]u8 = undefined,
|
||||
|
||||
staticBuild: bool = false,
|
||||
|
||||
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) = .{},
|
||||
|
||||
const engineDepList = [_][]const u8{
|
||||
"assets",
|
||||
"audio",
|
||||
"core",
|
||||
"net",
|
||||
"papyrus",
|
||||
"platform",
|
||||
"rend",
|
||||
"ui",
|
||||
"imgui",
|
||||
"physics",
|
||||
"sys",
|
||||
};
|
||||
|
||||
const BuildSystem = @This();
|
||||
pub const BuildSystem = @This();
|
||||
const std = @import("std");
|
||||
const Build = std.Build;
|
||||
const LazyPath = Build.LazyPath;
|
||||
|
|
@ -46,41 +31,47 @@ const ozz = @import("ozz");
|
|||
pub const InitOptions = struct {
|
||||
import_name: []const u8 = "Backlog",
|
||||
backlogRoot: []const u8 = "./BacklogEngine",
|
||||
staticBuild: bool = false,
|
||||
target: Build.ResolvedTarget,
|
||||
target: std.Build.ResolvedTarget,
|
||||
optimize: std.builtin.OptimizeMode,
|
||||
};
|
||||
|
||||
pub fn init(b: *std.Build, opts: InitOptions) BuildSystem {
|
||||
var buildOpts = declareBuildOptions(b);
|
||||
pub fn init(b: *std.Build, initOptions: InitOptions) BuildSystem {
|
||||
const buildOpts = declareBuildOptions(b);
|
||||
|
||||
const opts = bh.Options{
|
||||
.target = initOptions.target,
|
||||
.optimize = initOptions.optimize,
|
||||
.static_build = b.option(bool, "static_build", "builds backlog dependencies for static linking") orelse false,
|
||||
.tracy = b.option(bool, "tracy", "builds with tracy support") orelse false,
|
||||
};
|
||||
|
||||
if (opts.target.result.os.tag == .linux) {
|
||||
// using a static build for linux... object loading hell is not fun
|
||||
std.debug.print("Important! only supporting static builds for linux", .{});
|
||||
buildOpts.static_build = true;
|
||||
// using a static build for linux... object loading hell is not fun...
|
||||
// i have skill issues in that realm right now
|
||||
// std.debug.print("Important! only supporting static builds for linux", .{});
|
||||
// opts.static_build = true;
|
||||
}
|
||||
|
||||
const nwdep = b.dependency(opts.import_name, .{
|
||||
const nwdep = b.dependency(initOptions.import_name, .{
|
||||
.target = opts.target,
|
||||
.optimize = opts.optimize,
|
||||
.static_build = buildOpts.static_build,
|
||||
.static_build = opts.static_build,
|
||||
});
|
||||
|
||||
var self = BuildSystem{
|
||||
.b = b,
|
||||
.nw_builder = nwdep.builder,
|
||||
.target = opts.target,
|
||||
.optimize = opts.optimize,
|
||||
.bEngine = nwdep.builder,
|
||||
.opts = opts,
|
||||
.nw_mod = nwdep.module("Backlog"),
|
||||
.backlogRoot = opts.backlogRoot,
|
||||
.options = createGameOptions(b, buildOpts),
|
||||
.backlogRoot = initOptions.backlogRoot,
|
||||
.options = createGameOptions(b, buildOpts, opts),
|
||||
.gltf2ozz = ozz.GltfToOzz.init(nwdep.builder, .{}),
|
||||
.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,
|
||||
|
||||
.staticBuild = buildOpts.static_build,
|
||||
.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"),
|
||||
};
|
||||
|
|
@ -110,509 +101,80 @@ pub fn init(b: *std.Build, opts: InitOptions) BuildSystem {
|
|||
return self;
|
||||
}
|
||||
|
||||
pub const AddProgramOptions = struct {
|
||||
name: []const u8,
|
||||
desc: []const u8,
|
||||
root_source_file: LazyPath,
|
||||
imports: []const Build.Module.Import = &.{},
|
||||
};
|
||||
|
||||
pub fn addProgram(self: *BuildSystem, opts: AddProgramOptions) *std.Build.Module {
|
||||
const b = self.b;
|
||||
|
||||
const exe = self.nw_builder.addExecutable(.{
|
||||
.name = opts.name,
|
||||
.root_module = b.createModule(.{
|
||||
.target = self.target,
|
||||
.optimize = self.optimize,
|
||||
.root_source_file = self.nw_builder.path("engine/main.zig"),
|
||||
}),
|
||||
});
|
||||
|
||||
b.installArtifact(exe);
|
||||
const runArtifact = b.addRunArtifact(exe);
|
||||
if (b.args) |args| {
|
||||
runArtifact.addArgs(args);
|
||||
}
|
||||
const run_exe = b.step(self.b.fmt("run-{s}", .{opts.name}), opts.desc);
|
||||
run_exe.dependOn(&runArtifact.step);
|
||||
|
||||
// main path = name/main.zig
|
||||
const mod = b.addModule(opts.name, .{
|
||||
.target = self.target,
|
||||
.optimize = self.optimize,
|
||||
.root_source_file = opts.root_source_file,
|
||||
.imports = opts.imports,
|
||||
});
|
||||
|
||||
exe.root_module.addImport("main", mod);
|
||||
// todo.. remove this one and see what happens
|
||||
exe.root_module.addImport("core", self.nwdep.module("core"));
|
||||
// mod.addImport("Backlog", self.nw_mod);
|
||||
exe.root_module.addOptions("BacklogOptions", self.options);
|
||||
|
||||
if (self.cookShaders) {
|
||||
const cookShadersScript = b.fmt("{s}/tools/scripts/cookShaders.py", .{self.backlogRoot});
|
||||
const cookShadersCommand = b.addSystemCommand(&[_][]const u8{"python"});
|
||||
cookShadersCommand.addArg(cookShadersScript);
|
||||
|
||||
run_exe.dependOn(&cookShadersCommand.step);
|
||||
}
|
||||
|
||||
b.getInstallStep().dependOn(self.nw_builder.getInstallStep());
|
||||
|
||||
// run_exe.dependOn(b.getInstallStep());
|
||||
|
||||
return mod;
|
||||
}
|
||||
|
||||
pub const BuildOptions = struct {
|
||||
// Build Options for the engine,
|
||||
// should generally be written as false = default
|
||||
// true = enabling something
|
||||
const BuildOptions = struct {
|
||||
mutex_job_queue: bool,
|
||||
static_build: bool,
|
||||
zero_logging: bool,
|
||||
slow_logging: bool,
|
||||
force_mailbox: bool,
|
||||
};
|
||||
|
||||
pub fn declareBuildOptions(b: *std.Build) BuildOptions {
|
||||
fn declareBuildOptions(b: *std.Build) BuildOptions {
|
||||
return .{
|
||||
.mutex_job_queue = b.option(bool, "mutex_job_queue", "temporary test, reverts to old mutex based queue behaviour in jobs.zig:JobManager") orelse false,
|
||||
.static_build = b.option(bool, "static_build", "builds the entire game as a single executable") orelse false,
|
||||
.zero_logging = b.option(bool, "zero_logging", "disables all logging, only intended for use on job dispatch testing") orelse false,
|
||||
.slow_logging = b.option(bool, "slow_logging", "Disables buffered logging, takes a hit to performance but gain timing information on logging") orelse false,
|
||||
.force_mailbox = b.option(bool, "force_mailbox", "forces mailbox mode for present mode. unlocks framerate to irresponsible levels") orelse false,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn createGameOptions(b: *std.Build, options: BuildOptions) *std.Build.Step.Options {
|
||||
fn createGameOptions(b: *std.Build, options: BuildOptions, bhopts: bh.Options) *std.Build.Step.Options {
|
||||
const opts = b.addOptions();
|
||||
|
||||
inline for (@typeInfo(BuildOptions).@"struct".fields) |field| {
|
||||
opts.addOption(bool, field.name, @field(options, field.name));
|
||||
}
|
||||
|
||||
// build options for core.zig
|
||||
// opts.addOption(
|
||||
// bool,
|
||||
// "mutex_job_queue",
|
||||
// );
|
||||
|
||||
// opts.addOption(
|
||||
// bool,
|
||||
// "static_build",
|
||||
// );
|
||||
|
||||
// opts.addOption(
|
||||
// bool,
|
||||
// "zero_logging",
|
||||
// );
|
||||
// opts.addOption(
|
||||
// bool,
|
||||
// "slow_logging",
|
||||
// );
|
||||
// opts.addOption(
|
||||
// bool,
|
||||
// "force_mailbox",
|
||||
// );
|
||||
// forward the options to the build options
|
||||
opts.addOption(bool, "tracy", bhopts.tracy);
|
||||
opts.addOption(bool, "static_build", bhopts.static_build);
|
||||
|
||||
return opts;
|
||||
}
|
||||
|
||||
pub fn addExtraModule(self: *BuildSystem, mod: *std.Build.Module, moduleName: []const u8) void {
|
||||
const dep = self.b.dependency(moduleName, .{ .target = self.target, .optimize = self.optimize, .static_build = self.staticBuild });
|
||||
const dep = self.b.dependency(moduleName, .{ .target = self.opts.target, .optimize = self.opts.optimize, .static_build = self.opts.static_build });
|
||||
mod.addImport(moduleName, dep.module(moduleName));
|
||||
}
|
||||
|
||||
pub fn addDependencyInstalls(self: *BuildSystem, b: *std.Build, optimize: std.builtin.OptimizeMode) void {
|
||||
//if (self.staticBuild) {
|
||||
//return;
|
||||
// }
|
||||
fn addDependencyInstalls(self: *BuildSystem, b: *std.Build, optimize: std.builtin.OptimizeMode) void {
|
||||
if (self.opts.static_build) {
|
||||
return;
|
||||
}
|
||||
|
||||
inline for (DynamicDepList) |d| {
|
||||
b.installArtifact(b.dependency(
|
||||
d.dep,
|
||||
.{ .target = self.target, .optimize = optimize, .static_build = self.staticBuild },
|
||||
.{ .target = self.opts.target, .optimize = optimize, .static_build = self.opts.static_build },
|
||||
).artifact(d.artifact));
|
||||
}
|
||||
|
||||
// b.installArtifact(b.dependency(
|
||||
// "sdl3",
|
||||
// .{ .target = self.target, .optimize = optimize, .static_build = self.staticBuild },
|
||||
// ).artifact("SDL3"));
|
||||
}
|
||||
|
||||
const DynamicDepList: []const struct { dep: []const u8, artifact: []const u8 } = &.{
|
||||
.{ .dep = "sdl3", .artifact = "SDL3" },
|
||||
.{ .dep = "spng", .artifact = "spng" },
|
||||
.{ .dep = "lua", .artifact = "lua" },
|
||||
.{ .dep = "miniaudio", .artifact = "miniaudio" },
|
||||
.{ .dep = "zphysics", .artifact = "zphysics" },
|
||||
.{ .dep = "spng", .artifact = "spng_c" },
|
||||
.{ .dep = "lua", .artifact = "luac" },
|
||||
.{ .dep = "miniaudio", .artifact = "miniaudio_c" },
|
||||
.{ .dep = "zphysics", .artifact = "joltc" },
|
||||
// .{ .dep = "enet", .artifact = "enet_c" },
|
||||
.{ .dep = "ozz", .artifact = "ozz" },
|
||||
.{ .dep = "ozz", .artifact = "ozz_cpp" },
|
||||
};
|
||||
|
||||
// all other modules are disabled by default
|
||||
pub const defaultEnabledModules: []const []const u8 = &.{
|
||||
"core",
|
||||
"assets",
|
||||
"platform",
|
||||
"rend",
|
||||
};
|
||||
|
||||
pub const moduleOrder: []const []const u8 = &.{
|
||||
"core",
|
||||
"sys",
|
||||
"assets",
|
||||
"platform",
|
||||
"net",
|
||||
"physics",
|
||||
"audio",
|
||||
"rend",
|
||||
"ui",
|
||||
"imgui",
|
||||
"papyrus",
|
||||
};
|
||||
|
||||
pub const DynamicModule = struct {
|
||||
pub fn addProgram(
|
||||
self: *@This(),
|
||||
name: []const u8,
|
||||
allocator: std.mem.Allocator,
|
||||
buildSystem: *BuildSystem,
|
||||
programName: []const u8,
|
||||
opts: AddProgramOptions,
|
||||
|
||||
extras: std.ArrayListUnmanaged(GameModule) = .{},
|
||||
gameModules: std.ArrayListUnmanaged(GameModule) = .{},
|
||||
|
||||
library: ?*std.Build.Step.Compile = null,
|
||||
|
||||
pub fn addExtraModule(self: *@This(), module: []const u8) void {
|
||||
self.extras.append(self.allocator, .{ .name = module, .enabled = true }) catch @panic("out of memory");
|
||||
}
|
||||
|
||||
pub fn init(name: []const u8, p: *Program) *@This() {
|
||||
var self: *@This() = p.allocator.create(@This()) catch @panic("out of memory");
|
||||
|
||||
self.* = .{
|
||||
.opts = p.opts,
|
||||
.programName = p.opts.name,
|
||||
.buildSystem = p.buildSystem,
|
||||
.allocator = p.allocator,
|
||||
.name = name,
|
||||
};
|
||||
|
||||
for (p.gameModules.items) |module| {
|
||||
self.gameModules.append(self.allocator, module) catch @panic("out of memory");
|
||||
}
|
||||
|
||||
for (p.extras.items) |module| {
|
||||
self.extras.append(self.allocator, module) catch @panic("out of memory");
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
pub fn compileInstall(self: *@This()) *std.Build.Step.Compile {
|
||||
if (self.library) |lib| {
|
||||
return lib;
|
||||
}
|
||||
|
||||
const b = self.buildSystem.b;
|
||||
const static = self.buildSystem.staticBuild;
|
||||
const lib = b.addLibrary(.{
|
||||
.name = self.name,
|
||||
.linkage = if (static) .static else .dynamic,
|
||||
.root_module = b.createModule(.{
|
||||
.root_source_file = self.opts.root_source_file,
|
||||
.link_libc = true,
|
||||
.optimize = self.buildSystem.optimize,
|
||||
.target = self.buildSystem.target,
|
||||
}),
|
||||
});
|
||||
|
||||
const allocator = self.buildSystem.b.allocator;
|
||||
|
||||
var modlist = std.ArrayList([]const u8){};
|
||||
|
||||
for (self.gameModules.items) |mod| {
|
||||
if (mod.enabled) {
|
||||
modlist.append(allocator, mod.name) catch @panic("out of memory");
|
||||
}
|
||||
}
|
||||
|
||||
for (self.extras.items) |extra| {
|
||||
self.buildSystem.addExtraModule(lib.root_module, extra.name);
|
||||
}
|
||||
|
||||
lib.root_module.addImport("backlog", self.buildSystem.generateApi(self.name, modlist.items, null));
|
||||
lib.root_module.addOptions("BacklogOptions", self.buildSystem.options);
|
||||
|
||||
if (static) {
|
||||
// generateApi should create static callers for the main program
|
||||
} else {
|
||||
const installExtern = b.addInstallArtifact(lib, .{
|
||||
.dest_dir = .{ .override = .{ .custom = "modules" } },
|
||||
});
|
||||
b.getInstallStep().dependOn(&installExtern.step);
|
||||
}
|
||||
|
||||
return lib;
|
||||
}
|
||||
};
|
||||
|
||||
pub const GameModule = struct {
|
||||
name: []const u8,
|
||||
enabled: bool = true,
|
||||
};
|
||||
|
||||
pub const Program = struct {
|
||||
allocator: std.mem.Allocator,
|
||||
opts: AddProgramOptions,
|
||||
gameModules: std.ArrayListUnmanaged(GameModule) = .{},
|
||||
extras: std.ArrayListUnmanaged(GameModule) = .{},
|
||||
dynamicModules: std.ArrayListUnmanaged(*DynamicModule) = .{},
|
||||
buildSystem: *BuildSystem,
|
||||
|
||||
iconPath: ?std.Build.LazyPath = null,
|
||||
|
||||
pub fn setIconPath(self: *@This(), path: []const u8) void {
|
||||
if (self.iconPath != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
self.iconPath = self.buildSystem.generateRc(self.opts.name, path) catch return;
|
||||
}
|
||||
|
||||
pub fn setModuleEnabled(self: *@This(), module: []const u8, enable: bool) void {
|
||||
for (self.gameModules.items) |*m| {
|
||||
if (std.mem.eql(u8, m.name, module)) {
|
||||
m.enabled = enable;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// module not found, add it here.
|
||||
self.gameModules.append(self.allocator, .{ .name = module, .enabled = enable }) catch @panic("out of memory");
|
||||
}
|
||||
|
||||
pub fn addExtraModule(self: *@This(), module: []const u8) void {
|
||||
self.extras.append(self.allocator, .{ .name = module, .enabled = true }) catch @panic("out of memory");
|
||||
}
|
||||
|
||||
pub fn addDynamicModule(self: *@This(), module: []const u8, root_source_file: std.Build.LazyPath) *DynamicModule {
|
||||
const dynamicModule = DynamicModule.init(module, self);
|
||||
dynamicModule.opts.root_source_file = root_source_file;
|
||||
self.dynamicModules.append(self.allocator, dynamicModule) catch @panic("out of memory");
|
||||
|
||||
return dynamicModule;
|
||||
}
|
||||
|
||||
pub fn compileInstall(self: *@This()) *std.Build.Module {
|
||||
const exe = self.buildSystem.addProgram(self.opts);
|
||||
const allocator = self.buildSystem.b.allocator;
|
||||
|
||||
var modlist = std.ArrayList([]const u8){};
|
||||
|
||||
for (self.gameModules.items) |mod| {
|
||||
if (mod.enabled) {
|
||||
modlist.append(allocator, mod.name) catch @panic("out of memory");
|
||||
}
|
||||
}
|
||||
|
||||
for (self.extras.items) |extra| {
|
||||
self.buildSystem.addExtraModule(exe, extra.name);
|
||||
}
|
||||
|
||||
exe.addImport("backlog", self.buildSystem.generateApi(self.opts.name, modlist.items, self.dynamicModules.items));
|
||||
|
||||
if (self.buildSystem.target.result.os.tag == .windows) {
|
||||
if (self.iconPath) |ip| {
|
||||
exe.addWin32ResourceFile(.{
|
||||
.file = ip,
|
||||
.flags = &.{},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return exe;
|
||||
}
|
||||
};
|
||||
|
||||
pub fn program(self: *BuildSystem, opts: AddProgramOptions) *Program {
|
||||
const prog = self.b.allocator.create(Program) catch unreachable;
|
||||
|
||||
prog.* = .{
|
||||
.allocator = self.b.allocator,
|
||||
.opts = opts,
|
||||
) *Program {
|
||||
const p = self.b.allocator.create(Program) catch unreachable;
|
||||
p.* = .{
|
||||
.name = name,
|
||||
.opts = self.opts,
|
||||
.buildSystem = self,
|
||||
.allocator = self.b.allocator,
|
||||
};
|
||||
|
||||
for (moduleOrder) |module| {
|
||||
prog.setModuleEnabled(module, false);
|
||||
}
|
||||
|
||||
for (defaultEnabledModules) |module| {
|
||||
prog.setModuleEnabled(module, true);
|
||||
}
|
||||
|
||||
return prog;
|
||||
}
|
||||
|
||||
// ========= standalone build instance =======
|
||||
// maybe the default should be like an engine launcher/project launcher or something
|
||||
pub fn build(b: *std.Build) void {
|
||||
const target = b.standardTargetOptions(.{});
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
const static_build = b.option(bool, "static_build", "builds backlog dependencies for static linking") orelse false;
|
||||
|
||||
const fwdGeneratorExe = b.addExecutable(.{
|
||||
.name = "backlog-generate-fwd",
|
||||
.root_module = b.createModule(.{
|
||||
.target = b.graph.host,
|
||||
.optimize = .Debug,
|
||||
.root_source_file = b.path("build/generateFwd.zig"),
|
||||
}),
|
||||
});
|
||||
|
||||
const generateExe = b.addExecutable(.{
|
||||
.name = "backlog-apigen",
|
||||
.root_module = b.createModule(.{
|
||||
.target = b.graph.host,
|
||||
.optimize = .Debug,
|
||||
.root_source_file = b.path("build/generateApi.zig"),
|
||||
}),
|
||||
});
|
||||
|
||||
const generateShaders = b.addExecutable(.{
|
||||
.name = "backlog-shaderEmbedGen",
|
||||
.root_module = b.createModule(.{
|
||||
.target = b.graph.host,
|
||||
.optimize = .Debug,
|
||||
.root_source_file = b.path("build/generateEmbeddedShaders.zig"),
|
||||
}),
|
||||
});
|
||||
|
||||
const generateRcExe = b.addExecutable(.{
|
||||
.name = "backlog-generate-rc",
|
||||
.root_module = b.createModule(.{
|
||||
.target = b.graph.host,
|
||||
.optimize = .Debug,
|
||||
.root_source_file = b.path("build/generateRc.zig"),
|
||||
}),
|
||||
});
|
||||
|
||||
const generateLoadDynamicsExe = b.addExecutable(.{
|
||||
.name = "backlog-generate-loadDynamics",
|
||||
.root_module = b.createModule(.{
|
||||
.target = b.graph.host,
|
||||
.optimize = .Debug,
|
||||
.root_source_file = b.path("build/generateLoadDynamics.zig"),
|
||||
}),
|
||||
});
|
||||
|
||||
b.installArtifact(generateLoadDynamicsExe);
|
||||
b.installArtifact(generateExe);
|
||||
b.installArtifact(generateShaders);
|
||||
b.installArtifact(generateRcExe);
|
||||
|
||||
{
|
||||
const loadDynamicsStub = b.addModule("loadDynamicsStub", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.root_source_file = b.path("engine/loadDynamicsStub.zig"),
|
||||
});
|
||||
|
||||
_ = loadDynamicsStub;
|
||||
|
||||
const mod = b.addModule("Backlog", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.root_source_file = b.path("engine/backlog.zig"),
|
||||
});
|
||||
|
||||
for (engineDepList) |depName| {
|
||||
const dep = b.dependency(
|
||||
depName,
|
||||
.{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.static_build = static_build,
|
||||
},
|
||||
);
|
||||
|
||||
const run = b.addRunArtifact(fwdGeneratorExe);
|
||||
const output = run.addOutputFileArg(b.fmt("{s}_fwd.zig", .{depName}));
|
||||
|
||||
const modFwd = b.addModule(depName, .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.root_source_file = output,
|
||||
});
|
||||
|
||||
mod.addImport(b.fmt("{s}", .{depName}), modFwd);
|
||||
modFwd.addImport("module", dep.module(depName));
|
||||
|
||||
b.installArtifact(dep.artifact(depName));
|
||||
|
||||
// mod.addImport(depName, dep.module(depName));
|
||||
}
|
||||
|
||||
// link in large platform support functions... special case.
|
||||
{
|
||||
const dep = b.dependency("sdl3", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.static_build = static_build,
|
||||
});
|
||||
const lib = dep.module("sdl3");
|
||||
|
||||
mod.addImport("sdl3_fwd", lib);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn generateApi(self: *@This(), programName: []const u8, moduleList: []const []const u8, dynamicModules: ?[]const *DynamicModule) *std.Build.Module {
|
||||
// std.debug.print("GENERATE API:: {s}\n", .{programName});
|
||||
|
||||
for (moduleList) |mod| {
|
||||
_ = mod;
|
||||
// std.debug.print("{s}\n", .{mod});
|
||||
}
|
||||
//
|
||||
if (self.generatedApis.get(programName)) |m| {
|
||||
return m;
|
||||
}
|
||||
|
||||
const run = self.b.addRunArtifact(self.apigen);
|
||||
const pfile = self.b.fmt("{s}Api.zig", .{programName});
|
||||
const output = run.addOutputFileArg(pfile);
|
||||
for (moduleList) |modName| {
|
||||
run.addArg(modName);
|
||||
}
|
||||
|
||||
const mod = self.b.addModule(pfile, .{
|
||||
.target = self.target,
|
||||
.optimize = self.optimize,
|
||||
.root_source_file = output,
|
||||
});
|
||||
for (moduleList) |modName| {
|
||||
mod.addImport(modName, self.nwdep.module(modName));
|
||||
mod.linkLibrary(self.nwdep.artifact(modName));
|
||||
}
|
||||
|
||||
const loadStatics = self.generateInstallStaticResources(programName, "content/_shaders") catch unreachable;
|
||||
mod.addImport("staticShaderLoader", loadStatics);
|
||||
|
||||
// deal with dynamics
|
||||
if (dynamicModules) |dynamics| {
|
||||
const loadDynamics = self.generateLoadDynamics(programName, dynamics) catch @panic("unknown");
|
||||
mod.addImport("loadDynamics", loadDynamics);
|
||||
} else {
|
||||
mod.addImport("loadDynamics", self.nwdep.module("loadDynamicsStub"));
|
||||
}
|
||||
|
||||
self.generatedApis.put(self.b.allocator, programName, mod) catch @panic("out of memory");
|
||||
|
||||
return mod;
|
||||
return p;
|
||||
}
|
||||
|
||||
pub fn generateRc(self: *@This(), programName: []const u8, iconPath: []const u8) !std.Build.LazyPath {
|
||||
|
|
@ -624,35 +186,6 @@ pub fn generateRc(self: *@This(), programName: []const u8, iconPath: []const u8)
|
|||
return output;
|
||||
}
|
||||
|
||||
pub fn generateLoadDynamics(self: *@This(), programName: []const u8, dynamics: []const *DynamicModule) !*std.Build.Module {
|
||||
const run = self.b.addRunArtifact(self.loadDynamicsGen);
|
||||
const pfile = self.b.fmt("{s}LoadDynamics.zig", .{programName});
|
||||
const output = run.addOutputFileArg(pfile);
|
||||
if (self.staticBuild) {
|
||||
run.addArg("static");
|
||||
} else {
|
||||
run.addArg("dynamic");
|
||||
}
|
||||
|
||||
for (dynamics) |dyn| {
|
||||
run.addArg(dyn.name);
|
||||
}
|
||||
|
||||
const mod = self.b.addModule(pfile, .{
|
||||
.target = self.target,
|
||||
.optimize = self.optimize,
|
||||
.root_source_file = output,
|
||||
});
|
||||
|
||||
mod.addImport("core", self.nwdep.module("core"));
|
||||
for (dynamics) |dyn| {
|
||||
const dynmod = dyn.compileInstall();
|
||||
mod.addImport(dyn.name, dynmod.root_module);
|
||||
}
|
||||
|
||||
return mod;
|
||||
}
|
||||
|
||||
pub fn generateInstallStaticResources(self: *@This(), programName: []const u8, shadersPath: []const u8) !*std.Build.Module {
|
||||
const run = self.b.addRunArtifact(self.shaderEmbedGen);
|
||||
const pfile = self.b.fmt("{s}ShaderGen.zig", .{programName});
|
||||
|
|
@ -661,8 +194,8 @@ pub fn generateInstallStaticResources(self: *@This(), programName: []const u8, s
|
|||
|
||||
const b = self.b;
|
||||
const mod = self.b.addModule(pfile, .{
|
||||
.target = self.target,
|
||||
.optimize = self.optimize,
|
||||
.target = self.opts.target,
|
||||
.optimize = self.opts.optimize,
|
||||
.root_source_file = output,
|
||||
});
|
||||
mod.addImport("core", self.nwdep.module("core"));
|
||||
|
|
@ -687,3 +220,15 @@ pub fn generateInstallStaticResources(self: *@This(), programName: []const u8, s
|
|||
|
||||
return mod;
|
||||
}
|
||||
|
||||
// ========= standalone build instance =======
|
||||
// maybe the default should be like an engine launcher/project launcher or something
|
||||
pub fn build(b: *std.Build) void {
|
||||
const opts = bh.declareOptions(b);
|
||||
engineDeps.buildGenerators(b, opts);
|
||||
}
|
||||
|
||||
const bh = @import("bh");
|
||||
const engineDeps = @import("build/engineDeps.zig");
|
||||
const program = @import("build/program.zig");
|
||||
const Program = program.Program;
|
||||
|
|
|
|||
|
|
@ -1,28 +1,23 @@
|
|||
.{
|
||||
.name = .Backlog,
|
||||
.version = "0.0.0",
|
||||
.dependencies = .{
|
||||
.assets = .{ .path = "engine/assets" },
|
||||
.audio = .{ .path = "engine/audio" },
|
||||
.core = .{ .path = "engine/core" },
|
||||
.net = .{ .path = "engine/net" },
|
||||
.papyrus = .{ .path = "engine/papyrus" },
|
||||
.physics = .{ .path = "engine/physics" },
|
||||
.platform = .{ .path = "engine/platform" },
|
||||
.imgui = .{ .path = "engine/imgui" },
|
||||
.ui = .{ .path = "engine/ui" },
|
||||
.sys = .{ .path = "engine/sys" },
|
||||
.rend = .{.path = "engine/rend" },
|
||||
.{ .name = .Backlog, .version = "0.0.0", .dependencies = .{
|
||||
.assets = .{ .path = "engine/assets" },
|
||||
.audio = .{ .path = "engine/audio" },
|
||||
.core = .{ .path = "engine/core" },
|
||||
.net = .{ .path = "engine/net" },
|
||||
.papyrus = .{ .path = "engine/papyrus" },
|
||||
.physics = .{ .path = "engine/physics" },
|
||||
.platform = .{ .path = "engine/platform" },
|
||||
.imgui = .{ .path = "engine/imgui" },
|
||||
.ui = .{ .path = "engine/ui" },
|
||||
.sys = .{ .path = "engine/sys" },
|
||||
.rend = .{ .path = "engine/rend" },
|
||||
|
||||
.ozz = .{ .path = "lib/ozz" },
|
||||
.spng = .{ .path = "lib/spng" },
|
||||
.zphysics = .{ .path = "lib/zphysics" },
|
||||
.ozz = .{ .path = "lib/ozz" },
|
||||
.spng = .{ .path = "lib/spng" },
|
||||
.zphysics = .{ .path = "lib/zphysics" },
|
||||
|
||||
.sdl3 = .{ .path = "lib/sdl3" },
|
||||
.enet = .{ .path = "lib/enet" },
|
||||
},
|
||||
.paths = .{
|
||||
"",
|
||||
},
|
||||
.fingerprint = 0xcf9bab998abe37e3
|
||||
}
|
||||
.sdl3 = .{ .path = "lib/sdl3" },
|
||||
.enet = .{ .path = "lib/enet" },
|
||||
.bh = .{ .path = "lib/bh" },
|
||||
}, .paths = .{
|
||||
"",
|
||||
}, .fingerprint = 0xcf9bab998abe37e3 }
|
||||
|
|
|
|||
|
|
@ -0,0 +1,84 @@
|
|||
pub const AddProgramOptions = struct {
|
||||
name: []const u8,
|
||||
desc: []const u8,
|
||||
root_source_file: LazyPath,
|
||||
imports: []const Build.Module.Import = &.{},
|
||||
};
|
||||
|
||||
pub const Program = struct {
|
||||
allocator: std.mem.Allocator,
|
||||
opts: AddProgramOptions,
|
||||
gameModules: std.ArrayListUnmanaged(GameModule) = .{},
|
||||
extras: std.ArrayListUnmanaged(GameModule) = .{},
|
||||
dynamicModules: std.ArrayListUnmanaged(*DynamicModule) = .{},
|
||||
buildSystem: *BuildSystem,
|
||||
|
||||
iconPath: ?std.Build.LazyPath = null,
|
||||
|
||||
pub fn setIconPath(self: *@This(), path: []const u8) void {
|
||||
if (self.iconPath != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
self.iconPath = self.buildSystem.generateRc(self.opts.name, path) catch return;
|
||||
}
|
||||
|
||||
pub fn setModuleEnabled(self: *@This(), module: []const u8, enable: bool) void {
|
||||
for (self.gameModules.items) |*m| {
|
||||
if (std.mem.eql(u8, m.name, module)) {
|
||||
m.enabled = enable;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// module not found, add it here.
|
||||
self.gameModules.append(self.allocator, .{ .name = module, .enabled = enable }) catch @panic("out of memory");
|
||||
}
|
||||
|
||||
pub fn addExtraModule(self: *@This(), module: []const u8) void {
|
||||
self.extras.append(self.allocator, .{ .name = module, .enabled = true }) catch @panic("out of memory");
|
||||
}
|
||||
|
||||
pub fn addDynamicModule(self: *@This(), module: []const u8, root_source_file: std.Build.LazyPath) *DynamicModule {
|
||||
const dynamicModule = DynamicModule.init(module, self);
|
||||
dynamicModule.opts.root_source_file = root_source_file;
|
||||
self.dynamicModules.append(self.allocator, dynamicModule) catch @panic("out of memory");
|
||||
|
||||
return dynamicModule;
|
||||
}
|
||||
|
||||
pub fn compileInstall(self: *@This()) *std.Build.Module {
|
||||
const exe = self.buildSystem.addProgram(self.opts);
|
||||
const allocator = self.buildSystem.b.allocator;
|
||||
|
||||
var modlist = std.ArrayList([]const u8){};
|
||||
|
||||
for (self.gameModules.items) |mod| {
|
||||
if (mod.enabled) {
|
||||
modlist.append(allocator, mod.name) catch @panic("out of memory");
|
||||
}
|
||||
}
|
||||
|
||||
for (self.extras.items) |extra| {
|
||||
self.buildSystem.addExtraModule(exe, extra.name);
|
||||
}
|
||||
|
||||
exe.addImport("backlog", self.buildSystem.generateApi(self.opts.name, modlist.items, self.dynamicModules.items));
|
||||
|
||||
if (self.buildSystem.target.result.os.tag == .windows) {
|
||||
if (self.iconPath) |ip| {
|
||||
exe.addWin32ResourceFile(.{
|
||||
.file = ip,
|
||||
.flags = &.{},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return exe;
|
||||
}
|
||||
};
|
||||
|
||||
const std = @import("std");
|
||||
const Build = std.Build;
|
||||
const LazyPath = Build.LazyPath;
|
||||
|
||||
|
|
@ -0,0 +1,138 @@
|
|||
const engineDepList = [_][]const u8{
|
||||
"assets",
|
||||
"audio",
|
||||
"core",
|
||||
"net",
|
||||
"papyrus",
|
||||
"platform",
|
||||
"rend",
|
||||
"ui",
|
||||
"imgui",
|
||||
"physics",
|
||||
"sys",
|
||||
};
|
||||
|
||||
pub fn depList() []const []const u8 {
|
||||
return &engineDepList;
|
||||
}
|
||||
|
||||
pub fn buildGenerators(b: *std.Build, opts: bh.Options) void {
|
||||
const target = opts.target;
|
||||
const optimize = opts.optimize;
|
||||
const static_build = opts.static_build;
|
||||
|
||||
const fwdGeneratorExe = b.addExecutable(.{
|
||||
.name = "backlog-generate-fwd",
|
||||
.root_module = b.createModule(.{
|
||||
.target = b.graph.host,
|
||||
.optimize = .Debug,
|
||||
.root_source_file = b.path("buildgen/generateFwd.zig"),
|
||||
}),
|
||||
});
|
||||
|
||||
const generateModApiExe = b.addExecutable(.{
|
||||
.name = "backlog-generate-modapi",
|
||||
.root_module = b.createModule(.{
|
||||
.target = b.graph.host,
|
||||
.optimize = .Debug,
|
||||
.root_source_file = b.path("buildgen/generateModApi.zig"),
|
||||
}),
|
||||
});
|
||||
|
||||
const generateProgramSpecExe = b.addExecutable(.{
|
||||
.name = "backlog-generate-spec",
|
||||
.root_module = b.createModule(.{
|
||||
.target = b.graph.host,
|
||||
.optimize = .Debug,
|
||||
.root_source_file = b.path("buildgen/generateProgramSpec.zig"),
|
||||
}),
|
||||
});
|
||||
|
||||
const generateShaders = b.addExecutable(.{
|
||||
.name = "backlog-shaderEmbedGen",
|
||||
.root_module = b.createModule(.{
|
||||
.target = b.graph.host,
|
||||
.optimize = .Debug,
|
||||
.root_source_file = b.path("buildgen/generateEmbeddedShaders.zig"),
|
||||
}),
|
||||
});
|
||||
|
||||
const generateRcExe = b.addExecutable(.{
|
||||
.name = "backlog-generate-rc",
|
||||
.root_module = b.createModule(.{
|
||||
.target = b.graph.host,
|
||||
.optimize = .Debug,
|
||||
.root_source_file = b.path("buildgen/generateRc.zig"),
|
||||
}),
|
||||
});
|
||||
|
||||
const generateLoadDynamicsExe = b.addExecutable(.{
|
||||
.name = "backlog-generate-loadDynamics",
|
||||
.root_module = b.createModule(.{
|
||||
.target = b.graph.host,
|
||||
.optimize = .Debug,
|
||||
.root_source_file = b.path("buildgen/generateLoadDynamics.zig"),
|
||||
}),
|
||||
});
|
||||
|
||||
b.installArtifact(fwdGeneratorExe);
|
||||
b.installArtifact(generateLoadDynamicsExe);
|
||||
b.installArtifact(generateProgramSpecExe);
|
||||
b.installArtifact(generateShaders);
|
||||
b.installArtifact(generateRcExe);
|
||||
b.installArtifact(generateModApiExe);
|
||||
|
||||
{
|
||||
const loadDynamicsStub = b.addModule("loadDynamicsStub", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.root_source_file = b.path("engine/loadDynamicsStub.zig"),
|
||||
});
|
||||
|
||||
_ = loadDynamicsStub;
|
||||
|
||||
const mod = b.addModule("Backlog", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.root_source_file = b.path("engine/backlog.zig"),
|
||||
});
|
||||
|
||||
for (depList()) |depName| {
|
||||
const dep = b.dependency(
|
||||
depName,
|
||||
.{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.static_build = static_build,
|
||||
},
|
||||
);
|
||||
|
||||
const run = b.addRunArtifact(fwdGeneratorExe);
|
||||
const output = run.addOutputFileArg(b.fmt("{s}_fwd.zig", .{depName}));
|
||||
|
||||
const modFwd = b.addModule(depName, .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.root_source_file = output,
|
||||
});
|
||||
|
||||
mod.addImport(b.fmt("{s}", .{depName}), modFwd);
|
||||
modFwd.addImport("module", dep.module(depName));
|
||||
}
|
||||
|
||||
// link in large platform support functions... special case.
|
||||
{
|
||||
const dep = b.dependency("sdl3", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.static_build = static_build,
|
||||
});
|
||||
const lib = dep.module("SDL3");
|
||||
|
||||
mod.addImport("sdl3_fwd", lib);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const std = @import("std");
|
||||
const bh = @import("bh");
|
||||
|
|
@ -0,0 +1,182 @@
|
|||
// legacy code, kept here as reference
|
||||
pub const GameModule = struct {
|
||||
name: []const u8,
|
||||
enabled: bool = true,
|
||||
};
|
||||
|
||||
pub fn program(self: *BuildSystem, opts: AddProgramOptions) *Program {
|
||||
const prog = self.b.allocator.create(Program) catch unreachable;
|
||||
|
||||
prog.* = .{
|
||||
.allocator = self.b.allocator,
|
||||
.opts = opts,
|
||||
.buildSystem = self,
|
||||
};
|
||||
|
||||
for (moduleOrder) |module| {
|
||||
prog.setModuleEnabled(module, false);
|
||||
}
|
||||
|
||||
for (defaultEnabledModules) |module| {
|
||||
prog.setModuleEnabled(module, true);
|
||||
}
|
||||
|
||||
return prog;
|
||||
}
|
||||
|
||||
pub const DynamicModule = struct {
|
||||
name: []const u8,
|
||||
allocator: std.mem.Allocator,
|
||||
buildSystem: *BuildSystem,
|
||||
programName: []const u8,
|
||||
opts: Program.AddProgramOptions,
|
||||
|
||||
extras: std.ArrayListUnmanaged(Program.GameModule) = .{},
|
||||
gameModules: std.ArrayListUnmanaged(Program.GameModule) = .{},
|
||||
|
||||
library: ?*std.Build.Step.Compile = null,
|
||||
|
||||
pub fn addExtraModule(self: *@This(), module: []const u8) void {
|
||||
self.extras.append(self.allocator, .{ .name = module, .enabled = true }) catch @panic("out of memory");
|
||||
}
|
||||
|
||||
pub fn init(name: []const u8, p: *Program) *@This() {
|
||||
var self: *@This() = p.allocator.create(@This()) catch @panic("out of memory");
|
||||
|
||||
self.* = .{
|
||||
.opts = p.opts,
|
||||
.programName = p.opts.name,
|
||||
.buildSystem = p.buildSystem,
|
||||
.allocator = p.allocator,
|
||||
.name = name,
|
||||
};
|
||||
|
||||
for (p.gameModules.items) |module| {
|
||||
self.gameModules.append(self.allocator, module) catch @panic("out of memory");
|
||||
}
|
||||
|
||||
for (p.extras.items) |module| {
|
||||
self.extras.append(self.allocator, module) catch @panic("out of memory");
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
pub fn compileInstall(self: *@This()) *std.Build.Step.Compile {
|
||||
if (self.library) |lib| {
|
||||
return lib;
|
||||
}
|
||||
|
||||
const b = self.buildSystem.b;
|
||||
const static = self.buildSystem.staticBuild;
|
||||
const lib = b.addLibrary(.{
|
||||
.name = self.name,
|
||||
.linkage = if (static) .static else .dynamic,
|
||||
.root_module = b.createModule(.{
|
||||
.root_source_file = self.opts.root_source_file,
|
||||
.link_libc = true,
|
||||
.optimize = self.buildSystem.optimize,
|
||||
.target = self.buildSystem.target,
|
||||
}),
|
||||
});
|
||||
|
||||
const allocator = self.buildSystem.b.allocator;
|
||||
|
||||
var modlist = std.ArrayList([]const u8){};
|
||||
|
||||
for (self.gameModules.items) |mod| {
|
||||
if (mod.enabled) {
|
||||
modlist.append(allocator, mod.name) catch @panic("out of memory");
|
||||
}
|
||||
}
|
||||
|
||||
for (self.extras.items) |extra| {
|
||||
self.buildSystem.addExtraModule(lib.root_module, extra.name);
|
||||
}
|
||||
|
||||
lib.root_module.addImport("backlog", self.buildSystem.generateApi(self.name, modlist.items, null));
|
||||
lib.root_module.addOptions("BacklogOptions", self.buildSystem.options);
|
||||
|
||||
if (!static) {
|
||||
const installExtern = b.addInstallArtifact(lib, .{
|
||||
.dest_dir = .{ .override = .{ .custom = "modules" } },
|
||||
});
|
||||
b.getInstallStep().dependOn(&installExtern.step);
|
||||
}
|
||||
|
||||
return lib;
|
||||
}
|
||||
};
|
||||
|
||||
pub fn generateApi(self: *@This(), programName: []const u8, moduleList: []const []const u8, dynamicModules: ?[]const *DynamicModule,) *std.Build.Module {
|
||||
// std.debug.print("GENERATE API:: {s}\n", .{programName});
|
||||
|
||||
for (moduleList) |mod| {
|
||||
_ = mod;
|
||||
// std.debug.print("{s}\n", .{mod});
|
||||
}
|
||||
//
|
||||
if (self.generatedApis.get(programName)) |m| {
|
||||
return m;
|
||||
}
|
||||
|
||||
const run = self.b.addRunArtifact(self.apigen);
|
||||
const pfile = self.b.fmt("{s}Api.zig", .{programName});
|
||||
const output = run.addOutputFileArg(pfile);
|
||||
for (moduleList) |modName| {
|
||||
run.addArg(modName);
|
||||
}
|
||||
|
||||
const mod = self.b.addModule(pfile, .{
|
||||
.target = self.target,
|
||||
.optimize = self.optimize,
|
||||
.root_source_file = output,
|
||||
});
|
||||
for (moduleList) |modName| {
|
||||
mod.addImport(modName, self.nwdep.module(modName));
|
||||
}
|
||||
|
||||
const loadStatics = self.generateInstallStaticResources(programName, "content/_shaders") catch unreachable;
|
||||
mod.addImport("staticShaderLoader", loadStatics);
|
||||
|
||||
// deal with dynamics
|
||||
if (dynamicModules) |dynamics| {
|
||||
const loadDynamics = self.generateLoadDynamics(programName, dynamics) catch @panic("unknown");
|
||||
mod.addImport("loadDynamics", loadDynamics);
|
||||
} else {
|
||||
mod.addImport("loadDynamics", self.nwdep.module("loadDynamicsStub"));
|
||||
}
|
||||
|
||||
self.generatedApis.put(self.b.allocator, programName, mod) catch @panic("out of memory");
|
||||
|
||||
return mod;
|
||||
}
|
||||
|
||||
pub fn generateLoadDynamics(self: *@This(), programName: []const u8, dynamics: []const *DynamicModule) !*std.Build.Module {
|
||||
const run = self.b.addRunArtifact(self.loadDynamicsGen);
|
||||
const pfile = self.b.fmt("{s}LoadDynamics.zig", .{programName});
|
||||
const output = run.addOutputFileArg(pfile);
|
||||
if (self.staticBuild) {
|
||||
run.addArg("static");
|
||||
} else {
|
||||
run.addArg("dynamic");
|
||||
}
|
||||
|
||||
for (dynamics) |dyn| {
|
||||
run.addArg(dyn.name);
|
||||
}
|
||||
|
||||
const mod = self.b.addModule(pfile, .{
|
||||
.target = self.target,
|
||||
.optimize = self.optimize,
|
||||
.root_source_file = output,
|
||||
});
|
||||
|
||||
mod.addImport("core", self.nwdep.module("core"));
|
||||
for (dynamics) |dyn| {
|
||||
const dynmod = dyn.compileInstall();
|
||||
mod.addImport(dyn.name, dynmod.root_module);
|
||||
}
|
||||
|
||||
return mod;
|
||||
}
|
||||
|
|
@ -0,0 +1,227 @@
|
|||
pub const AddProgramOptions = struct {
|
||||
name: []const u8,
|
||||
opt: bh.Options,
|
||||
root_source_file: std.Build.LazyPath,
|
||||
};
|
||||
|
||||
// all other modules are disabled by default
|
||||
pub const defaultEnabledModules: []const []const u8 = &.{
|
||||
"core",
|
||||
"assets",
|
||||
"platform",
|
||||
"rend",
|
||||
};
|
||||
|
||||
pub const moduleOrder: []const []const u8 = &.{
|
||||
"core",
|
||||
"sys",
|
||||
"assets",
|
||||
"platform",
|
||||
"net",
|
||||
"physics",
|
||||
"audio",
|
||||
"rend",
|
||||
"ui",
|
||||
"imgui",
|
||||
"papyrus",
|
||||
};
|
||||
|
||||
pub const GameModule = struct {
|
||||
name: []const u8,
|
||||
enabled: bool = true,
|
||||
};
|
||||
|
||||
pub const Program = struct {
|
||||
name: []const u8,
|
||||
opts: bh.Options,
|
||||
|
||||
// root_path: not used yet, we will create a second module that dynamically loads in to that root_path
|
||||
|
||||
gameModules: std.ArrayListUnmanaged(GameModule) = .{},
|
||||
gameModulesMap: std.StringHashMapUnmanaged(bool) = .{},
|
||||
buildSystem: *backlog.BuildSystem,
|
||||
iconPath: ?std.Build.LazyPath = null,
|
||||
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) catch unreachable;
|
||||
r.value_ptr.* = enabled;
|
||||
}
|
||||
|
||||
fn finalizeModules(self: *@This()) void {
|
||||
self.gameModules.clearRetainingCapacity();
|
||||
|
||||
for (moduleOrder) |mod| {
|
||||
var enabled: bool = false;
|
||||
for (defaultEnabledModules) |default| {
|
||||
if (std.mem.eql(u8, default, mod)) {
|
||||
enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (self.gameModulesMap.get(mod)) |value| {
|
||||
enabled = value;
|
||||
}
|
||||
|
||||
if (enabled) {
|
||||
self.gameModules.append(self.allocator, .{ .name = mod, .enabled = enabled }) catch unreachable;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn setIconPath(self: *@This(), path: []const u8) void {
|
||||
if (self.iconPath != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
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 makeGameApi(self: *@This()) *std.Build.Module {
|
||||
const b = self.buildSystem.b;
|
||||
const apigen = self.buildSystem.nwdep.artifact("backlog-generate-modapi");
|
||||
const run = b.addRunArtifact(apigen);
|
||||
const pfile = run.addOutputFileArg(b.fmt("{s}-api.zig", .{self.name}));
|
||||
|
||||
run.addArg(self.name);
|
||||
|
||||
for (self.gameModules.items) |mod| {
|
||||
if (mod.enabled) {
|
||||
run.addArg(mod.name);
|
||||
}
|
||||
}
|
||||
|
||||
const api = b.createModule(.{
|
||||
.target = self.opts.target,
|
||||
.optimize = self.opts.optimize,
|
||||
.root_source_file = pfile,
|
||||
});
|
||||
|
||||
for (self.gameModules.items) |mod| {
|
||||
if (mod.enabled) {
|
||||
api.addImport(mod.name, self.buildSystem.nwdep.module(mod.name));
|
||||
}
|
||||
}
|
||||
|
||||
return api;
|
||||
}
|
||||
|
||||
pub fn makeGameModule(self: *@This()) *std.Build.Step.Compile {
|
||||
const b = self.buildSystem.b;
|
||||
const bEngine = self.buildSystem.bEngine;
|
||||
|
||||
const opts = self.opts;
|
||||
|
||||
// 1. generate the main launch codeset.
|
||||
const lib = b.addLibrary(.{
|
||||
.name = b.fmt("{s}-mod", .{self.name}),
|
||||
.linkage = if (opts.static_build) .static else .dynamic,
|
||||
.root_module = b.createModule(.{
|
||||
.target = opts.target,
|
||||
.optimize = opts.optimize,
|
||||
.root_source_file = bEngine.path("engine/modulelaunch.zig"),
|
||||
}),
|
||||
});
|
||||
|
||||
if (opts.static_build) {
|
||||
// b.installArtifact(lib);
|
||||
} else {
|
||||
const installExtern = b.addInstallArtifact(lib, .{
|
||||
.dest_dir = .{ .override = .{ .custom = "modules" } },
|
||||
});
|
||||
b.getInstallStep().dependOn(&installExtern.step);
|
||||
}
|
||||
|
||||
return lib;
|
||||
}
|
||||
|
||||
pub fn generateStaticShaders(self: *@This()) *std.Build.Module {
|
||||
const loadStatics = self.buildSystem.generateInstallStaticResources(self.name, "content/_shaders") catch unreachable;
|
||||
return loadStatics;
|
||||
}
|
||||
|
||||
// spec is linked in both the base trampoline
|
||||
pub fn compileInstall(self: *@This()) *std.Build.Step.Compile {
|
||||
const bEngine = self.buildSystem.bEngine;
|
||||
const b = self.buildSystem.b;
|
||||
const core = self.buildSystem.nwdep.module("core");
|
||||
self.finalizeModules();
|
||||
|
||||
// 1. create the loader
|
||||
const exe = bEngine.addExecutable(.{
|
||||
.name = self.name,
|
||||
.root_module = bEngine.createModule(.{
|
||||
.target = self.opts.target,
|
||||
.optimize = self.opts.optimize,
|
||||
.root_source_file = bEngine.path("engine/main2.zig"),
|
||||
}),
|
||||
});
|
||||
|
||||
// link core
|
||||
const spec = self.makeSpec();
|
||||
exe.root_module.addImport("gamespec", spec);
|
||||
exe.root_module.addImport("core", core);
|
||||
exe.root_module.addOptions("BacklogOptions", self.buildSystem.options);
|
||||
|
||||
if (!self.opts.static_build) {
|
||||
const platform = self.buildSystem.nwdep.module("platform");
|
||||
exe.root_module.addImport("platform", platform);
|
||||
}
|
||||
|
||||
if (self.opts.static_build) {
|
||||
exe.root_module.addImport("staticShaderLoader", self.generateStaticShaders());
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
// self.buildSystem.b.installArtifact(exe);
|
||||
const installed = self.buildSystem.b.addInstallArtifact(exe, .{});
|
||||
|
||||
{
|
||||
const run = b.addSystemCommand(&.{b.fmt("zig-out/bin/{s}", .{self.name})});
|
||||
run.step.dependOn(&installed.step);
|
||||
|
||||
if (b.args) |args| {
|
||||
run.addArgs(args);
|
||||
}
|
||||
|
||||
const run_exe = b.step(b.fmt("run-{s}", .{self.name}), "runs the program");
|
||||
run_exe.dependOn(&run.step);
|
||||
}
|
||||
|
||||
return exe;
|
||||
}
|
||||
};
|
||||
|
||||
const std = @import("std");
|
||||
const bh = @import("bh");
|
||||
const backlog = @import("../build.zig");
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
const std = @import("std");
|
||||
const Build = std.Build;
|
||||
const LazyPath = Build.LazyPath;
|
||||
125
build/utils.zig
125
build/utils.zig
|
|
@ -1,19 +1,114 @@
|
|||
pub fn loadFileAlloc(filename: []const u8, comptime alignment: usize, allocator: std.mem.Allocator) ![]u8 {
|
||||
var file = try std.fs.cwd().openFile(filename, .{});
|
||||
defer file.close();
|
||||
const filesize = (try file.stat()).size + 1; // add null byte
|
||||
const buffer: []align(alignment) u8 = try allocator.alignedAlloc(u8, alignment, filesize);
|
||||
errdefer allocator.free(buffer);
|
||||
try file.reader().readNoEof(buffer[0 .. buffer.len - 1]);
|
||||
buffer[buffer.len - 1] = 0;
|
||||
return buffer;
|
||||
|
||||
pub fn buildGenerators(b: *std.Build, opts: bh.Options) void {
|
||||
const target = opts.target;
|
||||
const optimize = opts.optimize;
|
||||
const static_build = opts.static_build;
|
||||
|
||||
const fwdGeneratorExe = b.addExecutable(.{
|
||||
.name = "backlog-generate-fwd",
|
||||
.root_module = b.createModule(.{
|
||||
.target = b.graph.host,
|
||||
.optimize = .Debug,
|
||||
.root_source_file = b.path("buildgen/generateFwd.zig"),
|
||||
}),
|
||||
});
|
||||
|
||||
const generateExe = b.addExecutable(.{
|
||||
.name = "backlog-apigen",
|
||||
.root_module = b.createModule(.{
|
||||
.target = b.graph.host,
|
||||
.optimize = .Debug,
|
||||
.root_source_file = b.path("buildgen/generateApi.zig"),
|
||||
}),
|
||||
});
|
||||
|
||||
const generateShaders = b.addExecutable(.{
|
||||
.name = "backlog-shaderEmbedGen",
|
||||
.root_module = b.createModule(.{
|
||||
.target = b.graph.host,
|
||||
.optimize = .Debug,
|
||||
.root_source_file = b.path("buildgen/generateEmbeddedShaders.zig"),
|
||||
}),
|
||||
});
|
||||
|
||||
const generateRcExe = b.addExecutable(.{
|
||||
.name = "backlog-generate-rc",
|
||||
.root_module = b.createModule(.{
|
||||
.target = b.graph.host,
|
||||
.optimize = .Debug,
|
||||
.root_source_file = b.path("buildgen/generateRc.zig"),
|
||||
}),
|
||||
});
|
||||
|
||||
const generateLoadDynamicsExe = b.addExecutable(.{
|
||||
.name = "backlog-generate-loadDynamics",
|
||||
.root_module = b.createModule(.{
|
||||
.target = b.graph.host,
|
||||
.optimize = .Debug,
|
||||
.root_source_file = b.path("buildgen/generateLoadDynamics.zig"),
|
||||
}),
|
||||
});
|
||||
|
||||
b.installArtifact(fwdGeneratorExe);
|
||||
b.installArtifact(generateLoadDynamicsExe);
|
||||
b.installArtifact(generateExe);
|
||||
b.installArtifact(generateShaders);
|
||||
b.installArtifact(generateRcExe);
|
||||
|
||||
{
|
||||
const loadDynamicsStub = b.addModule("loadDynamicsStub", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.root_source_file = b.path("engine/loadDynamicsStub.zig"),
|
||||
});
|
||||
|
||||
_ = loadDynamicsStub;
|
||||
|
||||
const mod = b.addModule("Backlog", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.root_source_file = b.path("engine/backlog.zig"),
|
||||
});
|
||||
|
||||
for (depList()) |depName| {
|
||||
const dep = b.dependency(
|
||||
depName,
|
||||
.{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.static_build = static_build,
|
||||
},
|
||||
);
|
||||
|
||||
const run = b.addRunArtifact(fwdGeneratorExe);
|
||||
const output = run.addOutputFileArg(b.fmt("{s}_fwd.zig", .{depName}));
|
||||
|
||||
const modFwd = b.addModule(depName, .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.root_source_file = output,
|
||||
});
|
||||
|
||||
mod.addImport(b.fmt("{s}", .{depName}), modFwd);
|
||||
modFwd.addImport("module", dep.module(depName));
|
||||
|
||||
// mod.addImport(depName, dep.module(depName));
|
||||
}
|
||||
|
||||
// link in large platform support functions... special case.
|
||||
{
|
||||
const dep = b.dependency("sdl3", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.static_build = static_build,
|
||||
});
|
||||
const lib = dep.module("SDL3");
|
||||
|
||||
mod.addImport("sdl3_fwd", lib);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn checkAndFormatAst(allocator: std.mem.Allocator, input: []const u8) ![]u8 {
|
||||
var ast = try std.zig.Ast.parse(allocator, @as([:0]const u8, @ptrCast(input)), .zig);
|
||||
const out = try ast.render(allocator);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
const std = @import("std");
|
||||
const bh = @import("bh");
|
||||
|
|
|
|||
|
|
@ -73,10 +73,10 @@ pub fn main() !void {
|
|||
|
||||
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);
|
||||
|
||||
std.debug.print("output=\n{s}", .{out});
|
||||
// Write the content to the file
|
||||
try file.writeAll(out);
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn usage() void {
|
||||
std.debug.print("generates a loader module which calls the start_modules for all the modules that the game module depends on.\ngenerate-mod-api <output file name> <module_name> <module list>\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 module_name = args[2];
|
||||
const module_list = args[3..];
|
||||
|
||||
var writer = std.ArrayList(u8){};
|
||||
|
||||
try writer.print(allocator, "pub const moduleName:[]const u8 = \"{s}\";\n", .{module_name});
|
||||
|
||||
try writer.print(allocator, "pub const moduleList:[]const []const u8 = &.{{\n", .{});
|
||||
for (module_list) |mod| {
|
||||
try writer.print(allocator, "\"{s}\",\n", .{mod});
|
||||
}
|
||||
try writer.print(allocator, "}};\n", .{});
|
||||
|
||||
for (module_list) |mod| {
|
||||
try writer.print(allocator, "pub const {s} = @import(\"{s}\").module;\n", .{ mod, mod });
|
||||
}
|
||||
|
||||
try writer.append(allocator, 0);
|
||||
|
||||
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}", .{writer.items[0 .. writer.items.len - 1]});
|
||||
defer ast.deinit(allocator);
|
||||
const out = try ast.renderAlloc(allocator);
|
||||
|
||||
// Write the content to the file
|
||||
try file.writeAll(out);
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn usage() void {
|
||||
std.debug.print("generate-program-spec <output file name> <spec_name> <module list>\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});
|
||||
try writer.print(allocator, ".moduleName = \"{s}-mod\",\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.print(allocator, "pub const programName = \"{s}\";", .{programName});
|
||||
|
||||
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);
|
||||
}
|
||||
|
|
@ -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 {}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
pub export fn startup_module(p_allocator: *anyopaque, p_a: ?*anyopaque) bool {
|
||||
const allocator = core.modulePreamble(p_allocator, p_a) catch return false;
|
||||
_ = allocator;
|
||||
core.engine_logs("module started");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
pub export fn shutdown_module() void {}
|
||||
|
||||
// const backlog = @import("backlog");
|
||||
// const core = backlog.core;
|
||||
|
||||
const core = @import("core").module;
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
pub fn loadFileAlloc(filename: []const u8, comptime alignment: usize, allocator: std.mem.Allocator) ![]u8 {
|
||||
var file = try std.fs.cwd().openFile(filename, .{});
|
||||
defer file.close();
|
||||
const filesize = (try file.stat()).size + 1; // add null byte
|
||||
const buffer: []align(alignment) u8 = try allocator.alignedAlloc(u8, alignment, filesize);
|
||||
errdefer allocator.free(buffer);
|
||||
try file.reader().readNoEof(buffer[0 .. buffer.len - 1]);
|
||||
buffer[buffer.len - 1] = 0;
|
||||
return buffer;
|
||||
}
|
||||
|
||||
pub fn checkAndFormatAst(allocator: std.mem.Allocator, input: []const u8) ![]u8 {
|
||||
var ast = try std.zig.Ast.parse(allocator, @as([:0]const u8, @ptrCast(input)), .zig);
|
||||
const out = try ast.render(allocator);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
const std = @import("std");
|
||||
|
|
@ -21,7 +21,8 @@ pub fn tick(self: *@This(), dt: f64) void {
|
|||
}
|
||||
|
||||
pub fn deinit(self: *@This()) void {
|
||||
self.allocator.destroy(self);
|
||||
// Engine handles memory deallocation
|
||||
_ = self;
|
||||
}
|
||||
|
||||
pub fn main() anyerror!void {
|
||||
|
|
|
|||
|
|
@ -1,25 +1,28 @@
|
|||
const std = @import("std");
|
||||
const core = @import("core");
|
||||
|
||||
const depList = [_][]const u8{
|
||||
"core",
|
||||
"packer",
|
||||
};
|
||||
|
||||
pub fn build(b: *std.Build) void {
|
||||
const target = b.standardTargetOptions(.{});
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
const static_build = b.option(bool, "static_build", "builds backlog dependencies for static linking") orelse false;
|
||||
|
||||
const engineMod = core.MakeModLib(b, .{
|
||||
.name = "assets",
|
||||
const mod = b.addModule("assets", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.static_build = static_build,
|
||||
.root_source_file = b.path("src/assets.zig"),
|
||||
});
|
||||
|
||||
engineMod.linkModLibs(&depList);
|
||||
engineMod.install();
|
||||
const core_dep = b.dependency(
|
||||
"core",
|
||||
.{ .target = target, .optimize = optimize, .static_build = static_build },
|
||||
);
|
||||
mod.addImport("core", core_dep.module("core"));
|
||||
|
||||
const packer_dep = b.dependency(
|
||||
"packer",
|
||||
.{ .target = target, .optimize = optimize, .static_build = static_build },
|
||||
);
|
||||
|
||||
mod.addImport("packer", packer_dep.module("packer"));
|
||||
|
||||
const test_step = b.step("test", "run unit tests for assets");
|
||||
const tests = b.addTest(.{
|
||||
|
|
@ -30,7 +33,7 @@ pub fn build(b: *std.Build) void {
|
|||
}),
|
||||
});
|
||||
|
||||
tests.root_module.addImport("assets", engineMod.mod);
|
||||
tests.root_module.addImport("assets", mod);
|
||||
const runArtifact = b.addRunArtifact(tests);
|
||||
test_step.dependOn(&runArtifact.step);
|
||||
b.installArtifact(tests);
|
||||
|
|
|
|||
|
|
@ -120,11 +120,6 @@ pub const AssetLoaderInterface = struct {
|
|||
unreachable;
|
||||
}
|
||||
|
||||
if (!@hasDecl(TargetType, "destroy")) {
|
||||
@compileLog("Tried to generate AssetLoaderInterface for type ", TargetType, "but it's missing func destroy.");
|
||||
unreachable;
|
||||
}
|
||||
|
||||
const self = @This(){
|
||||
.typeName = @typeName(TargetType),
|
||||
.typeSize = @sizeOf(TargetType),
|
||||
|
|
@ -159,15 +154,15 @@ pub const AssetReferenceSys = struct {
|
|||
|
||||
pub var NeonObjectTable = core.EngineObjectVTable.from(@This(), "AssetReference");
|
||||
|
||||
pub fn init(allocator: std.mem.Allocator) !*@This() {
|
||||
const self = try allocator.create(@This());
|
||||
pub fn init(self: *@This(), allocator: std.mem.Allocator, first: bool) !void {
|
||||
if (!first)
|
||||
return;
|
||||
|
||||
self.* = @This(){
|
||||
.loaders = .{},
|
||||
.allocator = allocator,
|
||||
.outstandingAssetJobs = std.atomic.Value(i32).init(0),
|
||||
};
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
pub fn registerLoader(self: *@This(), loader: anytype) !void {
|
||||
|
|
@ -210,6 +205,5 @@ pub const AssetReferenceSys = struct {
|
|||
// i.destroy(self.allocator);
|
||||
// }
|
||||
self.loaders.deinit(self.allocator);
|
||||
self.allocator.destroy(self);
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
const std = @import("std");
|
||||
const core = @import("core");
|
||||
|
||||
const depList = [_][]const u8{
|
||||
"miniaudio",
|
||||
|
|
@ -12,15 +11,17 @@ pub fn build(b: *std.Build) void {
|
|||
const optimize = b.standardOptimizeOption(.{});
|
||||
const static_build = b.option(bool, "static_build", "builds backlog dependencies for static linking") orelse false;
|
||||
|
||||
const engineMod = core.MakeModLib(b, .{
|
||||
.name = "audio",
|
||||
const mod = b.addModule("audio", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.static_build = static_build,
|
||||
.root_source_file = b.path("src/audio.zig"),
|
||||
});
|
||||
|
||||
engineMod.linkModLibs(&depList);
|
||||
engineMod.install();
|
||||
for (depList) |depName| {
|
||||
const dep = b.dependency(depName, .{ .target = target, .optimize = optimize, .static_build = static_build });
|
||||
|
||||
mod.addImport(depName, dep.module(depName));
|
||||
}
|
||||
|
||||
const test_step = b.step("test", "run unit tests for audio");
|
||||
const tests = b.addTest(.{
|
||||
|
|
@ -31,7 +32,7 @@ pub fn build(b: *std.Build) void {
|
|||
}),
|
||||
});
|
||||
|
||||
tests.root_module.addImport("audio", engineMod.mod);
|
||||
tests.root_module.addImport("audio", mod);
|
||||
const runArtifact = b.addRunArtifact(tests);
|
||||
test_step.dependOn(&runArtifact.step);
|
||||
b.installArtifact(tests);
|
||||
|
|
|
|||
|
|
@ -73,8 +73,10 @@ pub const SoundEngine = struct {
|
|||
allocator: std.mem.Allocator,
|
||||
volume: f32 = 1.0,
|
||||
|
||||
pub fn init(allocator: std.mem.Allocator) !*@This() {
|
||||
const self = try allocator.create(@This());
|
||||
pub fn init(self: *@This(), allocator: std.mem.Allocator, first: bool) !void {
|
||||
if (!first)
|
||||
return;
|
||||
|
||||
self.* = @This(){
|
||||
.engine = allocator.create(ma.ma_engine) catch unreachable,
|
||||
.sounds = .{},
|
||||
|
|
@ -83,8 +85,6 @@ pub const SoundEngine = struct {
|
|||
};
|
||||
|
||||
_ = ma.ma_engine_init(null, self.engine);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
pub fn shutdown(self: *@This()) void {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,7 @@
|
|||
pub const std = @import("std");
|
||||
const core = @import("core");
|
||||
const impl = core;
|
||||
|
||||
pub const inputs = struct {
|
||||
pub const getInputStack = inputs.getInputStack;
|
||||
};
|
||||
|
|
@ -1,8 +1,4 @@
|
|||
const std = @import("std");
|
||||
pub const bh = @import("bh");
|
||||
|
||||
pub const ModLib = bh.ModLib;
|
||||
pub const MakeModLib = bh.MakeModLib;
|
||||
|
||||
const dependencyList = [_][]const u8{
|
||||
"p2",
|
||||
|
|
@ -11,43 +7,31 @@ const dependencyList = [_][]const u8{
|
|||
"packer", // packer no longer has C deps.
|
||||
};
|
||||
|
||||
pub fn MakeEngineMod(b: *std.Build, name: []const u8) ModLib {
|
||||
const target = b.standardTargetOptions(.{});
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
const static_build = b.option(bool, "static_build", "builds backlog dependencies for static linking") orelse false;
|
||||
|
||||
const engineMod = MakeModLib(b, .{
|
||||
.name = name,
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.static_build = static_build,
|
||||
});
|
||||
|
||||
return engineMod;
|
||||
}
|
||||
|
||||
pub fn build(b: *std.Build) void {
|
||||
const target = b.standardTargetOptions(.{});
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
const static_build = b.option(bool, "static_build", "builds backlog dependencies for static linking") orelse false;
|
||||
|
||||
const engineMod = MakeModLib(b, .{
|
||||
.name = "core",
|
||||
const mod = b.addModule("core", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.static_build = static_build,
|
||||
.root_source_file = b.path("src/core.zig"),
|
||||
});
|
||||
|
||||
engineMod.install();
|
||||
engineMod.linkModLibs(&dependencyList);
|
||||
for (dependencyList) |depName| {
|
||||
const dep = b.dependency(depName, .{ .target = target, .optimize = optimize, .static_build = static_build });
|
||||
mod.addImport(depName, dep.module(depName));
|
||||
}
|
||||
|
||||
const test_step = b.step("test", "run unit tests for core");
|
||||
const tests = b.addTest(.{
|
||||
.root_module = b.createModule(.{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.link_libc = true,
|
||||
.root_source_file = b.path("tests/tests.zig"),
|
||||
}),
|
||||
.use_llvm = true,
|
||||
});
|
||||
|
||||
const sampleGameExtern = b.addLibrary(.{
|
||||
|
|
@ -58,9 +42,10 @@ pub fn build(b: *std.Build) void {
|
|||
.target = target,
|
||||
}),
|
||||
.linkage = .dynamic,
|
||||
.use_llvm = true,
|
||||
.name = "external",
|
||||
});
|
||||
sampleGameExtern.root_module.addImport("core", engineMod.mod);
|
||||
sampleGameExtern.root_module.addImport("core", mod);
|
||||
|
||||
const installExtern = b.addInstallArtifact(sampleGameExtern, .{
|
||||
.dest_dir = .{ .override = .{ .custom = "modules" } },
|
||||
|
|
@ -68,7 +53,7 @@ pub fn build(b: *std.Build) void {
|
|||
|
||||
b.getInstallStep().dependOn(&installExtern.step);
|
||||
|
||||
tests.root_module.addImport("core", engineMod.mod);
|
||||
tests.root_module.addImport("core", mod);
|
||||
const runArtifact = b.addRunArtifact(tests);
|
||||
test_step.dependOn(&runArtifact.step);
|
||||
runArtifact.step.dependOn(b.getInstallStep());
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@
|
|||
|
||||
// with -Dtracy = false, this one pulls in no C dependencies
|
||||
.tracy = .{ .path = "../../lib/tracy" },
|
||||
.bh = .{ .path = "../../lib/bh" },
|
||||
|
||||
// these are zig only
|
||||
.zmath = .{ .path = "../../lib/zmath" },
|
||||
|
|
|
|||
|
|
@ -1,17 +1,16 @@
|
|||
pub const ConfigRegistry = struct {
|
||||
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This(), "core.ConfigRegistry");
|
||||
|
||||
allocator: std.mem.Allocator,
|
||||
allocator: std.mem.Allocator = undefined,
|
||||
configMap: ?ConfigMap = null,
|
||||
|
||||
pub fn create(allocator: std.mem.Allocator) !*@This() {
|
||||
const self = try allocator.create(@This());
|
||||
pub fn init(self: *@This(), allocator: std.mem.Allocator, first: bool) !void {
|
||||
if (!first)
|
||||
return;
|
||||
|
||||
self.* = .{
|
||||
.allocator = allocator,
|
||||
};
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
// by convention this should be in the root
|
||||
|
|
@ -38,11 +37,10 @@ pub const ConfigRegistry = struct {
|
|||
|
||||
}
|
||||
|
||||
pub fn destroy(self: *@This()) void {
|
||||
pub fn deinit(self: *@This()) void {
|
||||
if (self.configMap) |*map| {
|
||||
map.deinit();
|
||||
}
|
||||
self.allocator.destroy(self);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -8,21 +8,22 @@ pub const ConsoleCommand = struct {
|
|||
pub const Console = struct {
|
||||
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This(), "core.Console");
|
||||
|
||||
allocator: std.mem.Allocator,
|
||||
arena: std.heap.ArenaAllocator,
|
||||
allocator: std.mem.Allocator = undefined,
|
||||
arena: std.heap.ArenaAllocator = undefined,
|
||||
|
||||
commandMap: std.StringHashMapUnmanaged(ConsoleCommand) = .{},
|
||||
|
||||
pub fn create(allocator: std.mem.Allocator) !*@This() {
|
||||
const self = try allocator.create(@This());
|
||||
pub fn init(self: *@This(), allocator: std.mem.Allocator, first: bool) !void {
|
||||
if (!first) {
|
||||
return;
|
||||
}
|
||||
|
||||
self.* = .{
|
||||
.arena = std.heap.ArenaAllocator.init(allocator),
|
||||
.allocator = allocator,
|
||||
};
|
||||
|
||||
core.engine_logs("console system created");
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
pub fn addConsoleCommand(self: *@This(), funcName: []const u8, func: ConsoleFunc) !void {
|
||||
|
|
@ -56,10 +57,9 @@ pub const Console = struct {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn destroy(self: *@This()) void {
|
||||
pub fn deinit(self: *@This()) void {
|
||||
self.arena.deinit();
|
||||
self.commandMap.deinit(self.allocator);
|
||||
self.allocator.destroy(self);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -29,6 +29,8 @@ pub const debugLine = debug_draw.debugLine;
|
|||
|
||||
pub const engineTime = @import("engineTime.zig");
|
||||
pub const engineObject = @import("engineObject.zig");
|
||||
pub const EngineObjectOpts = engineObject.EngineObjectOpts;
|
||||
pub const ObjectOpts = engineObject.EngineObjectOpts;
|
||||
pub const EngineObjectVTable = engineObject.EngineObjectVTable;
|
||||
pub const MakeTypeName = engineObject.MakeTypeName;
|
||||
pub const PatchStruct = engineObject.PatchStruct;
|
||||
|
|
@ -170,7 +172,7 @@ pub const packer = @import("packer");
|
|||
|
||||
pub const StackCompactor = stacks.StackCompactor;
|
||||
|
||||
var staticsInitialized = false;
|
||||
pub var staticsInitialized = false;
|
||||
var gEngine: *Engine = undefined;
|
||||
pub const PackerFS = packer.PackerFS;
|
||||
var gPackerFS: *PackerFS = undefined;
|
||||
|
|
@ -272,8 +274,6 @@ pub fn maybeInitPackerFs(allocator: std.mem.Allocator) !void {
|
|||
}
|
||||
|
||||
pub fn start_module_(map: *SpecVariantMap, args: anytype, allocator: std.mem.Allocator) !void {
|
||||
staticsInitialized = true;
|
||||
|
||||
if (map.get("utility")) |x| {
|
||||
if (x.boolean == true) {
|
||||
engine_logs("utility mode - no gui");
|
||||
|
|
@ -297,8 +297,7 @@ pub fn start_module_(map: *SpecVariantMap, args: anytype, allocator: std.mem.All
|
|||
|
||||
gEngine = try allocator.create(Engine);
|
||||
gEngine.* = try Engine.init(allocator);
|
||||
_ = try createObject(ModuleLoader, .{});
|
||||
try console.start();
|
||||
staticsInitialized = true;
|
||||
|
||||
const engineName = try std.fmt.allocPrint(allocator, "{s}Engine.ini", .{name});
|
||||
defer allocator.free(engineName);
|
||||
|
|
@ -309,14 +308,15 @@ pub fn start_module_(map: *SpecVariantMap, args: anytype, allocator: std.mem.All
|
|||
try logging.setupLogging(gEngine);
|
||||
}
|
||||
|
||||
try ecs.setup(allocator);
|
||||
|
||||
_ = try gEngine.createObject(scene.SceneSystem, .{ .can_tick = true });
|
||||
|
||||
try algorithm.string_pool.setup(allocator);
|
||||
gEngine.stringContext = algorithm.string_pool.gStringContext;
|
||||
|
||||
_ = try createObject(ModuleLoader, .{});
|
||||
_ = try createObject(ecs.EcsRegistry, .{ .can_tick = true, .isCore = true });
|
||||
_ = try createObject(scene.SceneSystem, .{ .can_tick = true });
|
||||
_ = try createObject(GameObjectSystem, .{ .can_tick = true });
|
||||
_ = try inputs.initInputStack();
|
||||
_ = try createObject(inputs.InputStack, .{});
|
||||
_ = try createObject(console.Console, .{});
|
||||
|
||||
// components define
|
||||
try ecs.defineComponentList(ComponentList, allocator);
|
||||
|
|
@ -328,6 +328,7 @@ pub fn setupFromModule(__args: ModuleLoaderArgs) !void {
|
|||
gEngine = __args.engine;
|
||||
gPackerFS = __args.packerFS;
|
||||
algorithm.names.gRegistry = __args.nameRegistry;
|
||||
algorithm.string_pool.gStringContext = gEngine.stringContext;
|
||||
logging.setupLoggingFromModule();
|
||||
staticsInitialized = true;
|
||||
|
||||
|
|
@ -525,7 +526,11 @@ pub fn startup_getArgs(p_allocator: *anyopaque) ModuleLoaderArgs {
|
|||
pub fn modulePreamble(p_allocator: *anyopaque, p_a: ?*anyopaque) !std.mem.Allocator {
|
||||
const args = startup_getArgs(p_a.?);
|
||||
const allocator = startup_getAllocator(p_allocator);
|
||||
try setupFromModule(args);
|
||||
|
||||
if (comptime !BuildOption("static_build")) {
|
||||
try setupFromModule(args);
|
||||
}
|
||||
|
||||
return allocator;
|
||||
}
|
||||
|
||||
|
|
@ -609,3 +614,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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -210,15 +210,15 @@ pub const EcsRegistry = struct {
|
|||
|
||||
pub var NeonObjectTable = core.EngineObjectVTable.from(@This(), "core.EcsRegistry");
|
||||
|
||||
pub fn init(allocator: std.mem.Allocator) !*@This() {
|
||||
const self = try allocator.create(@This());
|
||||
pub fn init(self: *@This(), allocator: std.mem.Allocator, first: bool) !void {
|
||||
if (!first) {
|
||||
return;
|
||||
}
|
||||
|
||||
self.* = .{
|
||||
.allocator = allocator,
|
||||
.baseSet = BaseSet.init(allocator),
|
||||
};
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
pub fn registerContainer(self: *@This(), ref: EcsContainerRef, _containerName: core.Name) !void {
|
||||
|
|
@ -279,13 +279,11 @@ pub const EcsRegistry = struct {
|
|||
}
|
||||
|
||||
pub fn deinit(self: *@This()) void {
|
||||
self.destroy();
|
||||
}
|
||||
// this should never work... wtf?
|
||||
// for (self.containers.items) |ref| {
|
||||
// ref.vtable.evictFromRegistry(ref.ptr);
|
||||
// }
|
||||
|
||||
pub fn destroy(self: *@This()) void {
|
||||
for (self.containers.items) |ref| {
|
||||
ref.vtable.evictFromRegistry(ref.ptr);
|
||||
}
|
||||
for (self.systems.items) |ref| {
|
||||
ref.vtable.destroy(ref.ptr);
|
||||
}
|
||||
|
|
@ -300,7 +298,6 @@ pub const EcsRegistry = struct {
|
|||
self.containers.deinit(self.allocator);
|
||||
self.containerNames.deinit(self.allocator);
|
||||
self.containersByName.deinit(self.allocator);
|
||||
self.allocator.destroy(self);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ const time = @import("engineTime.zig");
|
|||
const core = @import("core.zig");
|
||||
const jobs = @import("jobs.zig");
|
||||
const math = @import("math.zig");
|
||||
const builtin = @import("builtin");
|
||||
const pscopes = core.algorithm.pscopes;
|
||||
|
||||
const tracy = @import("tracy").t;
|
||||
|
|
@ -91,6 +92,9 @@ pub const Engine = struct {
|
|||
calibrationPeriod: f64 = 1.0, // in seconds
|
||||
first: bool = true,
|
||||
|
||||
shutdownModuleFunction: ?*const fn () callconv(.c) void = null,
|
||||
stringContext: *core.algorithm.string_pool.StringContext = undefined,
|
||||
|
||||
pub fn init(allocator: std.mem.Allocator) !@This() {
|
||||
const rv = Engine{
|
||||
.allocator = allocator,
|
||||
|
|
@ -126,9 +130,7 @@ pub const Engine = struct {
|
|||
var i: i32 = @intCast(self.destroyListCore.items.len - 1);
|
||||
while (i >= 0) : (i -= 1) {
|
||||
const item = self.destroyListCore.items[@as(usize, @intCast(i))];
|
||||
if (item.vtable.deinit_func) |deinitFn| {
|
||||
deinitFn(item.ptr);
|
||||
}
|
||||
self.destroyObject(item);
|
||||
}
|
||||
}
|
||||
self.destroyListCore.deinit(self.allocator);
|
||||
|
|
@ -159,6 +161,10 @@ pub const Engine = struct {
|
|||
return @ptrCast(@alignCast(rv));
|
||||
}
|
||||
|
||||
const DebugSlack = struct {
|
||||
slack: [1024 * 64]u8 align(16) = undefined,
|
||||
};
|
||||
|
||||
// creates an engine object using the engine's allocator.
|
||||
pub fn createObjectVTable(self: *@This(), vtable: *core.EngineObjectVTable, params: NeonObjectParams) !*anyopaque {
|
||||
if (self.createObjectLock) {
|
||||
|
|
@ -170,7 +176,17 @@ pub const Engine = struct {
|
|||
self.createObjectLock = true;
|
||||
defer self.createObjectLock = false;
|
||||
const newIndex = self.engineObjects.items.len;
|
||||
const newObjectPtr = try vtable.init_func(self.allocator); // call this thing with the special allocator that adds vtable. slackSize to it.
|
||||
var newObjectPtr: *anyopaque = undefined; //self.allocator.create(DebugSlack);
|
||||
|
||||
if (comptime core.BuildOption("static_build")) {
|
||||
newObjectPtr = @ptrCast(@alignCast((try self.allocator.alignedAlloc(u8, .@"16", vtable.typeSize))));
|
||||
} else {
|
||||
newObjectPtr = @ptrCast(@alignCast((try self.allocator.create(DebugSlack))));
|
||||
}
|
||||
|
||||
try vtable.init_func(newObjectPtr, self.allocator, true);
|
||||
|
||||
// try vtable.init_func(self.allocator); // call this thing with the special allocator that adds vtable. slackSize to it.
|
||||
|
||||
const newObjectRef = EngineObjectRef{
|
||||
.ptr = @as(*anyopaque, @ptrCast(newObjectPtr)),
|
||||
|
|
@ -356,14 +372,29 @@ pub const Engine = struct {
|
|||
self.destroyDependents();
|
||||
}
|
||||
|
||||
fn destroyObject(self: *@This(), item: EngineObjectRef) void {
|
||||
core.engine_log("destroying object {s}", .{item.vtable.typeName});
|
||||
if (item.vtable.deinit_func) |deinitFn| {
|
||||
deinitFn(item.ptr);
|
||||
}
|
||||
|
||||
if (comptime core.BuildOption("static_build")) {
|
||||
var slice: []u8 = undefined;
|
||||
slice.ptr = @ptrCast(@alignCast(item.ptr));
|
||||
slice.len = item.vtable.typeSize;
|
||||
self.allocator.rawFree(slice, .@"16", @returnAddress());
|
||||
} else {
|
||||
const asStruct: *DebugSlack = @ptrCast(@alignCast(item.ptr));
|
||||
self.allocator.destroy(asStruct);
|
||||
}
|
||||
}
|
||||
|
||||
fn destroyDependents(self: *@This()) void {
|
||||
if (self.destroyListSimple.items.len > 0) {
|
||||
var i: i32 = @intCast(self.destroyListSimple.items.len - 1);
|
||||
while (i >= 0) : (i -= 1) {
|
||||
const item = self.destroyListSimple.items[@as(usize, @intCast(i))];
|
||||
if (item.vtable.deinit_func) |deinitFn| {
|
||||
deinitFn(item.ptr);
|
||||
}
|
||||
self.destroyObject(item);
|
||||
}
|
||||
}
|
||||
self.dependentsDestroyed.store(true, .seq_cst);
|
||||
|
|
|
|||
|
|
@ -68,10 +68,6 @@ pub fn updateEngineVTable(comptime T: type) void {
|
|||
|
||||
vtable.* = T.NeonObjectTable;
|
||||
vtable.version = version + 1;
|
||||
|
||||
if (@hasDecl(T, "objectReload")) {
|
||||
core.get(T).objectReload();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn PatchStruct(comptime T: type, p: *T, old: []const FieldInfo) void {
|
||||
|
|
@ -167,7 +163,8 @@ pub const EngineObjectVTable = struct {
|
|||
|
||||
singletonName: ?[]const u8 = null,
|
||||
|
||||
init_func: *const fn (std.mem.Allocator) EngineDataEventError!*anyopaque,
|
||||
// new init_function passes in an already created object
|
||||
init_func: *const fn (*anyopaque, std.mem.Allocator, bool) EngineDataEventError!void,
|
||||
tick_func: ?*const fn (*anyopaque, f64) void = null,
|
||||
engineDraw_func: ?*const fn (*anyopaque, f64) void = null,
|
||||
preTick_func: ?*const fn (*anyopaque, f64) EngineDataEventError!void = null,
|
||||
|
|
@ -271,11 +268,10 @@ pub const EngineObjectVTable = struct {
|
|||
|
||||
if (@hasDecl(TargetType, "init")) {
|
||||
const wrappedInit = struct {
|
||||
const funcFind: @TypeOf(@field(TargetType, "init")) = @field(TargetType, "init");
|
||||
|
||||
pub fn func(allocator: std.mem.Allocator) EngineDataEventError!*anyopaque {
|
||||
const newObject = funcFind(allocator) catch return error.BadInit;
|
||||
return @as(*anyopaque, @ptrCast(newObject));
|
||||
pub fn func(p: *anyopaque, allocator: std.mem.Allocator, first: bool) EngineDataEventError!void {
|
||||
const newObject: *TargetType = @ptrCast(@alignCast(p)); // funcFind(allocator) catch return error.BadInit;
|
||||
newObject.init(allocator, first) catch return error.BadInit;
|
||||
// return @as(*anyopaque, @ptrCast(newObject));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -284,11 +280,10 @@ pub const EngineObjectVTable = struct {
|
|||
|
||||
if (@hasDecl(TargetType, "create")) {
|
||||
const wrappedInit = struct {
|
||||
const funcFind: @TypeOf(@field(TargetType, "create")) = @field(TargetType, "create");
|
||||
|
||||
pub fn func(allocator: std.mem.Allocator) EngineDataEventError!*anyopaque {
|
||||
const newObject = funcFind(allocator) catch return error.BadInit;
|
||||
return @as(*anyopaque, @ptrCast(newObject));
|
||||
pub fn func(p: *anyopaque, allocator: std.mem.Allocator, first: bool) EngineDataEventError!void {
|
||||
const newObject: *TargetType = @ptrCast(@alignCast(p)); // funcFind(allocator) catch return error.BadInit;
|
||||
newObject.create(allocator, first) catch return error.BadInit;
|
||||
// return @as(*anyopaque, @ptrCast(newObject));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -5,8 +5,12 @@ const pscopes = core.algorithm.pscopes;
|
|||
|
||||
// returns time since engine started in nanoseconds
|
||||
pub fn getEngineTime() f64 {
|
||||
const read = core.getEngine().rootTimer.read();
|
||||
return @as(f64, @floatFromInt(read)) / std.time.ns_per_s;
|
||||
if (core.staticsInitialized) {
|
||||
const read = core.getEngine().rootTimer.read();
|
||||
return @as(f64, @floatFromInt(read)) / std.time.ns_per_s;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// returns a pscopes.TimingScope for the current time.
|
||||
|
|
|
|||
|
|
@ -121,22 +121,23 @@ fn dllChangedCallback(pathChanged: []const u8, ctx: ?*anyopaque) void {
|
|||
}
|
||||
|
||||
pub const ModuleLoader = struct {
|
||||
backingAllocator: std.mem.Allocator,
|
||||
arena: std.heap.ArenaAllocator,
|
||||
backingAllocator: std.mem.Allocator = undefined,
|
||||
arena: std.heap.ArenaAllocator = undefined,
|
||||
loadedModules: std.ArrayListUnmanaged(*LoadedModule) = .{},
|
||||
watchInitialized: bool = false,
|
||||
watchInitializeFn: ?*const fn () void = null,
|
||||
|
||||
pub var NeonObjectTable = core.EngineObjectVTable.from(@This(), "core.ModuleLoader");
|
||||
pub fn create(allocator: std.mem.Allocator) !*@This() {
|
||||
const self = try allocator.create(@This());
|
||||
|
||||
pub fn init(self: *@This(), allocator: std.mem.Allocator, first: bool) !void {
|
||||
if (!first) {
|
||||
return;
|
||||
}
|
||||
|
||||
self.* = .{
|
||||
.backingAllocator = allocator,
|
||||
.arena = std.heap.ArenaAllocator.init(allocator),
|
||||
};
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
pub fn addModule(self: *@This(), moduleName: []const u8) !void {
|
||||
|
|
@ -169,6 +170,7 @@ pub const ModuleLoader = struct {
|
|||
}
|
||||
|
||||
try core.fs().addFileChangedCallback(libFileName, dllChangedCallback, loaded);
|
||||
core.engine_log("[ModuleLoader]: addFileChangedCallback '{s}'", .{libFileName});
|
||||
|
||||
try self.loadedModules.append(self.arena.allocator(), loaded);
|
||||
}
|
||||
|
|
@ -214,10 +216,9 @@ pub const ModuleLoader = struct {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn destroy(self: *@This()) void {
|
||||
pub fn deinit(self: *@This()) void {
|
||||
// std.fs.cwd().deleteTree(".modulecache") catch {};
|
||||
self.arena.deinit();
|
||||
self.backingAllocator.destroy(self);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -71,21 +71,20 @@ pub const GameObjectSystem = struct {
|
|||
// this is the new one, GameObjectList should be deleted after this passes initial usability
|
||||
pub var NeonObjectTable = core.EngineObjectVTable.from(@This(), "core.GameObjectSystem");
|
||||
|
||||
allocator: std.mem.Allocator,
|
||||
allocator: std.mem.Allocator = undefined,
|
||||
objectDefinitions: std.AutoHashMapUnmanaged(u32, GameObjectInterfaceVTable) = .{},
|
||||
typesArena: std.heap.ArenaAllocator,
|
||||
typesArena: std.heap.ArenaAllocator = undefined,
|
||||
|
||||
objectSpawnEvents: std.ArrayListUnmanaged(SpawnEvent) = .{},
|
||||
|
||||
pub fn create(allocator: std.mem.Allocator) !*@This() {
|
||||
const self = try allocator.create(@This());
|
||||
pub fn init(self: *@This(), allocator: std.mem.Allocator, first: bool) !void {
|
||||
if (!first)
|
||||
return;
|
||||
|
||||
self.* = .{
|
||||
.allocator = allocator,
|
||||
.typesArena = std.heap.ArenaAllocator.init(self.allocator),
|
||||
};
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
pub fn spawnObject(self: *@This(), comptime T: type, objectName: []const u8, parameters: SpawnParameters) !*T {
|
||||
|
|
@ -177,9 +176,8 @@ pub const GameObjectSystem = struct {
|
|||
_ = dt;
|
||||
}
|
||||
|
||||
pub fn destroy(self: *@This()) void {
|
||||
pub fn deinit(self: *@This()) void {
|
||||
self.typesArena.deinit();
|
||||
self.allocator.destroy(self);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -574,11 +574,11 @@ pub const BindingLayer = struct {
|
|||
|
||||
// not gonna actually deal with layers right now
|
||||
pub const InputStack = struct {
|
||||
allocator: std.mem.Allocator,
|
||||
allocator: std.mem.Allocator = undefined,
|
||||
|
||||
active: ?*BindingLayer,
|
||||
active: ?*BindingLayer = undefined,
|
||||
bindingStack: std.ArrayListUnmanaged(*BindingLayer) = .{},
|
||||
arena: std.heap.ArenaAllocator,
|
||||
arena: std.heap.ArenaAllocator = undefined,
|
||||
|
||||
keysDown: std.AutoHashMapUnmanaged(Key, bool) = .{},
|
||||
|
||||
|
|
@ -591,8 +591,10 @@ pub const InputStack = struct {
|
|||
|
||||
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This(), "core.InputStack");
|
||||
|
||||
pub fn init(allocator: std.mem.Allocator) !*@This() {
|
||||
const self = try allocator.create(@This());
|
||||
pub fn init(self: *@This(), allocator: std.mem.Allocator, first: bool) !void {
|
||||
if (!first) {
|
||||
return;
|
||||
}
|
||||
|
||||
self.* = .{
|
||||
.allocator = allocator,
|
||||
|
|
@ -601,8 +603,6 @@ pub const InputStack = struct {
|
|||
};
|
||||
|
||||
core.EngineObject(@This()).gInstance = self;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
pub fn updatePreviousInputs(self: *@This()) void {
|
||||
|
|
@ -716,7 +716,6 @@ pub const InputStack = struct {
|
|||
if (self.active) |active| {
|
||||
active.destroy();
|
||||
}
|
||||
self.allocator.destroy(self);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -192,13 +192,13 @@ pub const FileLog = struct {
|
|||
pub const LoggerSys = struct {
|
||||
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This(), "core.LoggerSys");
|
||||
|
||||
writeOutBuffer: std.ArrayList(u8),
|
||||
flushBuffer: std.ArrayList(u8),
|
||||
allocator: std.mem.Allocator,
|
||||
logFilePath: []const u8,
|
||||
logFile: std.fs.File,
|
||||
consoleFile: std.fs.File,
|
||||
writerBuffer: []u8,
|
||||
writeOutBuffer: std.ArrayList(u8) = .{},
|
||||
flushBuffer: std.ArrayList(u8) = .{},
|
||||
allocator: std.mem.Allocator = undefined,
|
||||
logFilePath: []const u8 = "none",
|
||||
logFile: std.fs.File = undefined,
|
||||
consoleFile: std.fs.File = undefined,
|
||||
writerBuffer: []u8 = undefined,
|
||||
lock: std.Thread.Mutex = .{},
|
||||
flushing: std.atomic.Value(bool) = std.atomic.Value(bool).init(false),
|
||||
|
||||
|
|
@ -306,12 +306,14 @@ pub const LoggerSys = struct {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn init(allocator: std.mem.Allocator) !*@This() {
|
||||
pub fn init(self: *@This(), allocator: std.mem.Allocator, first: bool) !void {
|
||||
if (!first) {
|
||||
return;
|
||||
}
|
||||
const cwd = std.fs.cwd();
|
||||
const ofile = std.fmt.allocPrint(allocator, core.DefaultSavePath ++ "/{s}", .{"Session_Log.txt"}) catch unreachable;
|
||||
cwd.makePath(core.DefaultSavePath) catch unreachable;
|
||||
|
||||
const self = try allocator.create(@This());
|
||||
self.* = @This(){
|
||||
.allocator = allocator,
|
||||
.writeOutBuffer = std.ArrayList(u8).initCapacity(allocator, LogBufferSize) catch unreachable,
|
||||
|
|
@ -321,8 +323,6 @@ pub const LoggerSys = struct {
|
|||
.logFile = cwd.createFile(ofile, .{}) catch unreachable,
|
||||
.consoleFile = std.fs.File.stdout(),
|
||||
};
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
pub fn deinit(self: *@This()) void {
|
||||
|
|
@ -333,8 +333,6 @@ pub const LoggerSys = struct {
|
|||
|
||||
self.writeOutBuffer.deinit(self.allocator);
|
||||
self.flushBuffer.deinit(self.allocator);
|
||||
|
||||
self.allocator.destroy(self);
|
||||
}
|
||||
|
||||
pub fn processEvents(self: *@This(), frameNumber: u64) core.EngineDataEventError!void {
|
||||
|
|
|
|||
|
|
@ -296,9 +296,9 @@ fn childAllocator() std.mem.Allocator {
|
|||
pub const SceneSystem = struct {
|
||||
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This(), "core.SceneSystem");
|
||||
|
||||
allocator: std.mem.Allocator,
|
||||
allocator: std.mem.Allocator = undefined,
|
||||
dynamicObjects: ArrayListUnmanaged(core.ObjectHandle) = .{},
|
||||
childrenArena: std.heap.ArenaAllocator,
|
||||
childrenArena: std.heap.ArenaAllocator = undefined,
|
||||
tickCount: u32 = 0,
|
||||
sceneObjectContainer: *SceneObjectSet = undefined,
|
||||
|
||||
|
|
@ -385,8 +385,11 @@ pub const SceneSystem = struct {
|
|||
pub const MaxWorkerCount = 24;
|
||||
|
||||
// ----- NeonObject interace ----
|
||||
pub fn init(allocator: std.mem.Allocator) !*@This() {
|
||||
const self = try allocator.create(@This());
|
||||
pub fn init(self: *@This(), allocator: std.mem.Allocator, first: bool) !void {
|
||||
if (!first) {
|
||||
return;
|
||||
}
|
||||
|
||||
self.* = .{
|
||||
.allocator = allocator,
|
||||
.childrenArena = std.heap.ArenaAllocator.init(allocator),
|
||||
|
|
@ -401,8 +404,6 @@ pub const SceneSystem = struct {
|
|||
try self.cachedOutputs.append(self.allocator, .{});
|
||||
try self.writeOutList.append(self.allocator, .{});
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
pub fn getOutputList(self: *@This(), threadId: u32) !*std.ArrayList(usize) {
|
||||
|
|
@ -446,7 +447,6 @@ pub const SceneSystem = struct {
|
|||
Scene.SceneObjectContainer.destroy();
|
||||
self.cachedOutputs.deinit(self.allocator);
|
||||
self.writeOutList.deinit(self.allocator);
|
||||
self.allocator.destroy(self);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,22 +1,17 @@
|
|||
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This(), "testing.sampleSubsystem");
|
||||
|
||||
allocator: std.mem.Allocator,
|
||||
scene: *anyopaque,
|
||||
setPositionPtr: *const anyopaque,
|
||||
allocator: std.mem.Allocator = undefined,
|
||||
scene: *anyopaque = undefined,
|
||||
setPositionPtr: *const anyopaque = undefined,
|
||||
|
||||
pub fn init(self: *@This(), allocator: std.mem.Allocator, first: bool) !void {
|
||||
if (!first) {
|
||||
return;
|
||||
}
|
||||
|
||||
pub fn create(allocator: std.mem.Allocator) !*@This() {
|
||||
const self = try allocator.create(@This());
|
||||
self.* = .{
|
||||
.allocator = allocator,
|
||||
.scene = undefined,
|
||||
.setPositionPtr = undefined,
|
||||
};
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
pub fn destroy(self: *@This()) void {
|
||||
self.allocator.destroy(self);
|
||||
}
|
||||
|
||||
const exampleScene = @import("exampleScene.zig");
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
const std = @import("std");
|
||||
const core = @import("core");
|
||||
|
||||
const dependencyList = [_][]const u8{
|
||||
"core",
|
||||
|
|
@ -14,15 +13,17 @@ pub fn build(b: *std.Build) void {
|
|||
const optimize = b.standardOptimizeOption(.{});
|
||||
const static_build = b.option(bool, "static_build", "builds backlog dependencies for static linking") orelse false;
|
||||
|
||||
const engineMod = core.MakeModLib(b, .{
|
||||
.name = "imgui",
|
||||
const mod = b.addModule("imgui", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.static_build = static_build,
|
||||
.root_source_file = b.path("src/imgui.zig"),
|
||||
});
|
||||
|
||||
engineMod.install();
|
||||
engineMod.linkModLibs(&dependencyList);
|
||||
for (dependencyList) |depName| {
|
||||
const dep = b.dependency(depName, .{ .target = target, .optimize = optimize, .static_build = static_build });
|
||||
const dep_mod = dep.module(depName);
|
||||
mod.addImport(depName, dep_mod);
|
||||
}
|
||||
|
||||
// ========== tests ==========
|
||||
const tests = b.addTest(.{
|
||||
|
|
@ -34,7 +35,7 @@ pub fn build(b: *std.Build) void {
|
|||
});
|
||||
const test_step = b.step("test", "run unit tests for imgui");
|
||||
|
||||
tests.root_module.addImport("platform", engineMod.mod);
|
||||
tests.root_module.addImport("platform", mod);
|
||||
const runArtifact = b.addRunArtifact(tests);
|
||||
test_step.dependOn(&runArtifact.step);
|
||||
b.installArtifact(tests);
|
||||
|
|
|
|||
|
|
@ -15,14 +15,13 @@ pub const Impl = struct {
|
|||
};
|
||||
|
||||
// renderer plugin
|
||||
pub fn create(allocator: std.mem.Allocator) !*@This() {
|
||||
const self = try allocator.create(@This());
|
||||
pub fn init(self: *@This(), allocator: std.mem.Allocator, first: bool) !void {
|
||||
if (!first)
|
||||
return;
|
||||
|
||||
self.* = .{
|
||||
.allocator = allocator,
|
||||
};
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
const ImguiArgs = struct { imguiIni: []const u8 = "imgui.ini" };
|
||||
|
|
@ -109,11 +108,6 @@ pub const Impl = struct {
|
|||
_ = ig.dockSpaceOverViewport(ig.getMainViewport(), .{ .passthru_central_node = true }, null);
|
||||
_ = dt;
|
||||
}
|
||||
|
||||
// renderer plugin
|
||||
pub fn destroy(self: *@This()) void {
|
||||
self.allocator.destroy(self);
|
||||
}
|
||||
};
|
||||
const c = @import("cimgui").c;
|
||||
const ig = @import("cimgui");
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
pub var NeonObjectTable = core.EngineObjectVTable.from(@This(), "game.TopBar");
|
||||
pub const Slack = core.SlackStruct(@This(), 256);
|
||||
|
||||
allocator: std.mem.Allocator,
|
||||
arena: std.heap.ArenaAllocator,
|
||||
|
|
@ -7,8 +6,10 @@ windowsMenu: std.ArrayListUnmanaged(*MenuEntry) = .{},
|
|||
entriesByName: std.AutoHashMapUnmanaged(u32, *MenuEntry) = .{},
|
||||
menuOpen: bool = false,
|
||||
|
||||
pub fn create(allocator: std.mem.Allocator) !*@This() {
|
||||
const self = try Slack.create(allocator);
|
||||
pub fn init(self: *@This(), allocator: std.mem.Allocator, first: bool) !void {
|
||||
if (!first)
|
||||
return;
|
||||
|
||||
self.* = .{
|
||||
.allocator = allocator,
|
||||
.arena = std.heap.ArenaAllocator.init(allocator),
|
||||
|
|
@ -21,8 +22,6 @@ pub fn create(allocator: std.mem.Allocator) !*@This() {
|
|||
.ctx = self,
|
||||
.windowFunction = windowOpen,
|
||||
});
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
pub fn setEntryOpen(self: *@This(), name: []const u8, open: ?bool) void {
|
||||
|
|
@ -108,7 +107,6 @@ pub fn tick(self: *@This(), dt: f64) void {
|
|||
|
||||
pub fn destroy(self: *@This()) void {
|
||||
self.arena.deinit();
|
||||
self.allocator.destroy(Slack.fromPtr(self));
|
||||
}
|
||||
|
||||
pub const MenuEntry = struct {
|
||||
|
|
|
|||
|
|
@ -6,16 +6,16 @@ consolePressedEnter: bool = false,
|
|||
|
||||
pub var NeonObjectTable = core.EngineObjectVTable.from(@This(), "extras.consoleWindow");
|
||||
|
||||
pub fn init(allocator: std.mem.Allocator) !*@This() {
|
||||
const self = try allocator.create(@This());
|
||||
pub fn init(self: *@This(), allocator: std.mem.Allocator, first: bool) !void {
|
||||
if (!first)
|
||||
return;
|
||||
|
||||
self.* = .{
|
||||
.allocator = allocator,
|
||||
.buffer = core.logging.LogBuffer.init(allocator),
|
||||
};
|
||||
|
||||
self.setup();
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
pub fn setup(self: *@This()) void {
|
||||
|
|
@ -65,7 +65,6 @@ pub fn windowOpen(entry: *imgui.utils.MenuEntry, dt: f64) void {
|
|||
|
||||
pub fn destroy(self: *@This()) void {
|
||||
self.buffer.deinit();
|
||||
self.allocator.destroy(self);
|
||||
}
|
||||
|
||||
const imgui = @import("../imgui.zig");
|
||||
|
|
|
|||
|
|
@ -0,0 +1,161 @@
|
|||
const std = @import("std");
|
||||
const core = @import("core").module;
|
||||
const panickers = core.panickers;
|
||||
|
||||
// const realMain = @import("main");
|
||||
|
||||
pub const gamespec = @import("gamespec");
|
||||
pub const options = @import("BacklogOptions");
|
||||
|
||||
pub const std_options = std.Options{
|
||||
.enable_segfault_handler = true,
|
||||
};
|
||||
|
||||
//pub const build_options = @import("build_options");
|
||||
//pub const tracy_enabled = build_options.tracy_enabled;
|
||||
|
||||
// pub fn panic(msg: []const u8, error_return_trace: ?*std.builtin.StackTrace, x: ?usize) noreturn {
|
||||
// core.forceFlush();
|
||||
// core.script.lua.takeDump();
|
||||
// std.debug.defaultPanic(error_return_trace, x, msg);
|
||||
// }
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
fn fileExists(path: []const u8) bool {
|
||||
std.fs.cwd().access(path, .{}) catch return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
pub fn run() !void {
|
||||
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 startEngine(spec: *core.SpecVariantMap) bool {
|
||||
const args = getArgs() catch return false;
|
||||
|
||||
var backingAllocator: std.mem.Allocator = std.heap.smp_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();
|
||||
|
||||
_ = core.createNameRegistry(allocator) catch return false;
|
||||
core.maybeInitPackerFs(allocator) catch return false;
|
||||
|
||||
if (comptime core.BuildOption("static_build")) {
|
||||
core.engine_log("static build, using embedded shaders", .{});
|
||||
const loader = @import("staticShaderLoader");
|
||||
loader.installStaticResources() catch return false;
|
||||
}
|
||||
|
||||
core.start_module(spec, args, allocator) catch return false;
|
||||
|
||||
const moduleName = spec.get("moduleName").?.string;
|
||||
|
||||
if (comptime core.BuildOption("static_build")) {
|
||||
core.engine_logs("static build");
|
||||
const modlaunch = @import("modulelaunch.zig");
|
||||
var modargs = core.externModule.getModuleLoaderArgs(true);
|
||||
var modalloc = allocator;
|
||||
_ = modlaunch.startup_module(&modalloc, &modargs);
|
||||
} else {
|
||||
core.engine_logs("using hot reloading");
|
||||
const platform = @import("platform").module;
|
||||
platform.watchModules();
|
||||
|
||||
//if (comptime @hasDecl(backlog, "platform")) {
|
||||
//backlog.platform.watchModules();
|
||||
// }
|
||||
core.loadModule(moduleName, true) catch return false;
|
||||
}
|
||||
|
||||
// load the shared object and call startup()
|
||||
// core.beginLoading("");
|
||||
|
||||
// if (!start_modules(spec, args, allocator)) return false;
|
||||
// defer shutdown_modules(allocator);
|
||||
|
||||
run() catch return false;
|
||||
|
||||
if (core.getEngine().shutdownModuleFunction) |shutdownFunc| {
|
||||
shutdownFunc();
|
||||
} else {
|
||||
core.shutdown_module(allocator);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
pub fn main() !void {
|
||||
if (!core.BuildOption("RootDeploymentOnly")) {
|
||||
// if we don't see a content/ folder or a
|
||||
// content.pak file in the current directory,
|
||||
// walk up the directory tree until we see one, then change dirs to that before doing anything else
|
||||
|
||||
var iterations: u32 = 0;
|
||||
var BUFFER: [8192]u8 = undefined;
|
||||
|
||||
while (iterations < 8) : (iterations += 1) {
|
||||
if (fileExists("content") or fileExists("content.pak")) {
|
||||
break;
|
||||
}
|
||||
|
||||
var dir = try std.fs.cwd().openDir("..", .{});
|
||||
defer dir.close();
|
||||
core.engine_log("content not found scanning dir {s}", .{try dir.realpath(".", &BUFFER)});
|
||||
try dir.setAsCwd();
|
||||
}
|
||||
core.engine_log("Working Dir set: {s}", .{try std.fs.cwd().realpath(".", &BUFFER)});
|
||||
}
|
||||
|
||||
const spec = try gamespec.getSpec();
|
||||
_ = startEngine(spec);
|
||||
|
||||
// panickers.attachSegfaultHandler();
|
||||
// try realMain.main();
|
||||
|
||||
shutdown_hook();
|
||||
}
|
||||
|
||||
pub fn shutdown_hook() void {
|
||||
std.debug.print("[engine] shutting down now! goodbye!", .{});
|
||||
}
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
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;
|
||||
gAllocator = allocator;
|
||||
|
||||
core.engine_log("module started {s}", .{backlog.moduleName});
|
||||
|
||||
const spec = gamespec.getSpec() catch return false;
|
||||
|
||||
const args = getArgs() catch NwArgs{};
|
||||
|
||||
const moduleArgs = core.startup_getArgs(p_a.?);
|
||||
|
||||
if (moduleArgs.firstLoad) {
|
||||
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.engine_logs("starting module >>>> " ++ feature ++ " <<<<");
|
||||
core.tracy.Message(Struct.Module.name);
|
||||
Struct.start_module(spec, args, allocator) catch @panic("start_module failed");
|
||||
|
||||
if (core.MemoryTracker.MTGet()) |_| {
|
||||
core.MemoryTracker.MTPrintStatsDelta();
|
||||
}
|
||||
|
||||
shutdownList.append(allocator, Struct.shutdown_module) catch return false;
|
||||
shutdownModuleNames.append(allocator, feature) catch return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
core.setShutdownModule(shutdown_module);
|
||||
} else {
|
||||
inline for (backlog.moduleList) |feature| {
|
||||
if (@hasDecl(backlog, feature)) {
|
||||
core.engine_log("reloading module: {s}", .{feature});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
core.shutdown_module(gAllocator);
|
||||
}
|
||||
|
||||
const gamespec = @import("gamespec");
|
||||
|
||||
const backlog = @import("backlog");
|
||||
const core = backlog.core;
|
||||
const std = @import("std");
|
||||
|
|
@ -1,5 +1,4 @@
|
|||
const std = @import("std");
|
||||
const core = @import("core");
|
||||
|
||||
const depList = [_][]const u8{
|
||||
"core",
|
||||
|
|
@ -11,15 +10,17 @@ pub fn build(b: *std.Build) void {
|
|||
const optimize = b.standardOptimizeOption(.{});
|
||||
const static_build = b.option(bool, "static_build", "builds backlog dependencies for static linking") orelse false;
|
||||
|
||||
const engineMod = core.MakeModLib(b, .{
|
||||
.name = "net",
|
||||
const mod = b.addModule("net", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.static_build = static_build,
|
||||
.root_source_file = b.path("src/net.zig"),
|
||||
});
|
||||
|
||||
engineMod.install();
|
||||
engineMod.linkModLibs(&depList);
|
||||
for (depList) |depName| {
|
||||
const dep = b.dependency(depName, .{ .target = target, .optimize = optimize, .static_build = static_build });
|
||||
|
||||
mod.addImport(depName, dep.module(depName));
|
||||
}
|
||||
|
||||
const test_step = b.step("test", "run unit tests for net");
|
||||
const tests = b.addTest(.{
|
||||
|
|
@ -30,7 +31,7 @@ pub fn build(b: *std.Build) void {
|
|||
}),
|
||||
});
|
||||
|
||||
tests.root_module.addImport("net", engineMod.mod);
|
||||
tests.root_module.addImport("net", mod);
|
||||
const runArtifact = b.addRunArtifact(tests);
|
||||
test_step.dependOn(&runArtifact.step);
|
||||
b.installArtifact(tests);
|
||||
|
|
|
|||
|
|
@ -159,8 +159,9 @@ const ENetSessionData = struct {
|
|||
}
|
||||
};
|
||||
|
||||
pub fn create(allocator: std.mem.Allocator) !*@This() {
|
||||
const self = try allocator.create(@This());
|
||||
pub fn create(self: *@This(), allocator: std.mem.Allocator, first: bool) !*@This() {
|
||||
if (!first)
|
||||
return;
|
||||
|
||||
self.* = .{
|
||||
.allocator = allocator,
|
||||
|
|
@ -399,7 +400,6 @@ pub fn destroy(self: *@This()) void {
|
|||
self.deadSessions.deinit(self.allocator);
|
||||
|
||||
enet_mod.deinitialize();
|
||||
self.allocator.destroy(self);
|
||||
}
|
||||
|
||||
const core = @import("core");
|
||||
|
|
|
|||
|
|
@ -28,15 +28,14 @@ pub const NetEngine = struct {
|
|||
arena: std.heap.ArenaAllocator,
|
||||
transport: ?TransportRef = null,
|
||||
|
||||
pub fn init(allocator: std.mem.Allocator) !*@This() {
|
||||
const self = try allocator.create(@This());
|
||||
pub fn init(self: *@This(), allocator: std.mem.Allocator, first: bool) !*@This() {
|
||||
if (!first)
|
||||
return;
|
||||
|
||||
self.* = @This(){
|
||||
.allocator = allocator,
|
||||
.arena = std.heap.ArenaAllocator.init(allocator),
|
||||
};
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
pub fn arenaAllocator(self: *@This()) std.mem.Allocator {
|
||||
|
|
|
|||
|
|
@ -1,9 +1,4 @@
|
|||
const std = @import("std");
|
||||
const core = @import("core");
|
||||
|
||||
const depList = [_][]const u8{
|
||||
"core",
|
||||
};
|
||||
|
||||
// very tiny, not intended to build anything just to run tests linked with libc
|
||||
pub fn build(b: *std.Build) void {
|
||||
|
|
@ -11,18 +6,18 @@ pub fn build(b: *std.Build) void {
|
|||
const optimize = b.standardOptimizeOption(.{});
|
||||
const static_build = b.option(bool, "static_build", "builds backlog dependencies for static linking") orelse false;
|
||||
|
||||
const engineMod = core.MakeModLib(b, .{
|
||||
.name = "papyrus",
|
||||
const mod = b.addModule("papyrus", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.static_build = static_build,
|
||||
.link_libc = true,
|
||||
.root_source_file = b.path("src/papyrus.zig"),
|
||||
});
|
||||
engineMod.lib.linkLibC();
|
||||
mod.addIncludePath(b.path("src/"));
|
||||
mod.addCSourceFile(.{ .file = b.path("src/compat.cpp") });
|
||||
|
||||
engineMod.install();
|
||||
engineMod.linkModLibs(&depList);
|
||||
engineMod.addIncludePath("src/");
|
||||
engineMod.lib.addCSourceFile(.{ .file = b.path("src/compat.cpp"), .flags = &.{} });
|
||||
const core_dep = b.dependency("core", .{ .target = target, .optimize = optimize, .static_build = static_build });
|
||||
|
||||
mod.addImport("core", core_dep.module("core"));
|
||||
|
||||
// Creates a step for unit testing.
|
||||
const main_tests = b.addTest(.{
|
||||
|
|
@ -34,9 +29,10 @@ pub fn build(b: *std.Build) void {
|
|||
}),
|
||||
});
|
||||
|
||||
main_tests.root_module.addImport("papyrus", engineMod.mod);
|
||||
main_tests.root_module.addImport("core", core_dep.module("core"));
|
||||
main_tests.root_module.addImport("papyrus", mod);
|
||||
main_tests.root_module.addIncludePath(b.path("src/"));
|
||||
main_tests.linkLibrary(engineMod.lib);
|
||||
|
||||
main_tests.linkLibC();
|
||||
main_tests.linkLibCpp();
|
||||
const run_tests = b.addRunArtifact(main_tests);
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ const std = @import("std");
|
|||
const papyrus = @import("papyrus.zig");
|
||||
const Context = papyrus.Context;
|
||||
|
||||
const core = papyrus.core;
|
||||
const core = @import("core");
|
||||
const Vector2i = core.Vector2i;
|
||||
const Vector2 = core.Vector2;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
const std = @import("std");
|
||||
const c = @import("c.zig").c;
|
||||
|
||||
const core = @import("papyrus.zig").core;
|
||||
const core = @import("core");
|
||||
const Vector2i = core.Vector2i;
|
||||
const Vector2f = core.Vector2f;
|
||||
const Name = core.Name;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
const std = @import("std");
|
||||
pub const c = @cImport({
|
||||
const c = @cImport({
|
||||
@cInclude("stb_ttf.h");
|
||||
});
|
||||
|
||||
|
|
@ -39,7 +39,7 @@ pub const TextEntrySystem = @import("TextEntrySystem.zig");
|
|||
pub const DrawCommand = @import("DrawCommand.zig");
|
||||
pub const DrawList = std.ArrayList(DrawCommand);
|
||||
|
||||
pub const core = @import("core");
|
||||
const core = @import("core");
|
||||
const colors = core.colors;
|
||||
pub const Color = colors.Color;
|
||||
pub const ColorRGBA8 = colors.RGBA8;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,10 @@ const std = @import("std");
|
|||
const papyrus = @import("papyrus");
|
||||
const localization = papyrus.localization;
|
||||
const utils = papyrus.utils;
|
||||
const c = papyrus.c;
|
||||
const c = @cImport({
|
||||
@cInclude("stb_ttf.h");
|
||||
});
|
||||
|
||||
const PapyrusContext = papyrus.Context;
|
||||
const PapyrusNode = papyrus.Node;
|
||||
const MakeText = localization.MakeText;
|
||||
|
|
@ -11,7 +14,7 @@ const grapvizDotToPng = utils.grapvizDotToPng;
|
|||
const BmpRenderer = papyrus.BmpRenderer;
|
||||
const BmpWriter = BmpRenderer.BmpWriter;
|
||||
|
||||
const core = papyrus.core;
|
||||
const core = @import("core");
|
||||
const colors = core.colors;
|
||||
const Color = colors.Color;
|
||||
const ColorRGBA8 = colors.ColorRGBA8;
|
||||
|
|
|
|||
|
|
@ -1,9 +1,4 @@
|
|||
const std = @import("std");
|
||||
const core = @import("core");
|
||||
|
||||
const depList = [_][]const u8{
|
||||
"core",
|
||||
};
|
||||
|
||||
// very tiny, not intended to build anything just to run tests linked with libc
|
||||
pub fn build(b: *std.Build) void {
|
||||
|
|
@ -11,24 +6,25 @@ pub fn build(b: *std.Build) void {
|
|||
const optimize = b.standardOptimizeOption(.{});
|
||||
const static_build = b.option(bool, "static_build", "builds backlog dependencies for static linking") orelse false;
|
||||
|
||||
const engineMod = core.MakeModLib(b, .{
|
||||
.name = "physics",
|
||||
const mod = b.addModule("physics", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.static_build = static_build,
|
||||
.link_libc = true,
|
||||
.root_source_file = b.path("src/physics.zig"),
|
||||
});
|
||||
|
||||
engineMod.install();
|
||||
engineMod.linkModLibs(&depList);
|
||||
const core_dep = b.dependency("core", .{ .target = target, .optimize = optimize, .static_build = static_build });
|
||||
|
||||
const zphysics_dep = b.dependency("zphysics", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.enable_cross_platform_determinism = false,
|
||||
.static_build = static_build,
|
||||
});
|
||||
|
||||
engineMod.mod.addImport("zphysics", zphysics_dep.module("root"));
|
||||
engineMod.lib.linkLibrary(zphysics_dep.artifact("zphysics"));
|
||||
mod.addImport("core", core_dep.module("core"));
|
||||
mod.addImport("zphysics", zphysics_dep.module("root"));
|
||||
mod.linkLibrary(zphysics_dep.artifact("joltc"));
|
||||
|
||||
const test_step = b.step("test", "run unit tests for physics");
|
||||
const tests = b.addTest(.{
|
||||
|
|
@ -39,8 +35,7 @@ pub fn build(b: *std.Build) void {
|
|||
}),
|
||||
});
|
||||
|
||||
tests.root_module.addImport("physics", engineMod.mod);
|
||||
tests.root_module.linkLibrary(zphysics_dep.artifact("zphysics"));
|
||||
tests.root_module.addImport("physics", mod);
|
||||
const runArtifact = b.addRunArtifact(tests);
|
||||
test_step.dependOn(&runArtifact.step);
|
||||
b.installArtifact(tests);
|
||||
|
|
|
|||
|
|
@ -139,8 +139,11 @@ pub const PhysicsRuntime = struct {
|
|||
try self.idToEntity.put(self.allocator, bodyId, entity);
|
||||
}
|
||||
|
||||
pub fn init(allocator: std.mem.Allocator) !*@This() {
|
||||
const self = try allocator.create(@This());
|
||||
pub fn init(self: *@This(), allocator: std.mem.Allocator, first: bool) !void {
|
||||
if (!first) {
|
||||
return;
|
||||
}
|
||||
|
||||
try zphysics.init(std.heap.smp_allocator, .{});
|
||||
//try zphysics.init(allocator, .{});
|
||||
|
||||
|
|
@ -162,11 +165,6 @@ pub const PhysicsRuntime = struct {
|
|||
);
|
||||
|
||||
self.system = system;
|
||||
|
||||
//try core.defineComponent(PhysicsCharacter, self.allocator);
|
||||
// try core.defineComponent(PhysicsCollider, self.allocator);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
pub fn tick(self: *@This(), dt: f64) void {
|
||||
|
|
@ -230,7 +228,6 @@ pub const PhysicsRuntime = struct {
|
|||
}
|
||||
|
||||
pub fn deinit(self: *@This()) void {
|
||||
const allocator = self.allocator;
|
||||
self.system.optimizeBroadPhase();
|
||||
for (PhysicsCharacter.BaseContainer.list.items) |physChar| {
|
||||
physChar.deinit();
|
||||
|
|
@ -266,8 +263,6 @@ pub const PhysicsRuntime = struct {
|
|||
self.system.destroy();
|
||||
|
||||
zphysics.deinit();
|
||||
|
||||
allocator.destroy(self);
|
||||
}
|
||||
|
||||
pub fn createShape(self: *@This(), name: *core.Name, settings: ShapeSettings) !void {
|
||||
|
|
|
|||
|
|
@ -1,308 +0,0 @@
|
|||
const std = @import("std");
|
||||
const zphysics = @import("zphysics");
|
||||
const core = @import("core");
|
||||
const zm = core.zm;
|
||||
|
||||
pub const ObjectLayers = struct {
|
||||
pub const non_moving: zphysics.ObjectLayer = 0;
|
||||
pub const moving: zphysics.ObjectLayer = 1;
|
||||
pub const len: u32 = 2;
|
||||
};
|
||||
|
||||
pub const BroadPhaseLayers = struct {
|
||||
pub const non_moving: zphysics.BroadPhaseLayer = 0;
|
||||
pub const moving: zphysics.BroadPhaseLayer = 1;
|
||||
pub const len: u32 = 2;
|
||||
};
|
||||
|
||||
const BroadPhaseLayerInterface = extern struct {
|
||||
usingnamespace zphysics.BroadPhaseLayerInterface.Methods(@This());
|
||||
__v: *const zphysics.BroadPhaseLayerInterface.VTable = &vtable,
|
||||
|
||||
object_to_broad_phase: [ObjectLayers.len]zphysics.BroadPhaseLayer = undefined,
|
||||
|
||||
const vtable = zphysics.BroadPhaseLayerInterface.VTable{
|
||||
.getNumBroadPhaseLayers = _getNumBroadPhaseLayers,
|
||||
.getBroadPhaseLayer = _getBroadPhaseLayer,
|
||||
};
|
||||
|
||||
fn init() BroadPhaseLayerInterface {
|
||||
var layer_interface: BroadPhaseLayerInterface = .{};
|
||||
layer_interface.object_to_broad_phase[ObjectLayers.non_moving] = BroadPhaseLayers.non_moving;
|
||||
layer_interface.object_to_broad_phase[ObjectLayers.moving] = BroadPhaseLayers.moving;
|
||||
return layer_interface;
|
||||
}
|
||||
|
||||
fn _getNumBroadPhaseLayers(_: *const zphysics.BroadPhaseLayerInterface) callconv(.c) u32 {
|
||||
return BroadPhaseLayers.len;
|
||||
}
|
||||
|
||||
fn _getBroadPhaseLayer(
|
||||
interface_self: *const zphysics.BroadPhaseLayerInterface,
|
||||
object_layer: zphysics.ObjectLayer,
|
||||
) callconv(.c) zphysics.BroadPhaseLayer {
|
||||
const self: *const BroadPhaseLayerInterface = @ptrCast(interface_self);
|
||||
return self.object_to_broad_phase[object_layer];
|
||||
}
|
||||
};
|
||||
|
||||
const ObjectVsBroadPhaseLayerFilter = extern struct {
|
||||
usingnamespace zphysics.ObjectVsBroadPhaseLayerFilter.Methods(@This());
|
||||
__v: *const zphysics.ObjectVsBroadPhaseLayerFilter.VTable = &vtable,
|
||||
|
||||
const vtable = zphysics.ObjectVsBroadPhaseLayerFilter.VTable{ .shouldCollide = _shouldCollide };
|
||||
|
||||
fn _shouldCollide(
|
||||
_: *const zphysics.ObjectVsBroadPhaseLayerFilter,
|
||||
object_layer: zphysics.ObjectLayer,
|
||||
broad_phase_layer: zphysics.BroadPhaseLayer,
|
||||
) callconv(.c) bool {
|
||||
return switch (object_layer) {
|
||||
ObjectLayers.non_moving => broad_phase_layer == BroadPhaseLayers.moving,
|
||||
ObjectLayers.moving => true,
|
||||
else => unreachable,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
const ObjectLayerPairFilter = extern struct {
|
||||
usingnamespace zphysics.ObjectLayerPairFilter.Methods(@This());
|
||||
__v: *const zphysics.ObjectLayerPairFilter.VTable = &vtable,
|
||||
|
||||
const vtable = zphysics.ObjectLayerPairFilter.VTable{ .shouldCollide = _shouldCollide };
|
||||
|
||||
fn _shouldCollide(
|
||||
_: *const zphysics.ObjectLayerPairFilter,
|
||||
a: zphysics.ObjectLayer,
|
||||
b: zphysics.ObjectLayer,
|
||||
) callconv(.c) bool {
|
||||
return switch (a) {
|
||||
ObjectLayers.non_moving => b == ObjectLayers.moving,
|
||||
ObjectLayers.moving => true,
|
||||
else => unreachable,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
pub const PhysicsRuntime = struct {
|
||||
allocator: std.mem.Allocator,
|
||||
bpli: BroadPhaseLayerInterface,
|
||||
ovbplf: ObjectVsBroadPhaseLayerFilter,
|
||||
olpf: ObjectLayerPairFilter,
|
||||
max_bodies: u32,
|
||||
|
||||
system: *zphysics.PhysicsSystem = undefined,
|
||||
|
||||
primBoxSettings: *zphysics.BoxShapeSettings = undefined,
|
||||
primBoxShape: *zphysics.Shape = undefined,
|
||||
|
||||
primSphereSettings: *zphysics.SphereShapeSettings = undefined,
|
||||
primSphereShape: *zphysics.Shape = undefined,
|
||||
|
||||
floorShapeSettings: *zphysics.BoxShapeSettings = undefined,
|
||||
floorShape: *zphysics.Shape = undefined,
|
||||
|
||||
spherePositions: std.ArrayList(core.Vectorf),
|
||||
sphereRotations: std.ArrayList(core.Quat),
|
||||
sphereIds: std.ArrayList(zphysics.BodyId),
|
||||
|
||||
newBallTime: f64 = 5,
|
||||
offset: f32 = 0,
|
||||
|
||||
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This());
|
||||
|
||||
pub fn init(allocator: std.mem.Allocator) !*@This() {
|
||||
const self = try allocator.create(@This());
|
||||
|
||||
self.* = .{
|
||||
.allocator = allocator,
|
||||
.bpli = BroadPhaseLayerInterface.init(),
|
||||
.ovbplf = .{},
|
||||
.olpf = .{},
|
||||
.spherePositions = std.ArrayList(core.Vectorf).init(allocator),
|
||||
.sphereRotations = std.ArrayList(core.Quat).init(allocator),
|
||||
.sphereIds = std.ArrayList(zphysics.BodyId).init(allocator),
|
||||
.max_bodies = 8192,
|
||||
};
|
||||
|
||||
const system = try zphysics.PhysicsSystem.create(
|
||||
@as(*const zphysics.BroadPhaseLayerInterface, @ptrCast(&self.bpli)),
|
||||
@as(*const zphysics.ObjectVsBroadPhaseLayerFilter, @ptrCast(&self.ovbplf)),
|
||||
@as(*const zphysics.ObjectLayerPairFilter, @ptrCast(&self.olpf)),
|
||||
.{
|
||||
.max_bodies = self.max_bodies,
|
||||
.num_body_mutexes = 0,
|
||||
.max_body_pairs = 8192 * 2,
|
||||
.max_contact_constraints = 8192 * 2,
|
||||
},
|
||||
);
|
||||
|
||||
self.system = system;
|
||||
|
||||
const bodyInterface = self.system.getBodyInterfaceMut();
|
||||
|
||||
// primBoxSettings: *zphysics.BoxShapeSettings = undefined,
|
||||
// primBoxShape: *zphysics.Shape = undefined,
|
||||
|
||||
// primSphereSettings: *zphysics.SphereShapeSettings = undefined,
|
||||
// primSphereShape: *zphysics.Shape = undefined,
|
||||
|
||||
// setup primitives for settings.
|
||||
self.primBoxSettings = try zphysics.BoxShapeSettings.create(.{ 2.0, 2.0, 2.0 });
|
||||
self.primBoxShape = try self.primBoxSettings.createShape();
|
||||
|
||||
self.primSphereSettings = try zphysics.SphereShapeSettings.create(0.5);
|
||||
self.primSphereShape = try self.primSphereSettings.createShape();
|
||||
|
||||
self.floorShapeSettings = try zphysics.BoxShapeSettings.create(.{ 300, 1, 300 });
|
||||
self.floorShape = try self.floorShapeSettings.createShape();
|
||||
|
||||
// create floor
|
||||
_ = try bodyInterface.createAndAddBody(.{
|
||||
.position = .{ 0, -1, 0, 1 },
|
||||
.rotation = .{ 0, 0, 0, 1 },
|
||||
.shape = self.floorShape,
|
||||
.motion_type = .static,
|
||||
.object_layer = ObjectLayers.non_moving,
|
||||
}, .activate);
|
||||
|
||||
const roomSize = 7;
|
||||
// create up and down walls
|
||||
{
|
||||
const rotation = zm.quatFromMat(zm.rotationZ(core.radians(90.0)));
|
||||
_ = try bodyInterface.createAndAddBody(.{
|
||||
.position = .{ roomSize, -1, 0, 1 },
|
||||
.rotation = rotation,
|
||||
.shape = self.floorShape,
|
||||
.motion_type = .static,
|
||||
.object_layer = ObjectLayers.non_moving,
|
||||
}, .activate);
|
||||
|
||||
_ = try bodyInterface.createAndAddBody(.{
|
||||
.position = .{ -roomSize, -1, 0, 1 },
|
||||
.rotation = rotation,
|
||||
.shape = self.floorShape,
|
||||
.motion_type = .static,
|
||||
.object_layer = ObjectLayers.non_moving,
|
||||
}, .activate);
|
||||
}
|
||||
|
||||
// create left and right walls
|
||||
{
|
||||
const rotation = zm.quatFromMat(zm.rotationX(core.radians(90.0)));
|
||||
_ = try bodyInterface.createAndAddBody(.{
|
||||
.position = .{ 0, -1, -roomSize, 1 },
|
||||
.rotation = rotation,
|
||||
.shape = self.floorShape,
|
||||
.motion_type = .static,
|
||||
.object_layer = ObjectLayers.non_moving,
|
||||
}, .activate);
|
||||
|
||||
_ = try bodyInterface.createAndAddBody(.{
|
||||
.position = .{ 0, -1, roomSize, 1 },
|
||||
.rotation = rotation,
|
||||
.shape = self.floorShape,
|
||||
.motion_type = .static,
|
||||
.object_layer = ObjectLayers.non_moving,
|
||||
}, .activate);
|
||||
}
|
||||
|
||||
for (0..2) |i| {
|
||||
_ = try bodyInterface.createAndAddBody(
|
||||
.{
|
||||
.position = .{ 0, @as(f32, @floatFromInt(i)) * 1.1 + 1.0, 2, 1 },
|
||||
.rotation = .{ 0, 0, 0, 1 },
|
||||
.shape = self.primSphereShape,
|
||||
.motion_type = .dynamic,
|
||||
.object_layer = ObjectLayers.moving,
|
||||
.restitution = 0.4,
|
||||
.angular_velocity = .{ 0, 0, 0, 0 },
|
||||
},
|
||||
.activate,
|
||||
);
|
||||
_ = try bodyInterface.createAndAddBody(
|
||||
.{
|
||||
.position = .{ 5, @as(f32, @floatFromInt(i)) * 1.1 + 1.0, 2, 1 },
|
||||
.rotation = .{ 0, 0, 0, 1 },
|
||||
.shape = self.primSphereShape,
|
||||
.motion_type = .dynamic,
|
||||
.restitution = 0.4,
|
||||
.object_layer = ObjectLayers.moving,
|
||||
.angular_velocity = .{ 0, 0, 0, 0 },
|
||||
},
|
||||
.activate,
|
||||
);
|
||||
}
|
||||
|
||||
self.system.optimizeBroadPhase();
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
pub fn updateSpherePositions(self: *@This()) !void {
|
||||
try self.system.getBodyIds(&self.sphereIds);
|
||||
try self.spherePositions.resize(self.sphereIds.items.len);
|
||||
try self.sphereRotations.resize(self.sphereIds.items.len);
|
||||
const lockInterface = self.system.getBodyLockInterface();
|
||||
|
||||
for (self.sphereIds.items, 0..) |bodyId, i| {
|
||||
var readLock: zphysics.BodyLockRead = .{};
|
||||
readLock.lock(lockInterface, bodyId);
|
||||
defer readLock.unlock();
|
||||
|
||||
if (readLock.body) |body| {
|
||||
self.spherePositions.items[i] = core.Vectorf.fromArray(body.position);
|
||||
self.sphereRotations.items[i] = body.rotation;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// todo... schedule physics timers
|
||||
pub fn tick(self: *@This(), dt: f64) void {
|
||||
self.system.update(@floatCast(dt), .{}) catch unreachable;
|
||||
self.updateSpherePositions() catch unreachable;
|
||||
|
||||
// self.newBallTime -= dt;
|
||||
|
||||
// if (self.newBallTime < 0) {
|
||||
// const bodyInterface = self.system.getBodyInterfaceMut();
|
||||
// self.newBallTime = 5.0;
|
||||
// self.offset += 0.01;
|
||||
|
||||
// _ = bodyInterface.createAndAddBody(
|
||||
// .{
|
||||
// .position = .{ 0 + self.offset, 15, 0, 1 },
|
||||
// .rotation = .{ 0, 0, 0, 1 },
|
||||
// .shape = self.primSphereShape,
|
||||
// .motion_type = .dynamic,
|
||||
// .object_layer = ObjectLayers.moving,
|
||||
// .restitution = 0.4,
|
||||
// .angular_velocity = .{ 0, 0, 0, 0 },
|
||||
// .inertia_multiplier = 30,
|
||||
// },
|
||||
// .activate,
|
||||
// ) catch unreachable;
|
||||
|
||||
// self.system.optimizeBroadPhase();
|
||||
// }
|
||||
}
|
||||
|
||||
pub fn deinit(self: *@This()) void {
|
||||
const allocator = self.allocator;
|
||||
|
||||
self.primSphereShape.release();
|
||||
self.primSphereSettings.release();
|
||||
|
||||
self.floorShape.release();
|
||||
self.floorShapeSettings.release();
|
||||
|
||||
self.primBoxShape.release();
|
||||
self.primBoxSettings.release();
|
||||
|
||||
self.system.destroy();
|
||||
self.sphereIds.deinit();
|
||||
self.spherePositions.deinit();
|
||||
self.sphereRotations.deinit();
|
||||
allocator.destroy(self);
|
||||
}
|
||||
};
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
const std = @import("std");
|
||||
const sdl3 = @import("sdl3");
|
||||
const core = @import("core");
|
||||
|
||||
const dependencyList = [_][]const u8{
|
||||
"core",
|
||||
|
|
@ -14,16 +13,12 @@ pub fn build(b: *std.Build) void {
|
|||
const optimize = b.standardOptimizeOption(.{});
|
||||
const static_build = b.option(bool, "static_build", "builds backlog dependencies for static linking") orelse false;
|
||||
|
||||
const engineMod = core.MakeModLib(b, .{
|
||||
.name = "platform",
|
||||
.optimize = optimize,
|
||||
const mod = b.addModule("platform", .{
|
||||
.target = target,
|
||||
.static_build = static_build,
|
||||
.optimize = optimize,
|
||||
.root_source_file = b.path("src/platform.zig"),
|
||||
});
|
||||
|
||||
engineMod.linkModLibs(&dependencyList);
|
||||
engineMod.install();
|
||||
|
||||
const tests = b.addTest(.{
|
||||
.root_module = b.createModule(.{
|
||||
.target = target,
|
||||
|
|
@ -32,10 +27,16 @@ pub fn build(b: *std.Build) void {
|
|||
}),
|
||||
});
|
||||
|
||||
const test_step = b.step("test", "run unit tests for platform");
|
||||
tests.root_module.addImport("platform", engineMod.mod);
|
||||
tests.linkLibrary(engineMod.lib);
|
||||
for (dependencyList) |depName| {
|
||||
const dep = b.dependency(depName, .{ .target = target, .optimize = optimize, .static_build = static_build });
|
||||
const dep_mod = dep.module(depName);
|
||||
mod.addImport(depName, dep_mod);
|
||||
tests.root_module.addImport(depName, dep_mod);
|
||||
}
|
||||
|
||||
const test_step = b.step("test", "run unit tests for platform");
|
||||
|
||||
tests.root_module.addImport("platform", mod);
|
||||
const runArtifact = b.addRunArtifact(tests);
|
||||
test_step.dependOn(&runArtifact.step);
|
||||
b.installArtifact(tests);
|
||||
|
|
|
|||
|
|
@ -1,22 +0,0 @@
|
|||
const std = @import("std");
|
||||
const core = @import("core");
|
||||
const windowing = @import("windowing.zig");
|
||||
|
||||
// GameInput implements the RawInputListenerInterface
|
||||
// This is a data driven input system where mappings are defined,
|
||||
// and keys are assigned to mapping contexts
|
||||
|
||||
pub const GameInputSystem = struct {
|
||||
pub const RawInputListenerVTable = windowing.RawInputListenerInterface.from(@This());
|
||||
|
||||
stub: u32 = 0,
|
||||
|
||||
pub fn OnIoEvent(self: *@This(), event: windowing.IOEvent) windowing.InputListenerError!void {
|
||||
_ = event;
|
||||
_ = self;
|
||||
}
|
||||
|
||||
pub fn deinit(self: *@This()) void {
|
||||
_ = self;
|
||||
}
|
||||
};
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
const std = @import("std");
|
||||
pub const core = @import("core");
|
||||
const core = @import("core");
|
||||
const test_vert = @import("test.vert");
|
||||
|
||||
pub const nfd = @import("nfd");
|
||||
|
|
@ -89,7 +89,7 @@ pub fn start_module(spec: *core.SpecVariantMap, args: anytype, allocator: std.me
|
|||
return;
|
||||
}
|
||||
|
||||
core.getModuleLoader().watchInitializeFn = watchModules;
|
||||
// core.getModuleLoader().watchInitializeFn = watchModules;
|
||||
|
||||
const parameters = windowing.PlatformParams.init();
|
||||
|
||||
|
|
|
|||
|
|
@ -191,8 +191,6 @@ pub const PlatformInstance = struct {
|
|||
self.allocator.free(self.iconPath);
|
||||
self.processFuncs.deinit(self.allocator);
|
||||
self.platformRequests.deinit(self.allocator);
|
||||
self.allocator.destroy(self);
|
||||
// shutdown
|
||||
}
|
||||
|
||||
pub fn onExitSignal(self: *@This()) !void {
|
||||
|
|
@ -204,10 +202,10 @@ pub const PlatformInstance = struct {
|
|||
return self.windowDestroyed;
|
||||
}
|
||||
|
||||
pub fn init(
|
||||
allocator: std.mem.Allocator,
|
||||
) !*@This() {
|
||||
const self = try allocator.create(@This());
|
||||
pub fn init(self: *@This(), allocator: std.mem.Allocator, first: bool) !void {
|
||||
if (!first)
|
||||
return;
|
||||
|
||||
self.* = .{
|
||||
.allocator = allocator,
|
||||
.nfdRuntime = try nfd.NFDRuntime.create(allocator, .{}),
|
||||
|
|
@ -217,8 +215,6 @@ pub const PlatformInstance = struct {
|
|||
//.extent = .{ .x = @floatFromInt(params.extent.x), .y = @floatFromInt(params.extent.y) },
|
||||
//.hasVideo = params.hasVideo,
|
||||
};
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
pub fn setParams(self: *@This(), params: PlatformParams) !void {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
const core = @import("core");
|
||||
const platform = @import("platform");
|
||||
const core = @import("platform").core;
|
||||
|
||||
const std = @import("std");
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
const std = @import("std");
|
||||
const sdl3 = @import("sdl3");
|
||||
const core = @import("core");
|
||||
|
||||
const dependencyList = [_][]const u8{
|
||||
"core",
|
||||
|
|
@ -20,47 +19,38 @@ pub fn build(b: *std.Build) void {
|
|||
const optimize = b.standardOptimizeOption(.{});
|
||||
const static_build = b.option(bool, "static_build", "builds backlog dependencies for static linking") orelse false;
|
||||
|
||||
const engineMod = core.MakeModLib(b, .{
|
||||
.name = "rend",
|
||||
const mod = b.addModule("rend", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.static_build = static_build,
|
||||
.root_source_file = b.path("src/rend.zig"),
|
||||
});
|
||||
engineMod.linkModLibs(&dependencyList);
|
||||
engineMod.install();
|
||||
|
||||
// const mod = b.addModule("rend", .{
|
||||
// .target = target,
|
||||
// .optimize = optimize,
|
||||
// .root_source_file = b.path("src/rend.zig"),
|
||||
// });
|
||||
for (dependencyList) |depName| {
|
||||
const dep = b.dependency(depName, .{ .target = target, .optimize = optimize, .static_build = static_build });
|
||||
const dep_mod = dep.module(depName);
|
||||
mod.addImport(depName, dep_mod);
|
||||
|
||||
// for (dependencyList) |depName| {
|
||||
// const dep = b.dependency(depName, .{ .target = target, .optimize = optimize, .static_build = static_build });
|
||||
// const dep_mod = dep.module(depName);
|
||||
// mod.addImport(depName, dep_mod);
|
||||
if (std.mem.eql(u8, depName, "ozz")) {
|
||||
mod.linkLibrary(dep.artifact("ozz_cpp"));
|
||||
}
|
||||
}
|
||||
|
||||
// if (std.mem.eql(u8, depName, "ozz")) {
|
||||
// mod.linkLibrary(dep.artifact("ozz_cpp"));
|
||||
// }
|
||||
// }
|
||||
sdl3.shaderDefintion(b, mod, "../../lib/sdl3", target, optimize, "sample.vert", b.path("shaders/sample.vert.json"));
|
||||
sdl3.shaderDefintion(b, mod, "../../lib/sdl3", target, optimize, "meshes.vert", b.path("shaders/meshes.vert.json"));
|
||||
sdl3.shaderDefintion(b, mod, "../../lib/sdl3", target, optimize, "lit_mesh.frag", b.path("shaders/lit_mesh.frag.json"));
|
||||
|
||||
sdl3.shaderDefintion(b, engineMod.mod, "../../lib/sdl3", target, optimize, "sample.vert", b.path("shaders/sample.vert.json"));
|
||||
sdl3.shaderDefintion(b, engineMod.mod, "../../lib/sdl3", target, optimize, "meshes.vert", b.path("shaders/meshes.vert.json"));
|
||||
sdl3.shaderDefintion(b, engineMod.mod, "../../lib/sdl3", target, optimize, "lit_mesh.frag", b.path("shaders/lit_mesh.frag.json"));
|
||||
sdl3.shaderDefintion(b, mod, "../../lib/sdl3", target, optimize, "debug.frag", b.path("shaders/debug.frag.json"));
|
||||
sdl3.shaderDefintion(b, mod, "../../lib/sdl3", target, optimize, "debug.vert", b.path("shaders/debug.vert.json"));
|
||||
|
||||
sdl3.shaderDefintion(b, engineMod.mod, "../../lib/sdl3", target, optimize, "debug.frag", b.path("shaders/debug.frag.json"));
|
||||
sdl3.shaderDefintion(b, engineMod.mod, "../../lib/sdl3", target, optimize, "debug.vert", b.path("shaders/debug.vert.json"));
|
||||
sdl3.shaderDefintion(b, mod, "../../lib/sdl3", target, optimize, "depthOnly.frag", b.path("shaders/depthOnly.frag.json"));
|
||||
|
||||
sdl3.shaderDefintion(b, engineMod.mod, "../../lib/sdl3", target, optimize, "depthOnly.frag", b.path("shaders/depthOnly.frag.json"));
|
||||
sdl3.shaderDefintion(b, mod, "../../lib/sdl3", target, optimize, "skybox.frag", b.path("shaders/skybox.frag.json"));
|
||||
sdl3.shaderDefintion(b, mod, "../../lib/sdl3", target, optimize, "skybox.vert", b.path("shaders/skybox.vert.json"));
|
||||
|
||||
sdl3.shaderDefintion(b, engineMod.mod, "../../lib/sdl3", target, optimize, "skybox.frag", b.path("shaders/skybox.frag.json"));
|
||||
sdl3.shaderDefintion(b, engineMod.mod, "../../lib/sdl3", target, optimize, "skybox.vert", b.path("shaders/skybox.vert.json"));
|
||||
sdl3.shaderDefintion(b, mod, "../../lib/sdl3", target, optimize, "postProc.frag", b.path("shaders/postProc.frag.json"));
|
||||
sdl3.shaderDefintion(b, mod, "../../lib/sdl3", target, optimize, "postProc.vert", b.path("shaders/postProc.vert.json"));
|
||||
|
||||
sdl3.shaderDefintion(b, engineMod.mod, "../../lib/sdl3", target, optimize, "postProc.frag", b.path("shaders/postProc.frag.json"));
|
||||
sdl3.shaderDefintion(b, engineMod.mod, "../../lib/sdl3", target, optimize, "postProc.vert", b.path("shaders/postProc.vert.json"));
|
||||
|
||||
sdl3.shaderDefintion(b, engineMod.mod, "../../lib/sdl3", target, optimize, "ssao.frag", b.path("shaders/ssao.frag.json"));
|
||||
sdl3.shaderDefintion(b, mod, "../../lib/sdl3", target, optimize, "ssao.frag", b.path("shaders/ssao.frag.json"));
|
||||
|
||||
// ========== tests ==========
|
||||
const tests = b.addTest(.{
|
||||
|
|
|
|||
|
|
@ -417,8 +417,10 @@ pub const AnimationSystem = struct {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn init(alloc: std.mem.Allocator) !*@This() {
|
||||
const self = try alloc.create(@This());
|
||||
pub fn init(self: *@This(), alloc: std.mem.Allocator, first: bool) !void {
|
||||
if (!first)
|
||||
return;
|
||||
|
||||
self.* = .{
|
||||
.backingAllocator = alloc,
|
||||
.arena = std.heap.ArenaAllocator.init(alloc),
|
||||
|
|
@ -433,7 +435,6 @@ pub const AnimationSystem = struct {
|
|||
Animator.allocator = alloc;
|
||||
|
||||
core.engine_logs("Animation System initialized");
|
||||
return self;
|
||||
}
|
||||
|
||||
pub fn deinit(self: *@This()) void {
|
||||
|
|
@ -466,7 +467,6 @@ pub const AnimationSystem = struct {
|
|||
self.arena.deinit();
|
||||
self.skeletons.deinit(self.backingAllocator);
|
||||
self.animTracks.deinit(self.backingAllocator);
|
||||
self.backingAllocator.destroy(self);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -19,19 +19,14 @@ pub const AnimationLoader = struct {
|
|||
self.sys.newAnimTrack(assetRef.name, animation) catch return error.UnableToLoad;
|
||||
}
|
||||
|
||||
pub fn init(allocator: std.mem.Allocator) !*@This() {
|
||||
const self = try allocator.create(@This());
|
||||
pub fn init(self: *@This(), allocator: std.mem.Allocator, first: bool) !void {
|
||||
if (!first)
|
||||
return;
|
||||
|
||||
self.* = .{
|
||||
.sys = animation_system.gAnimationSys,
|
||||
.allocator = allocator,
|
||||
};
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
pub fn destroy(self: *@This()) void {
|
||||
self.allocator.destroy(self);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -56,19 +51,14 @@ pub const SkeletonLoader = struct {
|
|||
self.sys.newSkeleton(assetRef.name, sk) catch return error.UnableToLoad;
|
||||
}
|
||||
|
||||
pub fn init(allocator: std.mem.Allocator) !*@This() {
|
||||
const self = try allocator.create(@This());
|
||||
pub fn init(self: *@This(), allocator: std.mem.Allocator, first: bool) !void {
|
||||
if (!first)
|
||||
return;
|
||||
|
||||
self.* = .{
|
||||
.sys = animation_system.gAnimationSys,
|
||||
.allocator = allocator,
|
||||
};
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
pub fn destroy(self: *@This()) void {
|
||||
self.allocator.destroy(self);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -410,8 +410,9 @@ pub const ParticleSystem = struct {
|
|||
|
||||
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This(), "rend.ParticleSystem");
|
||||
|
||||
pub fn create(allocator: std.mem.Allocator) !*@This() {
|
||||
const self = try allocator.create(@This());
|
||||
pub fn init(self: *@This(), allocator: std.mem.Allocator, first: bool) !void {
|
||||
if (!first)
|
||||
return;
|
||||
|
||||
self.* = .{
|
||||
.particleArena = std.heap.ArenaAllocator.init(allocator),
|
||||
|
|
@ -420,8 +421,6 @@ pub const ParticleSystem = struct {
|
|||
|
||||
ParticleRandRangef.randomEngine = std.Random.DefaultPrng.init(0x1234);
|
||||
ParticleRandRangef.randomFunc = ParticleRandRangef.randomEngine.random();
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
pub fn tick(self: *@This(), dt: f64) void {
|
||||
|
|
@ -437,7 +436,6 @@ pub const ParticleSystem = struct {
|
|||
|
||||
pub fn destroy(self: *@This()) void {
|
||||
self.particleArena.deinit();
|
||||
self.allocator.destroy(self);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -35,8 +35,10 @@ const assetReferences = [_]assets.AssetImportReference{
|
|||
),
|
||||
};
|
||||
|
||||
pub fn create(allocator: std.mem.Allocator) !*@This() {
|
||||
const self = try allocator.create(@This());
|
||||
pub fn init(self: *@This(), allocator: std.mem.Allocator, first: bool) !void {
|
||||
if (!first)
|
||||
return;
|
||||
|
||||
self.* = .{
|
||||
.debugDraws = try core.RingQueueU(DebugPrimitive).init(allocator, MaxObjectCount),
|
||||
.allocator = allocator,
|
||||
|
|
@ -50,8 +52,6 @@ pub fn create(allocator: std.mem.Allocator) !*@This() {
|
|||
try assets.loadList(assetReferences);
|
||||
|
||||
gDebugDrawSys = self;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
pub fn updateMeshes(self: *@This()) void {
|
||||
|
|
@ -243,7 +243,6 @@ pub fn setup(self: *@This(), device: *gpu.GPUDevice) !void {
|
|||
pub fn destroy(self: *@This()) void {
|
||||
self.debugDraws.deinit(self.allocator);
|
||||
self.drawsThisFrame.deinit(self.allocator);
|
||||
self.allocator.destroy(self);
|
||||
}
|
||||
|
||||
// ==================== Primitives ===================
|
||||
|
|
|
|||
|
|
@ -5,23 +5,19 @@ allocator: std.mem.Allocator,
|
|||
pub var LoaderInterfaceVTable = assets.AssetLoaderInterface.from("Mesh", @This());
|
||||
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This(), "rend.MeshAssetLoader");
|
||||
|
||||
pub fn create(allocator: std.mem.Allocator) !*@This() {
|
||||
const self = try allocator.create(@This());
|
||||
pub fn init(self: *@This(), allocator: std.mem.Allocator, first: bool) !void {
|
||||
if (!first)
|
||||
return;
|
||||
|
||||
self.* = .{
|
||||
.allocator = allocator,
|
||||
};
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
pub fn discardAll(self: *@This()) void {
|
||||
_ = self;
|
||||
}
|
||||
|
||||
pub fn destroy(self: *@This()) void {
|
||||
self.allocator.destroy(self);
|
||||
}
|
||||
|
||||
// unfortunately this one is blocking
|
||||
pub fn loadAsset(self: *@This(), assetRef: assets.AssetRef, propertiesBag: ?assets.AssetPropertiesBag) assets.AssetLoaderError!void {
|
||||
_ = self;
|
||||
|
|
|
|||
|
|
@ -15,8 +15,10 @@ const SgpuParticleRenderInfo = struct {
|
|||
texture: *rend.Texture,
|
||||
};
|
||||
|
||||
pub fn create(allocator: std.mem.Allocator) !*@This() {
|
||||
const self = try allocator.create(@This());
|
||||
pub fn init(self: *@This(), allocator: std.mem.Allocator, first: bool) !void {
|
||||
if (!first)
|
||||
return;
|
||||
|
||||
self.* = .{
|
||||
.allocator = allocator,
|
||||
};
|
||||
|
|
@ -39,8 +41,6 @@ pub fn create(allocator: std.mem.Allocator) !*@This() {
|
|||
.size = MaxParticleCount * @sizeOf(meshes_vert.Scene),
|
||||
.props = 0,
|
||||
});
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
pub fn uploadSsbos(self: *@This(), copyPass: *gpu.GPUCopyPass) !void {
|
||||
|
|
@ -121,10 +121,9 @@ pub fn setup(self: *@This(), device: *gpu.GPUDevice) !void {
|
|||
_ = device;
|
||||
}
|
||||
|
||||
pub fn destroy(self: *@This()) void {
|
||||
pub fn deinit(self: *@This()) void {
|
||||
self.spans.deinit(self.allocator);
|
||||
self.renderInfo.deinit(self.allocator);
|
||||
self.allocator.destroy(self);
|
||||
}
|
||||
|
||||
const assets = @import("assets");
|
||||
|
|
|
|||
|
|
@ -16,11 +16,11 @@ brightnessFactor: f32 = 4.0,
|
|||
|
||||
sampler: *gpu.GPUSampler = undefined,
|
||||
|
||||
pub fn create(allocator: std.mem.Allocator) !*@This() {
|
||||
const self = try allocator.create(@This());
|
||||
self.* = .{ .allocator = allocator };
|
||||
pub fn init(self: *@This(), allocator: std.mem.Allocator, first: bool) !void {
|
||||
if (!first)
|
||||
return;
|
||||
|
||||
return self;
|
||||
self.* = .{ .allocator = allocator };
|
||||
}
|
||||
|
||||
pub fn setup(self: *@This(), device: *gpu.GPUDevice) !void {
|
||||
|
|
@ -87,10 +87,6 @@ fn createPipeline(self: *@This()) !void {
|
|||
}));
|
||||
}
|
||||
|
||||
pub fn destroy(self: *@This()) void {
|
||||
self.allocator.destroy(self);
|
||||
}
|
||||
|
||||
pub fn render(self: *@This(), cmd: *gpu.GPUCommandBuffer) void {
|
||||
const targetInfo: [2]gpu.GPUColorTargetInfo = .{
|
||||
std.mem.zeroInit(gpu.GPUColorTargetInfo, .{
|
||||
|
|
|
|||
|
|
@ -9,19 +9,19 @@
|
|||
pub var LoaderInterfaceVTable = assets.AssetLoaderInterface.from("Texture", @This());
|
||||
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This(), "rend.TextureList");
|
||||
|
||||
allocator: std.mem.Allocator,
|
||||
allocator: std.mem.Allocator = undefined,
|
||||
device: *gpu.GPUDevice = undefined,
|
||||
|
||||
map: std.AutoHashMapUnmanaged(u32, *Texture) = .{},
|
||||
requestMap: std.AutoHashMapUnmanaged(u32, bool) = .{},
|
||||
|
||||
pub fn create(allocator: std.mem.Allocator) !*@This() {
|
||||
const self = try allocator.create(@This());
|
||||
pub fn init(self: *@This(), allocator: std.mem.Allocator, first: bool) !void {
|
||||
if (!first)
|
||||
return;
|
||||
|
||||
self.* = .{
|
||||
.allocator = allocator,
|
||||
};
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
pub fn setup(self: *@This(), device: *gpu.GPUDevice) !void {
|
||||
|
|
@ -339,14 +339,13 @@ pub fn discardAll(self: *@This()) void {
|
|||
_ = self;
|
||||
}
|
||||
|
||||
pub fn destroy(self: *@This()) void {
|
||||
pub fn deinit(self: *@This()) void {
|
||||
var iter = self.map.valueIterator();
|
||||
while (iter.next()) |x| {
|
||||
self.allocator.destroy(x.*);
|
||||
}
|
||||
self.requestMap.deinit(self.allocator);
|
||||
self.map.deinit(self.allocator);
|
||||
self.allocator.destroy(self);
|
||||
}
|
||||
|
||||
const std = @import("std");
|
||||
|
|
|
|||
|
|
@ -99,15 +99,14 @@ pub const Renderer = struct {
|
|||
|
||||
pub const MaxObjectCount = 50000;
|
||||
|
||||
pub fn init(allocator: std.mem.Allocator) !*@This() {
|
||||
const self = try allocator.create(@This());
|
||||
|
||||
pub fn init(self: *@This(), allocator: std.mem.Allocator, first: bool) !void {
|
||||
if (!first)
|
||||
return;
|
||||
self.* = .{
|
||||
.allocator = allocator,
|
||||
};
|
||||
|
||||
self.hdrTextureFormat = .textureformatR16g16b16a16Float;
|
||||
return self;
|
||||
}
|
||||
|
||||
pub fn imageExtents(self: @This()) core.Vectorf {
|
||||
|
|
@ -1178,7 +1177,6 @@ pub const Renderer = struct {
|
|||
|
||||
self.uploads.deinit(self.allocator);
|
||||
self.destroys.deinit(self.allocator);
|
||||
self.allocator.destroy(self);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -21,14 +21,13 @@ enable: bool = true,
|
|||
// float bias; // = 0.025;
|
||||
// int numSamples; // up to 64
|
||||
|
||||
pub fn create(allocator: std.mem.Allocator) !*@This() {
|
||||
const self = try allocator.create(@This());
|
||||
pub fn init(self: *@This(), allocator: std.mem.Allocator, first: bool) !void {
|
||||
if (!first)
|
||||
return;
|
||||
|
||||
self.* = .{
|
||||
.allocator = allocator,
|
||||
};
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
pub fn setup(self: *@This(), device: *gpu.GPUDevice) !void {
|
||||
|
|
@ -216,10 +215,6 @@ pub fn createPipeline(self: *@This()) !void {
|
|||
self.ssaoPipeline = ctx.device.createGPUGraphicsPipeline(&pci);
|
||||
}
|
||||
|
||||
pub fn destroy(self: *@This()) void {
|
||||
self.allocator.destroy(self);
|
||||
}
|
||||
|
||||
const core = @import("core");
|
||||
const rend = @import("../rend.zig");
|
||||
const std = @import("std");
|
||||
|
|
|
|||
|
|
@ -1,27 +1,38 @@
|
|||
const std = @import("std");
|
||||
const sdl3 = @import("sdl3");
|
||||
const core = @import("core");
|
||||
|
||||
const dependencyList = [_][]const u8{
|
||||
"core",
|
||||
};
|
||||
|
||||
pub fn build(b: *std.Build) void {
|
||||
const engineMod = core.MakeEngineMod(b, "sys");
|
||||
engineMod.linkModLibs(&dependencyList);
|
||||
engineMod.install();
|
||||
const target = b.standardTargetOptions(.{});
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
const static_build = b.option(bool, "static_build", "builds backlog dependencies for static linking") orelse false;
|
||||
|
||||
const mod = b.addModule("sys", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.root_source_file = b.path("src/sys.zig"),
|
||||
});
|
||||
|
||||
for (dependencyList) |depName| {
|
||||
const dep = b.dependency(depName, .{ .target = target, .optimize = optimize, .static_build = static_build });
|
||||
const dep_mod = dep.module(depName);
|
||||
mod.addImport(depName, dep_mod);
|
||||
}
|
||||
|
||||
// ========== tests ==========
|
||||
const tests = b.addTest(.{
|
||||
.root_module = b.createModule(.{
|
||||
.target = engineMod.target,
|
||||
.optimize = engineMod.optimize,
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.root_source_file = b.path("tests/tests.zig"),
|
||||
}),
|
||||
});
|
||||
const test_step = b.step("test", "run unit tests for ui");
|
||||
|
||||
tests.root_module.addImport("sys", engineMod.mod);
|
||||
tests.root_module.addImport("sys", mod);
|
||||
const runArtifact = b.addRunArtifact(tests);
|
||||
b.installArtifact(tests);
|
||||
test_step.dependOn(&runArtifact.step);
|
||||
|
|
|
|||
|
|
@ -21,8 +21,8 @@ pub const SubprocessTask = struct {
|
|||
allocator: std.mem.Allocator,
|
||||
|
||||
child: ?std.process.Child = null,
|
||||
completed: std.atomic.Value(bool) = std.atomic.Value(bool).init(false),
|
||||
success: std.atomic.Value(bool) = std.atomic.Value(bool).init(false),
|
||||
completed: bool = false,
|
||||
success: bool = false,
|
||||
|
||||
workingDir: ?[]const u8 = null,
|
||||
|
||||
|
|
@ -76,29 +76,29 @@ pub const SubprocessTask = struct {
|
|||
}
|
||||
|
||||
pub fn destroy(self: *@This()) void {
|
||||
// self.mutex.lock();
|
||||
self.mutex.lock();
|
||||
self.argsArena.deinit();
|
||||
self.argsOwned.deinit(self.allocator);
|
||||
if (self.child) |*child| {
|
||||
_ = child;
|
||||
core.engine_log("destroying child process", .{});
|
||||
}
|
||||
// self.mutex.unlock();
|
||||
self.mutex.unlock();
|
||||
self.stdout.deinit(self.allocator);
|
||||
self.stderr.deinit(self.allocator);
|
||||
self.allocator.destroy(self);
|
||||
}
|
||||
|
||||
pub fn checkComplete(self: *@This()) bool {
|
||||
return self.completed.load(.monotonic);
|
||||
return self.completed;
|
||||
}
|
||||
|
||||
pub fn wait(self: *@This()) void {
|
||||
var completed: bool = self.completed.load(.monotonic);
|
||||
var completed: bool = self.completed;
|
||||
while (completed == false) {
|
||||
std.Thread.sleep(1 * 1000 * 1000);
|
||||
self.mutex.lock();
|
||||
completed = self.completed.load(.monotonic);
|
||||
completed = self.completed;
|
||||
self.mutex.unlock();
|
||||
}
|
||||
debugPrint("task completed", .{});
|
||||
|
|
@ -117,7 +117,7 @@ pub const SubprocessTask = struct {
|
|||
|
||||
switch (term) {
|
||||
.Exited => |m| {
|
||||
if (m == 0) self.success.store(true, .release);
|
||||
if (m == 0) self.success = true;
|
||||
},
|
||||
.Signal => |m| {
|
||||
core.engine_log("process Signaled {d}", .{m});
|
||||
|
|
@ -132,8 +132,8 @@ pub const SubprocessTask = struct {
|
|||
|
||||
self.mutex.lock();
|
||||
self.child = null;
|
||||
self.completed = true;
|
||||
self.mutex.unlock();
|
||||
self.completed.store(true, .release);
|
||||
}
|
||||
|
||||
pub fn runCommand(allocator: std.mem.Allocator, argv: []const []const u8, cwd: ?[]const u8) !*@This() {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
const core = @import("core");
|
||||
|
||||
const modules = @import("modtree");
|
||||
|
||||
pub fn launch() void {}
|
||||
|
||||
pub fn shutdown() void {}
|
||||
|
||||
pub fn loadModule() void {}
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
const std = @import("std");
|
||||
const sdl3 = @import("sdl3");
|
||||
const core = @import("core");
|
||||
|
||||
const dependencyList = [_][]const u8{
|
||||
"core",
|
||||
|
|
@ -12,18 +11,28 @@ const dependencyList = [_][]const u8{
|
|||
};
|
||||
|
||||
pub fn build(b: *std.Build) void {
|
||||
const engineMod = core.MakeEngineMod(b, "ui");
|
||||
engineMod.linkModLibs(&dependencyList);
|
||||
engineMod.install();
|
||||
const target = engineMod.target;
|
||||
const optimize = engineMod.optimize;
|
||||
const target = b.standardTargetOptions(.{});
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
const static_build = b.option(bool, "static_build", "builds backlog dependencies for static linking") orelse false;
|
||||
|
||||
const mod = b.addModule("ui", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.root_source_file = b.path("src/ui.zig"),
|
||||
});
|
||||
|
||||
for (dependencyList) |depName| {
|
||||
const dep = b.dependency(depName, .{ .target = target, .optimize = optimize, .static_build = static_build });
|
||||
const dep_mod = dep.module(depName);
|
||||
mod.addImport(depName, dep_mod);
|
||||
}
|
||||
|
||||
// shaders
|
||||
sdl3.shaderDefintion(b, engineMod.mod, "../../lib/sdl3", target, optimize, "rect.vert", b.path("shaders/rect.vert.json"));
|
||||
sdl3.shaderDefintion(b, engineMod.mod, "../../lib/sdl3", target, optimize, "rect.frag", b.path("shaders/rect.frag.json"));
|
||||
sdl3.shaderDefintion(b, mod, "../../lib/sdl3", target, optimize, "rect.vert", b.path("shaders/rect.vert.json"));
|
||||
sdl3.shaderDefintion(b, mod, "../../lib/sdl3", target, optimize, "rect.frag", b.path("shaders/rect.frag.json"));
|
||||
|
||||
sdl3.shaderDefintion(b, engineMod.mod, "../../lib/sdl3", target, optimize, "text.vert", b.path("shaders/text.vert.json"));
|
||||
sdl3.shaderDefintion(b, engineMod.mod, "../../lib/sdl3", target, optimize, "text.frag", b.path("shaders/text.frag.json"));
|
||||
sdl3.shaderDefintion(b, mod, "../../lib/sdl3", target, optimize, "text.vert", b.path("shaders/text.vert.json"));
|
||||
sdl3.shaderDefintion(b, mod, "../../lib/sdl3", target, optimize, "text.frag", b.path("shaders/text.frag.json"));
|
||||
|
||||
// ========== tests ==========
|
||||
const tests = b.addTest(.{
|
||||
|
|
@ -35,8 +44,7 @@ pub fn build(b: *std.Build) void {
|
|||
});
|
||||
const test_step = b.step("test", "run unit tests for ui");
|
||||
|
||||
tests.root_module.addImport("ui", engineMod.mod);
|
||||
tests.root_module.linkLibrary(engineMod.lib);
|
||||
tests.root_module.addImport("ui", mod);
|
||||
const runArtifact = b.addRunArtifact(tests);
|
||||
test_step.dependOn(&runArtifact.step);
|
||||
b.installArtifact(tests);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"permissions": {
|
||||
"allow": [
|
||||
"Bash(cat:*)",
|
||||
"Bash(git log:*)",
|
||||
"Bash(zig build:*)"
|
||||
],
|
||||
"deny": [],
|
||||
"ask": []
|
||||
}
|
||||
}
|
||||
|
|
@ -5,31 +5,9 @@ pub const ModLib = struct {
|
|||
lib: *std.Build.Step.Compile,
|
||||
mod: *std.Build.Module,
|
||||
|
||||
target: std.Build.ResolvedTarget,
|
||||
optimize: std.builtin.OptimizeMode,
|
||||
static_build: bool,
|
||||
|
||||
pub fn install(self: @This()) void {
|
||||
self.b.installArtifact(self.lib);
|
||||
}
|
||||
|
||||
pub fn addIncludePath(self: @This(), path: []const u8) void {
|
||||
self.lib.addIncludePath(self.b.path(path));
|
||||
self.mod.addIncludePath(self.b.path(path));
|
||||
}
|
||||
|
||||
pub fn linkModLibs(self: @This(), list: []const []const u8) void {
|
||||
for (list) |depName| {
|
||||
const dep = self.b.dependency(depName, .{
|
||||
.target = self.target,
|
||||
.optimize = self.optimize,
|
||||
.static_build = self.static_build,
|
||||
});
|
||||
|
||||
self.mod.addImport(depName, dep.module(depName));
|
||||
self.lib.linkLibrary(dep.artifact(depName));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
pub const ModLibOptions = struct {
|
||||
|
|
@ -44,11 +22,11 @@ pub const ModLibOptions = struct {
|
|||
stub: ?std.Build.LazyPath = null,
|
||||
};
|
||||
|
||||
pub fn MakeModLib(b: *std.Build, o: ModLibOptions) ModLib {
|
||||
pub fn MakeModlib(b: *std.Build, o: ModLibOptions) ModLib {
|
||||
const mod = b.addModule(o.name, .{
|
||||
.target = o.target,
|
||||
.optimize = o.optimize,
|
||||
.root_source_file = if (o.root != null) o.root.? else b.path(b.fmt("src/{s}.zig", .{o.name})),
|
||||
.root_source_file = if (o.root != null) o.root.? else b.path(b.fmt("src/{s}", .{o.name})),
|
||||
});
|
||||
|
||||
const empty_file = b.addWriteFile("stubs", "");
|
||||
|
|
@ -67,9 +45,23 @@ pub fn MakeModLib(b: *std.Build, o: ModLibOptions) ModLib {
|
|||
.b = b,
|
||||
.lib = lib,
|
||||
.mod = mod,
|
||||
.target = o.target,
|
||||
.optimize = o.optimize,
|
||||
.static_build = o.static_build,
|
||||
};
|
||||
}
|
||||
|
||||
pub const Options = struct {
|
||||
target: std.Build.ResolvedTarget,
|
||||
optimize: std.builtin.OptimizeMode,
|
||||
static_build: bool,
|
||||
tracy: bool,
|
||||
};
|
||||
|
||||
// standard set of options that all backlog modules and dependenices shall use.
|
||||
pub fn declareOptions(b: *std.Build) Options {
|
||||
return .{
|
||||
.target = b.standardTargetOptions(.{}),
|
||||
.optimize = b.standardOptimizeOption(.{}),
|
||||
.static_build = b.option(bool, "static_build", "builds backlog dependencies for static linking") orelse false,
|
||||
.tracy = b.option(bool, "tracy", "builds with tracy support") orelse false,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -78,7 +70,7 @@ pub fn build(b: *std.Build) void {
|
|||
const optimize = b.standardOptimizeOption(.{});
|
||||
const static_build = b.option(bool, "static_build", "builds backlog dependencies for static linking") orelse false;
|
||||
|
||||
const r = MakeModLib(b, .{
|
||||
const r = MakeModlib(b, .{
|
||||
.name = "bh",
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
|
|
|
|||
|
|
@ -3,37 +3,41 @@ const bh = @import("bh");
|
|||
|
||||
// very tiny, not intended to build anything just to run tests linked with libc
|
||||
pub fn build(b: *std.Build) void {
|
||||
const target = b.standardTargetOptions(.{});
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
const static_build = b.option(bool, "static_build", "builds backlog dependencies for static linking") orelse false;
|
||||
const opts = bh.declareOptions(b);
|
||||
|
||||
const cimgui = bh.MakeModLib(b, .{
|
||||
.name = "cimgui",
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.static_build = static_build,
|
||||
const mod = b.addModule("cimgui", .{
|
||||
.target = opts.target,
|
||||
.optimize = opts.optimize,
|
||||
.link_libc = true,
|
||||
.root_source_file = b.path("src/cimgui.zig"),
|
||||
});
|
||||
|
||||
cimgui.install();
|
||||
mod.addIncludePath(b.path("cimgui/imgui"));
|
||||
mod.addIncludePath(b.path("cimgui/SDL/include"));
|
||||
mod.addIncludePath(b.path("cimplot"));
|
||||
mod.addIncludePath(b.path("cimplot/implot"));
|
||||
|
||||
cimgui.mod.addIncludePath(b.path("cimgui/SDL/include"));
|
||||
cimgui.mod.addIncludePath(b.path("cimplot"));
|
||||
cimgui.mod.addIncludePath(b.path("cimgui/imgui"));
|
||||
cimgui.mod.addIncludePath(b.path("cimplot/implot"));
|
||||
const cimgui = b.addLibrary(.{
|
||||
.name = "cimgui",
|
||||
.root_module = b.createModule(.{
|
||||
.optimize = opts.optimize,
|
||||
.target = opts.target,
|
||||
}),
|
||||
});
|
||||
|
||||
cimgui.lib.linkLibC();
|
||||
cimgui.linkLibC();
|
||||
|
||||
if (target.result.abi != .msvc)
|
||||
cimgui.lib.linkLibCpp();
|
||||
if (opts.target.result.abi != .msvc)
|
||||
cimgui.linkLibCpp();
|
||||
|
||||
cimgui.lib.addIncludePath(b.path("cimgui"));
|
||||
cimgui.lib.addIncludePath(b.path("cimplot"));
|
||||
cimgui.lib.addIncludePath(b.path("cimgui/imgui"));
|
||||
cimgui.lib.addIncludePath(b.path("cimgui/imgui/backends"));
|
||||
cimgui.lib.addIncludePath(b.path("cimgui/imgui/backends"));
|
||||
cimgui.lib.addIncludePath(b.path("cimgui/SDL/include/"));
|
||||
cimgui.addIncludePath(b.path("cimgui"));
|
||||
cimgui.addIncludePath(b.path("cimplot"));
|
||||
cimgui.addIncludePath(b.path("cimgui/imgui"));
|
||||
cimgui.addIncludePath(b.path("cimgui/imgui/backends"));
|
||||
cimgui.addIncludePath(b.path("cimgui/imgui/backends"));
|
||||
cimgui.addIncludePath(b.path("cimgui/SDL/include/"));
|
||||
|
||||
cimgui.lib.addCSourceFiles(.{
|
||||
cimgui.addCSourceFiles(.{
|
||||
.root = b.path("cimgui/imgui"),
|
||||
.files = &[_][]const u8{
|
||||
"cimgui.cpp",
|
||||
|
|
@ -48,7 +52,7 @@ pub fn build(b: *std.Build) void {
|
|||
},
|
||||
});
|
||||
|
||||
cimgui.lib.addCSourceFiles(.{
|
||||
cimgui.addCSourceFiles(.{
|
||||
.root = b.path("cimplot"),
|
||||
.files = &[_][]const u8{
|
||||
"cimplot.cpp",
|
||||
|
|
@ -58,20 +62,20 @@ pub fn build(b: *std.Build) void {
|
|||
},
|
||||
});
|
||||
|
||||
mod.linkLibrary(cimgui);
|
||||
|
||||
// I could've made cimgui a seperate lib,
|
||||
// I can seperate it out later if needed.
|
||||
const test_step = b.step("test", "run unit tests for imgui");
|
||||
const tests = b.addTest(.{
|
||||
.root_module = b.createModule(.{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.target = opts.target,
|
||||
.optimize = opts.optimize,
|
||||
.root_source_file = b.path("tests/tests.zig"),
|
||||
}),
|
||||
});
|
||||
|
||||
tests.root_module.addImport("cimgui", cimgui.mod);
|
||||
tests.root_module.linkLibrary(cimgui.lib);
|
||||
|
||||
tests.root_module.addImport("cimgui", mod);
|
||||
const runArtifact = b.addRunArtifact(tests);
|
||||
test_step.dependOn(&runArtifact.step);
|
||||
b.installArtifact(tests);
|
||||
|
|
|
|||
|
|
@ -1,3 +0,0 @@
|
|||
const cimgui = @import("cimgui");
|
||||
|
||||
test "huh" {}
|
||||
|
|
@ -2,9 +2,7 @@ const std = @import("std");
|
|||
const bh = @import("bh");
|
||||
|
||||
pub fn build(b: *std.Build) void {
|
||||
const target = b.standardTargetOptions(.{});
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
const static_build = b.option(bool, "static_build", "builds backlog dependencies for static linking") orelse false;
|
||||
const opts = bh.declareOptions(b);
|
||||
|
||||
// am i good to always have enet as static?
|
||||
// const enet = if (true) b.addStaticLibrary(.{
|
||||
|
|
@ -17,18 +15,18 @@ pub fn build(b: *std.Build) void {
|
|||
// .optimize = optimize,
|
||||
// });
|
||||
|
||||
const enet = bh.MakeModLib(b, .{
|
||||
.name = "enet",
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.static_build = static_build,
|
||||
const enet = b.addLibrary(.{
|
||||
.name = "enet_c",
|
||||
.linkage = .static,
|
||||
.root_module = b.createModule(.{
|
||||
.target = opts.target,
|
||||
.optimize = opts.optimize,
|
||||
}),
|
||||
});
|
||||
|
||||
enet.install();
|
||||
enet.linkLibC();
|
||||
|
||||
enet.lib.linkLibC();
|
||||
|
||||
enet.lib.addCSourceFiles(.{
|
||||
enet.addCSourceFiles(.{
|
||||
.root = b.path("enet-1.3.18"),
|
||||
.files = &.{
|
||||
"callbacks.c",
|
||||
|
|
@ -43,13 +41,14 @@ pub fn build(b: *std.Build) void {
|
|||
},
|
||||
.flags = &.{"-DHAS_OFFSETOF=1"},
|
||||
});
|
||||
enet.addIncludePath("enet-1.3.18/include");
|
||||
|
||||
enet.addIncludePath(b.path("enet-1.3.18/include"));
|
||||
|
||||
// Platform-specific configuration
|
||||
switch (target.result.os.tag) {
|
||||
switch (opts.target.result.os.tag) {
|
||||
.windows => {
|
||||
enet.lib.linkSystemLibrary("ws2_32");
|
||||
enet.lib.linkSystemLibrary("winmm");
|
||||
enet.linkSystemLibrary("ws2_32");
|
||||
enet.linkSystemLibrary("winmm");
|
||||
// Use .def file to control exports and avoid CRT symbol conflicts
|
||||
},
|
||||
.linux, .macos => {
|
||||
|
|
@ -58,18 +57,29 @@ pub fn build(b: *std.Build) void {
|
|||
else => {},
|
||||
}
|
||||
|
||||
b.installArtifact(enet);
|
||||
|
||||
const mod = b.addModule("enet", .{
|
||||
.target = opts.target,
|
||||
.optimize = opts.optimize,
|
||||
.root_source_file = b.path("src/enet.zig"),
|
||||
.link_libc = true,
|
||||
});
|
||||
|
||||
mod.linkLibrary(enet);
|
||||
mod.addIncludePath(b.path("enet-1.3.18/include/"));
|
||||
|
||||
const test_step = b.step("test", "run unit tests for enet");
|
||||
const tests = b.addTest(.{
|
||||
.root_module = b.createModule(.{
|
||||
.link_libc = true,
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.target = opts.target,
|
||||
.optimize = opts.optimize,
|
||||
.root_source_file = b.path("src/tests.zig"),
|
||||
}),
|
||||
});
|
||||
|
||||
tests.linkLibrary(enet.lib);
|
||||
tests.root_module.addImport("enet", enet.mod);
|
||||
tests.root_module.addImport("enet", mod);
|
||||
tests.root_module.addIncludePath(b.path("enet-1.3.18/include/"));
|
||||
const runArtifact = b.addRunArtifact(tests);
|
||||
test_step.dependOn(&runArtifact.step);
|
||||
|
|
@ -79,11 +89,11 @@ pub fn build(b: *std.Build) void {
|
|||
.name = "test-server",
|
||||
.root_module = b.createModule(.{
|
||||
.root_source_file = b.path("src/test_server.zig"),
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.target = opts.target,
|
||||
.optimize = opts.optimize,
|
||||
}),
|
||||
});
|
||||
test_server.root_module.addImport("enet", enet.mod);
|
||||
test_server.root_module.addImport("enet", mod);
|
||||
test_server.linkLibC();
|
||||
|
||||
// Test client executable
|
||||
|
|
@ -91,11 +101,11 @@ pub fn build(b: *std.Build) void {
|
|||
.name = "test-client",
|
||||
.root_module = b.createModule(.{
|
||||
.root_source_file = b.path("src/test_client.zig"),
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.target = opts.target,
|
||||
.optimize = opts.optimize,
|
||||
}),
|
||||
});
|
||||
test_client.root_module.addImport("enet", enet.mod);
|
||||
test_client.root_module.addImport("enet", mod);
|
||||
test_client.linkLibC();
|
||||
|
||||
// Install test programs
|
||||
|
|
@ -123,12 +133,6 @@ pub fn build(b: *std.Build) void {
|
|||
const build_tests_step = b.step("build-tests", "Build test server and client programs");
|
||||
build_tests_step.dependOn(&install_test_server.step);
|
||||
build_tests_step.dependOn(&install_test_client.step);
|
||||
|
||||
test_server.linkLibrary(enet.lib);
|
||||
test_client.linkLibrary(enet.lib);
|
||||
|
||||
b.installArtifact(test_server);
|
||||
b.installArtifact(test_client);
|
||||
}
|
||||
|
||||
// Custom step to run server and client concurrently for loopback testing
|
||||
|
|
|
|||
|
|
@ -2,27 +2,28 @@ const std = @import("std");
|
|||
const bh = @import("bh");
|
||||
|
||||
pub fn build(b: *std.Build) void {
|
||||
const target = b.standardTargetOptions(.{});
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
const static_build = b.option(bool, "static_build", "builds backlog dependencies for static linking") orelse false;
|
||||
const opts = bh.declareOptions(b);
|
||||
|
||||
const lua = bh.MakeModLib(b, .{
|
||||
.name = "lua",
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.static_build = static_build,
|
||||
.root = b.path("src/lua.zig"),
|
||||
const mod = b.addModule("lua", .{
|
||||
.target = opts.target,
|
||||
.optimize = opts.optimize,
|
||||
.root_source_file = b.path("src/lua.zig"),
|
||||
.link_libc = true,
|
||||
});
|
||||
|
||||
lua.install();
|
||||
const luac = b.addLibrary(.{
|
||||
.name = "luac",
|
||||
.linkage = if (opts.static_build) .static else .dynamic,
|
||||
.root_module = b.createModule(.{
|
||||
.target = opts.target,
|
||||
.optimize = opts.optimize,
|
||||
.link_libc = true,
|
||||
}),
|
||||
});
|
||||
|
||||
// Add include paths to module (for Zig @cImport)
|
||||
lua.addIncludePath("lua/src/");
|
||||
lua.addIncludePath("src/");
|
||||
b.installArtifact(luac);
|
||||
|
||||
// Configure library
|
||||
lua.lib.linkLibC();
|
||||
lua.lib.addCSourceFiles(.{
|
||||
luac.addCSourceFiles(.{
|
||||
.root = b.path("lua/src/"),
|
||||
.files = &.{
|
||||
"lapi.c",
|
||||
|
|
@ -60,30 +61,37 @@ pub fn build(b: *std.Build) void {
|
|||
},
|
||||
});
|
||||
|
||||
lua.lib.addCSourceFile(.{ .file = b.path("src/limited_io.c") });
|
||||
luac.addCSourceFile(.{ .file = b.path("src/limited_io.c") });
|
||||
|
||||
if (target.result.os.tag == .windows) {
|
||||
lua.lib.addCSourceFile(.{ .file = b.path("src/minidumpsetup.cpp") });
|
||||
if (target.result.abi != .msvc)
|
||||
lua.lib.linkLibCpp();
|
||||
if (opts.target.result.os.tag == .windows) {
|
||||
luac.addCSourceFile(.{ .file = b.path("src/minidumpsetup.cpp") });
|
||||
if (opts.target.result.abi != .msvc)
|
||||
luac.linkLibCpp();
|
||||
luac.linkLibC();
|
||||
} else {
|
||||
lua.lib.addCSourceFile(.{ .file = b.path("src/minidumpstub.cpp") });
|
||||
luac.addCSourceFile(.{ .file = b.path("src/minidumpstub.cpp") });
|
||||
}
|
||||
|
||||
luac.addIncludePath(b.path("lua/src/"));
|
||||
luac.addIncludePath(b.path("src/"));
|
||||
|
||||
mod.addIncludePath(b.path("lua/src/"));
|
||||
mod.addIncludePath(b.path("src/"));
|
||||
|
||||
mod.linkLibrary(luac);
|
||||
|
||||
const run_step = b.step("test", "");
|
||||
const tests = b.addExecutable(.{
|
||||
.name = "run-lua",
|
||||
.root_module = b.createModule(.{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.target = opts.target,
|
||||
.optimize = opts.optimize,
|
||||
.root_source_file = b.path("test/test-lua.zig"),
|
||||
.link_libc = true,
|
||||
}),
|
||||
});
|
||||
|
||||
tests.root_module.addImport("lua", lua.mod);
|
||||
tests.root_module.linkLibrary(lua.lib);
|
||||
tests.root_module.addImport("lua", mod);
|
||||
const runArtifact = b.addRunArtifact(tests);
|
||||
run_step.dependOn(&runArtifact.step);
|
||||
b.installArtifact(tests);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,42 +2,40 @@ const std = @import("std");
|
|||
const bh = @import("bh");
|
||||
|
||||
pub fn build(b: *std.Build) void {
|
||||
const target = b.standardTargetOptions(.{});
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
const static_build = b.option(bool, "static_build", "builds backlog dependencies for static linking") orelse false;
|
||||
const opts = bh.declareOptions(b);
|
||||
|
||||
const miniaudio = bh.MakeModLib(b, .{
|
||||
.name = "miniaudio",
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.static_build = static_build,
|
||||
.root = b.path("src/miniaudio.zig"),
|
||||
const miniaudio_c = b.addLibrary(.{
|
||||
.name = "miniaudio_c",
|
||||
.linkage = if (opts.static_build) .static else .dynamic,
|
||||
.root_module = b.createModule(.{
|
||||
.target = opts.target,
|
||||
.optimize = opts.optimize,
|
||||
.link_libc = true,
|
||||
}),
|
||||
});
|
||||
|
||||
miniaudio.install();
|
||||
b.installArtifact(miniaudio_c);
|
||||
miniaudio_c.addCSourceFile(.{ .file = b.path("src/miniaudio.cpp"), .flags = &.{"-fno-sanitize=all"}, .language = .c });
|
||||
miniaudio_c.addIncludePath(b.path("include"));
|
||||
|
||||
// Add include paths to module (for Zig @cImport)
|
||||
miniaudio.addIncludePath("./include");
|
||||
const mod = b.addModule("miniaudio", .{ .target = opts.target, .optimize = opts.optimize, .root_source_file = b.path("src/miniaudio.zig") });
|
||||
|
||||
// Configure library
|
||||
miniaudio.lib.linkLibC();
|
||||
|
||||
miniaudio.lib.addCSourceFile(.{ .file = b.path("src/miniaudio.cpp"), .flags = &.{"-fno-sanitize=all"}, .language = .c });
|
||||
mod.linkLibrary(miniaudio_c);
|
||||
mod.addIncludePath(b.path("./include"));
|
||||
|
||||
// ======== tests ============
|
||||
const test_step = b.step("test", "");
|
||||
const tests = b.addTest(.{
|
||||
.root_module = b.createModule(.{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.target = opts.target,
|
||||
.optimize = opts.optimize,
|
||||
.root_source_file = b.path("src/miniaudio-test.zig"),
|
||||
.link_libc = true,
|
||||
}),
|
||||
});
|
||||
tests.addIncludePath(b.path("./include"));
|
||||
|
||||
tests.root_module.addImport("miniaudio", miniaudio.mod);
|
||||
tests.root_module.linkLibrary(miniaudio.lib);
|
||||
tests.root_module.addImport("miniaudio", mod);
|
||||
const runArtifact = b.addRunArtifact(tests);
|
||||
test_step.dependOn(&runArtifact.step);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,76 +2,67 @@ const std = @import("std");
|
|||
const bh = @import("bh");
|
||||
|
||||
pub fn build(b: *std.Build) void {
|
||||
const target = b.standardTargetOptions(.{});
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
const static_build = b.option(bool, "static_build", "builds backlog dependencies for static linking") orelse false;
|
||||
const opts = bh.declareOptions(b);
|
||||
|
||||
const nfd = bh.MakeModLib(b, .{
|
||||
.name = "nfd",
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.static_build = static_build,
|
||||
.root = b.path("src/nfd.zig"),
|
||||
const mod = b.addModule("nfd", .{
|
||||
.target = opts.target,
|
||||
.optimize = opts.optimize,
|
||||
.root_source_file = b.path("src/nfd.zig"),
|
||||
.link_libc = true,
|
||||
});
|
||||
|
||||
nfd.install();
|
||||
|
||||
// Add include paths to module (for Zig @cImport)
|
||||
nfd.addIncludePath("include");
|
||||
|
||||
// Configure library
|
||||
nfd.lib.linkLibC();
|
||||
nfd.lib.addCSourceFile(.{
|
||||
mod.addCSourceFile(.{
|
||||
.file = b.path("src/nfd_common.c"),
|
||||
.flags = &.{},
|
||||
});
|
||||
|
||||
if (target.result.os.tag == .macos) {
|
||||
nfd.lib.addCSourceFile(.{
|
||||
mod.addIncludePath(b.path("include"));
|
||||
|
||||
if (opts.target.result.os.tag == .macos) {
|
||||
mod.addCSourceFile(.{
|
||||
.file = b.path("src/nfd_cocoa.m"),
|
||||
.flags = &.{},
|
||||
});
|
||||
nfd.lib.linkFramework("AppKit");
|
||||
} else if (target.result.os.tag == .windows) {
|
||||
nfd.lib.addCSourceFile(.{
|
||||
mod.linkFramework("AppKit", .{});
|
||||
} else if (opts.target.result.os.tag == .windows) {
|
||||
mod.addCSourceFile(.{
|
||||
.file = b.path("src/nfd_win.cpp"),
|
||||
.flags = &.{},
|
||||
});
|
||||
nfd.lib.linkSystemLibrary("ole32");
|
||||
} else if (target.result.os.tag == .linux) {
|
||||
// nfd.lib.addCSourceFile(.{
|
||||
mod.linkSystemLibrary("ole32", .{});
|
||||
} else if (opts.target.result.os.tag == .linux) {
|
||||
// mod.addCSourceFile(.{
|
||||
// .file = b.path("src/nfd_gtk.c"),
|
||||
// .flags = &.{},
|
||||
// });
|
||||
nfd.lib.addCSourceFile(.{
|
||||
mod.addCSourceFile(.{
|
||||
.file = b.path("src/nfd_null.c"),
|
||||
.flags = &.{},
|
||||
});
|
||||
// nfd.lib.linkSystemLibrary("gdk-3", .{});
|
||||
// nfd.lib.linkSystemLibrary("atk-1.0", .{});
|
||||
// nfd.lib.linkSystemLibrary("gtk-3", .{});
|
||||
// nfd.lib.linkSystemLibrary("glib-2.0", .{});
|
||||
// nfd.lib.linkSystemLibrary("gobject-2.0", .{});
|
||||
// mod.linkSystemLibrary("gdk-3", .{});
|
||||
// mod.linkSystemLibrary("atk-1.0", .{});
|
||||
// mod.linkSystemLibrary("gtk-3", .{});
|
||||
// mod.linkSystemLibrary("glib-2.0", .{});
|
||||
// mod.linkSystemLibrary("gobject-2.0", .{});
|
||||
}
|
||||
|
||||
const p2dep = b.dependency("p2", .{ .target = target, .optimize = optimize, .static_build = static_build });
|
||||
const p2dep = b.dependency("p2", .{ .target = opts.target, .optimize = opts.optimize, .static_build = opts.static_build });
|
||||
|
||||
const p2mod = p2dep.module("p2");
|
||||
nfd.mod.addImport("p2", p2mod);
|
||||
mod.addImport("p2", p2mod);
|
||||
|
||||
const test_step = b.step("test", "");
|
||||
const tests = b.addTest(.{
|
||||
.root_module = b.createModule(.{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.target = opts.target,
|
||||
.optimize = opts.optimize,
|
||||
.root_source_file = b.path("src/nfd.zig"),
|
||||
.link_libc = true,
|
||||
}),
|
||||
});
|
||||
tests.addIncludePath(b.path("./include"));
|
||||
|
||||
tests.root_module.addImport("nfd", nfd.mod);
|
||||
tests.root_module.linkLibrary(nfd.lib);
|
||||
tests.root_module.addImport("nfd", mod);
|
||||
tests.root_module.addImport("p2", p2mod);
|
||||
const runArtifact = b.addRunArtifact(tests);
|
||||
test_step.dependOn(&runArtifact.step);
|
||||
|
|
|
|||
|
|
@ -2,32 +2,25 @@ const std = @import("std");
|
|||
const bh = @import("bh");
|
||||
|
||||
pub fn build(b: *std.Build) void {
|
||||
const target = b.standardTargetOptions(.{});
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
const static_build = b.option(bool, "static_build", "builds backlog dependencies for static linking") orelse false;
|
||||
const opts = bh.declareOptions(b);
|
||||
|
||||
const objLoader = bh.MakeModLib(b, .{
|
||||
.name = "objLoader",
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.static_build = static_build,
|
||||
.root = b.path("src/obj_loader.zig"),
|
||||
const mod = b.addModule("objLoader", .{
|
||||
.target = opts.target,
|
||||
.optimize = opts.optimize,
|
||||
.root_source_file = b.path("src/obj_loader.zig"),
|
||||
});
|
||||
|
||||
objLoader.install();
|
||||
|
||||
const test_step = b.step("test", "");
|
||||
const tests = b.addTest(.{
|
||||
.root_module = b.createModule(.{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.target = opts.target,
|
||||
.optimize = opts.optimize,
|
||||
.root_source_file = b.path("src/obj_loader.zig"),
|
||||
.link_libc = true,
|
||||
}),
|
||||
});
|
||||
|
||||
tests.root_module.addImport("objLoader", objLoader.mod);
|
||||
tests.root_module.linkLibrary(objLoader.lib);
|
||||
tests.root_module.addImport("objLoader", mod);
|
||||
const runArtifact = b.addRunArtifact(tests);
|
||||
test_step.dependOn(&runArtifact.step);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
// ozz_animation_offline_fbx -- fbx importing, requires linking wiht fbx sdk... maybe i dont want this... fuck adobe
|
||||
|
||||
const std = @import("std");
|
||||
const bh = @import("bh");
|
||||
|
||||
const Build = std.Build;
|
||||
const LazyPath = LazyPath;
|
||||
|
|
@ -86,7 +87,7 @@ pub const GltfToOzz = struct {
|
|||
});
|
||||
|
||||
const dep = b.dependency(opts.importName, .{});
|
||||
const ozz_mod = dep.artifact("ozz");
|
||||
const ozz_mod = dep.artifact("ozz_cpp");
|
||||
exe.root_module.linkLibrary(ozz_mod);
|
||||
|
||||
exe.root_module.addIncludePath(b.path("ozz-animation/include"));
|
||||
|
|
@ -142,16 +143,14 @@ pub const GltfToOzz = struct {
|
|||
};
|
||||
|
||||
pub fn build(b: *std.Build) void {
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
const target = b.standardTargetOptions(.{});
|
||||
const static_build = b.option(bool, "static_build", "builds backlog dependencies for static linking") orelse false;
|
||||
const opts = bh.declareOptions(b);
|
||||
|
||||
const ozz_cpp = b.addLibrary(.{
|
||||
.linkage = if (static_build) .static else .dynamic,
|
||||
.name = "ozz",
|
||||
.linkage = if (opts.static_build) .static else .dynamic,
|
||||
.name = "ozz_cpp",
|
||||
.root_module = b.createModule(.{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.target = opts.target,
|
||||
.optimize = opts.optimize,
|
||||
}),
|
||||
});
|
||||
|
||||
|
|
@ -161,7 +160,7 @@ pub fn build(b: *std.Build) void {
|
|||
ozz_cpp.addIncludePath(b.path("ozz-animation/src"));
|
||||
ozz_cpp.linkLibC();
|
||||
|
||||
if (target.result.abi != .msvc)
|
||||
if (opts.target.result.abi != .msvc)
|
||||
ozz_cpp.linkLibCpp();
|
||||
|
||||
const src_dir = "ozz-animation/src/";
|
||||
|
|
@ -208,8 +207,8 @@ pub fn build(b: *std.Build) void {
|
|||
.name = "ozz-tests",
|
||||
.root_module = b.createModule(.{
|
||||
.root_source_file = b.path("tests/test.zig"),
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.target = opts.target,
|
||||
.optimize = opts.optimize,
|
||||
}),
|
||||
});
|
||||
b.installArtifact(tests);
|
||||
|
|
|
|||
|
|
@ -2,32 +2,25 @@ const std = @import("std");
|
|||
const bh = @import("bh");
|
||||
|
||||
pub fn build(b: *std.Build) void {
|
||||
const target = b.standardTargetOptions(.{});
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
const static_build = b.option(bool, "static_build", "builds backlog dependencies for static linking") orelse true;
|
||||
const opts = bh.declareOptions(b);
|
||||
|
||||
const p2 = bh.MakeModLib(b, .{
|
||||
.name = "p2",
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.static_build = static_build,
|
||||
.root = b.path("src/p2.zig"),
|
||||
const mod = b.addModule("p2", .{
|
||||
.target = opts.target,
|
||||
.optimize = opts.optimize,
|
||||
.root_source_file = b.path("src/p2.zig"),
|
||||
});
|
||||
|
||||
p2.install();
|
||||
|
||||
const test_step = b.step("test", "test p2");
|
||||
const tests = b.addTest(.{
|
||||
.root_module = b.createModule(.{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.target = opts.target,
|
||||
.optimize = opts.optimize,
|
||||
.root_source_file = b.path("src/p2.zig"),
|
||||
}),
|
||||
// .link_libc = true,
|
||||
});
|
||||
|
||||
tests.root_module.addImport("p2", p2.mod);
|
||||
tests.root_module.linkLibrary(p2.lib);
|
||||
tests.root_module.addImport("p2", mod);
|
||||
const runArtifact = b.addRunArtifact(tests);
|
||||
test_step.dependOn(&runArtifact.step);
|
||||
if (b.args) |args| {
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ pub const IndexPool = index_pool.IndexPool;
|
|||
|
||||
pub const concurrent_queue = @import("structures/concurrent-queue.zig");
|
||||
pub const ConcurrentQueueU = concurrent_queue.ConcurrentQueueU;
|
||||
pub const ConcurrentQueueAdvanced = concurrent_queue.ConcurrentQueueAdvanced;
|
||||
pub const ConcurrentQueueUnmanagedAdvanced = concurrent_queue.ConcurrentQueueUnmanagedAdvanced;
|
||||
|
||||
pub const string_pool = @import("structures/string-pool.zig");
|
||||
|
||||
|
|
|
|||
|
|
@ -14,11 +14,13 @@ pub const ConcurrentQueueError = error{
|
|||
QueueIsFull,
|
||||
};
|
||||
|
||||
pub fn ConcurrentQueue(comptime T: type) type {
|
||||
return ConcurrentQueueAdvanced(T, .{});
|
||||
pub fn ConcurrentQueueU(comptime T: type) type {
|
||||
return ConcurrentQueueUnmanagedAdvanced(T, .{});
|
||||
}
|
||||
|
||||
pub const ConcurrentQueueU = ConcurrentQueue;
|
||||
pub fn ConcurrentQueueAssert(comptime T: type) type {
|
||||
return ConcurrentQueueUnmanagedAdvanced(T, .{ .allowAsserts = true });
|
||||
}
|
||||
|
||||
// lock-free concurrent queue, fixed capacity,
|
||||
// will never resize.
|
||||
|
|
@ -31,7 +33,7 @@ pub const ConcurrentStatus = packed struct(usize) {
|
|||
generation: u63 = 0,
|
||||
};
|
||||
|
||||
pub fn ConcurrentQueueAdvanced(comptime T: type, comptime opts: struct {
|
||||
pub fn ConcurrentQueueUnmanagedAdvanced(comptime T: type, comptime opts: struct {
|
||||
allowAsserts: bool = false,
|
||||
debug: bool = false,
|
||||
}) type {
|
||||
|
|
@ -140,7 +142,7 @@ test "concurrent queue basic correctness test" {
|
|||
|
||||
const allocator = std.testing.allocator;
|
||||
|
||||
var y = try ConcurrentQueueAdvanced(Info, .{ .allowAsserts = true, .debug = true }).initCapacity(allocator, 420);
|
||||
var y = try ConcurrentQueueUnmanagedAdvanced(Info, .{ .allowAsserts = true, .debug = true }).initCapacity(allocator, 420);
|
||||
defer y.deinit(allocator);
|
||||
|
||||
try y.push(.{});
|
||||
|
|
@ -156,7 +158,7 @@ test "concurrent queue basic correctness test" {
|
|||
|
||||
try utils.assertf(y.count() == 0, "expected there to be {d} elements in queue, we saw {d}", .{ 0, y.count() });
|
||||
|
||||
var x = try ConcurrentQueue(Info).initCapacity(allocator, 12);
|
||||
var x = try ConcurrentQueueU(Info).initCapacity(allocator, 12);
|
||||
defer x.deinit(allocator);
|
||||
|
||||
try x.push(.{ .x = 0 });
|
||||
|
|
@ -187,7 +189,7 @@ test "concurrent queue multiple producer single consumer" {
|
|||
arb: [4096]u8 = undefined,
|
||||
};
|
||||
|
||||
const QueueType = ConcurrentQueueAdvanced(Payload, .{ .debug = false, .allowAsserts = true });
|
||||
const QueueType = ConcurrentQueueUnmanagedAdvanced(Payload, .{ .debug = false, .allowAsserts = true });
|
||||
|
||||
const Wrap = struct {
|
||||
pub fn threadFunc(queueRef: *QueueType, id: i64, exitSignal: *Atomic(bool), pushedCountResults: *Atomic(i64)) void {
|
||||
|
|
|
|||
|
|
@ -42,6 +42,8 @@ pub fn SparseMultiSetAdvanced(comptime T: type, comptime SparseSize: u32) type {
|
|||
return struct {
|
||||
pub const SetType = std.MultiArrayList(T);
|
||||
|
||||
pub const InnerType = T;
|
||||
|
||||
allocator: std.mem.Allocator,
|
||||
denseIndices: ArrayListUnmanaged(SetHandle),
|
||||
dense: SetType,
|
||||
|
|
@ -311,6 +313,7 @@ pub fn SparseSetAdvanced(comptime T: type, comptime SparseSize: u32) type {
|
|||
opCount: u32 = 0,
|
||||
|
||||
pub const StableReferences = false;
|
||||
pub const InnerType = T;
|
||||
|
||||
pub fn getStateCount(self: @This()) u32 {
|
||||
return self.opCount;
|
||||
|
|
@ -596,6 +599,7 @@ pub fn SparseMap(comptime T: type) type {
|
|||
containerListener: ?ContainerListener = null,
|
||||
opCount: u32 = 0,
|
||||
|
||||
pub const InnerType = T;
|
||||
pub const StableReferences = true;
|
||||
|
||||
pub fn create(backingAllocator: std.mem.Allocator) !*@This() {
|
||||
|
|
@ -720,6 +724,7 @@ const interface = @import("interface.zig");
|
|||
|
||||
pub const EcsContainerInterface = interface.MakeInterface("EcsContainerInterfaceVTable", struct {
|
||||
containerTypeName: []const u8,
|
||||
componentName: []const u8,
|
||||
handleExists: *const fn (*const anyopaque, SetHandle) bool,
|
||||
get: *const fn (*const anyopaque, SetHandle) ?*anyopaque,
|
||||
createWithHandle: *const fn (*anyopaque, SetHandle) *anyopaque,
|
||||
|
|
@ -787,6 +792,7 @@ pub const EcsContainerInterface = interface.MakeInterface("EcsContainerInterface
|
|||
|
||||
return .{
|
||||
.containerTypeName = TargetType.ContainerTypeName,
|
||||
.componentName = @typeName(TargetType.InnerType),
|
||||
.handleExists = Wrap.handleExists,
|
||||
.get = Wrap.get,
|
||||
.createWithHandle = Wrap.createWithHandle,
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ const std = @import("std");
|
|||
// main purpose of this string-pool is to provide an RC-ableinterface for interface
|
||||
// with GC'ed systems such as lua
|
||||
|
||||
var gStringContext: *StringContext = undefined;
|
||||
pub var gStringContext: *StringContext = undefined;
|
||||
|
||||
pub const String = struct {
|
||||
index: u24,
|
||||
|
|
|
|||
|
|
@ -2,35 +2,27 @@ const std = @import("std");
|
|||
const bh = @import("bh");
|
||||
|
||||
pub fn build(b: *std.Build) void {
|
||||
const target = b.standardTargetOptions(.{});
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
const opts = bh.declareOptions(b);
|
||||
|
||||
const static_build = b.option(bool, "static_build", "builds backlog dependencies for static linking") orelse false;
|
||||
const p2dep = b.dependency("p2", .{ .target = opts.target, .optimize = opts.optimize, .static_build = opts.static_build });
|
||||
|
||||
const packer = bh.MakeModLib(b, .{
|
||||
.name = "packer",
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.static_build = static_build,
|
||||
.root = b.path("src/packer.zig"),
|
||||
const mod = b.addModule("packer", .{
|
||||
.target = opts.target,
|
||||
.optimize = opts.optimize,
|
||||
.root_source_file = b.path("src/packer.zig"),
|
||||
});
|
||||
|
||||
packer.install();
|
||||
|
||||
const p2dep = b.dependency("p2", .{ .target = target, .optimize = optimize, .static_build = static_build });
|
||||
|
||||
const p2mod = p2dep.module("p2");
|
||||
packer.mod.addImport("p2", p2mod);
|
||||
mod.addImport("p2", p2mod);
|
||||
|
||||
const test_exe = b.addTest(.{
|
||||
.root_module = b.createModule(.{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.target = opts.target,
|
||||
.optimize = opts.optimize,
|
||||
.root_source_file = b.path("tests/test.zig"),
|
||||
}),
|
||||
});
|
||||
test_exe.root_module.addImport("packer", packer.mod);
|
||||
test_exe.root_module.linkLibrary(packer.lib);
|
||||
test_exe.root_module.addImport("packer", mod);
|
||||
test_exe.root_module.addImport("p2", p2mod);
|
||||
|
||||
const test_step = b.step("test", "runs sample unit tests for packer");
|
||||
|
|
|
|||
|
|
@ -174,6 +174,7 @@ pub const PackerFS = struct {
|
|||
}
|
||||
|
||||
for (self.anyWatchCallbacks.items) |*watch| {
|
||||
// std.debug.print("anywatch callback: {s}\n", .{watch.path});
|
||||
watch.call(std.mem.span(path));
|
||||
}
|
||||
}
|
||||
|
|
@ -341,6 +342,8 @@ pub const PackerFS = struct {
|
|||
}
|
||||
|
||||
pub fn installFileBytesMount(self: *@This(), path: []const u8, fileBytes: []align(8) u8, embedded: bool) !?PackerBytesMapping {
|
||||
// std.debug.print("mounting file path {s}\n", .{path});
|
||||
|
||||
const pakMountIndex = self.pakMountings.items.len;
|
||||
try self.pakMountings.append(self.allocator, .{
|
||||
.filePath = try self.stringAlloc().dupe(u8, path),
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
const std = @import("std");
|
||||
const bh = @import("bh");
|
||||
|
||||
pub fn addShaderDefinition(
|
||||
b: *std.Build,
|
||||
|
|
@ -48,54 +49,47 @@ pub fn shaderDefintion(
|
|||
}
|
||||
|
||||
pub fn build(b: *std.Build) void {
|
||||
const target = b.standardTargetOptions(.{});
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
const opts = bh.declareOptions(b);
|
||||
|
||||
const static_build = b.option(bool, "static_build", "builds backlog dependencies for static linking") orelse false;
|
||||
|
||||
const preferred_linkage: std.builtin.LinkMode = if (static_build) .static else .dynamic;
|
||||
const preferred_linkage: std.builtin.LinkMode = if (opts.static_build) .static else .dynamic;
|
||||
|
||||
const sdl_dep = b.dependency("sdl", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.target = opts.target,
|
||||
.optimize = opts.optimize,
|
||||
.preferred_linkage = preferred_linkage,
|
||||
});
|
||||
|
||||
const sdl3_lib = sdl_dep.artifact("SDL3");
|
||||
b.installArtifact(sdl3_lib);
|
||||
|
||||
const sdl3_fwd = b.addLibrary(.{
|
||||
.name = "sdl3",
|
||||
.root_module = b.createModule(.{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.root_source_file = b.path("src/sdl3_lib_fwd.zig"),
|
||||
}),
|
||||
const sdl3_fwd = b.addModule("SDL3", .{
|
||||
.target = opts.target,
|
||||
.optimize = opts.optimize,
|
||||
.root_source_file = b.path("src/sdl3_lib_fwd.zig"),
|
||||
});
|
||||
|
||||
sdl3_fwd.linkLibrary(sdl3_lib);
|
||||
b.installArtifact(sdl3_fwd);
|
||||
|
||||
const mod = b.addModule("sdl3", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.target = opts.target,
|
||||
.optimize = opts.optimize,
|
||||
.root_source_file = b.path("src/sdl3.zig"),
|
||||
});
|
||||
|
||||
const shaderTypes = b.dependency("shaderTypes", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.target = opts.target,
|
||||
.optimize = opts.optimize,
|
||||
});
|
||||
mod.addImport("shaderTypes", shaderTypes.module("shaderTypes"));
|
||||
|
||||
mod.addIncludePath(b.path("SDL/include"));
|
||||
mod.linkLibrary(sdl_dep.artifact("SDL3"));
|
||||
mod.linkLibrary(sdl3_lib);
|
||||
|
||||
const test_step2 = b.step("test", "run unit tests for sdl3");
|
||||
const tests2 = b.addExecutable(.{
|
||||
.name = "hello-sdl",
|
||||
.root_module = b.createModule(.{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.target = opts.target,
|
||||
.optimize = opts.optimize,
|
||||
.root_source_file = b.path("src/samples/compiletest.zig"),
|
||||
.link_libc = true,
|
||||
}),
|
||||
|
|
@ -105,8 +99,8 @@ pub fn build(b: *std.Build) void {
|
|||
const tests = b.addExecutable(.{
|
||||
.name = "hello-triangle",
|
||||
.root_module = b.createModule(.{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.target = opts.target,
|
||||
.optimize = opts.optimize,
|
||||
.root_source_file = b.path("src/samples/hello-triangle.zig"),
|
||||
.link_libc = true,
|
||||
}),
|
||||
|
|
@ -116,8 +110,8 @@ pub fn build(b: *std.Build) void {
|
|||
const hello_window_exe = b.addExecutable(.{
|
||||
.name = "hello-window",
|
||||
.root_module = b.createModule(.{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.target = opts.target,
|
||||
.optimize = opts.optimize,
|
||||
.root_source_file = b.path("src/samples/hello-window.zig"),
|
||||
.link_libc = true,
|
||||
}),
|
||||
|
|
@ -128,7 +122,7 @@ pub fn build(b: *std.Build) void {
|
|||
|
||||
tests.root_module.addImport("sdl3", mod);
|
||||
|
||||
const vertexDefinitions = addShaderDefinition(b, ".", target, optimize, "hello-triangle.vert", b.path("content/hello-triangle.vert.json"));
|
||||
const vertexDefinitions = addShaderDefinition(b, ".", opts.target, opts.optimize, "hello-triangle.vert", b.path("content/hello-triangle.vert.json"));
|
||||
tests.root_module.addImport("hello-triangle.vert", vertexDefinitions);
|
||||
|
||||
const runArtifact = b.addRunArtifact(tests);
|
||||
|
|
@ -138,6 +132,7 @@ pub fn build(b: *std.Build) void {
|
|||
test_step2.dependOn(&runArtifact2.step);
|
||||
|
||||
b.installArtifact(hello_window_exe);
|
||||
b.installArtifact(sdl3_lib);
|
||||
b.installArtifact(tests);
|
||||
b.installArtifact(tests2);
|
||||
}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue