Compare commits
5 Commits
dev/varian
...
dev/parall
| Author | SHA1 | Date |
|---|---|---|
|
|
b0d1a81d84 | |
|
|
2176977c4c | |
|
|
13d73418f8 | |
|
|
fdb23323fe | |
|
|
fc8165eb83 |
31
CLAUDE.md
31
CLAUDE.md
|
|
@ -96,6 +96,37 @@ The shader compilation system automatically discovers `.hlsl` files in `engine/*
|
||||||
- The build system generates API wrappers automatically for enabled modules
|
- The build system generates API wrappers automatically for enabled modules
|
||||||
- Content directory location is determined by `content.txt` file pointing to `projects/content/`
|
- 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
|
## Common Development Tasks
|
||||||
|
|
||||||
- Adding new engine modules: Create in `engine/` with `build.zig` and add to `engineDepList`
|
- Adding new engine modules: Create in `engine/` with `build.zig` and add to `engineDepList`
|
||||||
|
|
|
||||||
|
|
@ -97,4 +97,11 @@ git bug bug comment abc123
|
||||||
- Issues sync with `git bug pull/push`
|
- Issues sync with `git bug pull/push`
|
||||||
- Keep descriptions factual and clear
|
- 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
|
||||||
|
/// --------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,662 +0,0 @@
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
|
|
@ -1,696 +0,0 @@
|
||||||
// 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,27 +1,42 @@
|
||||||
// MVK_CONFIG_USE_METAL_ARGUMENT_BUFFERS=1 -- use this if you're getting that odd crash on mac
|
// MVK_CONFIG_USE_METAL_ARGUMENT_BUFFERS=1 -- use this if you're getting that odd crash on mac
|
||||||
b: *std.Build,
|
b: *std.Build,
|
||||||
bEngine: *std.Build, // used to resolve executable paths from within the engine's root directory
|
nw_builder: *std.Build,
|
||||||
opts: bh.Options,
|
target: std.Build.ResolvedTarget,
|
||||||
|
optimize: std.builtin.OptimizeMode,
|
||||||
nw_mod: *std.Build.Module,
|
nw_mod: *std.Build.Module,
|
||||||
gltf2ozz: ozz.GltfToOzz,
|
gltf2ozz: ozz.GltfToOzz,
|
||||||
options: *std.Build.Step.Options,
|
options: *std.Build.Step.Options,
|
||||||
cookShaders: bool,
|
cookShaders: bool,
|
||||||
|
|
||||||
backlogRoot: []const u8,
|
backlogRoot: []const u8,
|
||||||
|
|
||||||
// list of all shaders discovered under
|
// list of all shaders discovered under
|
||||||
// content/_shaders/def
|
// content/_shaders/def
|
||||||
reflectShaderPathList: [][]u8 = undefined,
|
reflectShaderPathList: [][]u8 = undefined,
|
||||||
|
|
||||||
|
staticBuild: bool = false,
|
||||||
|
|
||||||
nwdep: *std.Build.Dependency,
|
nwdep: *std.Build.Dependency,
|
||||||
// apigen: *std.Build.Step.Compile,
|
apigen: *std.Build.Step.Compile,
|
||||||
shaderEmbedGen: *std.Build.Step.Compile,
|
shaderEmbedGen: *std.Build.Step.Compile,
|
||||||
loadDynamicsGen: *std.Build.Step.Compile,
|
loadDynamicsGen: *std.Build.Step.Compile,
|
||||||
rcGen: *std.Build.Step.Compile,
|
rcGen: *std.Build.Step.Compile,
|
||||||
specGen: *std.Build.Step.Compile,
|
|
||||||
generatedApis: std.StringHashMapUnmanaged(*std.Build.Module) = .{},
|
generatedApis: std.StringHashMapUnmanaged(*std.Build.Module) = .{},
|
||||||
|
|
||||||
pub const BuildSystem = @This();
|
const engineDepList = [_][]const u8{
|
||||||
|
"assets",
|
||||||
|
"audio",
|
||||||
|
"core",
|
||||||
|
"net",
|
||||||
|
"papyrus",
|
||||||
|
"platform",
|
||||||
|
"rend",
|
||||||
|
"ui",
|
||||||
|
"imgui",
|
||||||
|
"physics",
|
||||||
|
"sys",
|
||||||
|
};
|
||||||
|
|
||||||
|
const BuildSystem = @This();
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const Build = std.Build;
|
const Build = std.Build;
|
||||||
const LazyPath = Build.LazyPath;
|
const LazyPath = Build.LazyPath;
|
||||||
|
|
@ -31,47 +46,41 @@ const ozz = @import("ozz");
|
||||||
pub const InitOptions = struct {
|
pub const InitOptions = struct {
|
||||||
import_name: []const u8 = "Backlog",
|
import_name: []const u8 = "Backlog",
|
||||||
backlogRoot: []const u8 = "./BacklogEngine",
|
backlogRoot: []const u8 = "./BacklogEngine",
|
||||||
target: std.Build.ResolvedTarget,
|
staticBuild: bool = false,
|
||||||
|
target: Build.ResolvedTarget,
|
||||||
optimize: std.builtin.OptimizeMode,
|
optimize: std.builtin.OptimizeMode,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn init(b: *std.Build, initOptions: InitOptions) BuildSystem {
|
pub fn init(b: *std.Build, opts: InitOptions) BuildSystem {
|
||||||
const buildOpts = declareBuildOptions(b);
|
var 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) {
|
if (opts.target.result.os.tag == .linux) {
|
||||||
// using a static build for linux... object loading hell is not fun...
|
// 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", .{});
|
||||||
// std.debug.print("Important! only supporting static builds for linux", .{});
|
buildOpts.static_build = true;
|
||||||
// opts.static_build = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const nwdep = b.dependency(initOptions.import_name, .{
|
const nwdep = b.dependency(opts.import_name, .{
|
||||||
.target = opts.target,
|
.target = opts.target,
|
||||||
.optimize = opts.optimize,
|
.optimize = opts.optimize,
|
||||||
.static_build = opts.static_build,
|
.static_build = buildOpts.static_build,
|
||||||
});
|
});
|
||||||
|
|
||||||
var self = BuildSystem{
|
var self = BuildSystem{
|
||||||
.b = b,
|
.b = b,
|
||||||
.bEngine = nwdep.builder,
|
.nw_builder = nwdep.builder,
|
||||||
.opts = opts,
|
.target = opts.target,
|
||||||
|
.optimize = opts.optimize,
|
||||||
.nw_mod = nwdep.module("Backlog"),
|
.nw_mod = nwdep.module("Backlog"),
|
||||||
.backlogRoot = initOptions.backlogRoot,
|
.backlogRoot = opts.backlogRoot,
|
||||||
.options = createGameOptions(b, buildOpts, opts),
|
.options = createGameOptions(b, buildOpts),
|
||||||
.gltf2ozz = ozz.GltfToOzz.init(nwdep.builder, .{}),
|
.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,
|
.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,
|
.nwdep = nwdep,
|
||||||
// .apigen = nwdep.artifact("backlog-apigen"),
|
.apigen = nwdep.artifact("backlog-apigen"),
|
||||||
.loadDynamicsGen = nwdep.artifact("backlog-generate-loadDynamics"),
|
.loadDynamicsGen = nwdep.artifact("backlog-generate-loadDynamics"),
|
||||||
.specGen = nwdep.artifact("backlog-generate-spec"),
|
|
||||||
.rcGen = nwdep.artifact("backlog-generate-rc"),
|
.rcGen = nwdep.artifact("backlog-generate-rc"),
|
||||||
.shaderEmbedGen = nwdep.artifact("backlog-shaderEmbedGen"),
|
.shaderEmbedGen = nwdep.artifact("backlog-shaderEmbedGen"),
|
||||||
};
|
};
|
||||||
|
|
@ -101,80 +110,509 @@ pub fn init(b: *std.Build, initOptions: InitOptions) BuildSystem {
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build Options for the engine,
|
pub const AddProgramOptions = struct {
|
||||||
// should generally be written as false = default
|
name: []const u8,
|
||||||
// true = enabling something
|
desc: []const u8,
|
||||||
const BuildOptions = struct {
|
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,
|
mutex_job_queue: bool,
|
||||||
|
static_build: bool,
|
||||||
zero_logging: bool,
|
zero_logging: bool,
|
||||||
slow_logging: bool,
|
slow_logging: bool,
|
||||||
force_mailbox: bool,
|
force_mailbox: bool,
|
||||||
};
|
};
|
||||||
|
|
||||||
fn declareBuildOptions(b: *std.Build) BuildOptions {
|
pub fn declareBuildOptions(b: *std.Build) BuildOptions {
|
||||||
return .{
|
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,
|
.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,
|
.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,
|
.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,
|
.force_mailbox = b.option(bool, "force_mailbox", "forces mailbox mode for present mode. unlocks framerate to irresponsible levels") orelse false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn createGameOptions(b: *std.Build, options: BuildOptions, bhopts: bh.Options) *std.Build.Step.Options {
|
pub fn createGameOptions(b: *std.Build, options: BuildOptions) *std.Build.Step.Options {
|
||||||
const opts = b.addOptions();
|
const opts = b.addOptions();
|
||||||
|
|
||||||
inline for (@typeInfo(BuildOptions).@"struct".fields) |field| {
|
inline for (@typeInfo(BuildOptions).@"struct".fields) |field| {
|
||||||
opts.addOption(bool, field.name, @field(options, field.name));
|
opts.addOption(bool, field.name, @field(options, field.name));
|
||||||
}
|
}
|
||||||
|
|
||||||
// forward the options to the build options
|
// build options for core.zig
|
||||||
opts.addOption(bool, "tracy", bhopts.tracy);
|
// opts.addOption(
|
||||||
opts.addOption(bool, "static_build", bhopts.static_build);
|
// 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;
|
return opts;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn addExtraModule(self: *BuildSystem, mod: *std.Build.Module, moduleName: []const u8) void {
|
pub fn addExtraModule(self: *BuildSystem, mod: *std.Build.Module, moduleName: []const u8) void {
|
||||||
const dep = self.b.dependency(moduleName, .{ .target = self.opts.target, .optimize = self.opts.optimize, .static_build = self.opts.static_build });
|
const dep = self.b.dependency(moduleName, .{ .target = self.target, .optimize = self.optimize, .static_build = self.staticBuild });
|
||||||
mod.addImport(moduleName, dep.module(moduleName));
|
mod.addImport(moduleName, dep.module(moduleName));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn addDependencyInstalls(self: *BuildSystem, b: *std.Build, optimize: std.builtin.OptimizeMode) void {
|
pub fn addDependencyInstalls(self: *BuildSystem, b: *std.Build, optimize: std.builtin.OptimizeMode) void {
|
||||||
if (self.opts.static_build) {
|
//if (self.staticBuild) {
|
||||||
return;
|
//return;
|
||||||
}
|
// }
|
||||||
|
|
||||||
inline for (DynamicDepList) |d| {
|
inline for (DynamicDepList) |d| {
|
||||||
b.installArtifact(b.dependency(
|
b.installArtifact(b.dependency(
|
||||||
d.dep,
|
d.dep,
|
||||||
.{ .target = self.opts.target, .optimize = optimize, .static_build = self.opts.static_build },
|
.{ .target = self.target, .optimize = optimize, .static_build = self.staticBuild },
|
||||||
).artifact(d.artifact));
|
).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 } = &.{
|
const DynamicDepList: []const struct { dep: []const u8, artifact: []const u8 } = &.{
|
||||||
.{ .dep = "sdl3", .artifact = "SDL3" },
|
.{ .dep = "sdl3", .artifact = "SDL3" },
|
||||||
.{ .dep = "spng", .artifact = "spng_c" },
|
.{ .dep = "spng", .artifact = "spng" },
|
||||||
.{ .dep = "lua", .artifact = "luac" },
|
.{ .dep = "lua", .artifact = "lua" },
|
||||||
.{ .dep = "miniaudio", .artifact = "miniaudio_c" },
|
.{ .dep = "miniaudio", .artifact = "miniaudio" },
|
||||||
.{ .dep = "zphysics", .artifact = "joltc" },
|
.{ .dep = "zphysics", .artifact = "zphysics" },
|
||||||
// .{ .dep = "enet", .artifact = "enet_c" },
|
// .{ .dep = "enet", .artifact = "enet_c" },
|
||||||
.{ .dep = "ozz", .artifact = "ozz_cpp" },
|
.{ .dep = "ozz", .artifact = "ozz" },
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn addProgram(
|
// all other modules are disabled by default
|
||||||
self: *@This(),
|
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,
|
name: []const u8,
|
||||||
) *Program {
|
allocator: std.mem.Allocator,
|
||||||
const p = self.b.allocator.create(Program) catch unreachable;
|
buildSystem: *BuildSystem,
|
||||||
p.* = .{
|
programName: []const u8,
|
||||||
.name = name,
|
opts: AddProgramOptions,
|
||||||
.opts = self.opts,
|
|
||||||
.buildSystem = self,
|
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,
|
.allocator = self.b.allocator,
|
||||||
|
.opts = opts,
|
||||||
|
.buildSystem = self,
|
||||||
};
|
};
|
||||||
|
|
||||||
return p;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn generateRc(self: *@This(), programName: []const u8, iconPath: []const u8) !std.Build.LazyPath {
|
pub fn generateRc(self: *@This(), programName: []const u8, iconPath: []const u8) !std.Build.LazyPath {
|
||||||
|
|
@ -186,6 +624,35 @@ pub fn generateRc(self: *@This(), programName: []const u8, iconPath: []const u8)
|
||||||
return output;
|
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 {
|
pub fn generateInstallStaticResources(self: *@This(), programName: []const u8, shadersPath: []const u8) !*std.Build.Module {
|
||||||
const run = self.b.addRunArtifact(self.shaderEmbedGen);
|
const run = self.b.addRunArtifact(self.shaderEmbedGen);
|
||||||
const pfile = self.b.fmt("{s}ShaderGen.zig", .{programName});
|
const pfile = self.b.fmt("{s}ShaderGen.zig", .{programName});
|
||||||
|
|
@ -194,8 +661,8 @@ pub fn generateInstallStaticResources(self: *@This(), programName: []const u8, s
|
||||||
|
|
||||||
const b = self.b;
|
const b = self.b;
|
||||||
const mod = self.b.addModule(pfile, .{
|
const mod = self.b.addModule(pfile, .{
|
||||||
.target = self.opts.target,
|
.target = self.target,
|
||||||
.optimize = self.opts.optimize,
|
.optimize = self.optimize,
|
||||||
.root_source_file = output,
|
.root_source_file = output,
|
||||||
});
|
});
|
||||||
mod.addImport("core", self.nwdep.module("core"));
|
mod.addImport("core", self.nwdep.module("core"));
|
||||||
|
|
@ -220,15 +687,3 @@ pub fn generateInstallStaticResources(self: *@This(), programName: []const u8, s
|
||||||
|
|
||||||
return mod;
|
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,23 +1,28 @@
|
||||||
.{ .name = .Backlog, .version = "0.0.0", .dependencies = .{
|
.{
|
||||||
.assets = .{ .path = "engine/assets" },
|
.name = .Backlog,
|
||||||
.audio = .{ .path = "engine/audio" },
|
.version = "0.0.0",
|
||||||
.core = .{ .path = "engine/core" },
|
.dependencies = .{
|
||||||
.net = .{ .path = "engine/net" },
|
.assets = .{ .path = "engine/assets" },
|
||||||
.papyrus = .{ .path = "engine/papyrus" },
|
.audio = .{ .path = "engine/audio" },
|
||||||
.physics = .{ .path = "engine/physics" },
|
.core = .{ .path = "engine/core" },
|
||||||
.platform = .{ .path = "engine/platform" },
|
.net = .{ .path = "engine/net" },
|
||||||
.imgui = .{ .path = "engine/imgui" },
|
.papyrus = .{ .path = "engine/papyrus" },
|
||||||
.ui = .{ .path = "engine/ui" },
|
.physics = .{ .path = "engine/physics" },
|
||||||
.sys = .{ .path = "engine/sys" },
|
.platform = .{ .path = "engine/platform" },
|
||||||
.rend = .{ .path = "engine/rend" },
|
.imgui = .{ .path = "engine/imgui" },
|
||||||
|
.ui = .{ .path = "engine/ui" },
|
||||||
|
.sys = .{ .path = "engine/sys" },
|
||||||
|
.rend = .{.path = "engine/rend" },
|
||||||
|
|
||||||
.ozz = .{ .path = "lib/ozz" },
|
.ozz = .{ .path = "lib/ozz" },
|
||||||
.spng = .{ .path = "lib/spng" },
|
.spng = .{ .path = "lib/spng" },
|
||||||
.zphysics = .{ .path = "lib/zphysics" },
|
.zphysics = .{ .path = "lib/zphysics" },
|
||||||
|
|
||||||
.sdl3 = .{ .path = "lib/sdl3" },
|
.sdl3 = .{ .path = "lib/sdl3" },
|
||||||
.enet = .{ .path = "lib/enet" },
|
.enet = .{ .path = "lib/enet" },
|
||||||
.bh = .{ .path = "lib/bh" },
|
},
|
||||||
}, .paths = .{
|
.paths = .{
|
||||||
"",
|
"",
|
||||||
}, .fingerprint = 0xcf9bab998abe37e3 }
|
},
|
||||||
|
.fingerprint = 0xcf9bab998abe37e3
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,84 +0,0 @@
|
||||||
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;
|
|
||||||
|
|
||||||
|
|
@ -1,138 +0,0 @@
|
||||||
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");
|
|
||||||
|
|
@ -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);
|
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);
|
defer ast.deinit(allocator);
|
||||||
const out = try ast.renderAlloc(allocator);
|
const out = try ast.renderAlloc(allocator);
|
||||||
|
|
||||||
std.debug.print("output=\n{s}", .{out});
|
|
||||||
// Write the content to the file
|
// Write the content to the file
|
||||||
try file.writeAll(out);
|
try file.writeAll(out);
|
||||||
}
|
}
|
||||||
|
|
@ -1,182 +0,0 @@
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
|
|
@ -1,227 +0,0 @@
|
||||||
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");
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
const std = @import("std");
|
|
||||||
const Build = std.Build;
|
|
||||||
const LazyPath = Build.LazyPath;
|
|
||||||
125
build/utils.zig
125
build/utils.zig
|
|
@ -1,114 +1,19 @@
|
||||||
|
pub fn loadFileAlloc(filename: []const u8, comptime alignment: usize, allocator: std.mem.Allocator) ![]u8 {
|
||||||
pub fn buildGenerators(b: *std.Build, opts: bh.Options) void {
|
var file = try std.fs.cwd().openFile(filename, .{});
|
||||||
const target = opts.target;
|
defer file.close();
|
||||||
const optimize = opts.optimize;
|
const filesize = (try file.stat()).size + 1; // add null byte
|
||||||
const static_build = opts.static_build;
|
const buffer: []align(alignment) u8 = try allocator.alignedAlloc(u8, alignment, filesize);
|
||||||
|
errdefer allocator.free(buffer);
|
||||||
const fwdGeneratorExe = b.addExecutable(.{
|
try file.reader().readNoEof(buffer[0 .. buffer.len - 1]);
|
||||||
.name = "backlog-generate-fwd",
|
buffer[buffer.len - 1] = 0;
|
||||||
.root_module = b.createModule(.{
|
return buffer;
|
||||||
.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 std = @import("std");
|
||||||
const bh = @import("bh");
|
|
||||||
|
|
|
||||||
|
|
@ -1,49 +0,0 @@
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
@ -1,67 +0,0 @@
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
// 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 {}
|
|
||||||
|
|
@ -1,26 +0,0 @@
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
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;
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
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,8 +21,7 @@ pub fn tick(self: *@This(), dt: f64) void {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *@This()) void {
|
pub fn deinit(self: *@This()) void {
|
||||||
// Engine handles memory deallocation
|
self.allocator.destroy(self);
|
||||||
_ = self;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn main() anyerror!void {
|
pub fn main() anyerror!void {
|
||||||
|
|
|
||||||
|
|
@ -1,28 +1,25 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
const core = @import("core");
|
||||||
|
|
||||||
|
const depList = [_][]const u8{
|
||||||
|
"core",
|
||||||
|
"packer",
|
||||||
|
};
|
||||||
|
|
||||||
pub fn build(b: *std.Build) void {
|
pub fn build(b: *std.Build) void {
|
||||||
const target = b.standardTargetOptions(.{});
|
const target = b.standardTargetOptions(.{});
|
||||||
const optimize = b.standardOptimizeOption(.{});
|
const optimize = b.standardOptimizeOption(.{});
|
||||||
const static_build = b.option(bool, "static_build", "builds backlog dependencies for static linking") orelse false;
|
const static_build = b.option(bool, "static_build", "builds backlog dependencies for static linking") orelse false;
|
||||||
|
|
||||||
const mod = b.addModule("assets", .{
|
const engineMod = core.MakeModLib(b, .{
|
||||||
|
.name = "assets",
|
||||||
.target = target,
|
.target = target,
|
||||||
.optimize = optimize,
|
.optimize = optimize,
|
||||||
.root_source_file = b.path("src/assets.zig"),
|
.static_build = static_build,
|
||||||
});
|
});
|
||||||
|
|
||||||
const core_dep = b.dependency(
|
engineMod.linkModLibs(&depList);
|
||||||
"core",
|
engineMod.install();
|
||||||
.{ .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 test_step = b.step("test", "run unit tests for assets");
|
||||||
const tests = b.addTest(.{
|
const tests = b.addTest(.{
|
||||||
|
|
@ -33,7 +30,7 @@ pub fn build(b: *std.Build) void {
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
tests.root_module.addImport("assets", mod);
|
tests.root_module.addImport("assets", engineMod.mod);
|
||||||
const runArtifact = b.addRunArtifact(tests);
|
const runArtifact = b.addRunArtifact(tests);
|
||||||
test_step.dependOn(&runArtifact.step);
|
test_step.dependOn(&runArtifact.step);
|
||||||
b.installArtifact(tests);
|
b.installArtifact(tests);
|
||||||
|
|
|
||||||
|
|
@ -120,6 +120,11 @@ pub const AssetLoaderInterface = struct {
|
||||||
unreachable;
|
unreachable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!@hasDecl(TargetType, "destroy")) {
|
||||||
|
@compileLog("Tried to generate AssetLoaderInterface for type ", TargetType, "but it's missing func destroy.");
|
||||||
|
unreachable;
|
||||||
|
}
|
||||||
|
|
||||||
const self = @This(){
|
const self = @This(){
|
||||||
.typeName = @typeName(TargetType),
|
.typeName = @typeName(TargetType),
|
||||||
.typeSize = @sizeOf(TargetType),
|
.typeSize = @sizeOf(TargetType),
|
||||||
|
|
@ -154,15 +159,15 @@ pub const AssetReferenceSys = struct {
|
||||||
|
|
||||||
pub var NeonObjectTable = core.EngineObjectVTable.from(@This(), "AssetReference");
|
pub var NeonObjectTable = core.EngineObjectVTable.from(@This(), "AssetReference");
|
||||||
|
|
||||||
pub fn init(self: *@This(), allocator: std.mem.Allocator, first: bool) !void {
|
pub fn init(allocator: std.mem.Allocator) !*@This() {
|
||||||
if (!first)
|
const self = try allocator.create(@This());
|
||||||
return;
|
|
||||||
|
|
||||||
self.* = @This(){
|
self.* = @This(){
|
||||||
.loaders = .{},
|
.loaders = .{},
|
||||||
.allocator = allocator,
|
.allocator = allocator,
|
||||||
.outstandingAssetJobs = std.atomic.Value(i32).init(0),
|
.outstandingAssetJobs = std.atomic.Value(i32).init(0),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn registerLoader(self: *@This(), loader: anytype) !void {
|
pub fn registerLoader(self: *@This(), loader: anytype) !void {
|
||||||
|
|
@ -205,5 +210,6 @@ pub const AssetReferenceSys = struct {
|
||||||
// i.destroy(self.allocator);
|
// i.destroy(self.allocator);
|
||||||
// }
|
// }
|
||||||
self.loaders.deinit(self.allocator);
|
self.loaders.deinit(self.allocator);
|
||||||
|
self.allocator.destroy(self);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
const core = @import("core");
|
||||||
|
|
||||||
const depList = [_][]const u8{
|
const depList = [_][]const u8{
|
||||||
"miniaudio",
|
"miniaudio",
|
||||||
|
|
@ -11,17 +12,15 @@ pub fn build(b: *std.Build) void {
|
||||||
const optimize = b.standardOptimizeOption(.{});
|
const optimize = b.standardOptimizeOption(.{});
|
||||||
const static_build = b.option(bool, "static_build", "builds backlog dependencies for static linking") orelse false;
|
const static_build = b.option(bool, "static_build", "builds backlog dependencies for static linking") orelse false;
|
||||||
|
|
||||||
const mod = b.addModule("audio", .{
|
const engineMod = core.MakeModLib(b, .{
|
||||||
|
.name = "audio",
|
||||||
.target = target,
|
.target = target,
|
||||||
.optimize = optimize,
|
.optimize = optimize,
|
||||||
.root_source_file = b.path("src/audio.zig"),
|
.static_build = static_build,
|
||||||
});
|
});
|
||||||
|
|
||||||
for (depList) |depName| {
|
engineMod.linkModLibs(&depList);
|
||||||
const dep = b.dependency(depName, .{ .target = target, .optimize = optimize, .static_build = static_build });
|
engineMod.install();
|
||||||
|
|
||||||
mod.addImport(depName, dep.module(depName));
|
|
||||||
}
|
|
||||||
|
|
||||||
const test_step = b.step("test", "run unit tests for audio");
|
const test_step = b.step("test", "run unit tests for audio");
|
||||||
const tests = b.addTest(.{
|
const tests = b.addTest(.{
|
||||||
|
|
@ -32,7 +31,7 @@ pub fn build(b: *std.Build) void {
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
tests.root_module.addImport("audio", mod);
|
tests.root_module.addImport("audio", engineMod.mod);
|
||||||
const runArtifact = b.addRunArtifact(tests);
|
const runArtifact = b.addRunArtifact(tests);
|
||||||
test_step.dependOn(&runArtifact.step);
|
test_step.dependOn(&runArtifact.step);
|
||||||
b.installArtifact(tests);
|
b.installArtifact(tests);
|
||||||
|
|
|
||||||
|
|
@ -73,10 +73,8 @@ pub const SoundEngine = struct {
|
||||||
allocator: std.mem.Allocator,
|
allocator: std.mem.Allocator,
|
||||||
volume: f32 = 1.0,
|
volume: f32 = 1.0,
|
||||||
|
|
||||||
pub fn init(self: *@This(), allocator: std.mem.Allocator, first: bool) !void {
|
pub fn init(allocator: std.mem.Allocator) !*@This() {
|
||||||
if (!first)
|
const self = try allocator.create(@This());
|
||||||
return;
|
|
||||||
|
|
||||||
self.* = @This(){
|
self.* = @This(){
|
||||||
.engine = allocator.create(ma.ma_engine) catch unreachable,
|
.engine = allocator.create(ma.ma_engine) catch unreachable,
|
||||||
.sounds = .{},
|
.sounds = .{},
|
||||||
|
|
@ -85,6 +83,8 @@ pub const SoundEngine = struct {
|
||||||
};
|
};
|
||||||
|
|
||||||
_ = ma.ma_engine_init(null, self.engine);
|
_ = ma.ma_engine_init(null, self.engine);
|
||||||
|
|
||||||
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn shutdown(self: *@This()) void {
|
pub fn shutdown(self: *@This()) void {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
pub const std = @import("std");
|
|
||||||
const core = @import("core");
|
|
||||||
const impl = core;
|
|
||||||
|
|
||||||
pub const inputs = struct {
|
|
||||||
pub const getInputStack = inputs.getInputStack;
|
|
||||||
};
|
|
||||||
|
|
@ -1,4 +1,8 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
pub const bh = @import("bh");
|
||||||
|
|
||||||
|
pub const ModLib = bh.ModLib;
|
||||||
|
pub const MakeModLib = bh.MakeModLib;
|
||||||
|
|
||||||
const dependencyList = [_][]const u8{
|
const dependencyList = [_][]const u8{
|
||||||
"p2",
|
"p2",
|
||||||
|
|
@ -7,31 +11,43 @@ const dependencyList = [_][]const u8{
|
||||||
"packer", // packer no longer has C deps.
|
"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 {
|
pub fn build(b: *std.Build) void {
|
||||||
const target = b.standardTargetOptions(.{});
|
const target = b.standardTargetOptions(.{});
|
||||||
const optimize = b.standardOptimizeOption(.{});
|
const optimize = b.standardOptimizeOption(.{});
|
||||||
const static_build = b.option(bool, "static_build", "builds backlog dependencies for static linking") orelse false;
|
const static_build = b.option(bool, "static_build", "builds backlog dependencies for static linking") orelse false;
|
||||||
|
|
||||||
const mod = b.addModule("core", .{
|
const engineMod = MakeModLib(b, .{
|
||||||
|
.name = "core",
|
||||||
.target = target,
|
.target = target,
|
||||||
.optimize = optimize,
|
.optimize = optimize,
|
||||||
.root_source_file = b.path("src/core.zig"),
|
.static_build = static_build,
|
||||||
});
|
});
|
||||||
|
|
||||||
for (dependencyList) |depName| {
|
engineMod.install();
|
||||||
const dep = b.dependency(depName, .{ .target = target, .optimize = optimize, .static_build = static_build });
|
engineMod.linkModLibs(&dependencyList);
|
||||||
mod.addImport(depName, dep.module(depName));
|
|
||||||
}
|
|
||||||
|
|
||||||
const test_step = b.step("test", "run unit tests for core");
|
const test_step = b.step("test", "run unit tests for core");
|
||||||
const tests = b.addTest(.{
|
const tests = b.addTest(.{
|
||||||
.root_module = b.createModule(.{
|
.root_module = b.createModule(.{
|
||||||
.target = target,
|
.target = target,
|
||||||
.optimize = optimize,
|
.optimize = optimize,
|
||||||
.link_libc = true,
|
|
||||||
.root_source_file = b.path("tests/tests.zig"),
|
.root_source_file = b.path("tests/tests.zig"),
|
||||||
}),
|
}),
|
||||||
.use_llvm = true,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const sampleGameExtern = b.addLibrary(.{
|
const sampleGameExtern = b.addLibrary(.{
|
||||||
|
|
@ -42,10 +58,9 @@ pub fn build(b: *std.Build) void {
|
||||||
.target = target,
|
.target = target,
|
||||||
}),
|
}),
|
||||||
.linkage = .dynamic,
|
.linkage = .dynamic,
|
||||||
.use_llvm = true,
|
|
||||||
.name = "external",
|
.name = "external",
|
||||||
});
|
});
|
||||||
sampleGameExtern.root_module.addImport("core", mod);
|
sampleGameExtern.root_module.addImport("core", engineMod.mod);
|
||||||
|
|
||||||
const installExtern = b.addInstallArtifact(sampleGameExtern, .{
|
const installExtern = b.addInstallArtifact(sampleGameExtern, .{
|
||||||
.dest_dir = .{ .override = .{ .custom = "modules" } },
|
.dest_dir = .{ .override = .{ .custom = "modules" } },
|
||||||
|
|
@ -53,7 +68,7 @@ pub fn build(b: *std.Build) void {
|
||||||
|
|
||||||
b.getInstallStep().dependOn(&installExtern.step);
|
b.getInstallStep().dependOn(&installExtern.step);
|
||||||
|
|
||||||
tests.root_module.addImport("core", mod);
|
tests.root_module.addImport("core", engineMod.mod);
|
||||||
const runArtifact = b.addRunArtifact(tests);
|
const runArtifact = b.addRunArtifact(tests);
|
||||||
test_step.dependOn(&runArtifact.step);
|
test_step.dependOn(&runArtifact.step);
|
||||||
runArtifact.step.dependOn(b.getInstallStep());
|
runArtifact.step.dependOn(b.getInstallStep());
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
// with -Dtracy = false, this one pulls in no C dependencies
|
// with -Dtracy = false, this one pulls in no C dependencies
|
||||||
.tracy = .{ .path = "../../lib/tracy" },
|
.tracy = .{ .path = "../../lib/tracy" },
|
||||||
|
.bh = .{ .path = "../../lib/bh" },
|
||||||
|
|
||||||
// these are zig only
|
// these are zig only
|
||||||
.zmath = .{ .path = "../../lib/zmath" },
|
.zmath = .{ .path = "../../lib/zmath" },
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,17 @@
|
||||||
pub const ConfigRegistry = struct {
|
pub const ConfigRegistry = struct {
|
||||||
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This(), "core.ConfigRegistry");
|
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This(), "core.ConfigRegistry");
|
||||||
|
|
||||||
allocator: std.mem.Allocator = undefined,
|
allocator: std.mem.Allocator,
|
||||||
configMap: ?ConfigMap = null,
|
configMap: ?ConfigMap = null,
|
||||||
|
|
||||||
pub fn init(self: *@This(), allocator: std.mem.Allocator, first: bool) !void {
|
pub fn create(allocator: std.mem.Allocator) !*@This() {
|
||||||
if (!first)
|
const self = try allocator.create(@This());
|
||||||
return;
|
|
||||||
|
|
||||||
self.* = .{
|
self.* = .{
|
||||||
.allocator = allocator,
|
.allocator = allocator,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
// by convention this should be in the root
|
// by convention this should be in the root
|
||||||
|
|
@ -37,10 +38,11 @@ pub const ConfigRegistry = struct {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *@This()) void {
|
pub fn destroy(self: *@This()) void {
|
||||||
if (self.configMap) |*map| {
|
if (self.configMap) |*map| {
|
||||||
map.deinit();
|
map.deinit();
|
||||||
}
|
}
|
||||||
|
self.allocator.destroy(self);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,22 +8,21 @@ pub const ConsoleCommand = struct {
|
||||||
pub const Console = struct {
|
pub const Console = struct {
|
||||||
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This(), "core.Console");
|
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This(), "core.Console");
|
||||||
|
|
||||||
allocator: std.mem.Allocator = undefined,
|
allocator: std.mem.Allocator,
|
||||||
arena: std.heap.ArenaAllocator = undefined,
|
arena: std.heap.ArenaAllocator,
|
||||||
|
|
||||||
commandMap: std.StringHashMapUnmanaged(ConsoleCommand) = .{},
|
commandMap: std.StringHashMapUnmanaged(ConsoleCommand) = .{},
|
||||||
|
|
||||||
pub fn init(self: *@This(), allocator: std.mem.Allocator, first: bool) !void {
|
pub fn create(allocator: std.mem.Allocator) !*@This() {
|
||||||
if (!first) {
|
const self = try allocator.create(@This());
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.* = .{
|
self.* = .{
|
||||||
.arena = std.heap.ArenaAllocator.init(allocator),
|
.arena = std.heap.ArenaAllocator.init(allocator),
|
||||||
.allocator = allocator,
|
.allocator = allocator,
|
||||||
};
|
};
|
||||||
|
|
||||||
core.engine_logs("console system created");
|
core.engine_logs("console system created");
|
||||||
|
|
||||||
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn addConsoleCommand(self: *@This(), funcName: []const u8, func: ConsoleFunc) !void {
|
pub fn addConsoleCommand(self: *@This(), funcName: []const u8, func: ConsoleFunc) !void {
|
||||||
|
|
@ -57,9 +56,10 @@ pub const Console = struct {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *@This()) void {
|
pub fn destroy(self: *@This()) void {
|
||||||
self.arena.deinit();
|
self.arena.deinit();
|
||||||
self.commandMap.deinit(self.allocator);
|
self.commandMap.deinit(self.allocator);
|
||||||
|
self.allocator.destroy(self);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,8 +29,6 @@ pub const debugLine = debug_draw.debugLine;
|
||||||
|
|
||||||
pub const engineTime = @import("engineTime.zig");
|
pub const engineTime = @import("engineTime.zig");
|
||||||
pub const engineObject = @import("engineObject.zig");
|
pub const engineObject = @import("engineObject.zig");
|
||||||
pub const EngineObjectOpts = engineObject.EngineObjectOpts;
|
|
||||||
pub const ObjectOpts = engineObject.EngineObjectOpts;
|
|
||||||
pub const EngineObjectVTable = engineObject.EngineObjectVTable;
|
pub const EngineObjectVTable = engineObject.EngineObjectVTable;
|
||||||
pub const MakeTypeName = engineObject.MakeTypeName;
|
pub const MakeTypeName = engineObject.MakeTypeName;
|
||||||
pub const PatchStruct = engineObject.PatchStruct;
|
pub const PatchStruct = engineObject.PatchStruct;
|
||||||
|
|
@ -172,7 +170,7 @@ pub const packer = @import("packer");
|
||||||
|
|
||||||
pub const StackCompactor = stacks.StackCompactor;
|
pub const StackCompactor = stacks.StackCompactor;
|
||||||
|
|
||||||
pub var staticsInitialized = false;
|
var staticsInitialized = false;
|
||||||
var gEngine: *Engine = undefined;
|
var gEngine: *Engine = undefined;
|
||||||
pub const PackerFS = packer.PackerFS;
|
pub const PackerFS = packer.PackerFS;
|
||||||
var gPackerFS: *PackerFS = undefined;
|
var gPackerFS: *PackerFS = undefined;
|
||||||
|
|
@ -274,6 +272,8 @@ pub fn maybeInitPackerFs(allocator: std.mem.Allocator) !void {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn start_module_(map: *SpecVariantMap, args: anytype, 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 (map.get("utility")) |x| {
|
||||||
if (x.boolean == true) {
|
if (x.boolean == true) {
|
||||||
engine_logs("utility mode - no gui");
|
engine_logs("utility mode - no gui");
|
||||||
|
|
@ -297,7 +297,8 @@ pub fn start_module_(map: *SpecVariantMap, args: anytype, allocator: std.mem.All
|
||||||
|
|
||||||
gEngine = try allocator.create(Engine);
|
gEngine = try allocator.create(Engine);
|
||||||
gEngine.* = try Engine.init(allocator);
|
gEngine.* = try Engine.init(allocator);
|
||||||
staticsInitialized = true;
|
_ = try createObject(ModuleLoader, .{});
|
||||||
|
try console.start();
|
||||||
|
|
||||||
const engineName = try std.fmt.allocPrint(allocator, "{s}Engine.ini", .{name});
|
const engineName = try std.fmt.allocPrint(allocator, "{s}Engine.ini", .{name});
|
||||||
defer allocator.free(engineName);
|
defer allocator.free(engineName);
|
||||||
|
|
@ -308,15 +309,14 @@ pub fn start_module_(map: *SpecVariantMap, args: anytype, allocator: std.mem.All
|
||||||
try logging.setupLogging(gEngine);
|
try logging.setupLogging(gEngine);
|
||||||
}
|
}
|
||||||
|
|
||||||
try algorithm.string_pool.setup(allocator);
|
try ecs.setup(allocator);
|
||||||
gEngine.stringContext = algorithm.string_pool.gStringContext;
|
|
||||||
|
_ = try gEngine.createObject(scene.SceneSystem, .{ .can_tick = true });
|
||||||
|
|
||||||
|
try algorithm.string_pool.setup(allocator);
|
||||||
|
|
||||||
_ = 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 createObject(GameObjectSystem, .{ .can_tick = true });
|
||||||
_ = try createObject(inputs.InputStack, .{});
|
_ = try inputs.initInputStack();
|
||||||
_ = try createObject(console.Console, .{});
|
|
||||||
|
|
||||||
// components define
|
// components define
|
||||||
try ecs.defineComponentList(ComponentList, allocator);
|
try ecs.defineComponentList(ComponentList, allocator);
|
||||||
|
|
@ -328,7 +328,6 @@ pub fn setupFromModule(__args: ModuleLoaderArgs) !void {
|
||||||
gEngine = __args.engine;
|
gEngine = __args.engine;
|
||||||
gPackerFS = __args.packerFS;
|
gPackerFS = __args.packerFS;
|
||||||
algorithm.names.gRegistry = __args.nameRegistry;
|
algorithm.names.gRegistry = __args.nameRegistry;
|
||||||
algorithm.string_pool.gStringContext = gEngine.stringContext;
|
|
||||||
logging.setupLoggingFromModule();
|
logging.setupLoggingFromModule();
|
||||||
staticsInitialized = true;
|
staticsInitialized = true;
|
||||||
|
|
||||||
|
|
@ -526,11 +525,7 @@ pub fn startup_getArgs(p_allocator: *anyopaque) ModuleLoaderArgs {
|
||||||
pub fn modulePreamble(p_allocator: *anyopaque, p_a: ?*anyopaque) !std.mem.Allocator {
|
pub fn modulePreamble(p_allocator: *anyopaque, p_a: ?*anyopaque) !std.mem.Allocator {
|
||||||
const args = startup_getArgs(p_a.?);
|
const args = startup_getArgs(p_a.?);
|
||||||
const allocator = startup_getAllocator(p_allocator);
|
const allocator = startup_getAllocator(p_allocator);
|
||||||
|
try setupFromModule(args);
|
||||||
if (comptime !BuildOption("static_build")) {
|
|
||||||
try setupFromModule(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
return allocator;
|
return allocator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -614,7 +609,3 @@ pub fn itof32(i: anytype) f32 {
|
||||||
pub fn itof64(i: anytype) f32 {
|
pub fn itof64(i: anytype) f32 {
|
||||||
return @as(f32, @floatFromInt(i));
|
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 var NeonObjectTable = core.EngineObjectVTable.from(@This(), "core.EcsRegistry");
|
||||||
|
|
||||||
pub fn init(self: *@This(), allocator: std.mem.Allocator, first: bool) !void {
|
pub fn init(allocator: std.mem.Allocator) !*@This() {
|
||||||
if (!first) {
|
const self = try allocator.create(@This());
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.* = .{
|
self.* = .{
|
||||||
.allocator = allocator,
|
.allocator = allocator,
|
||||||
.baseSet = BaseSet.init(allocator),
|
.baseSet = BaseSet.init(allocator),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn registerContainer(self: *@This(), ref: EcsContainerRef, _containerName: core.Name) !void {
|
pub fn registerContainer(self: *@This(), ref: EcsContainerRef, _containerName: core.Name) !void {
|
||||||
|
|
@ -279,11 +279,13 @@ pub const EcsRegistry = struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *@This()) void {
|
pub fn deinit(self: *@This()) void {
|
||||||
// this should never work... wtf?
|
self.destroy();
|
||||||
// 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| {
|
for (self.systems.items) |ref| {
|
||||||
ref.vtable.destroy(ref.ptr);
|
ref.vtable.destroy(ref.ptr);
|
||||||
}
|
}
|
||||||
|
|
@ -298,6 +300,7 @@ pub const EcsRegistry = struct {
|
||||||
self.containers.deinit(self.allocator);
|
self.containers.deinit(self.allocator);
|
||||||
self.containerNames.deinit(self.allocator);
|
self.containerNames.deinit(self.allocator);
|
||||||
self.containersByName.deinit(self.allocator);
|
self.containersByName.deinit(self.allocator);
|
||||||
|
self.allocator.destroy(self);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ const time = @import("engineTime.zig");
|
||||||
const core = @import("core.zig");
|
const core = @import("core.zig");
|
||||||
const jobs = @import("jobs.zig");
|
const jobs = @import("jobs.zig");
|
||||||
const math = @import("math.zig");
|
const math = @import("math.zig");
|
||||||
const builtin = @import("builtin");
|
|
||||||
const pscopes = core.algorithm.pscopes;
|
const pscopes = core.algorithm.pscopes;
|
||||||
|
|
||||||
const tracy = @import("tracy").t;
|
const tracy = @import("tracy").t;
|
||||||
|
|
@ -92,9 +91,6 @@ pub const Engine = struct {
|
||||||
calibrationPeriod: f64 = 1.0, // in seconds
|
calibrationPeriod: f64 = 1.0, // in seconds
|
||||||
first: bool = true,
|
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() {
|
pub fn init(allocator: std.mem.Allocator) !@This() {
|
||||||
const rv = Engine{
|
const rv = Engine{
|
||||||
.allocator = allocator,
|
.allocator = allocator,
|
||||||
|
|
@ -130,7 +126,9 @@ pub const Engine = struct {
|
||||||
var i: i32 = @intCast(self.destroyListCore.items.len - 1);
|
var i: i32 = @intCast(self.destroyListCore.items.len - 1);
|
||||||
while (i >= 0) : (i -= 1) {
|
while (i >= 0) : (i -= 1) {
|
||||||
const item = self.destroyListCore.items[@as(usize, @intCast(i))];
|
const item = self.destroyListCore.items[@as(usize, @intCast(i))];
|
||||||
self.destroyObject(item);
|
if (item.vtable.deinit_func) |deinitFn| {
|
||||||
|
deinitFn(item.ptr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.destroyListCore.deinit(self.allocator);
|
self.destroyListCore.deinit(self.allocator);
|
||||||
|
|
@ -161,10 +159,6 @@ pub const Engine = struct {
|
||||||
return @ptrCast(@alignCast(rv));
|
return @ptrCast(@alignCast(rv));
|
||||||
}
|
}
|
||||||
|
|
||||||
const DebugSlack = struct {
|
|
||||||
slack: [1024 * 64]u8 align(16) = undefined,
|
|
||||||
};
|
|
||||||
|
|
||||||
// creates an engine object using the engine's allocator.
|
// creates an engine object using the engine's allocator.
|
||||||
pub fn createObjectVTable(self: *@This(), vtable: *core.EngineObjectVTable, params: NeonObjectParams) !*anyopaque {
|
pub fn createObjectVTable(self: *@This(), vtable: *core.EngineObjectVTable, params: NeonObjectParams) !*anyopaque {
|
||||||
if (self.createObjectLock) {
|
if (self.createObjectLock) {
|
||||||
|
|
@ -176,17 +170,7 @@ pub const Engine = struct {
|
||||||
self.createObjectLock = true;
|
self.createObjectLock = true;
|
||||||
defer self.createObjectLock = false;
|
defer self.createObjectLock = false;
|
||||||
const newIndex = self.engineObjects.items.len;
|
const newIndex = self.engineObjects.items.len;
|
||||||
var newObjectPtr: *anyopaque = undefined; //self.allocator.create(DebugSlack);
|
const newObjectPtr = try vtable.init_func(self.allocator); // call this thing with the special allocator that adds vtable. slackSize to it.
|
||||||
|
|
||||||
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{
|
const newObjectRef = EngineObjectRef{
|
||||||
.ptr = @as(*anyopaque, @ptrCast(newObjectPtr)),
|
.ptr = @as(*anyopaque, @ptrCast(newObjectPtr)),
|
||||||
|
|
@ -372,29 +356,14 @@ pub const Engine = struct {
|
||||||
self.destroyDependents();
|
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 {
|
fn destroyDependents(self: *@This()) void {
|
||||||
if (self.destroyListSimple.items.len > 0) {
|
if (self.destroyListSimple.items.len > 0) {
|
||||||
var i: i32 = @intCast(self.destroyListSimple.items.len - 1);
|
var i: i32 = @intCast(self.destroyListSimple.items.len - 1);
|
||||||
while (i >= 0) : (i -= 1) {
|
while (i >= 0) : (i -= 1) {
|
||||||
const item = self.destroyListSimple.items[@as(usize, @intCast(i))];
|
const item = self.destroyListSimple.items[@as(usize, @intCast(i))];
|
||||||
self.destroyObject(item);
|
if (item.vtable.deinit_func) |deinitFn| {
|
||||||
|
deinitFn(item.ptr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.dependentsDestroyed.store(true, .seq_cst);
|
self.dependentsDestroyed.store(true, .seq_cst);
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,10 @@ pub fn updateEngineVTable(comptime T: type) void {
|
||||||
|
|
||||||
vtable.* = T.NeonObjectTable;
|
vtable.* = T.NeonObjectTable;
|
||||||
vtable.version = version + 1;
|
vtable.version = version + 1;
|
||||||
|
|
||||||
|
if (@hasDecl(T, "objectReload")) {
|
||||||
|
core.get(T).objectReload();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn PatchStruct(comptime T: type, p: *T, old: []const FieldInfo) void {
|
pub fn PatchStruct(comptime T: type, p: *T, old: []const FieldInfo) void {
|
||||||
|
|
@ -163,8 +167,7 @@ pub const EngineObjectVTable = struct {
|
||||||
|
|
||||||
singletonName: ?[]const u8 = null,
|
singletonName: ?[]const u8 = null,
|
||||||
|
|
||||||
// new init_function passes in an already created object
|
init_func: *const fn (std.mem.Allocator) EngineDataEventError!*anyopaque,
|
||||||
init_func: *const fn (*anyopaque, std.mem.Allocator, bool) EngineDataEventError!void,
|
|
||||||
tick_func: ?*const fn (*anyopaque, f64) void = null,
|
tick_func: ?*const fn (*anyopaque, f64) void = null,
|
||||||
engineDraw_func: ?*const fn (*anyopaque, f64) void = null,
|
engineDraw_func: ?*const fn (*anyopaque, f64) void = null,
|
||||||
preTick_func: ?*const fn (*anyopaque, f64) EngineDataEventError!void = null,
|
preTick_func: ?*const fn (*anyopaque, f64) EngineDataEventError!void = null,
|
||||||
|
|
@ -268,10 +271,11 @@ pub const EngineObjectVTable = struct {
|
||||||
|
|
||||||
if (@hasDecl(TargetType, "init")) {
|
if (@hasDecl(TargetType, "init")) {
|
||||||
const wrappedInit = struct {
|
const wrappedInit = struct {
|
||||||
pub fn func(p: *anyopaque, allocator: std.mem.Allocator, first: bool) EngineDataEventError!void {
|
const funcFind: @TypeOf(@field(TargetType, "init")) = @field(TargetType, "init");
|
||||||
const newObject: *TargetType = @ptrCast(@alignCast(p)); // funcFind(allocator) catch return error.BadInit;
|
|
||||||
newObject.init(allocator, first) catch return error.BadInit;
|
pub fn func(allocator: std.mem.Allocator) EngineDataEventError!*anyopaque {
|
||||||
// return @as(*anyopaque, @ptrCast(newObject));
|
const newObject = funcFind(allocator) catch return error.BadInit;
|
||||||
|
return @as(*anyopaque, @ptrCast(newObject));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -280,10 +284,11 @@ pub const EngineObjectVTable = struct {
|
||||||
|
|
||||||
if (@hasDecl(TargetType, "create")) {
|
if (@hasDecl(TargetType, "create")) {
|
||||||
const wrappedInit = struct {
|
const wrappedInit = struct {
|
||||||
pub fn func(p: *anyopaque, allocator: std.mem.Allocator, first: bool) EngineDataEventError!void {
|
const funcFind: @TypeOf(@field(TargetType, "create")) = @field(TargetType, "create");
|
||||||
const newObject: *TargetType = @ptrCast(@alignCast(p)); // funcFind(allocator) catch return error.BadInit;
|
|
||||||
newObject.create(allocator, first) catch return error.BadInit;
|
pub fn func(allocator: std.mem.Allocator) EngineDataEventError!*anyopaque {
|
||||||
// return @as(*anyopaque, @ptrCast(newObject));
|
const newObject = funcFind(allocator) catch return error.BadInit;
|
||||||
|
return @as(*anyopaque, @ptrCast(newObject));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,12 +5,8 @@ const pscopes = core.algorithm.pscopes;
|
||||||
|
|
||||||
// returns time since engine started in nanoseconds
|
// returns time since engine started in nanoseconds
|
||||||
pub fn getEngineTime() f64 {
|
pub fn getEngineTime() f64 {
|
||||||
if (core.staticsInitialized) {
|
const read = core.getEngine().rootTimer.read();
|
||||||
const read = core.getEngine().rootTimer.read();
|
return @as(f64, @floatFromInt(read)) / std.time.ns_per_s;
|
||||||
return @as(f64, @floatFromInt(read)) / std.time.ns_per_s;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns a pscopes.TimingScope for the current time.
|
// returns a pscopes.TimingScope for the current time.
|
||||||
|
|
|
||||||
|
|
@ -121,23 +121,22 @@ fn dllChangedCallback(pathChanged: []const u8, ctx: ?*anyopaque) void {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const ModuleLoader = struct {
|
pub const ModuleLoader = struct {
|
||||||
backingAllocator: std.mem.Allocator = undefined,
|
backingAllocator: std.mem.Allocator,
|
||||||
arena: std.heap.ArenaAllocator = undefined,
|
arena: std.heap.ArenaAllocator,
|
||||||
loadedModules: std.ArrayListUnmanaged(*LoadedModule) = .{},
|
loadedModules: std.ArrayListUnmanaged(*LoadedModule) = .{},
|
||||||
watchInitialized: bool = false,
|
watchInitialized: bool = false,
|
||||||
watchInitializeFn: ?*const fn () void = null,
|
watchInitializeFn: ?*const fn () void = null,
|
||||||
|
|
||||||
pub var NeonObjectTable = core.EngineObjectVTable.from(@This(), "core.ModuleLoader");
|
pub var NeonObjectTable = core.EngineObjectVTable.from(@This(), "core.ModuleLoader");
|
||||||
|
pub fn create(allocator: std.mem.Allocator) !*@This() {
|
||||||
pub fn init(self: *@This(), allocator: std.mem.Allocator, first: bool) !void {
|
const self = try allocator.create(@This());
|
||||||
if (!first) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.* = .{
|
self.* = .{
|
||||||
.backingAllocator = allocator,
|
.backingAllocator = allocator,
|
||||||
.arena = std.heap.ArenaAllocator.init(allocator),
|
.arena = std.heap.ArenaAllocator.init(allocator),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn addModule(self: *@This(), moduleName: []const u8) !void {
|
pub fn addModule(self: *@This(), moduleName: []const u8) !void {
|
||||||
|
|
@ -170,7 +169,6 @@ pub const ModuleLoader = struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
try core.fs().addFileChangedCallback(libFileName, dllChangedCallback, loaded);
|
try core.fs().addFileChangedCallback(libFileName, dllChangedCallback, loaded);
|
||||||
core.engine_log("[ModuleLoader]: addFileChangedCallback '{s}'", .{libFileName});
|
|
||||||
|
|
||||||
try self.loadedModules.append(self.arena.allocator(), loaded);
|
try self.loadedModules.append(self.arena.allocator(), loaded);
|
||||||
}
|
}
|
||||||
|
|
@ -216,9 +214,10 @@ pub const ModuleLoader = struct {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *@This()) void {
|
pub fn destroy(self: *@This()) void {
|
||||||
// std.fs.cwd().deleteTree(".modulecache") catch {};
|
// std.fs.cwd().deleteTree(".modulecache") catch {};
|
||||||
self.arena.deinit();
|
self.arena.deinit();
|
||||||
|
self.backingAllocator.destroy(self);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -71,20 +71,21 @@ pub const GameObjectSystem = struct {
|
||||||
// this is the new one, GameObjectList should be deleted after this passes initial usability
|
// this is the new one, GameObjectList should be deleted after this passes initial usability
|
||||||
pub var NeonObjectTable = core.EngineObjectVTable.from(@This(), "core.GameObjectSystem");
|
pub var NeonObjectTable = core.EngineObjectVTable.from(@This(), "core.GameObjectSystem");
|
||||||
|
|
||||||
allocator: std.mem.Allocator = undefined,
|
allocator: std.mem.Allocator,
|
||||||
objectDefinitions: std.AutoHashMapUnmanaged(u32, GameObjectInterfaceVTable) = .{},
|
objectDefinitions: std.AutoHashMapUnmanaged(u32, GameObjectInterfaceVTable) = .{},
|
||||||
typesArena: std.heap.ArenaAllocator = undefined,
|
typesArena: std.heap.ArenaAllocator,
|
||||||
|
|
||||||
objectSpawnEvents: std.ArrayListUnmanaged(SpawnEvent) = .{},
|
objectSpawnEvents: std.ArrayListUnmanaged(SpawnEvent) = .{},
|
||||||
|
|
||||||
pub fn init(self: *@This(), allocator: std.mem.Allocator, first: bool) !void {
|
pub fn create(allocator: std.mem.Allocator) !*@This() {
|
||||||
if (!first)
|
const self = try allocator.create(@This());
|
||||||
return;
|
|
||||||
|
|
||||||
self.* = .{
|
self.* = .{
|
||||||
.allocator = allocator,
|
.allocator = allocator,
|
||||||
.typesArena = std.heap.ArenaAllocator.init(self.allocator),
|
.typesArena = std.heap.ArenaAllocator.init(self.allocator),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn spawnObject(self: *@This(), comptime T: type, objectName: []const u8, parameters: SpawnParameters) !*T {
|
pub fn spawnObject(self: *@This(), comptime T: type, objectName: []const u8, parameters: SpawnParameters) !*T {
|
||||||
|
|
@ -176,8 +177,9 @@ pub const GameObjectSystem = struct {
|
||||||
_ = dt;
|
_ = dt;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *@This()) void {
|
pub fn destroy(self: *@This()) void {
|
||||||
self.typesArena.deinit();
|
self.typesArena.deinit();
|
||||||
|
self.allocator.destroy(self);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -574,11 +574,11 @@ pub const BindingLayer = struct {
|
||||||
|
|
||||||
// not gonna actually deal with layers right now
|
// not gonna actually deal with layers right now
|
||||||
pub const InputStack = struct {
|
pub const InputStack = struct {
|
||||||
allocator: std.mem.Allocator = undefined,
|
allocator: std.mem.Allocator,
|
||||||
|
|
||||||
active: ?*BindingLayer = undefined,
|
active: ?*BindingLayer,
|
||||||
bindingStack: std.ArrayListUnmanaged(*BindingLayer) = .{},
|
bindingStack: std.ArrayListUnmanaged(*BindingLayer) = .{},
|
||||||
arena: std.heap.ArenaAllocator = undefined,
|
arena: std.heap.ArenaAllocator,
|
||||||
|
|
||||||
keysDown: std.AutoHashMapUnmanaged(Key, bool) = .{},
|
keysDown: std.AutoHashMapUnmanaged(Key, bool) = .{},
|
||||||
|
|
||||||
|
|
@ -591,10 +591,8 @@ pub const InputStack = struct {
|
||||||
|
|
||||||
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This(), "core.InputStack");
|
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This(), "core.InputStack");
|
||||||
|
|
||||||
pub fn init(self: *@This(), allocator: std.mem.Allocator, first: bool) !void {
|
pub fn init(allocator: std.mem.Allocator) !*@This() {
|
||||||
if (!first) {
|
const self = try allocator.create(@This());
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.* = .{
|
self.* = .{
|
||||||
.allocator = allocator,
|
.allocator = allocator,
|
||||||
|
|
@ -603,6 +601,8 @@ pub const InputStack = struct {
|
||||||
};
|
};
|
||||||
|
|
||||||
core.EngineObject(@This()).gInstance = self;
|
core.EngineObject(@This()).gInstance = self;
|
||||||
|
|
||||||
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn updatePreviousInputs(self: *@This()) void {
|
pub fn updatePreviousInputs(self: *@This()) void {
|
||||||
|
|
@ -716,6 +716,7 @@ pub const InputStack = struct {
|
||||||
if (self.active) |active| {
|
if (self.active) |active| {
|
||||||
active.destroy();
|
active.destroy();
|
||||||
}
|
}
|
||||||
|
self.allocator.destroy(self);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -192,13 +192,13 @@ pub const FileLog = struct {
|
||||||
pub const LoggerSys = struct {
|
pub const LoggerSys = struct {
|
||||||
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This(), "core.LoggerSys");
|
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This(), "core.LoggerSys");
|
||||||
|
|
||||||
writeOutBuffer: std.ArrayList(u8) = .{},
|
writeOutBuffer: std.ArrayList(u8),
|
||||||
flushBuffer: std.ArrayList(u8) = .{},
|
flushBuffer: std.ArrayList(u8),
|
||||||
allocator: std.mem.Allocator = undefined,
|
allocator: std.mem.Allocator,
|
||||||
logFilePath: []const u8 = "none",
|
logFilePath: []const u8,
|
||||||
logFile: std.fs.File = undefined,
|
logFile: std.fs.File,
|
||||||
consoleFile: std.fs.File = undefined,
|
consoleFile: std.fs.File,
|
||||||
writerBuffer: []u8 = undefined,
|
writerBuffer: []u8,
|
||||||
lock: std.Thread.Mutex = .{},
|
lock: std.Thread.Mutex = .{},
|
||||||
flushing: std.atomic.Value(bool) = std.atomic.Value(bool).init(false),
|
flushing: std.atomic.Value(bool) = std.atomic.Value(bool).init(false),
|
||||||
|
|
||||||
|
|
@ -306,14 +306,12 @@ pub const LoggerSys = struct {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init(self: *@This(), allocator: std.mem.Allocator, first: bool) !void {
|
pub fn init(allocator: std.mem.Allocator) !*@This() {
|
||||||
if (!first) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const cwd = std.fs.cwd();
|
const cwd = std.fs.cwd();
|
||||||
const ofile = std.fmt.allocPrint(allocator, core.DefaultSavePath ++ "/{s}", .{"Session_Log.txt"}) catch unreachable;
|
const ofile = std.fmt.allocPrint(allocator, core.DefaultSavePath ++ "/{s}", .{"Session_Log.txt"}) catch unreachable;
|
||||||
cwd.makePath(core.DefaultSavePath) catch unreachable;
|
cwd.makePath(core.DefaultSavePath) catch unreachable;
|
||||||
|
|
||||||
|
const self = try allocator.create(@This());
|
||||||
self.* = @This(){
|
self.* = @This(){
|
||||||
.allocator = allocator,
|
.allocator = allocator,
|
||||||
.writeOutBuffer = std.ArrayList(u8).initCapacity(allocator, LogBufferSize) catch unreachable,
|
.writeOutBuffer = std.ArrayList(u8).initCapacity(allocator, LogBufferSize) catch unreachable,
|
||||||
|
|
@ -323,6 +321,8 @@ pub const LoggerSys = struct {
|
||||||
.logFile = cwd.createFile(ofile, .{}) catch unreachable,
|
.logFile = cwd.createFile(ofile, .{}) catch unreachable,
|
||||||
.consoleFile = std.fs.File.stdout(),
|
.consoleFile = std.fs.File.stdout(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *@This()) void {
|
pub fn deinit(self: *@This()) void {
|
||||||
|
|
@ -333,6 +333,8 @@ pub const LoggerSys = struct {
|
||||||
|
|
||||||
self.writeOutBuffer.deinit(self.allocator);
|
self.writeOutBuffer.deinit(self.allocator);
|
||||||
self.flushBuffer.deinit(self.allocator);
|
self.flushBuffer.deinit(self.allocator);
|
||||||
|
|
||||||
|
self.allocator.destroy(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn processEvents(self: *@This(), frameNumber: u64) core.EngineDataEventError!void {
|
pub fn processEvents(self: *@This(), frameNumber: u64) core.EngineDataEventError!void {
|
||||||
|
|
|
||||||
|
|
@ -296,9 +296,9 @@ fn childAllocator() std.mem.Allocator {
|
||||||
pub const SceneSystem = struct {
|
pub const SceneSystem = struct {
|
||||||
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This(), "core.SceneSystem");
|
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This(), "core.SceneSystem");
|
||||||
|
|
||||||
allocator: std.mem.Allocator = undefined,
|
allocator: std.mem.Allocator,
|
||||||
dynamicObjects: ArrayListUnmanaged(core.ObjectHandle) = .{},
|
dynamicObjects: ArrayListUnmanaged(core.ObjectHandle) = .{},
|
||||||
childrenArena: std.heap.ArenaAllocator = undefined,
|
childrenArena: std.heap.ArenaAllocator,
|
||||||
tickCount: u32 = 0,
|
tickCount: u32 = 0,
|
||||||
sceneObjectContainer: *SceneObjectSet = undefined,
|
sceneObjectContainer: *SceneObjectSet = undefined,
|
||||||
|
|
||||||
|
|
@ -385,11 +385,8 @@ pub const SceneSystem = struct {
|
||||||
pub const MaxWorkerCount = 24;
|
pub const MaxWorkerCount = 24;
|
||||||
|
|
||||||
// ----- NeonObject interace ----
|
// ----- NeonObject interace ----
|
||||||
pub fn init(self: *@This(), allocator: std.mem.Allocator, first: bool) !void {
|
pub fn init(allocator: std.mem.Allocator) !*@This() {
|
||||||
if (!first) {
|
const self = try allocator.create(@This());
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.* = .{
|
self.* = .{
|
||||||
.allocator = allocator,
|
.allocator = allocator,
|
||||||
.childrenArena = std.heap.ArenaAllocator.init(allocator),
|
.childrenArena = std.heap.ArenaAllocator.init(allocator),
|
||||||
|
|
@ -404,6 +401,8 @@ pub const SceneSystem = struct {
|
||||||
try self.cachedOutputs.append(self.allocator, .{});
|
try self.cachedOutputs.append(self.allocator, .{});
|
||||||
try self.writeOutList.append(self.allocator, .{});
|
try self.writeOutList.append(self.allocator, .{});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getOutputList(self: *@This(), threadId: u32) !*std.ArrayList(usize) {
|
pub fn getOutputList(self: *@This(), threadId: u32) !*std.ArrayList(usize) {
|
||||||
|
|
@ -447,6 +446,7 @@ pub const SceneSystem = struct {
|
||||||
Scene.SceneObjectContainer.destroy();
|
Scene.SceneObjectContainer.destroy();
|
||||||
self.cachedOutputs.deinit(self.allocator);
|
self.cachedOutputs.deinit(self.allocator);
|
||||||
self.writeOutList.deinit(self.allocator);
|
self.writeOutList.deinit(self.allocator);
|
||||||
|
self.allocator.destroy(self);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,22 @@
|
||||||
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This(), "testing.sampleSubsystem");
|
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This(), "testing.sampleSubsystem");
|
||||||
|
|
||||||
allocator: std.mem.Allocator = undefined,
|
allocator: std.mem.Allocator,
|
||||||
scene: *anyopaque = undefined,
|
scene: *anyopaque,
|
||||||
setPositionPtr: *const anyopaque = undefined,
|
setPositionPtr: *const anyopaque,
|
||||||
|
|
||||||
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.* = .{
|
self.* = .{
|
||||||
.allocator = allocator,
|
.allocator = allocator,
|
||||||
|
.scene = undefined,
|
||||||
|
.setPositionPtr = undefined,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn destroy(self: *@This()) void {
|
||||||
|
self.allocator.destroy(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
const exampleScene = @import("exampleScene.zig");
|
const exampleScene = @import("exampleScene.zig");
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
const core = @import("core");
|
||||||
|
|
||||||
const dependencyList = [_][]const u8{
|
const dependencyList = [_][]const u8{
|
||||||
"core",
|
"core",
|
||||||
|
|
@ -13,17 +14,15 @@ pub fn build(b: *std.Build) void {
|
||||||
const optimize = b.standardOptimizeOption(.{});
|
const optimize = b.standardOptimizeOption(.{});
|
||||||
const static_build = b.option(bool, "static_build", "builds backlog dependencies for static linking") orelse false;
|
const static_build = b.option(bool, "static_build", "builds backlog dependencies for static linking") orelse false;
|
||||||
|
|
||||||
const mod = b.addModule("imgui", .{
|
const engineMod = core.MakeModLib(b, .{
|
||||||
|
.name = "imgui",
|
||||||
.target = target,
|
.target = target,
|
||||||
.optimize = optimize,
|
.optimize = optimize,
|
||||||
.root_source_file = b.path("src/imgui.zig"),
|
.static_build = static_build,
|
||||||
});
|
});
|
||||||
|
|
||||||
for (dependencyList) |depName| {
|
engineMod.install();
|
||||||
const dep = b.dependency(depName, .{ .target = target, .optimize = optimize, .static_build = static_build });
|
engineMod.linkModLibs(&dependencyList);
|
||||||
const dep_mod = dep.module(depName);
|
|
||||||
mod.addImport(depName, dep_mod);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ========== tests ==========
|
// ========== tests ==========
|
||||||
const tests = b.addTest(.{
|
const tests = b.addTest(.{
|
||||||
|
|
@ -35,7 +34,7 @@ pub fn build(b: *std.Build) void {
|
||||||
});
|
});
|
||||||
const test_step = b.step("test", "run unit tests for imgui");
|
const test_step = b.step("test", "run unit tests for imgui");
|
||||||
|
|
||||||
tests.root_module.addImport("platform", mod);
|
tests.root_module.addImport("platform", engineMod.mod);
|
||||||
const runArtifact = b.addRunArtifact(tests);
|
const runArtifact = b.addRunArtifact(tests);
|
||||||
test_step.dependOn(&runArtifact.step);
|
test_step.dependOn(&runArtifact.step);
|
||||||
b.installArtifact(tests);
|
b.installArtifact(tests);
|
||||||
|
|
|
||||||
|
|
@ -15,13 +15,14 @@ pub const Impl = struct {
|
||||||
};
|
};
|
||||||
|
|
||||||
// renderer plugin
|
// renderer plugin
|
||||||
pub fn init(self: *@This(), allocator: std.mem.Allocator, first: bool) !void {
|
pub fn create(allocator: std.mem.Allocator) !*@This() {
|
||||||
if (!first)
|
const self = try allocator.create(@This());
|
||||||
return;
|
|
||||||
|
|
||||||
self.* = .{
|
self.* = .{
|
||||||
.allocator = allocator,
|
.allocator = allocator,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ImguiArgs = struct { imguiIni: []const u8 = "imgui.ini" };
|
const ImguiArgs = struct { imguiIni: []const u8 = "imgui.ini" };
|
||||||
|
|
@ -108,6 +109,11 @@ pub const Impl = struct {
|
||||||
_ = ig.dockSpaceOverViewport(ig.getMainViewport(), .{ .passthru_central_node = true }, null);
|
_ = ig.dockSpaceOverViewport(ig.getMainViewport(), .{ .passthru_central_node = true }, null);
|
||||||
_ = dt;
|
_ = dt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// renderer plugin
|
||||||
|
pub fn destroy(self: *@This()) void {
|
||||||
|
self.allocator.destroy(self);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
const c = @import("cimgui").c;
|
const c = @import("cimgui").c;
|
||||||
const ig = @import("cimgui");
|
const ig = @import("cimgui");
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
pub var NeonObjectTable = core.EngineObjectVTable.from(@This(), "game.TopBar");
|
pub var NeonObjectTable = core.EngineObjectVTable.from(@This(), "game.TopBar");
|
||||||
|
pub const Slack = core.SlackStruct(@This(), 256);
|
||||||
|
|
||||||
allocator: std.mem.Allocator,
|
allocator: std.mem.Allocator,
|
||||||
arena: std.heap.ArenaAllocator,
|
arena: std.heap.ArenaAllocator,
|
||||||
|
|
@ -6,10 +7,8 @@ windowsMenu: std.ArrayListUnmanaged(*MenuEntry) = .{},
|
||||||
entriesByName: std.AutoHashMapUnmanaged(u32, *MenuEntry) = .{},
|
entriesByName: std.AutoHashMapUnmanaged(u32, *MenuEntry) = .{},
|
||||||
menuOpen: bool = false,
|
menuOpen: bool = false,
|
||||||
|
|
||||||
pub fn init(self: *@This(), allocator: std.mem.Allocator, first: bool) !void {
|
pub fn create(allocator: std.mem.Allocator) !*@This() {
|
||||||
if (!first)
|
const self = try Slack.create(allocator);
|
||||||
return;
|
|
||||||
|
|
||||||
self.* = .{
|
self.* = .{
|
||||||
.allocator = allocator,
|
.allocator = allocator,
|
||||||
.arena = std.heap.ArenaAllocator.init(allocator),
|
.arena = std.heap.ArenaAllocator.init(allocator),
|
||||||
|
|
@ -22,6 +21,8 @@ pub fn init(self: *@This(), allocator: std.mem.Allocator, first: bool) !void {
|
||||||
.ctx = self,
|
.ctx = self,
|
||||||
.windowFunction = windowOpen,
|
.windowFunction = windowOpen,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setEntryOpen(self: *@This(), name: []const u8, open: ?bool) void {
|
pub fn setEntryOpen(self: *@This(), name: []const u8, open: ?bool) void {
|
||||||
|
|
@ -107,6 +108,7 @@ pub fn tick(self: *@This(), dt: f64) void {
|
||||||
|
|
||||||
pub fn destroy(self: *@This()) void {
|
pub fn destroy(self: *@This()) void {
|
||||||
self.arena.deinit();
|
self.arena.deinit();
|
||||||
|
self.allocator.destroy(Slack.fromPtr(self));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const MenuEntry = struct {
|
pub const MenuEntry = struct {
|
||||||
|
|
|
||||||
|
|
@ -6,16 +6,16 @@ consolePressedEnter: bool = false,
|
||||||
|
|
||||||
pub var NeonObjectTable = core.EngineObjectVTable.from(@This(), "extras.consoleWindow");
|
pub var NeonObjectTable = core.EngineObjectVTable.from(@This(), "extras.consoleWindow");
|
||||||
|
|
||||||
pub fn init(self: *@This(), allocator: std.mem.Allocator, first: bool) !void {
|
pub fn init(allocator: std.mem.Allocator) !*@This() {
|
||||||
if (!first)
|
const self = try allocator.create(@This());
|
||||||
return;
|
|
||||||
|
|
||||||
self.* = .{
|
self.* = .{
|
||||||
.allocator = allocator,
|
.allocator = allocator,
|
||||||
.buffer = core.logging.LogBuffer.init(allocator),
|
.buffer = core.logging.LogBuffer.init(allocator),
|
||||||
};
|
};
|
||||||
|
|
||||||
self.setup();
|
self.setup();
|
||||||
|
|
||||||
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setup(self: *@This()) void {
|
pub fn setup(self: *@This()) void {
|
||||||
|
|
@ -65,6 +65,7 @@ pub fn windowOpen(entry: *imgui.utils.MenuEntry, dt: f64) void {
|
||||||
|
|
||||||
pub fn destroy(self: *@This()) void {
|
pub fn destroy(self: *@This()) void {
|
||||||
self.buffer.deinit();
|
self.buffer.deinit();
|
||||||
|
self.allocator.destroy(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
const imgui = @import("../imgui.zig");
|
const imgui = @import("../imgui.zig");
|
||||||
|
|
|
||||||
161
engine/main2.zig
161
engine/main2.zig
|
|
@ -1,161 +0,0 @@
|
||||||
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!", .{});
|
|
||||||
}
|
|
||||||
|
|
@ -1,83 +0,0 @@
|
||||||
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,4 +1,5 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
const core = @import("core");
|
||||||
|
|
||||||
const depList = [_][]const u8{
|
const depList = [_][]const u8{
|
||||||
"core",
|
"core",
|
||||||
|
|
@ -10,17 +11,15 @@ pub fn build(b: *std.Build) void {
|
||||||
const optimize = b.standardOptimizeOption(.{});
|
const optimize = b.standardOptimizeOption(.{});
|
||||||
const static_build = b.option(bool, "static_build", "builds backlog dependencies for static linking") orelse false;
|
const static_build = b.option(bool, "static_build", "builds backlog dependencies for static linking") orelse false;
|
||||||
|
|
||||||
const mod = b.addModule("net", .{
|
const engineMod = core.MakeModLib(b, .{
|
||||||
|
.name = "net",
|
||||||
.target = target,
|
.target = target,
|
||||||
.optimize = optimize,
|
.optimize = optimize,
|
||||||
.root_source_file = b.path("src/net.zig"),
|
.static_build = static_build,
|
||||||
});
|
});
|
||||||
|
|
||||||
for (depList) |depName| {
|
engineMod.install();
|
||||||
const dep = b.dependency(depName, .{ .target = target, .optimize = optimize, .static_build = static_build });
|
engineMod.linkModLibs(&depList);
|
||||||
|
|
||||||
mod.addImport(depName, dep.module(depName));
|
|
||||||
}
|
|
||||||
|
|
||||||
const test_step = b.step("test", "run unit tests for net");
|
const test_step = b.step("test", "run unit tests for net");
|
||||||
const tests = b.addTest(.{
|
const tests = b.addTest(.{
|
||||||
|
|
@ -31,7 +30,7 @@ pub fn build(b: *std.Build) void {
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
tests.root_module.addImport("net", mod);
|
tests.root_module.addImport("net", engineMod.mod);
|
||||||
const runArtifact = b.addRunArtifact(tests);
|
const runArtifact = b.addRunArtifact(tests);
|
||||||
test_step.dependOn(&runArtifact.step);
|
test_step.dependOn(&runArtifact.step);
|
||||||
b.installArtifact(tests);
|
b.installArtifact(tests);
|
||||||
|
|
|
||||||
|
|
@ -159,9 +159,8 @@ const ENetSessionData = struct {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn create(self: *@This(), allocator: std.mem.Allocator, first: bool) !*@This() {
|
pub fn create(allocator: std.mem.Allocator) !*@This() {
|
||||||
if (!first)
|
const self = try allocator.create(@This());
|
||||||
return;
|
|
||||||
|
|
||||||
self.* = .{
|
self.* = .{
|
||||||
.allocator = allocator,
|
.allocator = allocator,
|
||||||
|
|
@ -400,6 +399,7 @@ pub fn destroy(self: *@This()) void {
|
||||||
self.deadSessions.deinit(self.allocator);
|
self.deadSessions.deinit(self.allocator);
|
||||||
|
|
||||||
enet_mod.deinitialize();
|
enet_mod.deinitialize();
|
||||||
|
self.allocator.destroy(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
const core = @import("core");
|
const core = @import("core");
|
||||||
|
|
|
||||||
|
|
@ -28,14 +28,15 @@ pub const NetEngine = struct {
|
||||||
arena: std.heap.ArenaAllocator,
|
arena: std.heap.ArenaAllocator,
|
||||||
transport: ?TransportRef = null,
|
transport: ?TransportRef = null,
|
||||||
|
|
||||||
pub fn init(self: *@This(), allocator: std.mem.Allocator, first: bool) !*@This() {
|
pub fn init(allocator: std.mem.Allocator) !*@This() {
|
||||||
if (!first)
|
const self = try allocator.create(@This());
|
||||||
return;
|
|
||||||
|
|
||||||
self.* = @This(){
|
self.* = @This(){
|
||||||
.allocator = allocator,
|
.allocator = allocator,
|
||||||
.arena = std.heap.ArenaAllocator.init(allocator),
|
.arena = std.heap.ArenaAllocator.init(allocator),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn arenaAllocator(self: *@This()) std.mem.Allocator {
|
pub fn arenaAllocator(self: *@This()) std.mem.Allocator {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,9 @@
|
||||||
const std = @import("std");
|
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
|
// very tiny, not intended to build anything just to run tests linked with libc
|
||||||
pub fn build(b: *std.Build) void {
|
pub fn build(b: *std.Build) void {
|
||||||
|
|
@ -6,18 +11,18 @@ pub fn build(b: *std.Build) void {
|
||||||
const optimize = b.standardOptimizeOption(.{});
|
const optimize = b.standardOptimizeOption(.{});
|
||||||
const static_build = b.option(bool, "static_build", "builds backlog dependencies for static linking") orelse false;
|
const static_build = b.option(bool, "static_build", "builds backlog dependencies for static linking") orelse false;
|
||||||
|
|
||||||
const mod = b.addModule("papyrus", .{
|
const engineMod = core.MakeModLib(b, .{
|
||||||
|
.name = "papyrus",
|
||||||
.target = target,
|
.target = target,
|
||||||
.optimize = optimize,
|
.optimize = optimize,
|
||||||
.link_libc = true,
|
.static_build = static_build,
|
||||||
.root_source_file = b.path("src/papyrus.zig"),
|
|
||||||
});
|
});
|
||||||
mod.addIncludePath(b.path("src/"));
|
engineMod.lib.linkLibC();
|
||||||
mod.addCSourceFile(.{ .file = b.path("src/compat.cpp") });
|
|
||||||
|
|
||||||
const core_dep = b.dependency("core", .{ .target = target, .optimize = optimize, .static_build = static_build });
|
engineMod.install();
|
||||||
|
engineMod.linkModLibs(&depList);
|
||||||
mod.addImport("core", core_dep.module("core"));
|
engineMod.addIncludePath("src/");
|
||||||
|
engineMod.lib.addCSourceFile(.{ .file = b.path("src/compat.cpp"), .flags = &.{} });
|
||||||
|
|
||||||
// Creates a step for unit testing.
|
// Creates a step for unit testing.
|
||||||
const main_tests = b.addTest(.{
|
const main_tests = b.addTest(.{
|
||||||
|
|
@ -29,10 +34,9 @@ pub fn build(b: *std.Build) void {
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
main_tests.root_module.addImport("core", core_dep.module("core"));
|
main_tests.root_module.addImport("papyrus", engineMod.mod);
|
||||||
main_tests.root_module.addImport("papyrus", mod);
|
|
||||||
main_tests.root_module.addIncludePath(b.path("src/"));
|
main_tests.root_module.addIncludePath(b.path("src/"));
|
||||||
|
main_tests.linkLibrary(engineMod.lib);
|
||||||
main_tests.linkLibC();
|
main_tests.linkLibC();
|
||||||
main_tests.linkLibCpp();
|
main_tests.linkLibCpp();
|
||||||
const run_tests = b.addRunArtifact(main_tests);
|
const run_tests = b.addRunArtifact(main_tests);
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ const std = @import("std");
|
||||||
const papyrus = @import("papyrus.zig");
|
const papyrus = @import("papyrus.zig");
|
||||||
const Context = papyrus.Context;
|
const Context = papyrus.Context;
|
||||||
|
|
||||||
const core = @import("core");
|
const core = papyrus.core;
|
||||||
const Vector2i = core.Vector2i;
|
const Vector2i = core.Vector2i;
|
||||||
const Vector2 = core.Vector2;
|
const Vector2 = core.Vector2;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const c = @import("c.zig").c;
|
const c = @import("c.zig").c;
|
||||||
|
|
||||||
const core = @import("core");
|
const core = @import("papyrus.zig").core;
|
||||||
const Vector2i = core.Vector2i;
|
const Vector2i = core.Vector2i;
|
||||||
const Vector2f = core.Vector2f;
|
const Vector2f = core.Vector2f;
|
||||||
const Name = core.Name;
|
const Name = core.Name;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const c = @cImport({
|
pub const c = @cImport({
|
||||||
@cInclude("stb_ttf.h");
|
@cInclude("stb_ttf.h");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -39,7 +39,7 @@ pub const TextEntrySystem = @import("TextEntrySystem.zig");
|
||||||
pub const DrawCommand = @import("DrawCommand.zig");
|
pub const DrawCommand = @import("DrawCommand.zig");
|
||||||
pub const DrawList = std.ArrayList(DrawCommand);
|
pub const DrawList = std.ArrayList(DrawCommand);
|
||||||
|
|
||||||
const core = @import("core");
|
pub const core = @import("core");
|
||||||
const colors = core.colors;
|
const colors = core.colors;
|
||||||
pub const Color = colors.Color;
|
pub const Color = colors.Color;
|
||||||
pub const ColorRGBA8 = colors.RGBA8;
|
pub const ColorRGBA8 = colors.RGBA8;
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,7 @@ const std = @import("std");
|
||||||
const papyrus = @import("papyrus");
|
const papyrus = @import("papyrus");
|
||||||
const localization = papyrus.localization;
|
const localization = papyrus.localization;
|
||||||
const utils = papyrus.utils;
|
const utils = papyrus.utils;
|
||||||
const c = @cImport({
|
const c = papyrus.c;
|
||||||
@cInclude("stb_ttf.h");
|
|
||||||
});
|
|
||||||
|
|
||||||
const PapyrusContext = papyrus.Context;
|
const PapyrusContext = papyrus.Context;
|
||||||
const PapyrusNode = papyrus.Node;
|
const PapyrusNode = papyrus.Node;
|
||||||
const MakeText = localization.MakeText;
|
const MakeText = localization.MakeText;
|
||||||
|
|
@ -14,7 +11,7 @@ const grapvizDotToPng = utils.grapvizDotToPng;
|
||||||
const BmpRenderer = papyrus.BmpRenderer;
|
const BmpRenderer = papyrus.BmpRenderer;
|
||||||
const BmpWriter = BmpRenderer.BmpWriter;
|
const BmpWriter = BmpRenderer.BmpWriter;
|
||||||
|
|
||||||
const core = @import("core");
|
const core = papyrus.core;
|
||||||
const colors = core.colors;
|
const colors = core.colors;
|
||||||
const Color = colors.Color;
|
const Color = colors.Color;
|
||||||
const ColorRGBA8 = colors.ColorRGBA8;
|
const ColorRGBA8 = colors.ColorRGBA8;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,9 @@
|
||||||
const std = @import("std");
|
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
|
// very tiny, not intended to build anything just to run tests linked with libc
|
||||||
pub fn build(b: *std.Build) void {
|
pub fn build(b: *std.Build) void {
|
||||||
|
|
@ -6,25 +11,24 @@ pub fn build(b: *std.Build) void {
|
||||||
const optimize = b.standardOptimizeOption(.{});
|
const optimize = b.standardOptimizeOption(.{});
|
||||||
const static_build = b.option(bool, "static_build", "builds backlog dependencies for static linking") orelse false;
|
const static_build = b.option(bool, "static_build", "builds backlog dependencies for static linking") orelse false;
|
||||||
|
|
||||||
const mod = b.addModule("physics", .{
|
const engineMod = core.MakeModLib(b, .{
|
||||||
|
.name = "physics",
|
||||||
.target = target,
|
.target = target,
|
||||||
.optimize = optimize,
|
.optimize = optimize,
|
||||||
.link_libc = true,
|
.static_build = static_build,
|
||||||
.root_source_file = b.path("src/physics.zig"),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const core_dep = b.dependency("core", .{ .target = target, .optimize = optimize, .static_build = static_build });
|
engineMod.install();
|
||||||
|
engineMod.linkModLibs(&depList);
|
||||||
|
|
||||||
const zphysics_dep = b.dependency("zphysics", .{
|
const zphysics_dep = b.dependency("zphysics", .{
|
||||||
.target = target,
|
.target = target,
|
||||||
.optimize = optimize,
|
.optimize = optimize,
|
||||||
.enable_cross_platform_determinism = false,
|
|
||||||
.static_build = static_build,
|
.static_build = static_build,
|
||||||
});
|
});
|
||||||
|
|
||||||
mod.addImport("core", core_dep.module("core"));
|
engineMod.mod.addImport("zphysics", zphysics_dep.module("root"));
|
||||||
mod.addImport("zphysics", zphysics_dep.module("root"));
|
engineMod.lib.linkLibrary(zphysics_dep.artifact("zphysics"));
|
||||||
mod.linkLibrary(zphysics_dep.artifact("joltc"));
|
|
||||||
|
|
||||||
const test_step = b.step("test", "run unit tests for physics");
|
const test_step = b.step("test", "run unit tests for physics");
|
||||||
const tests = b.addTest(.{
|
const tests = b.addTest(.{
|
||||||
|
|
@ -35,7 +39,8 @@ pub fn build(b: *std.Build) void {
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
tests.root_module.addImport("physics", mod);
|
tests.root_module.addImport("physics", engineMod.mod);
|
||||||
|
tests.root_module.linkLibrary(zphysics_dep.artifact("zphysics"));
|
||||||
const runArtifact = b.addRunArtifact(tests);
|
const runArtifact = b.addRunArtifact(tests);
|
||||||
test_step.dependOn(&runArtifact.step);
|
test_step.dependOn(&runArtifact.step);
|
||||||
b.installArtifact(tests);
|
b.installArtifact(tests);
|
||||||
|
|
|
||||||
|
|
@ -139,11 +139,8 @@ pub const PhysicsRuntime = struct {
|
||||||
try self.idToEntity.put(self.allocator, bodyId, entity);
|
try self.idToEntity.put(self.allocator, bodyId, entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init(self: *@This(), allocator: std.mem.Allocator, first: bool) !void {
|
pub fn init(allocator: std.mem.Allocator) !*@This() {
|
||||||
if (!first) {
|
const self = try allocator.create(@This());
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try zphysics.init(std.heap.smp_allocator, .{});
|
try zphysics.init(std.heap.smp_allocator, .{});
|
||||||
//try zphysics.init(allocator, .{});
|
//try zphysics.init(allocator, .{});
|
||||||
|
|
||||||
|
|
@ -165,6 +162,11 @@ pub const PhysicsRuntime = struct {
|
||||||
);
|
);
|
||||||
|
|
||||||
self.system = system;
|
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 {
|
pub fn tick(self: *@This(), dt: f64) void {
|
||||||
|
|
@ -228,6 +230,7 @@ pub const PhysicsRuntime = struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *@This()) void {
|
pub fn deinit(self: *@This()) void {
|
||||||
|
const allocator = self.allocator;
|
||||||
self.system.optimizeBroadPhase();
|
self.system.optimizeBroadPhase();
|
||||||
for (PhysicsCharacter.BaseContainer.list.items) |physChar| {
|
for (PhysicsCharacter.BaseContainer.list.items) |physChar| {
|
||||||
physChar.deinit();
|
physChar.deinit();
|
||||||
|
|
@ -263,6 +266,8 @@ pub const PhysicsRuntime = struct {
|
||||||
self.system.destroy();
|
self.system.destroy();
|
||||||
|
|
||||||
zphysics.deinit();
|
zphysics.deinit();
|
||||||
|
|
||||||
|
allocator.destroy(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn createShape(self: *@This(), name: *core.Name, settings: ShapeSettings) !void {
|
pub fn createShape(self: *@This(), name: *core.Name, settings: ShapeSettings) !void {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,308 @@
|
||||||
|
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,5 +1,6 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const sdl3 = @import("sdl3");
|
const sdl3 = @import("sdl3");
|
||||||
|
const core = @import("core");
|
||||||
|
|
||||||
const dependencyList = [_][]const u8{
|
const dependencyList = [_][]const u8{
|
||||||
"core",
|
"core",
|
||||||
|
|
@ -13,12 +14,16 @@ pub fn build(b: *std.Build) void {
|
||||||
const optimize = b.standardOptimizeOption(.{});
|
const optimize = b.standardOptimizeOption(.{});
|
||||||
const static_build = b.option(bool, "static_build", "builds backlog dependencies for static linking") orelse false;
|
const static_build = b.option(bool, "static_build", "builds backlog dependencies for static linking") orelse false;
|
||||||
|
|
||||||
const mod = b.addModule("platform", .{
|
const engineMod = core.MakeModLib(b, .{
|
||||||
.target = target,
|
.name = "platform",
|
||||||
.optimize = optimize,
|
.optimize = optimize,
|
||||||
.root_source_file = b.path("src/platform.zig"),
|
.target = target,
|
||||||
|
.static_build = static_build,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
engineMod.linkModLibs(&dependencyList);
|
||||||
|
engineMod.install();
|
||||||
|
|
||||||
const tests = b.addTest(.{
|
const tests = b.addTest(.{
|
||||||
.root_module = b.createModule(.{
|
.root_module = b.createModule(.{
|
||||||
.target = target,
|
.target = target,
|
||||||
|
|
@ -27,16 +32,10 @@ pub fn build(b: *std.Build) void {
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
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");
|
const test_step = b.step("test", "run unit tests for platform");
|
||||||
|
tests.root_module.addImport("platform", engineMod.mod);
|
||||||
|
tests.linkLibrary(engineMod.lib);
|
||||||
|
|
||||||
tests.root_module.addImport("platform", mod);
|
|
||||||
const runArtifact = b.addRunArtifact(tests);
|
const runArtifact = b.addRunArtifact(tests);
|
||||||
test_step.dependOn(&runArtifact.step);
|
test_step.dependOn(&runArtifact.step);
|
||||||
b.installArtifact(tests);
|
b.installArtifact(tests);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
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");
|
const std = @import("std");
|
||||||
const core = @import("core");
|
pub const core = @import("core");
|
||||||
const test_vert = @import("test.vert");
|
const test_vert = @import("test.vert");
|
||||||
|
|
||||||
pub const nfd = @import("nfd");
|
pub const nfd = @import("nfd");
|
||||||
|
|
@ -89,7 +89,7 @@ pub fn start_module(spec: *core.SpecVariantMap, args: anytype, allocator: std.me
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// core.getModuleLoader().watchInitializeFn = watchModules;
|
core.getModuleLoader().watchInitializeFn = watchModules;
|
||||||
|
|
||||||
const parameters = windowing.PlatformParams.init();
|
const parameters = windowing.PlatformParams.init();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -191,6 +191,8 @@ pub const PlatformInstance = struct {
|
||||||
self.allocator.free(self.iconPath);
|
self.allocator.free(self.iconPath);
|
||||||
self.processFuncs.deinit(self.allocator);
|
self.processFuncs.deinit(self.allocator);
|
||||||
self.platformRequests.deinit(self.allocator);
|
self.platformRequests.deinit(self.allocator);
|
||||||
|
self.allocator.destroy(self);
|
||||||
|
// shutdown
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn onExitSignal(self: *@This()) !void {
|
pub fn onExitSignal(self: *@This()) !void {
|
||||||
|
|
@ -202,10 +204,10 @@ pub const PlatformInstance = struct {
|
||||||
return self.windowDestroyed;
|
return self.windowDestroyed;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init(self: *@This(), allocator: std.mem.Allocator, first: bool) !void {
|
pub fn init(
|
||||||
if (!first)
|
allocator: std.mem.Allocator,
|
||||||
return;
|
) !*@This() {
|
||||||
|
const self = try allocator.create(@This());
|
||||||
self.* = .{
|
self.* = .{
|
||||||
.allocator = allocator,
|
.allocator = allocator,
|
||||||
.nfdRuntime = try nfd.NFDRuntime.create(allocator, .{}),
|
.nfdRuntime = try nfd.NFDRuntime.create(allocator, .{}),
|
||||||
|
|
@ -215,6 +217,8 @@ pub const PlatformInstance = struct {
|
||||||
//.extent = .{ .x = @floatFromInt(params.extent.x), .y = @floatFromInt(params.extent.y) },
|
//.extent = .{ .x = @floatFromInt(params.extent.x), .y = @floatFromInt(params.extent.y) },
|
||||||
//.hasVideo = params.hasVideo,
|
//.hasVideo = params.hasVideo,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setParams(self: *@This(), params: PlatformParams) !void {
|
pub fn setParams(self: *@This(), params: PlatformParams) !void {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
const core = @import("core");
|
|
||||||
const platform = @import("platform");
|
const platform = @import("platform");
|
||||||
|
const core = @import("platform").core;
|
||||||
|
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const sdl3 = @import("sdl3");
|
const sdl3 = @import("sdl3");
|
||||||
|
const core = @import("core");
|
||||||
|
|
||||||
const dependencyList = [_][]const u8{
|
const dependencyList = [_][]const u8{
|
||||||
"core",
|
"core",
|
||||||
|
|
@ -19,38 +20,47 @@ pub fn build(b: *std.Build) void {
|
||||||
const optimize = b.standardOptimizeOption(.{});
|
const optimize = b.standardOptimizeOption(.{});
|
||||||
const static_build = b.option(bool, "static_build", "builds backlog dependencies for static linking") orelse false;
|
const static_build = b.option(bool, "static_build", "builds backlog dependencies for static linking") orelse false;
|
||||||
|
|
||||||
const mod = b.addModule("rend", .{
|
const engineMod = core.MakeModLib(b, .{
|
||||||
|
.name = "rend",
|
||||||
.target = target,
|
.target = target,
|
||||||
.optimize = optimize,
|
.optimize = optimize,
|
||||||
.root_source_file = b.path("src/rend.zig"),
|
.static_build = static_build,
|
||||||
});
|
});
|
||||||
|
engineMod.linkModLibs(&dependencyList);
|
||||||
|
engineMod.install();
|
||||||
|
|
||||||
for (dependencyList) |depName| {
|
// const mod = b.addModule("rend", .{
|
||||||
const dep = b.dependency(depName, .{ .target = target, .optimize = optimize, .static_build = static_build });
|
// .target = target,
|
||||||
const dep_mod = dep.module(depName);
|
// .optimize = optimize,
|
||||||
mod.addImport(depName, dep_mod);
|
// .root_source_file = b.path("src/rend.zig"),
|
||||||
|
// });
|
||||||
|
|
||||||
if (std.mem.eql(u8, depName, "ozz")) {
|
// for (dependencyList) |depName| {
|
||||||
mod.linkLibrary(dep.artifact("ozz_cpp"));
|
// const dep = b.dependency(depName, .{ .target = target, .optimize = optimize, .static_build = static_build });
|
||||||
}
|
// const dep_mod = dep.module(depName);
|
||||||
}
|
// mod.addImport(depName, dep_mod);
|
||||||
|
|
||||||
sdl3.shaderDefintion(b, mod, "../../lib/sdl3", target, optimize, "sample.vert", b.path("shaders/sample.vert.json"));
|
// if (std.mem.eql(u8, depName, "ozz")) {
|
||||||
sdl3.shaderDefintion(b, mod, "../../lib/sdl3", target, optimize, "meshes.vert", b.path("shaders/meshes.vert.json"));
|
// mod.linkLibrary(dep.artifact("ozz_cpp"));
|
||||||
sdl3.shaderDefintion(b, 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, engineMod.mod, "../../lib/sdl3", target, optimize, "sample.vert", b.path("shaders/sample.vert.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, "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, "depthOnly.frag", b.path("shaders/depthOnly.frag.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, "skybox.frag", b.path("shaders/skybox.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.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, engineMod.mod, "../../lib/sdl3", target, optimize, "skybox.frag", b.path("shaders/skybox.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, "skybox.vert", b.path("shaders/skybox.vert.json"));
|
||||||
|
|
||||||
sdl3.shaderDefintion(b, mod, "../../lib/sdl3", target, optimize, "ssao.frag", b.path("shaders/ssao.frag.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"));
|
||||||
|
|
||||||
// ========== tests ==========
|
// ========== tests ==========
|
||||||
const tests = b.addTest(.{
|
const tests = b.addTest(.{
|
||||||
|
|
|
||||||
|
|
@ -417,10 +417,8 @@ pub const AnimationSystem = struct {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init(self: *@This(), alloc: std.mem.Allocator, first: bool) !void {
|
pub fn init(alloc: std.mem.Allocator) !*@This() {
|
||||||
if (!first)
|
const self = try alloc.create(@This());
|
||||||
return;
|
|
||||||
|
|
||||||
self.* = .{
|
self.* = .{
|
||||||
.backingAllocator = alloc,
|
.backingAllocator = alloc,
|
||||||
.arena = std.heap.ArenaAllocator.init(alloc),
|
.arena = std.heap.ArenaAllocator.init(alloc),
|
||||||
|
|
@ -435,6 +433,7 @@ pub const AnimationSystem = struct {
|
||||||
Animator.allocator = alloc;
|
Animator.allocator = alloc;
|
||||||
|
|
||||||
core.engine_logs("Animation System initialized");
|
core.engine_logs("Animation System initialized");
|
||||||
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *@This()) void {
|
pub fn deinit(self: *@This()) void {
|
||||||
|
|
@ -467,6 +466,7 @@ pub const AnimationSystem = struct {
|
||||||
self.arena.deinit();
|
self.arena.deinit();
|
||||||
self.skeletons.deinit(self.backingAllocator);
|
self.skeletons.deinit(self.backingAllocator);
|
||||||
self.animTracks.deinit(self.backingAllocator);
|
self.animTracks.deinit(self.backingAllocator);
|
||||||
|
self.backingAllocator.destroy(self);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,14 +19,19 @@ pub const AnimationLoader = struct {
|
||||||
self.sys.newAnimTrack(assetRef.name, animation) catch return error.UnableToLoad;
|
self.sys.newAnimTrack(assetRef.name, animation) catch return error.UnableToLoad;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init(self: *@This(), allocator: std.mem.Allocator, first: bool) !void {
|
pub fn init(allocator: std.mem.Allocator) !*@This() {
|
||||||
if (!first)
|
const self = try allocator.create(@This());
|
||||||
return;
|
|
||||||
|
|
||||||
self.* = .{
|
self.* = .{
|
||||||
.sys = animation_system.gAnimationSys,
|
.sys = animation_system.gAnimationSys,
|
||||||
.allocator = allocator,
|
.allocator = allocator,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn destroy(self: *@This()) void {
|
||||||
|
self.allocator.destroy(self);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -51,14 +56,19 @@ pub const SkeletonLoader = struct {
|
||||||
self.sys.newSkeleton(assetRef.name, sk) catch return error.UnableToLoad;
|
self.sys.newSkeleton(assetRef.name, sk) catch return error.UnableToLoad;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init(self: *@This(), allocator: std.mem.Allocator, first: bool) !void {
|
pub fn init(allocator: std.mem.Allocator) !*@This() {
|
||||||
if (!first)
|
const self = try allocator.create(@This());
|
||||||
return;
|
|
||||||
|
|
||||||
self.* = .{
|
self.* = .{
|
||||||
.sys = animation_system.gAnimationSys,
|
.sys = animation_system.gAnimationSys,
|
||||||
.allocator = allocator,
|
.allocator = allocator,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn destroy(self: *@This()) void {
|
||||||
|
self.allocator.destroy(self);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -410,9 +410,8 @@ pub const ParticleSystem = struct {
|
||||||
|
|
||||||
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This(), "rend.ParticleSystem");
|
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This(), "rend.ParticleSystem");
|
||||||
|
|
||||||
pub fn init(self: *@This(), allocator: std.mem.Allocator, first: bool) !void {
|
pub fn create(allocator: std.mem.Allocator) !*@This() {
|
||||||
if (!first)
|
const self = try allocator.create(@This());
|
||||||
return;
|
|
||||||
|
|
||||||
self.* = .{
|
self.* = .{
|
||||||
.particleArena = std.heap.ArenaAllocator.init(allocator),
|
.particleArena = std.heap.ArenaAllocator.init(allocator),
|
||||||
|
|
@ -421,6 +420,8 @@ pub const ParticleSystem = struct {
|
||||||
|
|
||||||
ParticleRandRangef.randomEngine = std.Random.DefaultPrng.init(0x1234);
|
ParticleRandRangef.randomEngine = std.Random.DefaultPrng.init(0x1234);
|
||||||
ParticleRandRangef.randomFunc = ParticleRandRangef.randomEngine.random();
|
ParticleRandRangef.randomFunc = ParticleRandRangef.randomEngine.random();
|
||||||
|
|
||||||
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tick(self: *@This(), dt: f64) void {
|
pub fn tick(self: *@This(), dt: f64) void {
|
||||||
|
|
@ -436,6 +437,7 @@ pub const ParticleSystem = struct {
|
||||||
|
|
||||||
pub fn destroy(self: *@This()) void {
|
pub fn destroy(self: *@This()) void {
|
||||||
self.particleArena.deinit();
|
self.particleArena.deinit();
|
||||||
|
self.allocator.destroy(self);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -35,10 +35,8 @@ const assetReferences = [_]assets.AssetImportReference{
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn init(self: *@This(), allocator: std.mem.Allocator, first: bool) !void {
|
pub fn create(allocator: std.mem.Allocator) !*@This() {
|
||||||
if (!first)
|
const self = try allocator.create(@This());
|
||||||
return;
|
|
||||||
|
|
||||||
self.* = .{
|
self.* = .{
|
||||||
.debugDraws = try core.RingQueueU(DebugPrimitive).init(allocator, MaxObjectCount),
|
.debugDraws = try core.RingQueueU(DebugPrimitive).init(allocator, MaxObjectCount),
|
||||||
.allocator = allocator,
|
.allocator = allocator,
|
||||||
|
|
@ -52,6 +50,8 @@ pub fn init(self: *@This(), allocator: std.mem.Allocator, first: bool) !void {
|
||||||
try assets.loadList(assetReferences);
|
try assets.loadList(assetReferences);
|
||||||
|
|
||||||
gDebugDrawSys = self;
|
gDebugDrawSys = self;
|
||||||
|
|
||||||
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn updateMeshes(self: *@This()) void {
|
pub fn updateMeshes(self: *@This()) void {
|
||||||
|
|
@ -243,6 +243,7 @@ pub fn setup(self: *@This(), device: *gpu.GPUDevice) !void {
|
||||||
pub fn destroy(self: *@This()) void {
|
pub fn destroy(self: *@This()) void {
|
||||||
self.debugDraws.deinit(self.allocator);
|
self.debugDraws.deinit(self.allocator);
|
||||||
self.drawsThisFrame.deinit(self.allocator);
|
self.drawsThisFrame.deinit(self.allocator);
|
||||||
|
self.allocator.destroy(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ==================== Primitives ===================
|
// ==================== Primitives ===================
|
||||||
|
|
|
||||||
|
|
@ -5,19 +5,23 @@ allocator: std.mem.Allocator,
|
||||||
pub var LoaderInterfaceVTable = assets.AssetLoaderInterface.from("Mesh", @This());
|
pub var LoaderInterfaceVTable = assets.AssetLoaderInterface.from("Mesh", @This());
|
||||||
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This(), "rend.MeshAssetLoader");
|
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This(), "rend.MeshAssetLoader");
|
||||||
|
|
||||||
pub fn init(self: *@This(), allocator: std.mem.Allocator, first: bool) !void {
|
pub fn create(allocator: std.mem.Allocator) !*@This() {
|
||||||
if (!first)
|
const self = try allocator.create(@This());
|
||||||
return;
|
|
||||||
|
|
||||||
self.* = .{
|
self.* = .{
|
||||||
.allocator = allocator,
|
.allocator = allocator,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn discardAll(self: *@This()) void {
|
pub fn discardAll(self: *@This()) void {
|
||||||
_ = self;
|
_ = self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn destroy(self: *@This()) void {
|
||||||
|
self.allocator.destroy(self);
|
||||||
|
}
|
||||||
|
|
||||||
// unfortunately this one is blocking
|
// unfortunately this one is blocking
|
||||||
pub fn loadAsset(self: *@This(), assetRef: assets.AssetRef, propertiesBag: ?assets.AssetPropertiesBag) assets.AssetLoaderError!void {
|
pub fn loadAsset(self: *@This(), assetRef: assets.AssetRef, propertiesBag: ?assets.AssetPropertiesBag) assets.AssetLoaderError!void {
|
||||||
_ = self;
|
_ = self;
|
||||||
|
|
|
||||||
|
|
@ -15,10 +15,8 @@ const SgpuParticleRenderInfo = struct {
|
||||||
texture: *rend.Texture,
|
texture: *rend.Texture,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn init(self: *@This(), allocator: std.mem.Allocator, first: bool) !void {
|
pub fn create(allocator: std.mem.Allocator) !*@This() {
|
||||||
if (!first)
|
const self = try allocator.create(@This());
|
||||||
return;
|
|
||||||
|
|
||||||
self.* = .{
|
self.* = .{
|
||||||
.allocator = allocator,
|
.allocator = allocator,
|
||||||
};
|
};
|
||||||
|
|
@ -41,6 +39,8 @@ pub fn init(self: *@This(), allocator: std.mem.Allocator, first: bool) !void {
|
||||||
.size = MaxParticleCount * @sizeOf(meshes_vert.Scene),
|
.size = MaxParticleCount * @sizeOf(meshes_vert.Scene),
|
||||||
.props = 0,
|
.props = 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn uploadSsbos(self: *@This(), copyPass: *gpu.GPUCopyPass) !void {
|
pub fn uploadSsbos(self: *@This(), copyPass: *gpu.GPUCopyPass) !void {
|
||||||
|
|
@ -121,9 +121,10 @@ pub fn setup(self: *@This(), device: *gpu.GPUDevice) !void {
|
||||||
_ = device;
|
_ = device;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *@This()) void {
|
pub fn destroy(self: *@This()) void {
|
||||||
self.spans.deinit(self.allocator);
|
self.spans.deinit(self.allocator);
|
||||||
self.renderInfo.deinit(self.allocator);
|
self.renderInfo.deinit(self.allocator);
|
||||||
|
self.allocator.destroy(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
const assets = @import("assets");
|
const assets = @import("assets");
|
||||||
|
|
|
||||||
|
|
@ -16,11 +16,11 @@ brightnessFactor: f32 = 4.0,
|
||||||
|
|
||||||
sampler: *gpu.GPUSampler = undefined,
|
sampler: *gpu.GPUSampler = undefined,
|
||||||
|
|
||||||
pub fn init(self: *@This(), allocator: std.mem.Allocator, first: bool) !void {
|
pub fn create(allocator: std.mem.Allocator) !*@This() {
|
||||||
if (!first)
|
const self = try allocator.create(@This());
|
||||||
return;
|
|
||||||
|
|
||||||
self.* = .{ .allocator = allocator };
|
self.* = .{ .allocator = allocator };
|
||||||
|
|
||||||
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setup(self: *@This(), device: *gpu.GPUDevice) !void {
|
pub fn setup(self: *@This(), device: *gpu.GPUDevice) !void {
|
||||||
|
|
@ -87,6 +87,10 @@ fn createPipeline(self: *@This()) !void {
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn destroy(self: *@This()) void {
|
||||||
|
self.allocator.destroy(self);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn render(self: *@This(), cmd: *gpu.GPUCommandBuffer) void {
|
pub fn render(self: *@This(), cmd: *gpu.GPUCommandBuffer) void {
|
||||||
const targetInfo: [2]gpu.GPUColorTargetInfo = .{
|
const targetInfo: [2]gpu.GPUColorTargetInfo = .{
|
||||||
std.mem.zeroInit(gpu.GPUColorTargetInfo, .{
|
std.mem.zeroInit(gpu.GPUColorTargetInfo, .{
|
||||||
|
|
|
||||||
|
|
@ -9,19 +9,19 @@
|
||||||
pub var LoaderInterfaceVTable = assets.AssetLoaderInterface.from("Texture", @This());
|
pub var LoaderInterfaceVTable = assets.AssetLoaderInterface.from("Texture", @This());
|
||||||
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This(), "rend.TextureList");
|
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This(), "rend.TextureList");
|
||||||
|
|
||||||
allocator: std.mem.Allocator = undefined,
|
allocator: std.mem.Allocator,
|
||||||
device: *gpu.GPUDevice = undefined,
|
device: *gpu.GPUDevice = undefined,
|
||||||
|
|
||||||
map: std.AutoHashMapUnmanaged(u32, *Texture) = .{},
|
map: std.AutoHashMapUnmanaged(u32, *Texture) = .{},
|
||||||
requestMap: std.AutoHashMapUnmanaged(u32, bool) = .{},
|
requestMap: std.AutoHashMapUnmanaged(u32, bool) = .{},
|
||||||
|
|
||||||
pub fn init(self: *@This(), allocator: std.mem.Allocator, first: bool) !void {
|
pub fn create(allocator: std.mem.Allocator) !*@This() {
|
||||||
if (!first)
|
const self = try allocator.create(@This());
|
||||||
return;
|
|
||||||
|
|
||||||
self.* = .{
|
self.* = .{
|
||||||
.allocator = allocator,
|
.allocator = allocator,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setup(self: *@This(), device: *gpu.GPUDevice) !void {
|
pub fn setup(self: *@This(), device: *gpu.GPUDevice) !void {
|
||||||
|
|
@ -339,13 +339,14 @@ pub fn discardAll(self: *@This()) void {
|
||||||
_ = self;
|
_ = self;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *@This()) void {
|
pub fn destroy(self: *@This()) void {
|
||||||
var iter = self.map.valueIterator();
|
var iter = self.map.valueIterator();
|
||||||
while (iter.next()) |x| {
|
while (iter.next()) |x| {
|
||||||
self.allocator.destroy(x.*);
|
self.allocator.destroy(x.*);
|
||||||
}
|
}
|
||||||
self.requestMap.deinit(self.allocator);
|
self.requestMap.deinit(self.allocator);
|
||||||
self.map.deinit(self.allocator);
|
self.map.deinit(self.allocator);
|
||||||
|
self.allocator.destroy(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
|
|
||||||
|
|
@ -99,14 +99,15 @@ pub const Renderer = struct {
|
||||||
|
|
||||||
pub const MaxObjectCount = 50000;
|
pub const MaxObjectCount = 50000;
|
||||||
|
|
||||||
pub fn init(self: *@This(), allocator: std.mem.Allocator, first: bool) !void {
|
pub fn init(allocator: std.mem.Allocator) !*@This() {
|
||||||
if (!first)
|
const self = try allocator.create(@This());
|
||||||
return;
|
|
||||||
self.* = .{
|
self.* = .{
|
||||||
.allocator = allocator,
|
.allocator = allocator,
|
||||||
};
|
};
|
||||||
|
|
||||||
self.hdrTextureFormat = .textureformatR16g16b16a16Float;
|
self.hdrTextureFormat = .textureformatR16g16b16a16Float;
|
||||||
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn imageExtents(self: @This()) core.Vectorf {
|
pub fn imageExtents(self: @This()) core.Vectorf {
|
||||||
|
|
@ -1177,6 +1178,7 @@ pub const Renderer = struct {
|
||||||
|
|
||||||
self.uploads.deinit(self.allocator);
|
self.uploads.deinit(self.allocator);
|
||||||
self.destroys.deinit(self.allocator);
|
self.destroys.deinit(self.allocator);
|
||||||
|
self.allocator.destroy(self);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,13 +21,14 @@ enable: bool = true,
|
||||||
// float bias; // = 0.025;
|
// float bias; // = 0.025;
|
||||||
// int numSamples; // up to 64
|
// int numSamples; // up to 64
|
||||||
|
|
||||||
pub fn init(self: *@This(), allocator: std.mem.Allocator, first: bool) !void {
|
pub fn create(allocator: std.mem.Allocator) !*@This() {
|
||||||
if (!first)
|
const self = try allocator.create(@This());
|
||||||
return;
|
|
||||||
|
|
||||||
self.* = .{
|
self.* = .{
|
||||||
.allocator = allocator,
|
.allocator = allocator,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setup(self: *@This(), device: *gpu.GPUDevice) !void {
|
pub fn setup(self: *@This(), device: *gpu.GPUDevice) !void {
|
||||||
|
|
@ -215,6 +216,10 @@ pub fn createPipeline(self: *@This()) !void {
|
||||||
self.ssaoPipeline = ctx.device.createGPUGraphicsPipeline(&pci);
|
self.ssaoPipeline = ctx.device.createGPUGraphicsPipeline(&pci);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn destroy(self: *@This()) void {
|
||||||
|
self.allocator.destroy(self);
|
||||||
|
}
|
||||||
|
|
||||||
const core = @import("core");
|
const core = @import("core");
|
||||||
const rend = @import("../rend.zig");
|
const rend = @import("../rend.zig");
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
|
|
||||||
|
|
@ -1,38 +1,27 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const sdl3 = @import("sdl3");
|
const sdl3 = @import("sdl3");
|
||||||
|
const core = @import("core");
|
||||||
|
|
||||||
const dependencyList = [_][]const u8{
|
const dependencyList = [_][]const u8{
|
||||||
"core",
|
"core",
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn build(b: *std.Build) void {
|
pub fn build(b: *std.Build) void {
|
||||||
const target = b.standardTargetOptions(.{});
|
const engineMod = core.MakeEngineMod(b, "sys");
|
||||||
const optimize = b.standardOptimizeOption(.{});
|
engineMod.linkModLibs(&dependencyList);
|
||||||
const static_build = b.option(bool, "static_build", "builds backlog dependencies for static linking") orelse false;
|
engineMod.install();
|
||||||
|
|
||||||
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 ==========
|
// ========== tests ==========
|
||||||
const tests = b.addTest(.{
|
const tests = b.addTest(.{
|
||||||
.root_module = b.createModule(.{
|
.root_module = b.createModule(.{
|
||||||
.target = target,
|
.target = engineMod.target,
|
||||||
.optimize = optimize,
|
.optimize = engineMod.optimize,
|
||||||
.root_source_file = b.path("tests/tests.zig"),
|
.root_source_file = b.path("tests/tests.zig"),
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
const test_step = b.step("test", "run unit tests for ui");
|
const test_step = b.step("test", "run unit tests for ui");
|
||||||
|
|
||||||
tests.root_module.addImport("sys", mod);
|
tests.root_module.addImport("sys", engineMod.mod);
|
||||||
const runArtifact = b.addRunArtifact(tests);
|
const runArtifact = b.addRunArtifact(tests);
|
||||||
b.installArtifact(tests);
|
b.installArtifact(tests);
|
||||||
test_step.dependOn(&runArtifact.step);
|
test_step.dependOn(&runArtifact.step);
|
||||||
|
|
|
||||||
|
|
@ -21,8 +21,8 @@ pub const SubprocessTask = struct {
|
||||||
allocator: std.mem.Allocator,
|
allocator: std.mem.Allocator,
|
||||||
|
|
||||||
child: ?std.process.Child = null,
|
child: ?std.process.Child = null,
|
||||||
completed: bool = false,
|
completed: std.atomic.Value(bool) = std.atomic.Value(bool).init(false),
|
||||||
success: bool = false,
|
success: std.atomic.Value(bool) = std.atomic.Value(bool).init(false),
|
||||||
|
|
||||||
workingDir: ?[]const u8 = null,
|
workingDir: ?[]const u8 = null,
|
||||||
|
|
||||||
|
|
@ -76,29 +76,29 @@ pub const SubprocessTask = struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn destroy(self: *@This()) void {
|
pub fn destroy(self: *@This()) void {
|
||||||
self.mutex.lock();
|
// self.mutex.lock();
|
||||||
self.argsArena.deinit();
|
self.argsArena.deinit();
|
||||||
self.argsOwned.deinit(self.allocator);
|
self.argsOwned.deinit(self.allocator);
|
||||||
if (self.child) |*child| {
|
if (self.child) |*child| {
|
||||||
_ = child;
|
_ = child;
|
||||||
core.engine_log("destroying child process", .{});
|
core.engine_log("destroying child process", .{});
|
||||||
}
|
}
|
||||||
self.mutex.unlock();
|
// self.mutex.unlock();
|
||||||
self.stdout.deinit(self.allocator);
|
self.stdout.deinit(self.allocator);
|
||||||
self.stderr.deinit(self.allocator);
|
self.stderr.deinit(self.allocator);
|
||||||
self.allocator.destroy(self);
|
self.allocator.destroy(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn checkComplete(self: *@This()) bool {
|
pub fn checkComplete(self: *@This()) bool {
|
||||||
return self.completed;
|
return self.completed.load(.monotonic);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn wait(self: *@This()) void {
|
pub fn wait(self: *@This()) void {
|
||||||
var completed: bool = self.completed;
|
var completed: bool = self.completed.load(.monotonic);
|
||||||
while (completed == false) {
|
while (completed == false) {
|
||||||
std.Thread.sleep(1 * 1000 * 1000);
|
std.Thread.sleep(1 * 1000 * 1000);
|
||||||
self.mutex.lock();
|
self.mutex.lock();
|
||||||
completed = self.completed;
|
completed = self.completed.load(.monotonic);
|
||||||
self.mutex.unlock();
|
self.mutex.unlock();
|
||||||
}
|
}
|
||||||
debugPrint("task completed", .{});
|
debugPrint("task completed", .{});
|
||||||
|
|
@ -117,7 +117,7 @@ pub const SubprocessTask = struct {
|
||||||
|
|
||||||
switch (term) {
|
switch (term) {
|
||||||
.Exited => |m| {
|
.Exited => |m| {
|
||||||
if (m == 0) self.success = true;
|
if (m == 0) self.success.store(true, .release);
|
||||||
},
|
},
|
||||||
.Signal => |m| {
|
.Signal => |m| {
|
||||||
core.engine_log("process Signaled {d}", .{m});
|
core.engine_log("process Signaled {d}", .{m});
|
||||||
|
|
@ -132,8 +132,8 @@ pub const SubprocessTask = struct {
|
||||||
|
|
||||||
self.mutex.lock();
|
self.mutex.lock();
|
||||||
self.child = null;
|
self.child = null;
|
||||||
self.completed = true;
|
|
||||||
self.mutex.unlock();
|
self.mutex.unlock();
|
||||||
|
self.completed.store(true, .release);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn runCommand(allocator: std.mem.Allocator, argv: []const []const u8, cwd: ?[]const u8) !*@This() {
|
pub fn runCommand(allocator: std.mem.Allocator, argv: []const []const u8, cwd: ?[]const u8) !*@This() {
|
||||||
|
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
const core = @import("core");
|
|
||||||
|
|
||||||
const modules = @import("modtree");
|
|
||||||
|
|
||||||
pub fn launch() void {}
|
|
||||||
|
|
||||||
pub fn shutdown() void {}
|
|
||||||
|
|
||||||
pub fn loadModule() void {}
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const sdl3 = @import("sdl3");
|
const sdl3 = @import("sdl3");
|
||||||
|
const core = @import("core");
|
||||||
|
|
||||||
const dependencyList = [_][]const u8{
|
const dependencyList = [_][]const u8{
|
||||||
"core",
|
"core",
|
||||||
|
|
@ -11,28 +12,18 @@ const dependencyList = [_][]const u8{
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn build(b: *std.Build) void {
|
pub fn build(b: *std.Build) void {
|
||||||
const target = b.standardTargetOptions(.{});
|
const engineMod = core.MakeEngineMod(b, "ui");
|
||||||
const optimize = b.standardOptimizeOption(.{});
|
engineMod.linkModLibs(&dependencyList);
|
||||||
const static_build = b.option(bool, "static_build", "builds backlog dependencies for static linking") orelse false;
|
engineMod.install();
|
||||||
|
const target = engineMod.target;
|
||||||
const mod = b.addModule("ui", .{
|
const optimize = engineMod.optimize;
|
||||||
.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
|
// shaders
|
||||||
sdl3.shaderDefintion(b, mod, "../../lib/sdl3", target, optimize, "rect.vert", b.path("shaders/rect.vert.json"));
|
sdl3.shaderDefintion(b, engineMod.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, "rect.frag", b.path("shaders/rect.frag.json"));
|
||||||
|
|
||||||
sdl3.shaderDefintion(b, mod, "../../lib/sdl3", target, optimize, "text.vert", b.path("shaders/text.vert.json"));
|
sdl3.shaderDefintion(b, engineMod.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"));
|
sdl3.shaderDefintion(b, engineMod.mod, "../../lib/sdl3", target, optimize, "text.frag", b.path("shaders/text.frag.json"));
|
||||||
|
|
||||||
// ========== tests ==========
|
// ========== tests ==========
|
||||||
const tests = b.addTest(.{
|
const tests = b.addTest(.{
|
||||||
|
|
@ -44,7 +35,8 @@ pub fn build(b: *std.Build) void {
|
||||||
});
|
});
|
||||||
const test_step = b.step("test", "run unit tests for ui");
|
const test_step = b.step("test", "run unit tests for ui");
|
||||||
|
|
||||||
tests.root_module.addImport("ui", mod);
|
tests.root_module.addImport("ui", engineMod.mod);
|
||||||
|
tests.root_module.linkLibrary(engineMod.lib);
|
||||||
const runArtifact = b.addRunArtifact(tests);
|
const runArtifact = b.addRunArtifact(tests);
|
||||||
test_step.dependOn(&runArtifact.step);
|
test_step.dependOn(&runArtifact.step);
|
||||||
b.installArtifact(tests);
|
b.installArtifact(tests);
|
||||||
|
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
{
|
|
||||||
"permissions": {
|
|
||||||
"allow": [
|
|
||||||
"Bash(cat:*)",
|
|
||||||
"Bash(git log:*)",
|
|
||||||
"Bash(zig build:*)"
|
|
||||||
],
|
|
||||||
"deny": [],
|
|
||||||
"ask": []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -5,9 +5,31 @@ pub const ModLib = struct {
|
||||||
lib: *std.Build.Step.Compile,
|
lib: *std.Build.Step.Compile,
|
||||||
mod: *std.Build.Module,
|
mod: *std.Build.Module,
|
||||||
|
|
||||||
|
target: std.Build.ResolvedTarget,
|
||||||
|
optimize: std.builtin.OptimizeMode,
|
||||||
|
static_build: bool,
|
||||||
|
|
||||||
pub fn install(self: @This()) void {
|
pub fn install(self: @This()) void {
|
||||||
self.b.installArtifact(self.lib);
|
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 {
|
pub const ModLibOptions = struct {
|
||||||
|
|
@ -22,11 +44,11 @@ pub const ModLibOptions = struct {
|
||||||
stub: ?std.Build.LazyPath = null,
|
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, .{
|
const mod = b.addModule(o.name, .{
|
||||||
.target = o.target,
|
.target = o.target,
|
||||||
.optimize = o.optimize,
|
.optimize = o.optimize,
|
||||||
.root_source_file = if (o.root != null) o.root.? else b.path(b.fmt("src/{s}", .{o.name})),
|
.root_source_file = if (o.root != null) o.root.? else b.path(b.fmt("src/{s}.zig", .{o.name})),
|
||||||
});
|
});
|
||||||
|
|
||||||
const empty_file = b.addWriteFile("stubs", "");
|
const empty_file = b.addWriteFile("stubs", "");
|
||||||
|
|
@ -45,23 +67,9 @@ pub fn MakeModlib(b: *std.Build, o: ModLibOptions) ModLib {
|
||||||
.b = b,
|
.b = b,
|
||||||
.lib = lib,
|
.lib = lib,
|
||||||
.mod = mod,
|
.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,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -70,7 +78,7 @@ pub fn build(b: *std.Build) void {
|
||||||
const optimize = b.standardOptimizeOption(.{});
|
const optimize = b.standardOptimizeOption(.{});
|
||||||
const static_build = b.option(bool, "static_build", "builds backlog dependencies for static linking") orelse false;
|
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",
|
.name = "bh",
|
||||||
.target = target,
|
.target = target,
|
||||||
.optimize = optimize,
|
.optimize = optimize,
|
||||||
|
|
|
||||||
|
|
@ -3,41 +3,37 @@ const bh = @import("bh");
|
||||||
|
|
||||||
// very tiny, not intended to build anything just to run tests linked with libc
|
// very tiny, not intended to build anything just to run tests linked with libc
|
||||||
pub fn build(b: *std.Build) void {
|
pub fn build(b: *std.Build) void {
|
||||||
const opts = bh.declareOptions(b);
|
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("cimgui", .{
|
const cimgui = bh.MakeModLib(b, .{
|
||||||
.target = opts.target,
|
|
||||||
.optimize = opts.optimize,
|
|
||||||
.link_libc = true,
|
|
||||||
.root_source_file = b.path("src/cimgui.zig"),
|
|
||||||
});
|
|
||||||
|
|
||||||
mod.addIncludePath(b.path("cimgui/imgui"));
|
|
||||||
mod.addIncludePath(b.path("cimgui/SDL/include"));
|
|
||||||
mod.addIncludePath(b.path("cimplot"));
|
|
||||||
mod.addIncludePath(b.path("cimplot/implot"));
|
|
||||||
|
|
||||||
const cimgui = b.addLibrary(.{
|
|
||||||
.name = "cimgui",
|
.name = "cimgui",
|
||||||
.root_module = b.createModule(.{
|
.target = target,
|
||||||
.optimize = opts.optimize,
|
.optimize = optimize,
|
||||||
.target = opts.target,
|
.static_build = static_build,
|
||||||
}),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
cimgui.linkLibC();
|
cimgui.install();
|
||||||
|
|
||||||
if (opts.target.result.abi != .msvc)
|
cimgui.mod.addIncludePath(b.path("cimgui/SDL/include"));
|
||||||
cimgui.linkLibCpp();
|
cimgui.mod.addIncludePath(b.path("cimplot"));
|
||||||
|
cimgui.mod.addIncludePath(b.path("cimgui/imgui"));
|
||||||
|
cimgui.mod.addIncludePath(b.path("cimplot/implot"));
|
||||||
|
|
||||||
cimgui.addIncludePath(b.path("cimgui"));
|
cimgui.lib.linkLibC();
|
||||||
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.addCSourceFiles(.{
|
if (target.result.abi != .msvc)
|
||||||
|
cimgui.lib.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.lib.addCSourceFiles(.{
|
||||||
.root = b.path("cimgui/imgui"),
|
.root = b.path("cimgui/imgui"),
|
||||||
.files = &[_][]const u8{
|
.files = &[_][]const u8{
|
||||||
"cimgui.cpp",
|
"cimgui.cpp",
|
||||||
|
|
@ -52,7 +48,7 @@ pub fn build(b: *std.Build) void {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
cimgui.addCSourceFiles(.{
|
cimgui.lib.addCSourceFiles(.{
|
||||||
.root = b.path("cimplot"),
|
.root = b.path("cimplot"),
|
||||||
.files = &[_][]const u8{
|
.files = &[_][]const u8{
|
||||||
"cimplot.cpp",
|
"cimplot.cpp",
|
||||||
|
|
@ -62,20 +58,20 @@ pub fn build(b: *std.Build) void {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
mod.linkLibrary(cimgui);
|
|
||||||
|
|
||||||
// I could've made cimgui a seperate lib,
|
// I could've made cimgui a seperate lib,
|
||||||
// I can seperate it out later if needed.
|
// I can seperate it out later if needed.
|
||||||
const test_step = b.step("test", "run unit tests for imgui");
|
const test_step = b.step("test", "run unit tests for imgui");
|
||||||
const tests = b.addTest(.{
|
const tests = b.addTest(.{
|
||||||
.root_module = b.createModule(.{
|
.root_module = b.createModule(.{
|
||||||
.target = opts.target,
|
.target = target,
|
||||||
.optimize = opts.optimize,
|
.optimize = optimize,
|
||||||
.root_source_file = b.path("tests/tests.zig"),
|
.root_source_file = b.path("tests/tests.zig"),
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
tests.root_module.addImport("cimgui", mod);
|
tests.root_module.addImport("cimgui", cimgui.mod);
|
||||||
|
tests.root_module.linkLibrary(cimgui.lib);
|
||||||
|
|
||||||
const runArtifact = b.addRunArtifact(tests);
|
const runArtifact = b.addRunArtifact(tests);
|
||||||
test_step.dependOn(&runArtifact.step);
|
test_step.dependOn(&runArtifact.step);
|
||||||
b.installArtifact(tests);
|
b.installArtifact(tests);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
const cimgui = @import("cimgui");
|
||||||
|
|
||||||
|
test "huh" {}
|
||||||
|
|
@ -2,7 +2,9 @@ const std = @import("std");
|
||||||
const bh = @import("bh");
|
const bh = @import("bh");
|
||||||
|
|
||||||
pub fn build(b: *std.Build) void {
|
pub fn build(b: *std.Build) void {
|
||||||
const opts = bh.declareOptions(b);
|
const target = b.standardTargetOptions(.{});
|
||||||
|
const optimize = b.standardOptimizeOption(.{});
|
||||||
|
const static_build = b.option(bool, "static_build", "builds backlog dependencies for static linking") orelse false;
|
||||||
|
|
||||||
// am i good to always have enet as static?
|
// am i good to always have enet as static?
|
||||||
// const enet = if (true) b.addStaticLibrary(.{
|
// const enet = if (true) b.addStaticLibrary(.{
|
||||||
|
|
@ -15,18 +17,18 @@ pub fn build(b: *std.Build) void {
|
||||||
// .optimize = optimize,
|
// .optimize = optimize,
|
||||||
// });
|
// });
|
||||||
|
|
||||||
const enet = b.addLibrary(.{
|
const enet = bh.MakeModLib(b, .{
|
||||||
.name = "enet_c",
|
.name = "enet",
|
||||||
.linkage = .static,
|
.target = target,
|
||||||
.root_module = b.createModule(.{
|
.optimize = optimize,
|
||||||
.target = opts.target,
|
.static_build = static_build,
|
||||||
.optimize = opts.optimize,
|
|
||||||
}),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
enet.linkLibC();
|
enet.install();
|
||||||
|
|
||||||
enet.addCSourceFiles(.{
|
enet.lib.linkLibC();
|
||||||
|
|
||||||
|
enet.lib.addCSourceFiles(.{
|
||||||
.root = b.path("enet-1.3.18"),
|
.root = b.path("enet-1.3.18"),
|
||||||
.files = &.{
|
.files = &.{
|
||||||
"callbacks.c",
|
"callbacks.c",
|
||||||
|
|
@ -41,14 +43,13 @@ pub fn build(b: *std.Build) void {
|
||||||
},
|
},
|
||||||
.flags = &.{"-DHAS_OFFSETOF=1"},
|
.flags = &.{"-DHAS_OFFSETOF=1"},
|
||||||
});
|
});
|
||||||
|
enet.addIncludePath("enet-1.3.18/include");
|
||||||
enet.addIncludePath(b.path("enet-1.3.18/include"));
|
|
||||||
|
|
||||||
// Platform-specific configuration
|
// Platform-specific configuration
|
||||||
switch (opts.target.result.os.tag) {
|
switch (target.result.os.tag) {
|
||||||
.windows => {
|
.windows => {
|
||||||
enet.linkSystemLibrary("ws2_32");
|
enet.lib.linkSystemLibrary("ws2_32");
|
||||||
enet.linkSystemLibrary("winmm");
|
enet.lib.linkSystemLibrary("winmm");
|
||||||
// Use .def file to control exports and avoid CRT symbol conflicts
|
// Use .def file to control exports and avoid CRT symbol conflicts
|
||||||
},
|
},
|
||||||
.linux, .macos => {
|
.linux, .macos => {
|
||||||
|
|
@ -57,29 +58,18 @@ pub fn build(b: *std.Build) void {
|
||||||
else => {},
|
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 test_step = b.step("test", "run unit tests for enet");
|
||||||
const tests = b.addTest(.{
|
const tests = b.addTest(.{
|
||||||
.root_module = b.createModule(.{
|
.root_module = b.createModule(.{
|
||||||
.link_libc = true,
|
.link_libc = true,
|
||||||
.target = opts.target,
|
.target = target,
|
||||||
.optimize = opts.optimize,
|
.optimize = optimize,
|
||||||
.root_source_file = b.path("src/tests.zig"),
|
.root_source_file = b.path("src/tests.zig"),
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
tests.root_module.addImport("enet", mod);
|
tests.linkLibrary(enet.lib);
|
||||||
|
tests.root_module.addImport("enet", enet.mod);
|
||||||
tests.root_module.addIncludePath(b.path("enet-1.3.18/include/"));
|
tests.root_module.addIncludePath(b.path("enet-1.3.18/include/"));
|
||||||
const runArtifact = b.addRunArtifact(tests);
|
const runArtifact = b.addRunArtifact(tests);
|
||||||
test_step.dependOn(&runArtifact.step);
|
test_step.dependOn(&runArtifact.step);
|
||||||
|
|
@ -89,11 +79,11 @@ pub fn build(b: *std.Build) void {
|
||||||
.name = "test-server",
|
.name = "test-server",
|
||||||
.root_module = b.createModule(.{
|
.root_module = b.createModule(.{
|
||||||
.root_source_file = b.path("src/test_server.zig"),
|
.root_source_file = b.path("src/test_server.zig"),
|
||||||
.target = opts.target,
|
.target = target,
|
||||||
.optimize = opts.optimize,
|
.optimize = optimize,
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
test_server.root_module.addImport("enet", mod);
|
test_server.root_module.addImport("enet", enet.mod);
|
||||||
test_server.linkLibC();
|
test_server.linkLibC();
|
||||||
|
|
||||||
// Test client executable
|
// Test client executable
|
||||||
|
|
@ -101,11 +91,11 @@ pub fn build(b: *std.Build) void {
|
||||||
.name = "test-client",
|
.name = "test-client",
|
||||||
.root_module = b.createModule(.{
|
.root_module = b.createModule(.{
|
||||||
.root_source_file = b.path("src/test_client.zig"),
|
.root_source_file = b.path("src/test_client.zig"),
|
||||||
.target = opts.target,
|
.target = target,
|
||||||
.optimize = opts.optimize,
|
.optimize = optimize,
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
test_client.root_module.addImport("enet", mod);
|
test_client.root_module.addImport("enet", enet.mod);
|
||||||
test_client.linkLibC();
|
test_client.linkLibC();
|
||||||
|
|
||||||
// Install test programs
|
// Install test programs
|
||||||
|
|
@ -133,6 +123,12 @@ pub fn build(b: *std.Build) void {
|
||||||
const build_tests_step = b.step("build-tests", "Build test server and client programs");
|
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_server.step);
|
||||||
build_tests_step.dependOn(&install_test_client.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
|
// Custom step to run server and client concurrently for loopback testing
|
||||||
|
|
|
||||||
|
|
@ -2,28 +2,27 @@ const std = @import("std");
|
||||||
const bh = @import("bh");
|
const bh = @import("bh");
|
||||||
|
|
||||||
pub fn build(b: *std.Build) void {
|
pub fn build(b: *std.Build) void {
|
||||||
const opts = bh.declareOptions(b);
|
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("lua", .{
|
const lua = bh.MakeModLib(b, .{
|
||||||
.target = opts.target,
|
.name = "lua",
|
||||||
.optimize = opts.optimize,
|
.target = target,
|
||||||
.root_source_file = b.path("src/lua.zig"),
|
.optimize = optimize,
|
||||||
.link_libc = true,
|
.static_build = static_build,
|
||||||
|
.root = b.path("src/lua.zig"),
|
||||||
});
|
});
|
||||||
|
|
||||||
const luac = b.addLibrary(.{
|
lua.install();
|
||||||
.name = "luac",
|
|
||||||
.linkage = if (opts.static_build) .static else .dynamic,
|
|
||||||
.root_module = b.createModule(.{
|
|
||||||
.target = opts.target,
|
|
||||||
.optimize = opts.optimize,
|
|
||||||
.link_libc = true,
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
b.installArtifact(luac);
|
// Add include paths to module (for Zig @cImport)
|
||||||
|
lua.addIncludePath("lua/src/");
|
||||||
|
lua.addIncludePath("src/");
|
||||||
|
|
||||||
luac.addCSourceFiles(.{
|
// Configure library
|
||||||
|
lua.lib.linkLibC();
|
||||||
|
lua.lib.addCSourceFiles(.{
|
||||||
.root = b.path("lua/src/"),
|
.root = b.path("lua/src/"),
|
||||||
.files = &.{
|
.files = &.{
|
||||||
"lapi.c",
|
"lapi.c",
|
||||||
|
|
@ -61,37 +60,30 @@ pub fn build(b: *std.Build) void {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
luac.addCSourceFile(.{ .file = b.path("src/limited_io.c") });
|
lua.lib.addCSourceFile(.{ .file = b.path("src/limited_io.c") });
|
||||||
|
|
||||||
if (opts.target.result.os.tag == .windows) {
|
if (target.result.os.tag == .windows) {
|
||||||
luac.addCSourceFile(.{ .file = b.path("src/minidumpsetup.cpp") });
|
lua.lib.addCSourceFile(.{ .file = b.path("src/minidumpsetup.cpp") });
|
||||||
if (opts.target.result.abi != .msvc)
|
if (target.result.abi != .msvc)
|
||||||
luac.linkLibCpp();
|
lua.lib.linkLibCpp();
|
||||||
luac.linkLibC();
|
|
||||||
} else {
|
} else {
|
||||||
luac.addCSourceFile(.{ .file = b.path("src/minidumpstub.cpp") });
|
lua.lib.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 run_step = b.step("test", "");
|
||||||
const tests = b.addExecutable(.{
|
const tests = b.addExecutable(.{
|
||||||
.name = "run-lua",
|
.name = "run-lua",
|
||||||
.root_module = b.createModule(.{
|
.root_module = b.createModule(.{
|
||||||
.target = opts.target,
|
.target = target,
|
||||||
.optimize = opts.optimize,
|
.optimize = optimize,
|
||||||
.root_source_file = b.path("test/test-lua.zig"),
|
.root_source_file = b.path("test/test-lua.zig"),
|
||||||
.link_libc = true,
|
.link_libc = true,
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
tests.root_module.addImport("lua", mod);
|
tests.root_module.addImport("lua", lua.mod);
|
||||||
|
tests.root_module.linkLibrary(lua.lib);
|
||||||
const runArtifact = b.addRunArtifact(tests);
|
const runArtifact = b.addRunArtifact(tests);
|
||||||
run_step.dependOn(&runArtifact.step);
|
run_step.dependOn(&runArtifact.step);
|
||||||
|
b.installArtifact(tests);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,40 +2,42 @@ const std = @import("std");
|
||||||
const bh = @import("bh");
|
const bh = @import("bh");
|
||||||
|
|
||||||
pub fn build(b: *std.Build) void {
|
pub fn build(b: *std.Build) void {
|
||||||
const opts = bh.declareOptions(b);
|
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 miniaudio_c = b.addLibrary(.{
|
const miniaudio = bh.MakeModLib(b, .{
|
||||||
.name = "miniaudio_c",
|
.name = "miniaudio",
|
||||||
.linkage = if (opts.static_build) .static else .dynamic,
|
.target = target,
|
||||||
.root_module = b.createModule(.{
|
.optimize = optimize,
|
||||||
.target = opts.target,
|
.static_build = static_build,
|
||||||
.optimize = opts.optimize,
|
.root = b.path("src/miniaudio.zig"),
|
||||||
.link_libc = true,
|
|
||||||
}),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
b.installArtifact(miniaudio_c);
|
miniaudio.install();
|
||||||
miniaudio_c.addCSourceFile(.{ .file = b.path("src/miniaudio.cpp"), .flags = &.{"-fno-sanitize=all"}, .language = .c });
|
|
||||||
miniaudio_c.addIncludePath(b.path("include"));
|
|
||||||
|
|
||||||
const mod = b.addModule("miniaudio", .{ .target = opts.target, .optimize = opts.optimize, .root_source_file = b.path("src/miniaudio.zig") });
|
// Add include paths to module (for Zig @cImport)
|
||||||
|
miniaudio.addIncludePath("./include");
|
||||||
|
|
||||||
mod.linkLibrary(miniaudio_c);
|
// Configure library
|
||||||
mod.addIncludePath(b.path("./include"));
|
miniaudio.lib.linkLibC();
|
||||||
|
|
||||||
|
miniaudio.lib.addCSourceFile(.{ .file = b.path("src/miniaudio.cpp"), .flags = &.{"-fno-sanitize=all"}, .language = .c });
|
||||||
|
|
||||||
// ======== tests ============
|
// ======== tests ============
|
||||||
const test_step = b.step("test", "");
|
const test_step = b.step("test", "");
|
||||||
const tests = b.addTest(.{
|
const tests = b.addTest(.{
|
||||||
.root_module = b.createModule(.{
|
.root_module = b.createModule(.{
|
||||||
.target = opts.target,
|
.target = target,
|
||||||
.optimize = opts.optimize,
|
.optimize = optimize,
|
||||||
.root_source_file = b.path("src/miniaudio-test.zig"),
|
.root_source_file = b.path("src/miniaudio-test.zig"),
|
||||||
.link_libc = true,
|
.link_libc = true,
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
tests.addIncludePath(b.path("./include"));
|
tests.addIncludePath(b.path("./include"));
|
||||||
|
|
||||||
tests.root_module.addImport("miniaudio", mod);
|
tests.root_module.addImport("miniaudio", miniaudio.mod);
|
||||||
|
tests.root_module.linkLibrary(miniaudio.lib);
|
||||||
const runArtifact = b.addRunArtifact(tests);
|
const runArtifact = b.addRunArtifact(tests);
|
||||||
test_step.dependOn(&runArtifact.step);
|
test_step.dependOn(&runArtifact.step);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,67 +2,76 @@ const std = @import("std");
|
||||||
const bh = @import("bh");
|
const bh = @import("bh");
|
||||||
|
|
||||||
pub fn build(b: *std.Build) void {
|
pub fn build(b: *std.Build) void {
|
||||||
const opts = bh.declareOptions(b);
|
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("nfd", .{
|
const nfd = bh.MakeModLib(b, .{
|
||||||
.target = opts.target,
|
.name = "nfd",
|
||||||
.optimize = opts.optimize,
|
.target = target,
|
||||||
.root_source_file = b.path("src/nfd.zig"),
|
.optimize = optimize,
|
||||||
.link_libc = true,
|
.static_build = static_build,
|
||||||
|
.root = b.path("src/nfd.zig"),
|
||||||
});
|
});
|
||||||
|
|
||||||
mod.addCSourceFile(.{
|
nfd.install();
|
||||||
|
|
||||||
|
// Add include paths to module (for Zig @cImport)
|
||||||
|
nfd.addIncludePath("include");
|
||||||
|
|
||||||
|
// Configure library
|
||||||
|
nfd.lib.linkLibC();
|
||||||
|
nfd.lib.addCSourceFile(.{
|
||||||
.file = b.path("src/nfd_common.c"),
|
.file = b.path("src/nfd_common.c"),
|
||||||
.flags = &.{},
|
.flags = &.{},
|
||||||
});
|
});
|
||||||
|
|
||||||
mod.addIncludePath(b.path("include"));
|
if (target.result.os.tag == .macos) {
|
||||||
|
nfd.lib.addCSourceFile(.{
|
||||||
if (opts.target.result.os.tag == .macos) {
|
|
||||||
mod.addCSourceFile(.{
|
|
||||||
.file = b.path("src/nfd_cocoa.m"),
|
.file = b.path("src/nfd_cocoa.m"),
|
||||||
.flags = &.{},
|
.flags = &.{},
|
||||||
});
|
});
|
||||||
mod.linkFramework("AppKit", .{});
|
nfd.lib.linkFramework("AppKit");
|
||||||
} else if (opts.target.result.os.tag == .windows) {
|
} else if (target.result.os.tag == .windows) {
|
||||||
mod.addCSourceFile(.{
|
nfd.lib.addCSourceFile(.{
|
||||||
.file = b.path("src/nfd_win.cpp"),
|
.file = b.path("src/nfd_win.cpp"),
|
||||||
.flags = &.{},
|
.flags = &.{},
|
||||||
});
|
});
|
||||||
mod.linkSystemLibrary("ole32", .{});
|
nfd.lib.linkSystemLibrary("ole32");
|
||||||
} else if (opts.target.result.os.tag == .linux) {
|
} else if (target.result.os.tag == .linux) {
|
||||||
// mod.addCSourceFile(.{
|
// nfd.lib.addCSourceFile(.{
|
||||||
// .file = b.path("src/nfd_gtk.c"),
|
// .file = b.path("src/nfd_gtk.c"),
|
||||||
// .flags = &.{},
|
// .flags = &.{},
|
||||||
// });
|
// });
|
||||||
mod.addCSourceFile(.{
|
nfd.lib.addCSourceFile(.{
|
||||||
.file = b.path("src/nfd_null.c"),
|
.file = b.path("src/nfd_null.c"),
|
||||||
.flags = &.{},
|
.flags = &.{},
|
||||||
});
|
});
|
||||||
// mod.linkSystemLibrary("gdk-3", .{});
|
// nfd.lib.linkSystemLibrary("gdk-3", .{});
|
||||||
// mod.linkSystemLibrary("atk-1.0", .{});
|
// nfd.lib.linkSystemLibrary("atk-1.0", .{});
|
||||||
// mod.linkSystemLibrary("gtk-3", .{});
|
// nfd.lib.linkSystemLibrary("gtk-3", .{});
|
||||||
// mod.linkSystemLibrary("glib-2.0", .{});
|
// nfd.lib.linkSystemLibrary("glib-2.0", .{});
|
||||||
// mod.linkSystemLibrary("gobject-2.0", .{});
|
// nfd.lib.linkSystemLibrary("gobject-2.0", .{});
|
||||||
}
|
}
|
||||||
|
|
||||||
const p2dep = b.dependency("p2", .{ .target = opts.target, .optimize = opts.optimize, .static_build = opts.static_build });
|
const p2dep = b.dependency("p2", .{ .target = target, .optimize = optimize, .static_build = static_build });
|
||||||
|
|
||||||
const p2mod = p2dep.module("p2");
|
const p2mod = p2dep.module("p2");
|
||||||
mod.addImport("p2", p2mod);
|
nfd.mod.addImport("p2", p2mod);
|
||||||
|
|
||||||
const test_step = b.step("test", "");
|
const test_step = b.step("test", "");
|
||||||
const tests = b.addTest(.{
|
const tests = b.addTest(.{
|
||||||
.root_module = b.createModule(.{
|
.root_module = b.createModule(.{
|
||||||
.target = opts.target,
|
.target = target,
|
||||||
.optimize = opts.optimize,
|
.optimize = optimize,
|
||||||
.root_source_file = b.path("src/nfd.zig"),
|
.root_source_file = b.path("src/nfd.zig"),
|
||||||
.link_libc = true,
|
.link_libc = true,
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
tests.addIncludePath(b.path("./include"));
|
tests.addIncludePath(b.path("./include"));
|
||||||
|
|
||||||
tests.root_module.addImport("nfd", mod);
|
tests.root_module.addImport("nfd", nfd.mod);
|
||||||
|
tests.root_module.linkLibrary(nfd.lib);
|
||||||
tests.root_module.addImport("p2", p2mod);
|
tests.root_module.addImport("p2", p2mod);
|
||||||
const runArtifact = b.addRunArtifact(tests);
|
const runArtifact = b.addRunArtifact(tests);
|
||||||
test_step.dependOn(&runArtifact.step);
|
test_step.dependOn(&runArtifact.step);
|
||||||
|
|
|
||||||
|
|
@ -2,25 +2,32 @@ const std = @import("std");
|
||||||
const bh = @import("bh");
|
const bh = @import("bh");
|
||||||
|
|
||||||
pub fn build(b: *std.Build) void {
|
pub fn build(b: *std.Build) void {
|
||||||
const opts = bh.declareOptions(b);
|
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("objLoader", .{
|
const objLoader = bh.MakeModLib(b, .{
|
||||||
.target = opts.target,
|
.name = "objLoader",
|
||||||
.optimize = opts.optimize,
|
.target = target,
|
||||||
.root_source_file = b.path("src/obj_loader.zig"),
|
.optimize = optimize,
|
||||||
|
.static_build = static_build,
|
||||||
|
.root = b.path("src/obj_loader.zig"),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
objLoader.install();
|
||||||
|
|
||||||
const test_step = b.step("test", "");
|
const test_step = b.step("test", "");
|
||||||
const tests = b.addTest(.{
|
const tests = b.addTest(.{
|
||||||
.root_module = b.createModule(.{
|
.root_module = b.createModule(.{
|
||||||
.target = opts.target,
|
.target = target,
|
||||||
.optimize = opts.optimize,
|
.optimize = optimize,
|
||||||
.root_source_file = b.path("src/obj_loader.zig"),
|
.root_source_file = b.path("src/obj_loader.zig"),
|
||||||
.link_libc = true,
|
.link_libc = true,
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
tests.root_module.addImport("objLoader", mod);
|
tests.root_module.addImport("objLoader", objLoader.mod);
|
||||||
|
tests.root_module.linkLibrary(objLoader.lib);
|
||||||
const runArtifact = b.addRunArtifact(tests);
|
const runArtifact = b.addRunArtifact(tests);
|
||||||
test_step.dependOn(&runArtifact.step);
|
test_step.dependOn(&runArtifact.step);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@
|
||||||
// ozz_animation_offline_fbx -- fbx importing, requires linking wiht fbx sdk... maybe i dont want this... fuck adobe
|
// ozz_animation_offline_fbx -- fbx importing, requires linking wiht fbx sdk... maybe i dont want this... fuck adobe
|
||||||
|
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const bh = @import("bh");
|
|
||||||
|
|
||||||
const Build = std.Build;
|
const Build = std.Build;
|
||||||
const LazyPath = LazyPath;
|
const LazyPath = LazyPath;
|
||||||
|
|
@ -87,7 +86,7 @@ pub const GltfToOzz = struct {
|
||||||
});
|
});
|
||||||
|
|
||||||
const dep = b.dependency(opts.importName, .{});
|
const dep = b.dependency(opts.importName, .{});
|
||||||
const ozz_mod = dep.artifact("ozz_cpp");
|
const ozz_mod = dep.artifact("ozz");
|
||||||
exe.root_module.linkLibrary(ozz_mod);
|
exe.root_module.linkLibrary(ozz_mod);
|
||||||
|
|
||||||
exe.root_module.addIncludePath(b.path("ozz-animation/include"));
|
exe.root_module.addIncludePath(b.path("ozz-animation/include"));
|
||||||
|
|
@ -143,14 +142,16 @@ pub const GltfToOzz = struct {
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn build(b: *std.Build) void {
|
pub fn build(b: *std.Build) void {
|
||||||
const opts = bh.declareOptions(b);
|
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 ozz_cpp = b.addLibrary(.{
|
const ozz_cpp = b.addLibrary(.{
|
||||||
.linkage = if (opts.static_build) .static else .dynamic,
|
.linkage = if (static_build) .static else .dynamic,
|
||||||
.name = "ozz_cpp",
|
.name = "ozz",
|
||||||
.root_module = b.createModule(.{
|
.root_module = b.createModule(.{
|
||||||
.target = opts.target,
|
.target = target,
|
||||||
.optimize = opts.optimize,
|
.optimize = optimize,
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -160,7 +161,7 @@ pub fn build(b: *std.Build) void {
|
||||||
ozz_cpp.addIncludePath(b.path("ozz-animation/src"));
|
ozz_cpp.addIncludePath(b.path("ozz-animation/src"));
|
||||||
ozz_cpp.linkLibC();
|
ozz_cpp.linkLibC();
|
||||||
|
|
||||||
if (opts.target.result.abi != .msvc)
|
if (target.result.abi != .msvc)
|
||||||
ozz_cpp.linkLibCpp();
|
ozz_cpp.linkLibCpp();
|
||||||
|
|
||||||
const src_dir = "ozz-animation/src/";
|
const src_dir = "ozz-animation/src/";
|
||||||
|
|
@ -207,8 +208,8 @@ pub fn build(b: *std.Build) void {
|
||||||
.name = "ozz-tests",
|
.name = "ozz-tests",
|
||||||
.root_module = b.createModule(.{
|
.root_module = b.createModule(.{
|
||||||
.root_source_file = b.path("tests/test.zig"),
|
.root_source_file = b.path("tests/test.zig"),
|
||||||
.target = opts.target,
|
.target = target,
|
||||||
.optimize = opts.optimize,
|
.optimize = optimize,
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
b.installArtifact(tests);
|
b.installArtifact(tests);
|
||||||
|
|
|
||||||
|
|
@ -2,25 +2,32 @@ const std = @import("std");
|
||||||
const bh = @import("bh");
|
const bh = @import("bh");
|
||||||
|
|
||||||
pub fn build(b: *std.Build) void {
|
pub fn build(b: *std.Build) void {
|
||||||
const opts = bh.declareOptions(b);
|
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 mod = b.addModule("p2", .{
|
const p2 = bh.MakeModLib(b, .{
|
||||||
.target = opts.target,
|
.name = "p2",
|
||||||
.optimize = opts.optimize,
|
.target = target,
|
||||||
.root_source_file = b.path("src/p2.zig"),
|
.optimize = optimize,
|
||||||
|
.static_build = static_build,
|
||||||
|
.root = b.path("src/p2.zig"),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
p2.install();
|
||||||
|
|
||||||
const test_step = b.step("test", "test p2");
|
const test_step = b.step("test", "test p2");
|
||||||
const tests = b.addTest(.{
|
const tests = b.addTest(.{
|
||||||
.root_module = b.createModule(.{
|
.root_module = b.createModule(.{
|
||||||
.target = opts.target,
|
.target = target,
|
||||||
.optimize = opts.optimize,
|
.optimize = optimize,
|
||||||
.root_source_file = b.path("src/p2.zig"),
|
.root_source_file = b.path("src/p2.zig"),
|
||||||
}),
|
}),
|
||||||
// .link_libc = true,
|
// .link_libc = true,
|
||||||
});
|
});
|
||||||
|
|
||||||
tests.root_module.addImport("p2", mod);
|
tests.root_module.addImport("p2", p2.mod);
|
||||||
|
tests.root_module.linkLibrary(p2.lib);
|
||||||
const runArtifact = b.addRunArtifact(tests);
|
const runArtifact = b.addRunArtifact(tests);
|
||||||
test_step.dependOn(&runArtifact.step);
|
test_step.dependOn(&runArtifact.step);
|
||||||
if (b.args) |args| {
|
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 concurrent_queue = @import("structures/concurrent-queue.zig");
|
||||||
pub const ConcurrentQueueU = concurrent_queue.ConcurrentQueueU;
|
pub const ConcurrentQueueU = concurrent_queue.ConcurrentQueueU;
|
||||||
pub const ConcurrentQueueUnmanagedAdvanced = concurrent_queue.ConcurrentQueueUnmanagedAdvanced;
|
pub const ConcurrentQueueAdvanced = concurrent_queue.ConcurrentQueueAdvanced;
|
||||||
|
|
||||||
pub const string_pool = @import("structures/string-pool.zig");
|
pub const string_pool = @import("structures/string-pool.zig");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,13 +14,11 @@ pub const ConcurrentQueueError = error{
|
||||||
QueueIsFull,
|
QueueIsFull,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn ConcurrentQueueU(comptime T: type) type {
|
pub fn ConcurrentQueue(comptime T: type) type {
|
||||||
return ConcurrentQueueUnmanagedAdvanced(T, .{});
|
return ConcurrentQueueAdvanced(T, .{});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ConcurrentQueueAssert(comptime T: type) type {
|
pub const ConcurrentQueueU = ConcurrentQueue;
|
||||||
return ConcurrentQueueUnmanagedAdvanced(T, .{ .allowAsserts = true });
|
|
||||||
}
|
|
||||||
|
|
||||||
// lock-free concurrent queue, fixed capacity,
|
// lock-free concurrent queue, fixed capacity,
|
||||||
// will never resize.
|
// will never resize.
|
||||||
|
|
@ -33,7 +31,7 @@ pub const ConcurrentStatus = packed struct(usize) {
|
||||||
generation: u63 = 0,
|
generation: u63 = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn ConcurrentQueueUnmanagedAdvanced(comptime T: type, comptime opts: struct {
|
pub fn ConcurrentQueueAdvanced(comptime T: type, comptime opts: struct {
|
||||||
allowAsserts: bool = false,
|
allowAsserts: bool = false,
|
||||||
debug: bool = false,
|
debug: bool = false,
|
||||||
}) type {
|
}) type {
|
||||||
|
|
@ -142,7 +140,7 @@ test "concurrent queue basic correctness test" {
|
||||||
|
|
||||||
const allocator = std.testing.allocator;
|
const allocator = std.testing.allocator;
|
||||||
|
|
||||||
var y = try ConcurrentQueueUnmanagedAdvanced(Info, .{ .allowAsserts = true, .debug = true }).initCapacity(allocator, 420);
|
var y = try ConcurrentQueueAdvanced(Info, .{ .allowAsserts = true, .debug = true }).initCapacity(allocator, 420);
|
||||||
defer y.deinit(allocator);
|
defer y.deinit(allocator);
|
||||||
|
|
||||||
try y.push(.{});
|
try y.push(.{});
|
||||||
|
|
@ -158,7 +156,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() });
|
try utils.assertf(y.count() == 0, "expected there to be {d} elements in queue, we saw {d}", .{ 0, y.count() });
|
||||||
|
|
||||||
var x = try ConcurrentQueueU(Info).initCapacity(allocator, 12);
|
var x = try ConcurrentQueue(Info).initCapacity(allocator, 12);
|
||||||
defer x.deinit(allocator);
|
defer x.deinit(allocator);
|
||||||
|
|
||||||
try x.push(.{ .x = 0 });
|
try x.push(.{ .x = 0 });
|
||||||
|
|
@ -189,7 +187,7 @@ test "concurrent queue multiple producer single consumer" {
|
||||||
arb: [4096]u8 = undefined,
|
arb: [4096]u8 = undefined,
|
||||||
};
|
};
|
||||||
|
|
||||||
const QueueType = ConcurrentQueueUnmanagedAdvanced(Payload, .{ .debug = false, .allowAsserts = true });
|
const QueueType = ConcurrentQueueAdvanced(Payload, .{ .debug = false, .allowAsserts = true });
|
||||||
|
|
||||||
const Wrap = struct {
|
const Wrap = struct {
|
||||||
pub fn threadFunc(queueRef: *QueueType, id: i64, exitSignal: *Atomic(bool), pushedCountResults: *Atomic(i64)) void {
|
pub fn threadFunc(queueRef: *QueueType, id: i64, exitSignal: *Atomic(bool), pushedCountResults: *Atomic(i64)) void {
|
||||||
|
|
|
||||||
|
|
@ -42,8 +42,6 @@ pub fn SparseMultiSetAdvanced(comptime T: type, comptime SparseSize: u32) type {
|
||||||
return struct {
|
return struct {
|
||||||
pub const SetType = std.MultiArrayList(T);
|
pub const SetType = std.MultiArrayList(T);
|
||||||
|
|
||||||
pub const InnerType = T;
|
|
||||||
|
|
||||||
allocator: std.mem.Allocator,
|
allocator: std.mem.Allocator,
|
||||||
denseIndices: ArrayListUnmanaged(SetHandle),
|
denseIndices: ArrayListUnmanaged(SetHandle),
|
||||||
dense: SetType,
|
dense: SetType,
|
||||||
|
|
@ -313,7 +311,6 @@ pub fn SparseSetAdvanced(comptime T: type, comptime SparseSize: u32) type {
|
||||||
opCount: u32 = 0,
|
opCount: u32 = 0,
|
||||||
|
|
||||||
pub const StableReferences = false;
|
pub const StableReferences = false;
|
||||||
pub const InnerType = T;
|
|
||||||
|
|
||||||
pub fn getStateCount(self: @This()) u32 {
|
pub fn getStateCount(self: @This()) u32 {
|
||||||
return self.opCount;
|
return self.opCount;
|
||||||
|
|
@ -599,7 +596,6 @@ pub fn SparseMap(comptime T: type) type {
|
||||||
containerListener: ?ContainerListener = null,
|
containerListener: ?ContainerListener = null,
|
||||||
opCount: u32 = 0,
|
opCount: u32 = 0,
|
||||||
|
|
||||||
pub const InnerType = T;
|
|
||||||
pub const StableReferences = true;
|
pub const StableReferences = true;
|
||||||
|
|
||||||
pub fn create(backingAllocator: std.mem.Allocator) !*@This() {
|
pub fn create(backingAllocator: std.mem.Allocator) !*@This() {
|
||||||
|
|
@ -724,7 +720,6 @@ const interface = @import("interface.zig");
|
||||||
|
|
||||||
pub const EcsContainerInterface = interface.MakeInterface("EcsContainerInterfaceVTable", struct {
|
pub const EcsContainerInterface = interface.MakeInterface("EcsContainerInterfaceVTable", struct {
|
||||||
containerTypeName: []const u8,
|
containerTypeName: []const u8,
|
||||||
componentName: []const u8,
|
|
||||||
handleExists: *const fn (*const anyopaque, SetHandle) bool,
|
handleExists: *const fn (*const anyopaque, SetHandle) bool,
|
||||||
get: *const fn (*const anyopaque, SetHandle) ?*anyopaque,
|
get: *const fn (*const anyopaque, SetHandle) ?*anyopaque,
|
||||||
createWithHandle: *const fn (*anyopaque, SetHandle) *anyopaque,
|
createWithHandle: *const fn (*anyopaque, SetHandle) *anyopaque,
|
||||||
|
|
@ -792,7 +787,6 @@ pub const EcsContainerInterface = interface.MakeInterface("EcsContainerInterface
|
||||||
|
|
||||||
return .{
|
return .{
|
||||||
.containerTypeName = TargetType.ContainerTypeName,
|
.containerTypeName = TargetType.ContainerTypeName,
|
||||||
.componentName = @typeName(TargetType.InnerType),
|
|
||||||
.handleExists = Wrap.handleExists,
|
.handleExists = Wrap.handleExists,
|
||||||
.get = Wrap.get,
|
.get = Wrap.get,
|
||||||
.createWithHandle = Wrap.createWithHandle,
|
.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
|
// main purpose of this string-pool is to provide an RC-ableinterface for interface
|
||||||
// with GC'ed systems such as lua
|
// with GC'ed systems such as lua
|
||||||
|
|
||||||
pub var gStringContext: *StringContext = undefined;
|
var gStringContext: *StringContext = undefined;
|
||||||
|
|
||||||
pub const String = struct {
|
pub const String = struct {
|
||||||
index: u24,
|
index: u24,
|
||||||
|
|
|
||||||
|
|
@ -2,27 +2,35 @@ const std = @import("std");
|
||||||
const bh = @import("bh");
|
const bh = @import("bh");
|
||||||
|
|
||||||
pub fn build(b: *std.Build) void {
|
pub fn build(b: *std.Build) void {
|
||||||
const opts = bh.declareOptions(b);
|
const target = b.standardTargetOptions(.{});
|
||||||
|
const optimize = b.standardOptimizeOption(.{});
|
||||||
|
|
||||||
const p2dep = b.dependency("p2", .{ .target = opts.target, .optimize = opts.optimize, .static_build = opts.static_build });
|
const static_build = b.option(bool, "static_build", "builds backlog dependencies for static linking") orelse false;
|
||||||
|
|
||||||
const mod = b.addModule("packer", .{
|
const packer = bh.MakeModLib(b, .{
|
||||||
.target = opts.target,
|
.name = "packer",
|
||||||
.optimize = opts.optimize,
|
.target = target,
|
||||||
.root_source_file = b.path("src/packer.zig"),
|
.optimize = optimize,
|
||||||
|
.static_build = static_build,
|
||||||
|
.root = 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");
|
const p2mod = p2dep.module("p2");
|
||||||
mod.addImport("p2", p2mod);
|
packer.mod.addImport("p2", p2mod);
|
||||||
|
|
||||||
const test_exe = b.addTest(.{
|
const test_exe = b.addTest(.{
|
||||||
.root_module = b.createModule(.{
|
.root_module = b.createModule(.{
|
||||||
.target = opts.target,
|
.target = target,
|
||||||
.optimize = opts.optimize,
|
.optimize = optimize,
|
||||||
.root_source_file = b.path("tests/test.zig"),
|
.root_source_file = b.path("tests/test.zig"),
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
test_exe.root_module.addImport("packer", mod);
|
test_exe.root_module.addImport("packer", packer.mod);
|
||||||
|
test_exe.root_module.linkLibrary(packer.lib);
|
||||||
test_exe.root_module.addImport("p2", p2mod);
|
test_exe.root_module.addImport("p2", p2mod);
|
||||||
|
|
||||||
const test_step = b.step("test", "runs sample unit tests for packer");
|
const test_step = b.step("test", "runs sample unit tests for packer");
|
||||||
|
|
|
||||||
|
|
@ -174,7 +174,6 @@ pub const PackerFS = struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (self.anyWatchCallbacks.items) |*watch| {
|
for (self.anyWatchCallbacks.items) |*watch| {
|
||||||
// std.debug.print("anywatch callback: {s}\n", .{watch.path});
|
|
||||||
watch.call(std.mem.span(path));
|
watch.call(std.mem.span(path));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -342,8 +341,6 @@ pub const PackerFS = struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn installFileBytesMount(self: *@This(), path: []const u8, fileBytes: []align(8) u8, embedded: bool) !?PackerBytesMapping {
|
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;
|
const pakMountIndex = self.pakMountings.items.len;
|
||||||
try self.pakMountings.append(self.allocator, .{
|
try self.pakMountings.append(self.allocator, .{
|
||||||
.filePath = try self.stringAlloc().dupe(u8, path),
|
.filePath = try self.stringAlloc().dupe(u8, path),
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const bh = @import("bh");
|
|
||||||
|
|
||||||
pub fn addShaderDefinition(
|
pub fn addShaderDefinition(
|
||||||
b: *std.Build,
|
b: *std.Build,
|
||||||
|
|
@ -49,47 +48,54 @@ pub fn shaderDefintion(
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build(b: *std.Build) void {
|
pub fn build(b: *std.Build) void {
|
||||||
const opts = bh.declareOptions(b);
|
const target = b.standardTargetOptions(.{});
|
||||||
|
const optimize = b.standardOptimizeOption(.{});
|
||||||
|
|
||||||
const preferred_linkage: std.builtin.LinkMode = if (opts.static_build) .static else .dynamic;
|
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 sdl_dep = b.dependency("sdl", .{
|
const sdl_dep = b.dependency("sdl", .{
|
||||||
.target = opts.target,
|
.target = target,
|
||||||
.optimize = opts.optimize,
|
.optimize = optimize,
|
||||||
.preferred_linkage = preferred_linkage,
|
.preferred_linkage = preferred_linkage,
|
||||||
});
|
});
|
||||||
|
|
||||||
const sdl3_lib = sdl_dep.artifact("SDL3");
|
const sdl3_lib = sdl_dep.artifact("SDL3");
|
||||||
|
b.installArtifact(sdl3_lib);
|
||||||
|
|
||||||
const sdl3_fwd = b.addModule("SDL3", .{
|
const sdl3_fwd = b.addLibrary(.{
|
||||||
.target = opts.target,
|
.name = "sdl3",
|
||||||
.optimize = opts.optimize,
|
.root_module = b.createModule(.{
|
||||||
.root_source_file = b.path("src/sdl3_lib_fwd.zig"),
|
.target = target,
|
||||||
|
.optimize = optimize,
|
||||||
|
.root_source_file = b.path("src/sdl3_lib_fwd.zig"),
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
sdl3_fwd.linkLibrary(sdl3_lib);
|
sdl3_fwd.linkLibrary(sdl3_lib);
|
||||||
|
b.installArtifact(sdl3_fwd);
|
||||||
|
|
||||||
const mod = b.addModule("sdl3", .{
|
const mod = b.addModule("sdl3", .{
|
||||||
.target = opts.target,
|
.target = target,
|
||||||
.optimize = opts.optimize,
|
.optimize = optimize,
|
||||||
.root_source_file = b.path("src/sdl3.zig"),
|
.root_source_file = b.path("src/sdl3.zig"),
|
||||||
});
|
});
|
||||||
|
|
||||||
const shaderTypes = b.dependency("shaderTypes", .{
|
const shaderTypes = b.dependency("shaderTypes", .{
|
||||||
.target = opts.target,
|
.target = target,
|
||||||
.optimize = opts.optimize,
|
.optimize = optimize,
|
||||||
});
|
});
|
||||||
mod.addImport("shaderTypes", shaderTypes.module("shaderTypes"));
|
mod.addImport("shaderTypes", shaderTypes.module("shaderTypes"));
|
||||||
|
|
||||||
mod.addIncludePath(b.path("SDL/include"));
|
mod.addIncludePath(b.path("SDL/include"));
|
||||||
mod.linkLibrary(sdl3_lib);
|
mod.linkLibrary(sdl_dep.artifact("SDL3"));
|
||||||
|
|
||||||
const test_step2 = b.step("test", "run unit tests for sdl3");
|
const test_step2 = b.step("test", "run unit tests for sdl3");
|
||||||
const tests2 = b.addExecutable(.{
|
const tests2 = b.addExecutable(.{
|
||||||
.name = "hello-sdl",
|
.name = "hello-sdl",
|
||||||
.root_module = b.createModule(.{
|
.root_module = b.createModule(.{
|
||||||
.target = opts.target,
|
.target = target,
|
||||||
.optimize = opts.optimize,
|
.optimize = optimize,
|
||||||
.root_source_file = b.path("src/samples/compiletest.zig"),
|
.root_source_file = b.path("src/samples/compiletest.zig"),
|
||||||
.link_libc = true,
|
.link_libc = true,
|
||||||
}),
|
}),
|
||||||
|
|
@ -99,8 +105,8 @@ pub fn build(b: *std.Build) void {
|
||||||
const tests = b.addExecutable(.{
|
const tests = b.addExecutable(.{
|
||||||
.name = "hello-triangle",
|
.name = "hello-triangle",
|
||||||
.root_module = b.createModule(.{
|
.root_module = b.createModule(.{
|
||||||
.target = opts.target,
|
.target = target,
|
||||||
.optimize = opts.optimize,
|
.optimize = optimize,
|
||||||
.root_source_file = b.path("src/samples/hello-triangle.zig"),
|
.root_source_file = b.path("src/samples/hello-triangle.zig"),
|
||||||
.link_libc = true,
|
.link_libc = true,
|
||||||
}),
|
}),
|
||||||
|
|
@ -110,8 +116,8 @@ pub fn build(b: *std.Build) void {
|
||||||
const hello_window_exe = b.addExecutable(.{
|
const hello_window_exe = b.addExecutable(.{
|
||||||
.name = "hello-window",
|
.name = "hello-window",
|
||||||
.root_module = b.createModule(.{
|
.root_module = b.createModule(.{
|
||||||
.target = opts.target,
|
.target = target,
|
||||||
.optimize = opts.optimize,
|
.optimize = optimize,
|
||||||
.root_source_file = b.path("src/samples/hello-window.zig"),
|
.root_source_file = b.path("src/samples/hello-window.zig"),
|
||||||
.link_libc = true,
|
.link_libc = true,
|
||||||
}),
|
}),
|
||||||
|
|
@ -122,7 +128,7 @@ pub fn build(b: *std.Build) void {
|
||||||
|
|
||||||
tests.root_module.addImport("sdl3", mod);
|
tests.root_module.addImport("sdl3", mod);
|
||||||
|
|
||||||
const vertexDefinitions = addShaderDefinition(b, ".", opts.target, opts.optimize, "hello-triangle.vert", b.path("content/hello-triangle.vert.json"));
|
const vertexDefinitions = addShaderDefinition(b, ".", target, optimize, "hello-triangle.vert", b.path("content/hello-triangle.vert.json"));
|
||||||
tests.root_module.addImport("hello-triangle.vert", vertexDefinitions);
|
tests.root_module.addImport("hello-triangle.vert", vertexDefinitions);
|
||||||
|
|
||||||
const runArtifact = b.addRunArtifact(tests);
|
const runArtifact = b.addRunArtifact(tests);
|
||||||
|
|
@ -132,7 +138,6 @@ pub fn build(b: *std.Build) void {
|
||||||
test_step2.dependOn(&runArtifact2.step);
|
test_step2.dependOn(&runArtifact2.step);
|
||||||
|
|
||||||
b.installArtifact(hello_window_exe);
|
b.installArtifact(hello_window_exe);
|
||||||
b.installArtifact(sdl3_lib);
|
|
||||||
b.installArtifact(tests);
|
b.installArtifact(tests);
|
||||||
b.installArtifact(tests2);
|
b.installArtifact(tests2);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue