hot reloading is working now
This commit is contained in:
parent
db49ef3606
commit
252a5271a1
59
build.zig
59
build.zig
|
|
@ -139,65 +139,6 @@ pub fn addProgram(self: *BuildSystem, opts: AddProgramOptions) *std.Build.Module
|
|||
run_exe.dependOn(&cookShadersCommand.step);
|
||||
}
|
||||
|
||||
// I want to generate definitions from the spirv-reflect-tool during pre-build.
|
||||
//
|
||||
// shaders will now be part of content, not code. However. .zig code definitions will be generated
|
||||
// from content via the build.zig script.
|
||||
//
|
||||
// heres some thoughts:
|
||||
//
|
||||
// -Dupdate_shaders=true
|
||||
//
|
||||
// -Dupdate_shaders basically adds a run step to the build process 'python', 'tools/scripts/cook-shaders.py'
|
||||
//
|
||||
// 1. ensure spirv-reflect is compiled.
|
||||
// 2. shadercross cooker generates all shader outputs - specifically spv files. they are output to content/_shaders/
|
||||
// - search paths for shaders:
|
||||
// - content/shaders/**
|
||||
// - engine/<module names>/shaders/**
|
||||
// - shaders must have a unique name across the entire project, naming scheme should be <module>.shadername.<stage>.hlsl
|
||||
// 3. spirv-cross --reflect is called on each shader, updating the content/_shaders/defs/shader-name.json folder with up to date .json files
|
||||
//
|
||||
// final tree
|
||||
//
|
||||
// engine/
|
||||
// - ui/
|
||||
// - shaders/
|
||||
// - papyrus.rect.vert.hlsl
|
||||
// content/
|
||||
// - _shaders/
|
||||
// - def/
|
||||
// papyrus.rect.vert.json
|
||||
// - msl/
|
||||
// papyrus.rect.vert.msl
|
||||
// - spv/
|
||||
// papyrus.rect.vert.spv
|
||||
// - dxil/
|
||||
// papyrus.rect.vert.dxil
|
||||
//
|
||||
//
|
||||
// During build:
|
||||
// 1. spirv-reflect is called on each json in each folder and .zig shader interfaces added to the executable as a global import.
|
||||
// 2. if -Dupdate_shaders is not
|
||||
//
|
||||
// At any time:
|
||||
// asset-cooker will cook shaders and place them under content/_shaders/<msl|dxil|dxil>/<shader-name>.<msl|spv|dxil>
|
||||
|
||||
// self.spirvReflect.addShaderInstallRef(exe, self.nw_builder.path("engine/graphics/shaders/triangle_mesh.vert"), "triangle_mesh_vert");
|
||||
// self.spirvReflect.addShaderInstallRef(exe, self.nw_builder.path("engine/graphics/shaders/default_lit.frag"), "default_lit");
|
||||
|
||||
// self.spirvReflect.addShaderInstallRef(exe, self.nw_builder.path("engine/graphics/shaders/debug.vert"), "debug_vert");
|
||||
// self.spirvReflect.addShaderInstallRef(exe, self.nw_builder.path("engine/graphics/shaders/debug.frag"), "debug_frag");
|
||||
|
||||
// self.spirvReflect.addShaderInstallRef(exe, self.nw_builder.path("engine/graphics/shaders/skybox/skybox.vert"), "skybox_vert");
|
||||
// self.spirvReflect.addShaderInstallRef(exe, self.nw_builder.path("engine/graphics/shaders/skybox/skybox.frag"), "skybox_frag");
|
||||
|
||||
// self.spirvReflect.addShaderInstallRef(exe, self.nw_builder.path("engine/ui/shaders/PapyrusRect.vert"), "papyrus_vk_vert");
|
||||
// self.spirvReflect.addShaderInstallRef(exe, self.nw_builder.path("engine/ui/shaders/PapyrusRect.frag"), "papyrus_vk_frag");
|
||||
|
||||
// self.spirvReflect.addShaderInstallRef(exe, self.nw_builder.path("engine/ui/shaders/FontSDF.vert"), "FontSDF_vert");
|
||||
// self.spirvReflect.addShaderInstallRef(exe, self.nw_builder.path("engine/ui/shaders/FontSDF.frag"), "FontSDF_frag");
|
||||
|
||||
b.getInstallStep().dependOn(self.nw_builder.getInstallStep());
|
||||
|
||||
return mod;
|
||||
|
|
|
|||
|
|
@ -157,12 +157,17 @@ pub const AssetReferenceSys = struct {
|
|||
allocator: std.mem.Allocator,
|
||||
outstandingAssetJobs: std.atomic.Value(i32),
|
||||
|
||||
pub fn init(allocator: std.mem.Allocator) @This() {
|
||||
return @This(){
|
||||
pub var NeonObjectTable = core.EngineObjectVTable.from(@This(), "AssetReference");
|
||||
|
||||
pub fn init(allocator: std.mem.Allocator) !*@This() {
|
||||
const self = try allocator.create(@This());
|
||||
self.* = @This(){
|
||||
.loaders = .{},
|
||||
.allocator = allocator,
|
||||
.outstandingAssetJobs = std.atomic.Value(i32).init(0),
|
||||
};
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
pub fn registerLoader(self: *@This(), loader: anytype) !void {
|
||||
|
|
@ -205,5 +210,6 @@ pub const AssetReferenceSys = struct {
|
|||
// i.destroy(self.allocator);
|
||||
// }
|
||||
self.loaders.deinit(self.allocator);
|
||||
self.allocator.destroy(self);
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -19,8 +19,6 @@ pub const MakeImportRefOptions = asset_references.MakeImportRefOptions;
|
|||
|
||||
pub const AsyncAssetJobContext = asset_jobs.AsyncAssetJobContext;
|
||||
|
||||
pub var gAssetSys: *AssetReferenceSys = undefined;
|
||||
|
||||
pub const Module = core.ModuleDescription{
|
||||
.name = "assets",
|
||||
.enabledByDefault = true,
|
||||
|
|
@ -28,6 +26,8 @@ pub const Module = core.ModuleDescription{
|
|||
|
||||
var cooking: bool = false;
|
||||
|
||||
pub const getAssets = core.EngineObject(AssetReferenceSys).get;
|
||||
|
||||
pub fn start_module(spec: *core.SpecVariantMap, args: anytype, allocator: std.mem.Allocator) !void {
|
||||
_ = args;
|
||||
|
||||
|
|
@ -38,8 +38,9 @@ pub fn start_module(spec: *core.SpecVariantMap, args: anytype, allocator: std.me
|
|||
try cook.startup(allocator);
|
||||
}
|
||||
|
||||
gAssetSys = allocator.create(AssetReferenceSys) catch @panic("unable to initialize asset reference");
|
||||
gAssetSys.* = AssetReferenceSys.init(allocator);
|
||||
//gAssetSys = allocator.create(AssetReferenceSys) catch @panic("unable to initialize asset reference");
|
||||
//gAssetSys.* = AssetReferenceSys.init(allocator);
|
||||
_ = try core.createObject(AssetReferenceSys, .{});
|
||||
|
||||
memory.MTPrintStatsDelta();
|
||||
}
|
||||
|
|
@ -48,9 +49,7 @@ pub fn shutdown_module(allocator: std.mem.Allocator) void {
|
|||
if (cooking) {
|
||||
cook.shutdown();
|
||||
}
|
||||
|
||||
gAssetSys.deinit();
|
||||
allocator.destroy(gAssetSys);
|
||||
_ = allocator;
|
||||
}
|
||||
|
||||
pub fn loadList(assetList: anytype) !void {
|
||||
|
|
@ -64,6 +63,6 @@ pub fn load(assetImport: AssetImportReference) !void {
|
|||
var assetRefName = assetImport.assetRef.name;
|
||||
core.tracy.Message(assetRefName.utf8());
|
||||
core.tracy.Message(assetImport.properties.path);
|
||||
try gAssetSys.loadRef(assetImport.assetRef, assetImport.properties);
|
||||
try getAssets().loadRef(assetImport.assetRef, assetImport.properties);
|
||||
z1.End();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,12 +20,12 @@ pub fn start_module(spec: *core.SpecVariantMap, args: anytype, allocator: std.me
|
|||
return;
|
||||
}
|
||||
|
||||
gSoundEngine = core.gEngine.createObject(NeonSoundEngine, .{ .can_tick = true }) catch unreachable;
|
||||
gSoundEngine = core.createObject(NeonSoundEngine, .{ .can_tick = true }) catch unreachable;
|
||||
|
||||
gSoundLoader = allocator.create(soundEngine.SoundLoader) catch unreachable;
|
||||
gSoundLoader.* = soundEngine.SoundLoader.init(gSoundEngine);
|
||||
|
||||
assets.gAssetSys.registerLoader(gSoundLoader) catch unreachable;
|
||||
assets.getAssets().registerLoader(gSoundLoader) catch unreachable;
|
||||
var name = core.MakeName("s_test");
|
||||
gSoundEngine.loadSound(&name, "content/sounds/engineTick.wav", .{}) catch unreachable;
|
||||
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ fn ma_res(value: anytype) !void {
|
|||
}
|
||||
// On init, SoundEngine will spawn a
|
||||
pub const NeonSoundEngine = struct {
|
||||
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This());
|
||||
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This(), "audio.SoundEngine");
|
||||
|
||||
engine: *ma.ma_engine,
|
||||
sounds: AutoHashMapUnmanaged(u32, *ma.ma_sound),
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ pub fn shutdown_everything(allocator: std.mem.Allocator) void {
|
|||
shutdown_modules(allocator);
|
||||
}
|
||||
|
||||
pub fn run_everything_vtable(gameVtable: *const core.EngineObjectVTable) !void {
|
||||
pub fn run_everything_vtable(gameVtable: *core.EngineObjectVTable) !void {
|
||||
core.engine_logs("creating Game context");
|
||||
|
||||
//_ = try core.createObject(GameContext, .{});
|
||||
|
|
@ -93,9 +93,9 @@ pub fn run_everything_vtable(gameVtable: *const core.EngineObjectVTable) !void {
|
|||
|
||||
core.engine_logs("calling gEngine.run");
|
||||
|
||||
try core.gEngine.run();
|
||||
try core.getEngine().run();
|
||||
|
||||
while (!core.gEngine.exitFinished()) {
|
||||
while (!core.getEngine().exitFinished()) {
|
||||
const z = core.tracy.ZoneN(@src(), "shutdown poll");
|
||||
z.End();
|
||||
}
|
||||
|
|
@ -109,9 +109,9 @@ pub fn run_everything(gameVtable: *const core.EngineObjectVTable) !void {
|
|||
|
||||
core.engine_logs("calling gEngine.run");
|
||||
|
||||
try core.gEngine.run();
|
||||
try core.getEngine().run();
|
||||
|
||||
while (!core.gEngine.exitFinished()) {
|
||||
while (!core.getEngine().exitFinished()) {
|
||||
const z = core.tracy.ZoneN(@src(), "shutdown poll");
|
||||
z.End();
|
||||
}
|
||||
|
|
@ -119,7 +119,7 @@ pub fn run_everything(gameVtable: *const core.EngineObjectVTable) !void {
|
|||
|
||||
pub const createSpecVariant = core.createSpecVariant;
|
||||
|
||||
pub export fn initAndRun(vtable: *const core.EngineObjectVTable, spec: *core.SpecVariantMap) bool {
|
||||
pub export fn initAndRun(vtable: *core.EngineObjectVTable, spec: *core.SpecVariantMap) bool {
|
||||
const args = getArgs() catch return false;
|
||||
|
||||
var backingAllocator: std.mem.Allocator = std.heap.c_allocator;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
var gConfigsObject: *ConfigRegistry = undefined;
|
||||
|
||||
pub const ConfigRegistry = struct {
|
||||
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This(), "core.ConfigRegistry");
|
||||
|
||||
|
|
@ -52,8 +50,10 @@ pub fn configVar(comptime T: type, configName: []const u8, default: T) T {
|
|||
return getConfigVar(T, configName) orelse default;
|
||||
}
|
||||
|
||||
pub const getConfigRegistry = core.EngineObject(ConfigRegistry).get;
|
||||
|
||||
pub fn getConfigVar(comptime T: type, configName: []const u8) ?T {
|
||||
const ctx = gConfigsObject;
|
||||
const ctx = getConfigRegistry();
|
||||
|
||||
if (ctx.configMap) |map| {
|
||||
if (map.mapValues.get(configName)) |v| {
|
||||
|
|
@ -314,8 +314,8 @@ pub const Parser = struct {
|
|||
};
|
||||
|
||||
pub fn setupConfigs(configFilePath: []const u8) !void {
|
||||
gConfigsObject = try core.createObject(ConfigRegistry, .{});
|
||||
try gConfigsObject.loadConfigFile(configFilePath);
|
||||
_ = try core.createObject(ConfigRegistry, .{});
|
||||
try getConfigRegistry().loadConfigFile(configFilePath);
|
||||
}
|
||||
|
||||
pub fn ConfigEntry(comptime T: type) type {
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ pub const ConsoleCommand = struct {
|
|||
};
|
||||
|
||||
pub const Console = struct {
|
||||
pub const NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This(), "core.Console");
|
||||
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This(), "core.Console");
|
||||
|
||||
allocator: std.mem.Allocator,
|
||||
arena: std.heap.ArenaAllocator,
|
||||
|
|
@ -63,20 +63,20 @@ pub const Console = struct {
|
|||
}
|
||||
};
|
||||
|
||||
var gConsoleObject: *Console = undefined;
|
||||
pub const getConsole = core.EngineObject(Console).get;
|
||||
|
||||
pub fn start() !void {
|
||||
gConsoleObject = try core.createObject(Console, .{});
|
||||
_ = try core.createObject(Console, .{});
|
||||
}
|
||||
|
||||
pub fn shutdown() void {}
|
||||
|
||||
pub fn addCommand(funcName: []const u8, func: ConsoleFunc) !void {
|
||||
try gConsoleObject.addConsoleCommand(funcName, func);
|
||||
try getConsole.addConsoleCommand(funcName, func);
|
||||
}
|
||||
|
||||
pub fn evaluate(cmd: []const u8) void {
|
||||
gConsoleObject.eval(cmd);
|
||||
getConsole.eval(cmd);
|
||||
}
|
||||
|
||||
const core = @import("core.zig");
|
||||
|
|
|
|||
|
|
@ -73,15 +73,31 @@ const log = logging.engine_log;
|
|||
pub const packer = @import("packer");
|
||||
|
||||
pub const FileSystem = packer.PackerFS;
|
||||
const PackerFS = packer.PackerFS;
|
||||
pub const PackerFS = packer.PackerFS;
|
||||
|
||||
pub const StackCompactor = stacks.StackCompactor;
|
||||
|
||||
var staticsInitialized = false;
|
||||
var gEngine: *Engine = undefined;
|
||||
var gPackerFS: *PackerFS = undefined;
|
||||
var gScene: *SceneSystem = undefined;
|
||||
var gModuleLoader: *ModuleLoader = undefined;
|
||||
|
||||
pub fn EngineObject(comptime T: type) type {
|
||||
return struct {
|
||||
pub var gInstance: ?*T = null;
|
||||
|
||||
pub fn get() *T {
|
||||
if (gInstance == null) {
|
||||
gInstance = getEngineObject(T);
|
||||
}
|
||||
|
||||
return gInstance.?;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub fn getModuleLoader() *ModuleLoader {
|
||||
return EngineObject(ModuleLoader).get();
|
||||
}
|
||||
|
||||
var gIsUtility: bool = false;
|
||||
|
||||
|
|
@ -89,6 +105,7 @@ pub const Scene = scene.Scene;
|
|||
|
||||
pub const externModule = @import("extern/externModule.zig");
|
||||
pub const ModuleLoader = externModule.ModuleLoader;
|
||||
pub const ModuleLoaderArgs = externModule.ModuleLoaderArgs;
|
||||
|
||||
pub const ecs = @import("ecs.zig");
|
||||
pub usingnamespace ecs;
|
||||
|
|
@ -118,6 +135,10 @@ pub fn checkArgBool(args: anytype, comptime field: []const u8) bool {
|
|||
return false;
|
||||
}
|
||||
|
||||
pub fn getSessionStamp() i64 {
|
||||
return gEngine.sessionStamp;
|
||||
}
|
||||
|
||||
pub fn start_module(map: *SpecVariantMap, args: anytype, allocator: std.mem.Allocator) !void {
|
||||
staticsInitialized = true;
|
||||
|
||||
|
|
@ -150,7 +171,7 @@ pub fn start_module(map: *SpecVariantMap, args: anytype, allocator: std.mem.Allo
|
|||
|
||||
gEngine = try allocator.create(Engine);
|
||||
gEngine.* = try Engine.init(allocator);
|
||||
gModuleLoader = try createObject(ModuleLoader, .{});
|
||||
_ = try createObject(ModuleLoader, .{});
|
||||
try console.start();
|
||||
|
||||
const engineName = try std.fmt.allocPrint(allocator, "{s}Engine.ini", .{name});
|
||||
|
|
@ -164,7 +185,7 @@ pub fn start_module(map: *SpecVariantMap, args: anytype, allocator: std.mem.Allo
|
|||
|
||||
try ecs.setup(allocator);
|
||||
|
||||
gScene = try gEngine.createObject(scene.SceneSystem, .{ .can_tick = true });
|
||||
_ = try gEngine.createObject(scene.SceneSystem, .{ .can_tick = true });
|
||||
|
||||
try algorithm.string_pool.setup(allocator);
|
||||
|
||||
|
|
@ -175,6 +196,15 @@ pub fn start_module(map: *SpecVariantMap, args: anytype, allocator: std.mem.Allo
|
|||
return;
|
||||
}
|
||||
|
||||
pub fn setupFromModule(__args: ModuleLoaderArgs) !void {
|
||||
gEngine = __args.engine;
|
||||
gPackerFS = __args.packerFS;
|
||||
script.setupLuaFromModule(__args.luaState, __args.luaAllocator);
|
||||
algorithm.names.gRegistry = __args.nameRegistry;
|
||||
logging.setupLoggingFromModule();
|
||||
staticsInitialized = true;
|
||||
}
|
||||
|
||||
pub fn shutdown_module(_: std.mem.Allocator) void {
|
||||
MemoryTracker.MTPrintStatsDelta();
|
||||
|
||||
|
|
@ -201,7 +231,7 @@ pub fn createObject(comptime T: type, params: engine.NeonObjectParams) !*T {
|
|||
return gEngine.createObject(T, params);
|
||||
}
|
||||
|
||||
pub fn createObjectVTable(vtable: *const engineObject.EngineObjectVTable, params: engine.NeonObjectParams) !*anyopaque {
|
||||
pub fn createObjectVTable(vtable: *engineObject.EngineObjectVTable, params: engine.NeonObjectParams) !*anyopaque {
|
||||
return gEngine.createObjectVTable(vtable, params);
|
||||
}
|
||||
|
||||
|
|
@ -298,6 +328,17 @@ pub fn createSpecVariant(comptime spec: anytype, allocator: std.mem.Allocator) !
|
|||
return variantMap;
|
||||
}
|
||||
|
||||
pub const EngineObjectRef = engineObject.EngineObjectRef;
|
||||
|
||||
pub fn getEngineObjectRef(comptime T: type) ?engineObject.EngineObjectRef {
|
||||
if (T.NeonObjectTable.singletonName) |name| {
|
||||
if (getEngine().engineObjectsByName.get(name)) |ref| {
|
||||
return ref;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
pub fn getEngineObject(comptime T: type) ?*T {
|
||||
if (T.NeonObjectTable.singletonName) |name| {
|
||||
if (getEngine().engineObjectsByName.get(name)) |ref| {
|
||||
|
|
@ -310,5 +351,20 @@ pub fn getEngineObject(comptime T: type) ?*T {
|
|||
pub fn loadModule(moduleName: []const u8, watch: bool) !void {
|
||||
if (watch == false) unreachable; // not implemented
|
||||
|
||||
try gModuleLoader.addModule(moduleName);
|
||||
try getModuleLoader().addModule(moduleName);
|
||||
}
|
||||
|
||||
pub fn startup_getAllocator(p_allocator: *anyopaque) std.mem.Allocator {
|
||||
return @as(*std.mem.Allocator, @ptrCast(@alignCast(p_allocator))).*;
|
||||
}
|
||||
|
||||
pub fn startup_getArgs(p_allocator: *anyopaque) ModuleLoaderArgs {
|
||||
return @as(*ModuleLoaderArgs, @ptrCast(@alignCast(p_allocator))).*;
|
||||
}
|
||||
|
||||
pub fn modulePreamble(p_allocator: *anyopaque, p_a: ?*anyopaque) !std.mem.Allocator {
|
||||
const args = startup_getArgs(p_a.?);
|
||||
const allocator = startup_getAllocator(p_allocator);
|
||||
try setupFromModule(args);
|
||||
return allocator;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
var gEcsRegistry: *EcsRegistry = undefined;
|
||||
|
||||
// wew lad. this is definitely an exploratory implementation I think.
|
||||
//
|
||||
// todo: cruft
|
||||
|
|
@ -112,19 +110,20 @@ var gEcsRegistry: *EcsRegistry = undefined;
|
|||
// SparseMultiSet (AOS version of sparseSet Really specialized, only used for core engine systems)
|
||||
|
||||
pub fn createEntity() !Entity {
|
||||
const rv = Entity{ .handle = try gEcsRegistry.baseSet.createObject(.{}) };
|
||||
const rv = Entity{ .handle = try getRegistry().baseSet.createObject(.{}) };
|
||||
core.engine_log("entity created: {d}", .{rv.handle.index});
|
||||
return rv;
|
||||
}
|
||||
|
||||
pub fn destroyEntity(e: Entity) void {
|
||||
core.engine_log("entity destroyed: {d}", .{e.handle.index});
|
||||
if (gEcsRegistry.baseSet.get(e.handle)) |entityEntry| {
|
||||
const registry = getRegistry();
|
||||
if (registry.baseSet.get(e.handle)) |entityEntry| {
|
||||
for (entityEntry.containers.items) |ref| {
|
||||
ref.vtable.destroyObject(ref.ptr, e.handle);
|
||||
}
|
||||
entityEntry.containers.deinit(gEcsRegistry.allocator);
|
||||
gEcsRegistry.baseSet.destroyObject(e.handle);
|
||||
entityEntry.containers.deinit(registry.allocator);
|
||||
registry.baseSet.destroyObject(e.handle);
|
||||
} else {
|
||||
core.engine_log("UNABLE TO DESTROY ENTITY {d}", .{e.handle.index});
|
||||
}
|
||||
|
|
@ -148,19 +147,17 @@ pub fn CreateEntity_Lua(state: lua.LuaState) i32 {
|
|||
|
||||
pub fn setup(allocator: std.mem.Allocator) !void {
|
||||
try ComponentRef.setupFormatBuffer(allocator);
|
||||
gEcsRegistry = try core.createObject(EcsRegistry, .{ .can_tick = true });
|
||||
_ = try core.createObject(EcsRegistry, .{ .can_tick = true });
|
||||
}
|
||||
|
||||
pub fn shutdown() void {
|
||||
ComponentRef.shutdownFormatBuffer();
|
||||
}
|
||||
|
||||
pub fn getRegistry() *EcsRegistry {
|
||||
return gEcsRegistry;
|
||||
}
|
||||
pub const getRegistry = core.EngineObject(EcsRegistry).get;
|
||||
|
||||
pub fn registerEcsContainer(ref: EcsContainerRef, name: core.Name) !void {
|
||||
try gEcsRegistry.registerContainer(ref, name);
|
||||
try getRegistry().registerContainer(ref, name);
|
||||
}
|
||||
|
||||
pub fn deregisterEcsContainer(ref: EcsContainerRef) void {
|
||||
|
|
@ -173,9 +170,10 @@ pub fn createSystem(comptime System: type, allocator: std.mem.Allocator) !*Syste
|
|||
const ref = p2.refFromPtr(EcsSystemInterface, system);
|
||||
core.engine_log("ptr = {any}", .{ref.vtable.tick});
|
||||
|
||||
try gEcsRegistry.systems.append(gEcsRegistry.allocator, ref);
|
||||
const registry = getRegistry();
|
||||
try registry.systems.append(registry.allocator, ref);
|
||||
if (ref.vtable.tick != null) {
|
||||
try gEcsRegistry.tickableSystems.append(gEcsRegistry.allocator, ref);
|
||||
try registry.tickableSystems.append(registry.allocator, ref);
|
||||
}
|
||||
|
||||
return system;
|
||||
|
|
@ -193,7 +191,7 @@ pub const EcsRegistry = struct {
|
|||
containerNames: std.ArrayListUnmanaged(core.Name) = .{},
|
||||
containersByName: std.AutoHashMapUnmanaged(u32, u32) = .{},
|
||||
|
||||
pub const NeonObjectTable = core.EngineObjectVTable.from(@This(), "core.EcsRegistry");
|
||||
pub var NeonObjectTable = core.EngineObjectVTable.from(@This(), "core.EcsRegistry");
|
||||
|
||||
pub fn init(allocator: std.mem.Allocator) !*@This() {
|
||||
const self = try allocator.create(@This());
|
||||
|
|
@ -325,8 +323,8 @@ pub const Entity = struct {
|
|||
core.engine_log("adding component: {d} {s}", .{ self.handle.index, @typeName(Component) });
|
||||
const rv = Component.BaseContainer.createWithHandleECS(self.handle);
|
||||
|
||||
const list = &gEcsRegistry.baseSet.get(self.handle).?.containers;
|
||||
const allocator = gEcsRegistry.allocator;
|
||||
const list = &getRegistry().baseSet.get(self.handle).?.containers;
|
||||
const allocator = getRegistry().allocator;
|
||||
list.append(allocator, getTypeContainer(Component)) catch return null;
|
||||
|
||||
// if (@hasDecl(Component, "init")) {
|
||||
|
|
|
|||
|
|
@ -80,6 +80,7 @@ pub const Engine = struct {
|
|||
rendererSetupFunc: ?PollFuncFn = null,
|
||||
|
||||
engineStartTime: f64 = 0,
|
||||
sessionStamp: i64 = 0,
|
||||
|
||||
nfdRuntime: *nfd.NFDRuntime,
|
||||
|
||||
|
|
@ -153,7 +154,7 @@ pub const Engine = struct {
|
|||
}
|
||||
|
||||
// creates an engine object using the engine's allocator.
|
||||
pub fn createObjectVTable(self: *@This(), vtable: *const core.EngineObjectVTable, params: NeonObjectParams) !*anyopaque {
|
||||
pub fn createObjectVTable(self: *@This(), vtable: *core.EngineObjectVTable, params: NeonObjectParams) !*anyopaque {
|
||||
if (self.createObjectLock) {
|
||||
core.engine_err("RECURSIVE OBJECT CREATION NOT ALLOWED", .{});
|
||||
return error.BadInit;
|
||||
|
|
@ -239,6 +240,7 @@ pub const Engine = struct {
|
|||
self.first = false;
|
||||
self.engineStartTime = newTime;
|
||||
self.lastEngineTime = newTime;
|
||||
self.sessionStamp = std.time.microTimestamp();
|
||||
}
|
||||
|
||||
if (newTime < self.lastEngineTime) {
|
||||
|
|
@ -414,7 +416,7 @@ pub fn loopDelay(comptime src: Src, interval: f64, dt: f64, comptime S: type, ca
|
|||
pub var __timeleft: f64 = 0.0;
|
||||
pub var __interval: f64 = 0.0;
|
||||
};
|
||||
C.__interval -= dt;
|
||||
C.__timeleft -= dt;
|
||||
|
||||
if (C.__timeleft <= 0.0) {
|
||||
S.func(capture);
|
||||
|
|
|
|||
|
|
@ -20,6 +20,13 @@ pub fn InterfaceRef(comptime Vtable: type) type {
|
|||
};
|
||||
}
|
||||
|
||||
pub fn InterfaceRef2(comptime Vtable: type) type {
|
||||
return struct {
|
||||
ptr: *anyopaque,
|
||||
vtable: *Vtable,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn MakeTypeName(comptime TargetType: type) Name {
|
||||
const hashedName = comptime std.fmt.comptimePrint("{s}_{d}", .{ @typeName(TargetType), @sizeOf(TargetType) });
|
||||
|
||||
|
|
@ -211,4 +218,4 @@ pub const EngineObjectVTable = struct {
|
|||
}
|
||||
};
|
||||
|
||||
pub const EngineObjectRef = InterfaceRef(EngineObjectVTable);
|
||||
pub const EngineObjectRef = InterfaceRef2(EngineObjectVTable);
|
||||
|
|
|
|||
|
|
@ -6,6 +6,15 @@ const ModuleInterface = struct {
|
|||
shutdown: *const fn () callconv(.C) void = undefined,
|
||||
};
|
||||
|
||||
pub const ModuleLoaderArgs = extern struct {
|
||||
firstLoad: bool,
|
||||
engine: *core.Engine,
|
||||
nameRegistry: *p2.NameRegistry,
|
||||
packerFS: *core.PackerFS,
|
||||
luaState: *anyopaque,
|
||||
luaAllocator: *anyopaque,
|
||||
};
|
||||
|
||||
pub const LoadedModule = struct {
|
||||
baseModulePath: []const u8,
|
||||
moduleName: []const u8,
|
||||
|
|
@ -18,6 +27,7 @@ pub const LoadedModule = struct {
|
|||
|
||||
startOnLoad: bool = true,
|
||||
started: bool = false,
|
||||
initialLoad: bool = true,
|
||||
|
||||
pub fn getInterface(self: @This()) ?ModuleInterface {
|
||||
return self.loaded.getLastOrNull();
|
||||
|
|
@ -25,7 +35,8 @@ pub const LoadedModule = struct {
|
|||
|
||||
pub fn stageModule(self: *@This(), allocator: std.mem.Allocator) !void {
|
||||
//const stagingDirectory = ".modulecache/<name>/0/";
|
||||
const stagingDirectoryPath = try std.fmt.allocPrint(allocator, ".modulecache/{s}/{d}", .{
|
||||
const stagingDirectoryPath = try std.fmt.allocPrint(allocator, ".modulecache/{d}/{s}/{d}", .{
|
||||
core.getSessionStamp(),
|
||||
self.moduleName,
|
||||
self.stagedPaths.items.len,
|
||||
});
|
||||
|
|
@ -53,35 +64,56 @@ pub const LoadedModule = struct {
|
|||
try self.loaded.append(allocator, mod);
|
||||
}
|
||||
|
||||
pub fn load(self: *@This(), allocator: std.mem.Allocator) !void {
|
||||
core.engine_log("[ModuleLoader] loading module: ", .{});
|
||||
self.lastLoad = std.time.microTimestamp();
|
||||
try self.stageModule(allocator);
|
||||
try self.loadStagedModule(allocator);
|
||||
}
|
||||
|
||||
// logic for testing if we should stage and load
|
||||
//
|
||||
// 1. modification check time > last load time
|
||||
// 2. current time > modification check time + debounce
|
||||
pub fn maybeStageAndLoad(self: *@This(), allocator: std.mem.Allocator) !bool {
|
||||
core.engine_log("[tick]:", .{});
|
||||
var shouldLoad: bool = false;
|
||||
|
||||
if (self.lastModification > self.lastLoad) {
|
||||
const currentTime = std.time.microTimestamp();
|
||||
|
||||
// give 100ms for debouncing
|
||||
if (currentTime > self.lastModification + 50_000) {
|
||||
self.lastLoad = currentTime;
|
||||
core.engine_log("[ModuleLoader] loading module: ", .{});
|
||||
try self.stageModule(allocator);
|
||||
try self.loadStagedModule(allocator);
|
||||
return true;
|
||||
shouldLoad = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (self.initialLoad) {
|
||||
self.initialLoad = false;
|
||||
shouldLoad = true;
|
||||
}
|
||||
|
||||
if (shouldLoad) {
|
||||
try self.load(allocator);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
fn dllChangedCallback(pathChanged: []const u8, ctx: ?*anyopaque) void {
|
||||
const loaded: *LoadedModule = @ptrCast(@alignCast(ctx.?));
|
||||
loaded.lastModification = std.time.microTimestamp();
|
||||
|
||||
core.engine_log("{s} change detected", .{pathChanged});
|
||||
}
|
||||
|
||||
pub const ModuleLoader = struct {
|
||||
backingAllocator: std.mem.Allocator,
|
||||
arena: std.heap.ArenaAllocator,
|
||||
loadedModules: std.ArrayListUnmanaged(LoadedModule) = .{},
|
||||
loadedModules: std.ArrayListUnmanaged(*LoadedModule) = .{},
|
||||
|
||||
pub const NeonObjectTable = core.EngineObjectVTable.from(@This(), "core.ModuleLoader");
|
||||
pub var NeonObjectTable = core.EngineObjectVTable.from(@This(), "core.ModuleLoader");
|
||||
pub fn create(allocator: std.mem.Allocator) !*@This() {
|
||||
const self = try allocator.create(@This());
|
||||
|
||||
|
|
@ -90,6 +122,8 @@ pub const ModuleLoader = struct {
|
|||
.arena = std.heap.ArenaAllocator.init(allocator),
|
||||
};
|
||||
|
||||
core.fs().watchPath("zig-out/modules/");
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
|
@ -97,18 +131,22 @@ pub const ModuleLoader = struct {
|
|||
// modules are always looked for under zig-out/modules
|
||||
core.engine_log("[ModuleLoader]: adding module to watch '{s}'", .{moduleName});
|
||||
const libFileName = try p2.sharedLibNameAlloc(self.arena.allocator(), moduleName);
|
||||
const loaded = LoadedModule{
|
||||
const loaded = try self.arena.allocator().create(LoadedModule);
|
||||
|
||||
loaded.* = LoadedModule{
|
||||
.baseModulePath = try std.fmt.allocPrint(self.arena.allocator(), "zig-out/modules/{s}", .{libFileName}),
|
||||
.moduleName = moduleName,
|
||||
.lastModification = std.time.microTimestamp(),
|
||||
};
|
||||
|
||||
try core.fs().addFileChangedCallback(libFileName, dllChangedCallback, loaded);
|
||||
|
||||
try self.loadedModules.append(self.arena.allocator(), loaded);
|
||||
}
|
||||
|
||||
pub fn tick(self: *@This(), dt: f64) void {
|
||||
_ = dt;
|
||||
for (self.loadedModules.items) |*loaded| {
|
||||
for (self.loadedModules.items) |loaded| {
|
||||
const didLoad = loaded.maybeStageAndLoad(self.arena.allocator()) catch |err| {
|
||||
core.engine_log("unable to load module error: {any}", .{err});
|
||||
if (@errorReturnTrace()) |trace| {
|
||||
|
|
@ -124,7 +162,15 @@ pub const ModuleLoader = struct {
|
|||
if (loaded.startOnLoad) {
|
||||
if (!loaded.started) {
|
||||
var a = self.backingAllocator;
|
||||
if (interface.startup(&a, null)) {
|
||||
var args = ModuleLoaderArgs{
|
||||
.firstLoad = loaded.loaded.items.len == 1,
|
||||
.engine = core.getEngine(),
|
||||
.nameRegistry = core.names.gRegistry,
|
||||
.packerFS = core.fs(),
|
||||
.luaState = @ptrCast(core.script.gLuaState.l),
|
||||
.luaAllocator = &core.script.gLuaAllocator,
|
||||
};
|
||||
if (interface.startup(&a, &args)) {
|
||||
core.engine_log("[ModuleLoader] module startup done", .{});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ pub const ActionBindingKey = struct {
|
|||
};
|
||||
|
||||
fn arenaAlloc() std.mem.Allocator {
|
||||
return gInputStack.arena.allocator();
|
||||
return getInputStack().arena.allocator();
|
||||
}
|
||||
|
||||
fn BindingData(Listener: type, Func: type) type {
|
||||
|
|
@ -151,11 +151,11 @@ pub const ActionBinding = struct {
|
|||
}
|
||||
// pushes this binding to the active layer
|
||||
pub fn activate(self: *@This()) void {
|
||||
gInputStack.active.addBindingByName(self.data.name, self) catch unreachable;
|
||||
getInputStack().active.addBindingByName(self.data.name, self) catch unreachable;
|
||||
}
|
||||
|
||||
pub fn deactivate(self: *@This()) void {
|
||||
gInputStack.active.removeBindingByName(self.data.name);
|
||||
getInputStack().active.removeBindingByName(self.data.name);
|
||||
}
|
||||
|
||||
pub fn addKey(self: *@This(), key: Key, event: ActionEvent) void {
|
||||
|
|
@ -205,7 +205,7 @@ pub const Axis1dBinding = struct {
|
|||
|
||||
// pushes this binding to the active layer
|
||||
pub fn activate(self: *@This()) void {
|
||||
gInputStack.active.addBindingByName(self.data.name, self) catch unreachable;
|
||||
getInputStack().active.addBindingByName(self.data.name, self) catch unreachable;
|
||||
}
|
||||
|
||||
pub fn setClamp(self: *@This(), clampValue: ?f32) void {
|
||||
|
|
@ -213,7 +213,7 @@ pub const Axis1dBinding = struct {
|
|||
}
|
||||
|
||||
pub fn deactivate(self: *@This()) void {
|
||||
gInputStack.active.removeBindingByName(self.data.name);
|
||||
getInputStack().active.removeBindingByName(self.data.name);
|
||||
}
|
||||
|
||||
pub fn addKey(self: *@This(), key: Key, magnitude: f32) void {
|
||||
|
|
@ -275,11 +275,11 @@ pub const Axis2dBinding = struct {
|
|||
|
||||
// pushes this binding to the active layer
|
||||
pub fn activate(self: *@This()) void {
|
||||
gInputStack.active.addBindingByName(self.data.name, self) catch unreachable;
|
||||
getInputStack().active.addBindingByName(self.data.name, self) catch unreachable;
|
||||
}
|
||||
|
||||
pub fn deactivate(self: *@This()) void {
|
||||
gInputStack.active.removeBindingByName(self.data.name);
|
||||
getInputStack().active.removeBindingByName(self.data.name);
|
||||
}
|
||||
|
||||
pub fn addKey(self: *@This(), key: Key, magnitude: f32, axis: enum { x, y }) void {
|
||||
|
|
@ -576,7 +576,7 @@ pub const InputStack = struct {
|
|||
.active = try BindingLayer.create(allocator),
|
||||
};
|
||||
|
||||
gInputStack = self;
|
||||
core.EngineObject(@This()).gInstance = self;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
|
@ -677,14 +677,12 @@ pub const InputStack = struct {
|
|||
}
|
||||
};
|
||||
|
||||
var gInputStack: *InputStack = undefined;
|
||||
|
||||
pub fn getInputStack() *InputStack {
|
||||
return gInputStack;
|
||||
return core.EngineObject(InputStack).get();
|
||||
}
|
||||
|
||||
pub fn initInputStack() !void {
|
||||
gInputStack = try core.createObject(InputStack, .{});
|
||||
_ = try core.createObject(InputStack, .{});
|
||||
}
|
||||
|
||||
// creates a binding for a lua type
|
||||
|
|
|
|||
|
|
@ -297,6 +297,10 @@ pub fn forceFlush() void {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn setupLoggingFromModule() void {
|
||||
gLoggerSys = core.getEngineObject(LoggerSys);
|
||||
}
|
||||
|
||||
pub fn setupLogging(engine: *core.Engine) !void {
|
||||
gLoggerSys = try engine.createObject(LoggerSys, .{
|
||||
.responds_to_events = true,
|
||||
|
|
|
|||
|
|
@ -216,8 +216,8 @@ pub const Scene = struct {
|
|||
|
||||
pub fn getAndResolveTransform(self: @This()) core.Transform {
|
||||
const repr: *SceneObjectRepr = SceneObjectContainer.get(self.handle, ._repr).?;
|
||||
if (repr.lastUpdate != gSceneSystem.tickCount) {
|
||||
gSceneSystem.updateTransform(repr, SceneObjectContainer.get(self.handle, .posRot).?);
|
||||
if (repr.lastUpdate != getSceneSystem().tickCount) {
|
||||
getSceneSystem().updateTransform(repr, SceneObjectContainer.get(self.handle, .posRot).?);
|
||||
}
|
||||
|
||||
return repr.transform;
|
||||
|
|
@ -268,10 +268,10 @@ pub const SceneObjectInitParams = union(enum) {
|
|||
},
|
||||
};
|
||||
|
||||
pub var gSceneSystem: *SceneSystem = undefined;
|
||||
pub const getSceneSystem = core.EngineObject(SceneSystem).get;
|
||||
|
||||
fn childAllocator() std.mem.Allocator {
|
||||
return gSceneSystem.childrenArena.allocator();
|
||||
return getSceneSystem().childrenArena.allocator();
|
||||
}
|
||||
|
||||
pub const SceneSystem = struct {
|
||||
|
|
@ -364,7 +364,7 @@ pub const SceneSystem = struct {
|
|||
.allocator = allocator,
|
||||
.childrenArena = std.heap.ArenaAllocator.init(allocator),
|
||||
};
|
||||
gSceneSystem = self;
|
||||
core.EngineObject(@This()).gInstance = self;
|
||||
try core.defineComponent(Scene, allocator);
|
||||
Scene.SceneObjectContainer = try SceneObjectSet.create(allocator);
|
||||
return self;
|
||||
|
|
|
|||
|
|
@ -13,8 +13,13 @@ pub const script_bindings = @import("script_bindings.zig");
|
|||
|
||||
const c = lua.c;
|
||||
|
||||
var gLuaState: lua.LuaState = undefined;
|
||||
var gLuaAllocator: std.mem.Allocator = undefined;
|
||||
pub var gLuaState: lua.LuaState = undefined;
|
||||
pub var gLuaAllocator: std.mem.Allocator = undefined;
|
||||
|
||||
pub fn setupLuaFromModule(pstate: *anyopaque, p_lua_allocator: *anyopaque) void {
|
||||
gLuaAllocator = core.startup_getAllocator(p_lua_allocator);
|
||||
gLuaState.l = @ptrCast(pstate);
|
||||
}
|
||||
|
||||
const luaRegLibs: []const c.luaL_Reg = &.{
|
||||
.{ .name = "print", .func = printWrapper },
|
||||
|
|
|
|||
|
|
@ -9,17 +9,18 @@ pub const Module: core.ModuleDescription = .{
|
|||
.enabledByDefault = false,
|
||||
};
|
||||
|
||||
var gImgui: *Impl = undefined;
|
||||
|
||||
pub fn start_module(spec: *core.SpecVariantMap, args: anytype, allocator: std.mem.Allocator) !void {
|
||||
_ = allocator;
|
||||
_ = args;
|
||||
_ = spec;
|
||||
|
||||
// gImgui = try rend.createRendererObject(Impl);
|
||||
// try gImgui.setup();
|
||||
gImgui = try core.createObject(Impl, .{});
|
||||
try gImgui.setup();
|
||||
const gimgui = try core.createObject(Impl, .{});
|
||||
try gimgui.setup();
|
||||
}
|
||||
|
||||
pub fn setupFromModule() void {
|
||||
const impl = core.getEngineObject(Impl).?;
|
||||
api.setCurrentContext(impl.context);
|
||||
}
|
||||
|
||||
pub fn shutdown_module(allocator: std.mem.Allocator) void {
|
||||
|
|
|
|||
|
|
@ -4,8 +4,9 @@ pub const Impl = struct {
|
|||
|
||||
drawData: [*c]ig.DrawData = undefined,
|
||||
rendererDebug: bool = true,
|
||||
context: *ig.Context = undefined,
|
||||
|
||||
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This());
|
||||
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This(), "imgui.BackendImpl");
|
||||
|
||||
pub const Settings = struct {
|
||||
x: u32 = 0,
|
||||
|
|
@ -29,6 +30,8 @@ pub const Impl = struct {
|
|||
|
||||
c.Imgui_SDL3_Init(@ptrCast(platform.getInstance().window), @ptrCast(self.device));
|
||||
try platform.getInstance().addSDLProcessFunction(processSDLEvents);
|
||||
|
||||
self.context = ig.getCurrentContext().?;
|
||||
}
|
||||
|
||||
pub fn processSDLEvents(event: *sdl3.Event) void {
|
||||
|
|
|
|||
|
|
@ -38,15 +38,15 @@ pub const PrimitiveType = enum {
|
|||
|
||||
// low level helpers - old api
|
||||
pub fn addPrimitiveBody(primitive: PrimitiveType, settings: BodyCreationSettings, activationMode: Activation) !BodyId {
|
||||
const interface = gPhysicsRuntime.system.getBodyInterfaceMut();
|
||||
const interface = context().system.getBodyInterfaceMut();
|
||||
var s = settings;
|
||||
|
||||
switch (primitive) {
|
||||
.box => {
|
||||
s.shape = gPhysicsRuntime.primBoxShape;
|
||||
s.shape = context().primBoxShape;
|
||||
},
|
||||
.sphere => {
|
||||
s.shape = gPhysicsRuntime.primSphereShape;
|
||||
s.shape = context().primSphereShape;
|
||||
},
|
||||
}
|
||||
|
||||
|
|
@ -54,24 +54,24 @@ pub fn addPrimitiveBody(primitive: PrimitiveType, settings: BodyCreationSettings
|
|||
}
|
||||
|
||||
pub fn setBodyPosition(id: BodyId, pos: core.Vectorf) void {
|
||||
const interface = gPhysicsRuntime.system.getBodyInterfaceMut();
|
||||
const interface = context().system.getBodyInterfaceMut();
|
||||
interface.setPosition(id, pos.toArr3(), .activate);
|
||||
}
|
||||
|
||||
pub fn setBodyRotation(id: BodyId, rot: core.Rotation) void {
|
||||
const interface = gPhysicsRuntime.system.getBodyInterfaceMut();
|
||||
const interface = context().system.getBodyInterfaceMut();
|
||||
interface.setRotation(id, rot.quat, .activate);
|
||||
}
|
||||
|
||||
pub fn optimizeBroadPhase() void {
|
||||
gPhysicsRuntime.system.optimizeBroadPhase();
|
||||
context().system.optimizeBroadPhase();
|
||||
}
|
||||
|
||||
pub var gPhysicsRuntime: *runtime.PhysicsRuntime = undefined;
|
||||
pub const context = core.EngineObject(runtime.PhysicsRuntime).get;
|
||||
|
||||
pub fn addShape(name: []const u8, settings: ShapeSettings) !void {
|
||||
var n = core.MakeName(name);
|
||||
try gPhysicsRuntime.createShape(&n, settings);
|
||||
try context().createShape(&n, settings);
|
||||
}
|
||||
|
||||
pub fn start_module(spec: *core.SpecVariantMap, args: anytype, allocator: std.mem.Allocator) !void {
|
||||
|
|
@ -79,7 +79,7 @@ pub fn start_module(spec: *core.SpecVariantMap, args: anytype, allocator: std.me
|
|||
_ = spec;
|
||||
|
||||
try zphysics.init(allocator, .{});
|
||||
gPhysicsRuntime = try core.createObject(runtime.PhysicsRuntime, .{ .can_tick = true });
|
||||
_ = try core.createObject(runtime.PhysicsRuntime, .{ .can_tick = true });
|
||||
}
|
||||
|
||||
pub fn shutdown_module(allocator: std.mem.Allocator) void {
|
||||
|
|
@ -94,7 +94,7 @@ pub const Module: core.ModuleDescription = .{
|
|||
|
||||
pub fn releaseShape(name: core.Name) void {
|
||||
var n = name;
|
||||
gPhysicsRuntime.shapes.get(n.handle()).?.shape.release();
|
||||
context().shapes.get(n.handle()).?.shape.release();
|
||||
}
|
||||
|
||||
pub const RayCastSettings = struct {
|
||||
|
|
@ -109,7 +109,7 @@ pub const RayCastResult = struct {
|
|||
};
|
||||
|
||||
pub fn traceLine(start: core.Vectorf, direction: core.Vectorf, settings: RayCastSettings) ?RayCastResult {
|
||||
const query = gPhysicsRuntime.system.getNarrowPhaseQuery();
|
||||
const query = context().system.getNarrowPhaseQuery();
|
||||
const result = query.castRay(.{
|
||||
.origin = start.toZm(),
|
||||
.direction = direction.toZm(),
|
||||
|
|
@ -127,13 +127,13 @@ pub fn traceLine(start: core.Vectorf, direction: core.Vectorf, settings: RayCast
|
|||
};
|
||||
|
||||
if (settings.entityLookup) {
|
||||
rv.entity = gPhysicsRuntime.idToEntity.get(rv.body).?;
|
||||
rv.entity = context().idToEntity.get(rv.body).?;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
pub fn applyForce(body: BodyId, impulse: core.Vectorf, position: core.Vectorf) void {
|
||||
const interface = gPhysicsRuntime.system.getBodyInterfaceMut();
|
||||
const interface = context().system.getBodyInterfaceMut();
|
||||
interface.addImpulseAtPosition(body, impulse.toArr3(), position.toArr3());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -144,7 +144,7 @@ pub const PhysicsRuntime = struct {
|
|||
timeSinceUpdate: f64 = 0.0,
|
||||
idToEntity: std.AutoHashMapUnmanaged(zphysics.BodyId, core.Entity) = .{},
|
||||
|
||||
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This());
|
||||
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This(), "physics.Runtime");
|
||||
|
||||
pub fn registerBodyEntity(self: *@This(), bodyId: zphysics.BodyId, entity: core.Entity) !void {
|
||||
try self.idToEntity.put(self.allocator, bodyId, entity);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This());
|
||||
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This(), "rend.DebugDrawSystem");
|
||||
|
||||
allocator: std.mem.Allocator,
|
||||
debugDraws: core.RingQueueU(DebugPrimitive),
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
allocator: std.mem.Allocator,
|
||||
|
||||
pub var LoaderInterfaceVTable = assets.AssetLoaderInterface.from("Mesh", @This());
|
||||
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This());
|
||||
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This(), "rend.MeshAssetLoader");
|
||||
|
||||
pub fn create(allocator: std.mem.Allocator) !*@This() {
|
||||
const self = try allocator.create(@This());
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This());
|
||||
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This(), "rend.Skybox");
|
||||
|
||||
allocator: std.mem.Allocator,
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
//
|
||||
|
||||
pub var LoaderInterfaceVTable = assets.AssetLoaderInterface.from("Texture", @This());
|
||||
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This());
|
||||
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This(), "rend.TextureList");
|
||||
|
||||
allocator: std.mem.Allocator,
|
||||
device: *gpu.GPUDevice = undefined,
|
||||
|
|
@ -26,7 +26,7 @@ pub fn create(allocator: std.mem.Allocator) !*@This() {
|
|||
|
||||
pub fn setup(self: *@This(), device: *gpu.GPUDevice) !void {
|
||||
core.engine_log("Texture List Added", .{});
|
||||
try assets.gAssetSys.registerLoader(self);
|
||||
try assets.getAssets().registerLoader(self);
|
||||
self.device = device;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ pub const MeshPool = struct {
|
|||
|
||||
core.graphics_log("mesh pool created {d}k vertices, {d}k indices", .{ settings.vertexCount / 1000, settings.indexCount / 1000 });
|
||||
|
||||
try assets.gAssetSys.registerLoader(try core.createObject(MeshAssetLoader, .{}));
|
||||
try assets.getAssets().registerLoader(try core.createObject(MeshAssetLoader, .{}));
|
||||
|
||||
return self;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ pub const Renderer = struct {
|
|||
positionTargetFormat: gpu.GPUTextureFormat = .textureformatR16g16b16a16Float,
|
||||
normalTargetFormat: gpu.GPUTextureFormat = .textureformatB8g8r8a8Unorm,
|
||||
|
||||
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This());
|
||||
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This(), "rend.Renderer");
|
||||
|
||||
pub const MaxObjectCount = 50000;
|
||||
|
||||
|
|
@ -913,8 +913,9 @@ pub const Renderer = struct {
|
|||
}
|
||||
};
|
||||
|
||||
pub var gRenderer: *Renderer = undefined;
|
||||
pub var gAllocator: std.mem.Allocator = undefined;
|
||||
// pub var gRenderer: *Renderer = undefined;
|
||||
|
||||
pub const context = core.EngineObject(Renderer).get;
|
||||
|
||||
const rend = @import("../rend.zig");
|
||||
|
||||
|
|
@ -949,45 +950,40 @@ const SkyboxSystem = @import("SkyboxSystem.zig");
|
|||
// debug api
|
||||
|
||||
pub fn reloadShaders() !void {
|
||||
_ = core.shell.runCmd(gRenderer.allocator, &.{ "python", "../tools/scripts/cookShaders.py" }, ".") catch {
|
||||
_ = core.shell.runCmd(context().allocator, &.{ "python", "../tools/scripts/cookShaders.py" }, ".") catch {
|
||||
core.graphics_logs("shader cook script failed");
|
||||
return;
|
||||
};
|
||||
try gRenderer.createMeshPipeline();
|
||||
try gRenderer.createPostProcessingPipeline();
|
||||
try gRenderer.ssaoSystem.createPipeline();
|
||||
try context().createMeshPipeline();
|
||||
try context().createPostProcessingPipeline();
|
||||
try context().ssaoSystem.createPipeline();
|
||||
}
|
||||
|
||||
// ====== renderer API =======
|
||||
pub fn createInstance() !void {
|
||||
gRenderer = try core.createObject(Renderer, .{ .can_tick = true, .isCore = true });
|
||||
gAllocator = gRenderer.allocator;
|
||||
_ = try core.createObject(Renderer, .{ .can_tick = true, .isCore = true });
|
||||
}
|
||||
|
||||
pub fn start() !void {
|
||||
try gRenderer.startRenderer();
|
||||
try context().startRenderer();
|
||||
}
|
||||
|
||||
pub fn shutdown() void {}
|
||||
|
||||
pub fn context() *Renderer {
|
||||
return gRenderer;
|
||||
}
|
||||
|
||||
pub fn setActiveCamera(camera: ?*rend.CameraComponent) void {
|
||||
gRenderer.activeCamera = camera;
|
||||
context().activeCamera = camera;
|
||||
}
|
||||
|
||||
pub fn createRendererObject(comptime T: type) !*T {
|
||||
return try gRenderer.createRendererObject(T);
|
||||
return try context().createRendererObject(T);
|
||||
}
|
||||
|
||||
pub fn registerRendererObject(comptime T: type, object: *anyopaque) !void {
|
||||
return try gRenderer.registerRendererObject(T, object);
|
||||
return try context().registerRendererObject(T, object);
|
||||
}
|
||||
|
||||
pub fn setSkyboxTexture(name: []const u8) void {
|
||||
gRenderer.skyboxSystem.skyboxTextureName = core.MakeName(name);
|
||||
context().skyboxSystem.skyboxTextureName = core.MakeName(name);
|
||||
}
|
||||
|
||||
pub const getMesh = mesh_pool.getMesh;
|
||||
|
|
@ -995,7 +991,7 @@ pub const getMeshByName = mesh_pool.getMeshByName;
|
|||
pub const pushMeshUpdate = mesh_pool.pushMeshUpdate;
|
||||
|
||||
pub fn getTexture(name: *core.Name) ?*rend.Texture {
|
||||
return gRenderer.textureList.map.get(name.handle());
|
||||
return context().textureList.map.get(name.handle());
|
||||
}
|
||||
|
||||
pub const RendererState = struct {
|
||||
|
|
@ -1011,7 +1007,7 @@ pub const RendererState = struct {
|
|||
|
||||
pub fn textureExists(name: []const u8) bool {
|
||||
var n = core.MakeName(name);
|
||||
return gRenderer.textureList.requestMap.contains(n.handle());
|
||||
return context().textureList.requestMap.contains(n.handle());
|
||||
}
|
||||
|
||||
pub const CustomMeshRenderFunc = *const fn (?*anyopaque) void;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This());
|
||||
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This(), "rend.Ssao");
|
||||
|
||||
allocator: std.mem.Allocator,
|
||||
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ pub fn maybeUpdate(self: *@This()) !void {
|
|||
const alloc = self.arena.allocator();
|
||||
for (engine.engineObjects.items) |x| {
|
||||
const newString = try std.fmt.allocPrint(alloc, "[{s}] {s} @ 0x{x} (size: {d} bytes) ", .{
|
||||
x.vtable.singletonName,
|
||||
x.vtable.singletonName orelse "n/a",
|
||||
x.vtable.typeName,
|
||||
@intFromPtr(x.ptr),
|
||||
x.vtable.typeSize,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
dtAverage: f64 = 0.0,
|
||||
allocator: std.mem.Allocator,
|
||||
|
||||
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This());
|
||||
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This(), null);
|
||||
|
||||
pub fn create(allocator: std.mem.Allocator) !*@This() {
|
||||
const self = try allocator.create(@This());
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ fn vkCast(comptime T: type, handle: anytype) T {
|
|||
// largely don't need to touch this structure from the user's side.
|
||||
pub const NeonVkImGui = struct {
|
||||
const Self = @This();
|
||||
pub const NeonObjectTable = core.EngineObjectVTable.from(Self);
|
||||
pub var NeonObjectTable = core.EngineObjectVTable.from(Self);
|
||||
pub const RendererInterfaceVTable = graphics.RendererInterface.from(Self);
|
||||
|
||||
allocator: std.mem.Allocator,
|
||||
|
|
|
|||
|
|
@ -2297,7 +2297,7 @@ pub inline fn getCurrentContext() ?*Context { //igGetCurrentContext
|
|||
return @ptrCast(c.igGetCurrentContext());
|
||||
}
|
||||
pub inline fn setCurrentContext(ctx: ?*Context) void { //igSetCurrentContext
|
||||
c.igSetCurrentContext(ctx);
|
||||
c.igSetCurrentContext(@ptrCast(ctx));
|
||||
}
|
||||
pub inline fn getIO() ?*Io { //igGetIO
|
||||
return @ptrCast(c.igGetIO_Nil());
|
||||
|
|
|
|||
|
|
@ -66,6 +66,8 @@ pub const MakeName = names.MakeName;
|
|||
pub const DefineName = names.DefineName;
|
||||
pub const createNameRegistry = names.createNameRegistry;
|
||||
pub const destroyNameRegistry = names.destroyNameRegistry;
|
||||
pub const setNameRegistry = names.setNameRegistry;
|
||||
pub const NameRegistry = names.NameRegistry;
|
||||
|
||||
pub const spans = @import("structures/spans.zig");
|
||||
pub const MergedSpans = spans.MergedSpans;
|
||||
|
|
|
|||
|
|
@ -106,6 +106,11 @@ pub fn createNameRegistry(allocator: std.mem.Allocator) !*NameRegistry {
|
|||
return gRegistry;
|
||||
}
|
||||
|
||||
pub fn setNameRegistry(registry: *NameRegistry) void {
|
||||
gRegistry = registry;
|
||||
registryCreated = true;
|
||||
}
|
||||
|
||||
pub fn getRegistry() *NameRegistry {
|
||||
// specifically in the case of unittests we can silently just initialize a temporary registry
|
||||
if (builtin.is_test) {
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@ pub fn build(b: *std.Build) void {
|
|||
.name = "externGame",
|
||||
});
|
||||
|
||||
sampleGameExtern.root_module.addImport("backlog", blbuild.nw_mod);
|
||||
|
||||
const installExtern = b.addInstallArtifact(sampleGameExtern, .{
|
||||
.dest_dir = .{ .override = .{ .custom = "modules" } },
|
||||
});
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -8,7 +8,7 @@ struct type_Uniforms
|
|||
float brightnessFactor;
|
||||
};
|
||||
|
||||
constant float4 _28 = {};
|
||||
constant float4 _29 = {};
|
||||
|
||||
struct main0_out
|
||||
{
|
||||
|
|
@ -24,9 +24,11 @@ struct main0_in
|
|||
fragment main0_out main0(main0_in in [[stage_in]], constant type_Uniforms& Uniforms [[buffer(0)]], texturecube<float> SkyboxTexture [[texture(0)]], sampler SkyboxSampler [[sampler(0)]])
|
||||
{
|
||||
main0_out out = {};
|
||||
float4 _38 = SkyboxTexture.sample(SkyboxSampler, in.in_var_TEXCOORD0) * Uniforms.brightnessFactor;
|
||||
out.out_var_SV_Target0 = _38;
|
||||
out.out_var_SV_Target1 = select(_28, _38, bool4(length(_38) > 1.0));
|
||||
float4 _39 = SkyboxTexture.sample(SkyboxSampler, in.in_var_TEXCOORD0) * Uniforms.brightnessFactor;
|
||||
float4 _44 = _39;
|
||||
_44.z = 0.0;
|
||||
out.out_var_SV_Target0 = _44;
|
||||
out.out_var_SV_Target1 = select(_29, _39, bool4(length(_39) > 1.0));
|
||||
return out;
|
||||
}
|
||||
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -1,3 +1,13 @@
|
|||
pub export fn startup(p_allocator: *anyopaque, p_a: ?*anyopaque) bool {
|
||||
const allocator = core.modulePreamble(p_allocator, p_a) catch return false;
|
||||
_ = allocator;
|
||||
imgui.setupFromModule();
|
||||
|
||||
start_module(core.startup_getArgs(p_a.?)) catch return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
pub export fn add(a: i32, b: i32) i32 {
|
||||
return a + b;
|
||||
}
|
||||
|
|
@ -6,4 +16,73 @@ pub export fn subtract(a: i32, b: i32) i32 {
|
|||
return a + b;
|
||||
}
|
||||
|
||||
var gAllocator: std.mem.Allocator = undefined;
|
||||
|
||||
pub fn log(comptime fmt: []const u8, args: anytype) void {
|
||||
core.engine_log("[ExternGame]: " ++ fmt, args);
|
||||
}
|
||||
|
||||
fn start_module(args: core.ModuleLoaderArgs) !void {
|
||||
if (args.firstLoad) {
|
||||
_ = core.createObject(ExternGameObject, .{}) catch {};
|
||||
return;
|
||||
}
|
||||
|
||||
log("extern game reloaded ", .{});
|
||||
log("hello mother fucker", .{});
|
||||
log("accessing old object at {x} same object? {d}", .{ @intFromPtr(core.EngineObject(ExternGameObject).get()), @sizeOf(ExternGameObject) });
|
||||
|
||||
log("gonna try something dumb- lets patch the vtable of that old object with my vtable's values", .{});
|
||||
const ref = core.getEngineObjectRef(ExternGameObject).?;
|
||||
|
||||
ref.vtable.tick_func = ExternGameObject.NeonObjectTable.tick_func;
|
||||
}
|
||||
|
||||
pub const ExternGameObject = struct {
|
||||
pub var NeonObjectTable = core.EngineObjectVTable.from(@This(), "game.ExternGameObject");
|
||||
|
||||
allocator: std.mem.Allocator,
|
||||
|
||||
pub fn create(allocator: std.mem.Allocator) !*@This() {
|
||||
const self = try allocator.create(@This());
|
||||
self.* = .{ .allocator = allocator };
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
pub fn tick(self: *@This(), dt: f64) void {
|
||||
_ = self;
|
||||
_ = dt;
|
||||
if (ig.begin("external game object", null, .{})) {
|
||||
ig.textf("sup", .{});
|
||||
ig.textf("hello !", .{});
|
||||
|
||||
ig.textf("sup", .{});
|
||||
ig.textf("hello !", .{});
|
||||
ig.textf("sup", .{});
|
||||
ig.textf("hello !", .{});
|
||||
ig.textf("sup", .{});
|
||||
ig.textf("hello !", .{});
|
||||
ig.textf("sup", .{});
|
||||
ig.textf("hello !", .{});
|
||||
ig.textf("sup", .{});
|
||||
ig.textf("hello !", .{});
|
||||
|
||||
_ = ig.sliderFloat("skybox red", &rend.context().skyboxSystem.brightnessFactor, 0, 200, null, .{});
|
||||
}
|
||||
ig.end();
|
||||
}
|
||||
|
||||
pub fn destroy(self: *@This()) void {
|
||||
self.allocator.destroy(self);
|
||||
}
|
||||
};
|
||||
|
||||
pub export fn shutdown() void {}
|
||||
|
||||
const std = @import("std");
|
||||
const backlog = @import("backlog");
|
||||
const core = backlog.core;
|
||||
const imgui = backlog.imgui;
|
||||
const rend = backlog.rend;
|
||||
const ig = imgui.api;
|
||||
|
|
|
|||
|
|
@ -28,13 +28,13 @@ rendererDebugger: *extras.RendererDebug = undefined,
|
|||
|
||||
tbMap: ?*bsp.maploader.TBMap = null,
|
||||
|
||||
addFunc: ?*const fn (i32, i32) callconv(.C) i32 = undefined,
|
||||
// addFunc: ?*const fn (i32, i32) callconv(.C) i32 = undefined,
|
||||
|
||||
engineTool: *extras.EngineTool = undefined,
|
||||
|
||||
modules: std.AutoHashMapUnmanaged(u32, []const u8) = .{},
|
||||
|
||||
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This());
|
||||
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This(), "SampleGame");
|
||||
|
||||
pub fn init(allocator: std.mem.Allocator) !*@This() {
|
||||
const self = try allocator.create(@This());
|
||||
|
|
@ -192,12 +192,14 @@ pub fn prepare(self: *@This()) !void {
|
|||
try script.loadTypes("scripts");
|
||||
try script.runScriptFile("scripts/prepare.lua");
|
||||
|
||||
try core.loadModule("externGame", true);
|
||||
|
||||
self.engineTool = try extras.EngineTool.create(self.allocator);
|
||||
|
||||
core.fs().watchPath("zig-out/modules");
|
||||
try core.fs().addFileChangedCallback(core.sharedLibName("externGame"), moduleChangedCallback, self);
|
||||
// core.fs().watchPath("zig-out/modules");
|
||||
// try core.fs().addFileChangedCallback(core.sharedLibName("externGame"), moduleChangedCallback, self);
|
||||
|
||||
try self.tryLoadExtern("externGame");
|
||||
// try self.tryLoadExtern("externGame");
|
||||
|
||||
self.rendererDebugger = try extras.RendererDebug.create(self.allocator); //try core.createObject(extras.RendererDebug, .{});
|
||||
|
||||
|
|
@ -413,7 +415,8 @@ pub fn tick(self: *@This(), dt: f64) void {
|
|||
s: @TypeOf(self),
|
||||
|
||||
pub fn func(c: @This()) void {
|
||||
c.s.tryLoadExtern("externGame") catch unreachable;
|
||||
_ = c;
|
||||
// c.s.tryLoadExtern("externGame") catch unreachable;
|
||||
}
|
||||
}, .{ .s = self });
|
||||
|
||||
|
|
@ -463,7 +466,6 @@ pub fn tick(self: *@This(), dt: f64) void {
|
|||
// show a window with the current camera's position
|
||||
|
||||
if (!self.mouseLook) {
|
||||
ig.showDemoWindow(null);
|
||||
self.engineTool.tick();
|
||||
self.objectSpawner.windowOpen = !self.mouseLook;
|
||||
self.objectSpawner.tick(dt);
|
||||
|
|
@ -485,7 +487,7 @@ pub fn tick(self: *@This(), dt: f64) void {
|
|||
ig.textFmt("- f2 to route all inputs to the doom player", .{}) catch return;
|
||||
ig.textFmt("- movingLight checkbox makes the light stop moving with you", .{}) catch return;
|
||||
|
||||
ig.textf("1 + 2 = {d}", .{self.addFunc.?(1, 2)});
|
||||
//ig.textf("1 + 2 = {d}", .{self.addFunc.?(1, 2)});
|
||||
|
||||
{
|
||||
ig.textf("modules dirty: ", .{});
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ const ModuleResults = struct {
|
|||
}
|
||||
};
|
||||
|
||||
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This());
|
||||
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This(), "testAll");
|
||||
|
||||
pub fn init(allocator: std.mem.Allocator) !*@This() {
|
||||
const self = try allocator.create(@This());
|
||||
|
|
|
|||
Loading…
Reference in New Issue