diff --git a/engine/core/src/configVars.zig b/engine/core/src/configVars.zig index b05284d..ee602d9 100644 --- a/engine/core/src/configVars.zig +++ b/engine/core/src/configVars.zig @@ -1,17 +1,16 @@ pub const ConfigRegistry = struct { pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This(), "core.ConfigRegistry"); - allocator: std.mem.Allocator, + allocator: std.mem.Allocator = undefined, configMap: ?ConfigMap = null, - pub fn create(allocator: std.mem.Allocator) !*@This() { - const self = try allocator.create(@This()); + pub fn create(self: *@This(), allocator: std.mem.Allocator, first: bool) !void { + if (!first) + return; self.* = .{ .allocator = allocator, }; - - return self; } // by convention this should be in the root @@ -42,7 +41,6 @@ pub const ConfigRegistry = struct { if (self.configMap) |*map| { map.deinit(); } - self.allocator.destroy(self); } }; diff --git a/engine/core/src/console.zig b/engine/core/src/console.zig index 98efa7b..7ce0066 100644 --- a/engine/core/src/console.zig +++ b/engine/core/src/console.zig @@ -8,21 +8,22 @@ pub const ConsoleCommand = struct { pub const Console = struct { pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This(), "core.Console"); - allocator: std.mem.Allocator, - arena: std.heap.ArenaAllocator, + allocator: std.mem.Allocator = undefined, + arena: std.heap.ArenaAllocator = undefined, commandMap: std.StringHashMapUnmanaged(ConsoleCommand) = .{}, - pub fn create(allocator: std.mem.Allocator) !*@This() { - const self = try allocator.create(@This()); + pub fn create(self: *@This(), allocator: std.mem.Allocator, first: bool) !void { + if (!first) { + return; + } + self.* = .{ .arena = std.heap.ArenaAllocator.init(allocator), .allocator = allocator, }; core.engine_logs("console system created"); - - return self; } pub fn addConsoleCommand(self: *@This(), funcName: []const u8, func: ConsoleFunc) !void { @@ -59,7 +60,6 @@ pub const Console = struct { pub fn destroy(self: *@This()) void { self.arena.deinit(); self.commandMap.deinit(self.allocator); - self.allocator.destroy(self); } }; diff --git a/engine/core/src/core.zig b/engine/core/src/core.zig index 142ee64..c029778 100644 --- a/engine/core/src/core.zig +++ b/engine/core/src/core.zig @@ -29,6 +29,8 @@ pub const debugLine = debug_draw.debugLine; pub const engineTime = @import("engineTime.zig"); pub const engineObject = @import("engineObject.zig"); +pub const EngineObjectOpts = engineObject.EngineObjectOpts; +pub const ObjectOpts = engineObject.EngineObjectOpts; pub const EngineObjectVTable = engineObject.EngineObjectVTable; pub const MakeTypeName = engineObject.MakeTypeName; pub const PatchStruct = engineObject.PatchStruct; diff --git a/engine/core/src/ecs.zig b/engine/core/src/ecs.zig index 48b4f5d..48421cf 100644 --- a/engine/core/src/ecs.zig +++ b/engine/core/src/ecs.zig @@ -210,15 +210,15 @@ pub const EcsRegistry = struct { pub var NeonObjectTable = core.EngineObjectVTable.from(@This(), "core.EcsRegistry"); - pub fn init(allocator: std.mem.Allocator) !*@This() { - const self = try allocator.create(@This()); + pub fn init(self: *@This(), allocator: std.mem.Allocator, first: bool) !void { + if (!first) { + return; + } self.* = .{ .allocator = allocator, .baseSet = BaseSet.init(allocator), }; - - return self; } pub fn registerContainer(self: *@This(), ref: EcsContainerRef, _containerName: core.Name) !void { @@ -279,7 +279,7 @@ pub const EcsRegistry = struct { } pub fn deinit(self: *@This()) void { - self.destroy(); + _ = self; } pub fn destroy(self: *@This()) void { @@ -300,7 +300,6 @@ pub const EcsRegistry = struct { self.containers.deinit(self.allocator); self.containerNames.deinit(self.allocator); self.containersByName.deinit(self.allocator); - self.allocator.destroy(self); } }; diff --git a/engine/core/src/engine.zig b/engine/core/src/engine.zig index cc82f4e..080dd77 100644 --- a/engine/core/src/engine.zig +++ b/engine/core/src/engine.zig @@ -5,6 +5,7 @@ const time = @import("engineTime.zig"); const core = @import("core.zig"); const jobs = @import("jobs.zig"); const math = @import("math.zig"); +const builtin = @import("builtin"); const pscopes = core.algorithm.pscopes; const tracy = @import("tracy").t; @@ -129,9 +130,7 @@ pub const Engine = struct { var i: i32 = @intCast(self.destroyListCore.items.len - 1); while (i >= 0) : (i -= 1) { const item = self.destroyListCore.items[@as(usize, @intCast(i))]; - if (item.vtable.deinit_func) |deinitFn| { - deinitFn(item.ptr); - } + self.destroyObject(item); } } self.destroyListCore.deinit(self.allocator); @@ -162,6 +161,10 @@ pub const Engine = struct { return @ptrCast(@alignCast(rv)); } + const DebugSlack = struct { + slack: [1024 * 16]u8 align(16) = undefined, + }; + // creates an engine object using the engine's allocator. pub fn createObjectVTable(self: *@This(), vtable: *core.EngineObjectVTable, params: NeonObjectParams) !*anyopaque { if (self.createObjectLock) { @@ -173,7 +176,17 @@ pub const Engine = struct { self.createObjectLock = true; defer self.createObjectLock = false; const newIndex = self.engineObjects.items.len; - const newObjectPtr = try vtable.init_func(self.allocator); // call this thing with the special allocator that adds vtable. slackSize to it. + var newObjectPtr: *anyopaque = undefined; //self.allocator.create(DebugSlack); + + if (comptime core.BuildOption("static_build")) { + newObjectPtr = @ptrCast(@alignCast((try self.allocator.alignedAlloc(u8, .@"16", vtable.typeSize)))); + } else { + newObjectPtr = @ptrCast(@alignCast(&(try self.allocator.create(DebugSlack)).slack)); + } + + try vtable.init_func(newObjectPtr, self.allocator, true); + + // try vtable.init_func(self.allocator); // call this thing with the special allocator that adds vtable. slackSize to it. const newObjectRef = EngineObjectRef{ .ptr = @as(*anyopaque, @ptrCast(newObjectPtr)), @@ -359,14 +372,28 @@ pub const Engine = struct { self.destroyDependents(); } + fn destroyObject(self: *@This(), item: EngineObjectRef) void { + if (item.vtable.deinit_func) |deinitFn| { + deinitFn(item.ptr); + } + + if (comptime core.BuildOption("static_build")) { + var slice: []u8 = undefined; + slice.ptr = @ptrCast(@alignCast(item.ptr)); + slice.len = item.vtable.typeSize; + self.allocator.rawFree(slice, .@"16", @returnAddress()); + } else { + const asStruct: *DebugSlack = @ptrCast(@alignCast(item.ptr)); + self.allocator.destroy(asStruct); + } + } + fn destroyDependents(self: *@This()) void { if (self.destroyListSimple.items.len > 0) { var i: i32 = @intCast(self.destroyListSimple.items.len - 1); while (i >= 0) : (i -= 1) { const item = self.destroyListSimple.items[@as(usize, @intCast(i))]; - if (item.vtable.deinit_func) |deinitFn| { - deinitFn(item.ptr); - } + self.destroyObject(item); } } self.dependentsDestroyed.store(true, .seq_cst); diff --git a/engine/core/src/engineObject.zig b/engine/core/src/engineObject.zig index 3185e6e..5ce49af 100644 --- a/engine/core/src/engineObject.zig +++ b/engine/core/src/engineObject.zig @@ -167,7 +167,8 @@ pub const EngineObjectVTable = struct { singletonName: ?[]const u8 = null, - init_func: *const fn (std.mem.Allocator) EngineDataEventError!*anyopaque, + // new init_function passes in an already created object + init_func: *const fn (*anyopaque, std.mem.Allocator, bool) EngineDataEventError!void, tick_func: ?*const fn (*anyopaque, f64) void = null, engineDraw_func: ?*const fn (*anyopaque, f64) void = null, preTick_func: ?*const fn (*anyopaque, f64) EngineDataEventError!void = null, @@ -271,11 +272,10 @@ pub const EngineObjectVTable = struct { if (@hasDecl(TargetType, "init")) { const wrappedInit = struct { - const funcFind: @TypeOf(@field(TargetType, "init")) = @field(TargetType, "init"); - - pub fn func(allocator: std.mem.Allocator) EngineDataEventError!*anyopaque { - const newObject = funcFind(allocator) catch return error.BadInit; - return @as(*anyopaque, @ptrCast(newObject)); + pub fn func(p: *anyopaque, allocator: std.mem.Allocator, first: bool) EngineDataEventError!void { + const newObject: *TargetType = @ptrCast(@alignCast(p)); // funcFind(allocator) catch return error.BadInit; + newObject.init(allocator, first) catch return error.BadInit; + // return @as(*anyopaque, @ptrCast(newObject)); } }; @@ -284,11 +284,10 @@ pub const EngineObjectVTable = struct { if (@hasDecl(TargetType, "create")) { const wrappedInit = struct { - const funcFind: @TypeOf(@field(TargetType, "create")) = @field(TargetType, "create"); - - pub fn func(allocator: std.mem.Allocator) EngineDataEventError!*anyopaque { - const newObject = funcFind(allocator) catch return error.BadInit; - return @as(*anyopaque, @ptrCast(newObject)); + pub fn func(p: *anyopaque, allocator: std.mem.Allocator, first: bool) EngineDataEventError!void { + const newObject: *TargetType = @ptrCast(@alignCast(p)); // funcFind(allocator) catch return error.BadInit; + newObject.create(allocator, first) catch return error.BadInit; + // return @as(*anyopaque, @ptrCast(newObject)); } }; diff --git a/engine/core/src/extern/externModule.zig b/engine/core/src/extern/externModule.zig index c71df79..57bd948 100644 --- a/engine/core/src/extern/externModule.zig +++ b/engine/core/src/extern/externModule.zig @@ -121,22 +121,23 @@ fn dllChangedCallback(pathChanged: []const u8, ctx: ?*anyopaque) void { } pub const ModuleLoader = struct { - backingAllocator: std.mem.Allocator, - arena: std.heap.ArenaAllocator, + backingAllocator: std.mem.Allocator = undefined, + arena: std.heap.ArenaAllocator = undefined, loadedModules: std.ArrayListUnmanaged(*LoadedModule) = .{}, watchInitialized: bool = false, watchInitializeFn: ?*const fn () void = null, pub var NeonObjectTable = core.EngineObjectVTable.from(@This(), "core.ModuleLoader"); - pub fn create(allocator: std.mem.Allocator) !*@This() { - const self = try allocator.create(@This()); + + pub fn create(self: *@This(), allocator: std.mem.Allocator, first: bool) !void { + if (!first) { + return; + } self.* = .{ .backingAllocator = allocator, .arena = std.heap.ArenaAllocator.init(allocator), }; - - return self; } pub fn addModule(self: *@This(), moduleName: []const u8) !void { @@ -217,7 +218,6 @@ pub const ModuleLoader = struct { pub fn destroy(self: *@This()) void { // std.fs.cwd().deleteTree(".modulecache") catch {}; self.arena.deinit(); - self.backingAllocator.destroy(self); } }; diff --git a/engine/core/src/gameObject.zig b/engine/core/src/gameObject.zig index f3ffb92..dfa07cd 100644 --- a/engine/core/src/gameObject.zig +++ b/engine/core/src/gameObject.zig @@ -71,21 +71,20 @@ pub const GameObjectSystem = struct { // this is the new one, GameObjectList should be deleted after this passes initial usability pub var NeonObjectTable = core.EngineObjectVTable.from(@This(), "core.GameObjectSystem"); - allocator: std.mem.Allocator, + allocator: std.mem.Allocator = undefined, objectDefinitions: std.AutoHashMapUnmanaged(u32, GameObjectInterfaceVTable) = .{}, - typesArena: std.heap.ArenaAllocator, + typesArena: std.heap.ArenaAllocator = undefined, objectSpawnEvents: std.ArrayListUnmanaged(SpawnEvent) = .{}, - pub fn create(allocator: std.mem.Allocator) !*@This() { - const self = try allocator.create(@This()); + pub fn create(self: *@This(), allocator: std.mem.Allocator, first: bool) !void { + if (!first) + return; self.* = .{ .allocator = allocator, .typesArena = std.heap.ArenaAllocator.init(self.allocator), }; - - return self; } pub fn spawnObject(self: *@This(), comptime T: type, objectName: []const u8, parameters: SpawnParameters) !*T { @@ -179,7 +178,6 @@ pub const GameObjectSystem = struct { pub fn destroy(self: *@This()) void { self.typesArena.deinit(); - self.allocator.destroy(self); } }; diff --git a/engine/core/src/inputs/inputStack.zig b/engine/core/src/inputs/inputStack.zig index 76ad037..9badecb 100644 --- a/engine/core/src/inputs/inputStack.zig +++ b/engine/core/src/inputs/inputStack.zig @@ -574,11 +574,11 @@ pub const BindingLayer = struct { // not gonna actually deal with layers right now pub const InputStack = struct { - allocator: std.mem.Allocator, + allocator: std.mem.Allocator = undefined, - active: ?*BindingLayer, + active: ?*BindingLayer = undefined, bindingStack: std.ArrayListUnmanaged(*BindingLayer) = .{}, - arena: std.heap.ArenaAllocator, + arena: std.heap.ArenaAllocator = undefined, keysDown: std.AutoHashMapUnmanaged(Key, bool) = .{}, @@ -591,8 +591,10 @@ pub const InputStack = struct { pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This(), "core.InputStack"); - pub fn init(allocator: std.mem.Allocator) !*@This() { - const self = try allocator.create(@This()); + pub fn init(self: *@This(), allocator: std.mem.Allocator, first: bool) !void { + if (!first) { + return; + } self.* = .{ .allocator = allocator, @@ -601,8 +603,6 @@ pub const InputStack = struct { }; core.EngineObject(@This()).gInstance = self; - - return self; } pub fn updatePreviousInputs(self: *@This()) void { @@ -716,7 +716,6 @@ pub const InputStack = struct { if (self.active) |active| { active.destroy(); } - self.allocator.destroy(self); } }; diff --git a/engine/core/src/logging.zig b/engine/core/src/logging.zig index e53ba6a..81b7b2b 100644 --- a/engine/core/src/logging.zig +++ b/engine/core/src/logging.zig @@ -192,13 +192,13 @@ pub const FileLog = struct { pub const LoggerSys = struct { pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This(), "core.LoggerSys"); - writeOutBuffer: std.ArrayList(u8), - flushBuffer: std.ArrayList(u8), - allocator: std.mem.Allocator, - logFilePath: []const u8, - logFile: std.fs.File, - consoleFile: std.fs.File, - writerBuffer: []u8, + writeOutBuffer: std.ArrayList(u8) = .{}, + flushBuffer: std.ArrayList(u8) = .{}, + allocator: std.mem.Allocator = undefined, + logFilePath: []const u8 = "none", + logFile: std.fs.File = undefined, + consoleFile: std.fs.File = undefined, + writerBuffer: []u8 = undefined, lock: std.Thread.Mutex = .{}, flushing: std.atomic.Value(bool) = std.atomic.Value(bool).init(false), @@ -306,12 +306,14 @@ pub const LoggerSys = struct { } } - pub fn init(allocator: std.mem.Allocator) !*@This() { + pub fn init(self: *@This(), allocator: std.mem.Allocator, first: bool) !void { + if (!first) { + return; + } const cwd = std.fs.cwd(); const ofile = std.fmt.allocPrint(allocator, core.DefaultSavePath ++ "/{s}", .{"Session_Log.txt"}) catch unreachable; cwd.makePath(core.DefaultSavePath) catch unreachable; - const self = try allocator.create(@This()); self.* = @This(){ .allocator = allocator, .writeOutBuffer = std.ArrayList(u8).initCapacity(allocator, LogBufferSize) catch unreachable, @@ -321,8 +323,6 @@ pub const LoggerSys = struct { .logFile = cwd.createFile(ofile, .{}) catch unreachable, .consoleFile = std.fs.File.stdout(), }; - - return self; } pub fn deinit(self: *@This()) void { @@ -333,8 +333,6 @@ pub const LoggerSys = struct { self.writeOutBuffer.deinit(self.allocator); self.flushBuffer.deinit(self.allocator); - - self.allocator.destroy(self); } pub fn processEvents(self: *@This(), frameNumber: u64) core.EngineDataEventError!void { diff --git a/engine/core/src/scene.zig b/engine/core/src/scene.zig index ae45cc5..514f262 100644 --- a/engine/core/src/scene.zig +++ b/engine/core/src/scene.zig @@ -296,9 +296,9 @@ fn childAllocator() std.mem.Allocator { pub const SceneSystem = struct { pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This(), "core.SceneSystem"); - allocator: std.mem.Allocator, + allocator: std.mem.Allocator = undefined, dynamicObjects: ArrayListUnmanaged(core.ObjectHandle) = .{}, - childrenArena: std.heap.ArenaAllocator, + childrenArena: std.heap.ArenaAllocator = undefined, tickCount: u32 = 0, sceneObjectContainer: *SceneObjectSet = undefined, @@ -385,8 +385,11 @@ pub const SceneSystem = struct { pub const MaxWorkerCount = 24; // ----- NeonObject interace ---- - pub fn init(allocator: std.mem.Allocator) !*@This() { - const self = try allocator.create(@This()); + pub fn init(self: *@This(), allocator: std.mem.Allocator, first: bool) !void { + if (!first) { + return; + } + self.* = .{ .allocator = allocator, .childrenArena = std.heap.ArenaAllocator.init(allocator), @@ -401,8 +404,6 @@ pub const SceneSystem = struct { try self.cachedOutputs.append(self.allocator, .{}); try self.writeOutList.append(self.allocator, .{}); } - - return self; } pub fn getOutputList(self: *@This(), threadId: u32) !*std.ArrayList(usize) { @@ -446,7 +447,6 @@ pub const SceneSystem = struct { Scene.SceneObjectContainer.destroy(); self.cachedOutputs.deinit(self.allocator); self.writeOutList.deinit(self.allocator); - self.allocator.destroy(self); } }; diff --git a/engine/core/tests/samplesubsystem.zig b/engine/core/tests/samplesubsystem.zig index 4892c2f..20f5b54 100644 --- a/engine/core/tests/samplesubsystem.zig +++ b/engine/core/tests/samplesubsystem.zig @@ -1,22 +1,17 @@ pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This(), "testing.sampleSubsystem"); -allocator: std.mem.Allocator, -scene: *anyopaque, -setPositionPtr: *const anyopaque, +allocator: std.mem.Allocator = undefined, +scene: *anyopaque = undefined, +setPositionPtr: *const anyopaque = undefined, + +pub fn init(self: *@This(), allocator: std.mem.Allocator, first: bool) !void { + if (!first) { + return; + } -pub fn create(allocator: std.mem.Allocator) !*@This() { - const self = try allocator.create(@This()); self.* = .{ .allocator = allocator, - .scene = undefined, - .setPositionPtr = undefined, }; - - return self; -} - -pub fn destroy(self: *@This()) void { - self.allocator.destroy(self); } const exampleScene = @import("exampleScene.zig");