diff --git a/engine/core/src/ecs.zig b/engine/core/src/ecs.zig index 8186b3e..8b93988 100644 --- a/engine/core/src/ecs.zig +++ b/engine/core/src/ecs.zig @@ -306,7 +306,19 @@ pub const Entity = struct { return rv; } + pub fn fetch(self: @This(), comptime Component: type) ?*Component { + if (@TypeOf(Component.BaseContainer.*).StableReferences) { + @compileError(@typeName(Component) ++ " states that it's references are stable, use get() instead of fetch()"); + } + const rv = Component.BaseContainer.get(self.handle); + return if (rv == null) null else @ptrCast(@alignCast(rv.?)); + } + + // acquire a reference to an entity's component if it exists pub fn get(self: @This(), comptime Component: type) ?*Component { + if (!@TypeOf(Component.BaseContainer.*).StableReferences) { + @compileError(@typeName(Component) ++ " doesn't state that it's references are stable, use fetch() instead of get()"); + } const rv = Component.BaseContainer.get(self.handle); return if (rv == null) null else @ptrCast(@alignCast(rv.?)); } diff --git a/engine/physics/src/physicsCharacter.zig b/engine/physics/src/physicsCharacter.zig index 69e73bb..fed60b0 100644 --- a/engine/physics/src/physicsCharacter.zig +++ b/engine/physics/src/physicsCharacter.zig @@ -12,7 +12,7 @@ pub const PhysicsCharacter = struct { @panic("adding a physics character to an entity already controlled by PhysicsCollider. I'm not going to support this"); } - if (self.entity.get(core.Scene) == null) { + if (self.entity.fetch(core.Scene) == null) { @panic("a scene component needs to be created in order to add a physics collider"); } } @@ -23,7 +23,7 @@ pub const PhysicsCharacter = struct { const interface = system.system.getBodyInterfaceMut(); const shape = system.shapes.get(n.handle()).?; - const scene = self.entity.get(core.Scene).?; + const scene = self.entity.fetch(core.Scene).?; const p = scene.getPosition(); var settings = try zphysics.CharacterSettings.create(); @@ -51,7 +51,7 @@ pub const PhysicsCharacter = struct { _ = dt; // self.character.update(@floatCast(dt), .{ 0, -1.0, 0 }, .{}); - const scene = self.entity.get(core.Scene).?; + const scene = self.entity.fetch(core.Scene).?; const p = self.character.getPosition(); // core.debugSphere(position, 20, .{}); scene.setPosition(.{ .x = p[0], .y = p[1], .z = p[2] }); diff --git a/engine/physics/src/physicsCollider.zig b/engine/physics/src/physicsCollider.zig index 1353c4c..31f47e6 100644 --- a/engine/physics/src/physicsCollider.zig +++ b/engine/physics/src/physicsCollider.zig @@ -12,7 +12,7 @@ pub const PhysicsCollider = struct { @panic("adding a physics collider to an entity already controlled by physics character. I don't want to support this"); } - if (self.entity.get(core.Scene) == null) { + if (self.entity.fetch(core.Scene) == null) { @panic("a scene component needs to be created in order to add a physics collider"); } } diff --git a/engine/physics/src/physicsSystem.zig b/engine/physics/src/physicsSystem.zig index 84019dd..33f3d1d 100644 --- a/engine/physics/src/physicsSystem.zig +++ b/engine/physics/src/physicsSystem.zig @@ -212,7 +212,7 @@ pub const PhysicsRuntime = struct { defer readLock.unlock(); if (readLock.body) |body| { - const scene = collider.entity.get(core.Scene).?; + const scene = collider.entity.fetch(core.Scene).?; scene.setPosition(core.Vectorf.fromArray(body.position)); scene.setRotation(.{ .quat = body.rotation }); } diff --git a/engine/rend/src/camera/CameraComponent.zig b/engine/rend/src/camera/CameraComponent.zig index d7cd342..1bb8319 100644 --- a/engine/rend/src/camera/CameraComponent.zig +++ b/engine/rend/src/camera/CameraComponent.zig @@ -41,7 +41,7 @@ pub fn updateProjections(self: *@This()) void { } pub fn resolve(self: *@This()) void { - const scene = self.entity.get(core.Scene).?; + const scene = self.entity.fetch(core.Scene).?; self.updateProjections(); diff --git a/engine/rend/src/meshes/MeshComponent.zig b/engine/rend/src/meshes/MeshComponent.zig index 7637fda..0e1c2a0 100644 --- a/engine/rend/src/meshes/MeshComponent.zig +++ b/engine/rend/src/meshes/MeshComponent.zig @@ -21,7 +21,7 @@ pub fn initECS(self: *@This(), handle: core.SetHandle) void { // get the mesh component self.entity = core.Entity{ .handle = handle }; - if (self.entity.get(core.Scene) == null) { + if (self.entity.fetch(core.Scene) == null) { @panic("mesh added to something that doesn't have a scene component, not supported"); } } diff --git a/lib/p2/src/structures/sparse-set.zig b/lib/p2/src/structures/sparse-set.zig index 9ecd5b6..1f3f6c9 100644 --- a/lib/p2/src/structures/sparse-set.zig +++ b/lib/p2/src/structures/sparse-set.zig @@ -55,6 +55,8 @@ pub fn SparseMultiSetAdvanced(comptime T: type, comptime SparseSize: u32) type { pub const IsMultiset = true; + pub const StableReferences = false; + pub fn init(allocator: std.mem.Allocator) @This() { var self = @This(){ .allocator = allocator, @@ -308,6 +310,8 @@ pub fn SparseSetAdvanced(comptime T: type, comptime SparseSize: u32) type { containerListener: ?ContainerListener = null, opCount: u32 = 0, + pub const StableReferences = false; + pub fn getStateCount(self: @This()) u32 { return self.opCount; } @@ -587,6 +591,8 @@ pub fn SparseMap(comptime T: type) type { containerListener: ?ContainerListener = null, opCount: u32 = 0, + pub const StableReferences = true; + pub fn create(backingAllocator: std.mem.Allocator) !*@This() { const self = try backingAllocator.create(@This()); diff --git a/projects/sampleGame/main.zig b/projects/sampleGame/main.zig index 97158e3..3df0012 100644 --- a/projects/sampleGame/main.zig +++ b/projects/sampleGame/main.zig @@ -134,7 +134,7 @@ pub fn onExit(ctx: ?*anyopaque, action: core.ActionEvent) void { pub fn tick(self: *@This(), dt: f64) void { const fdt: f32 = @floatCast(dt); - if (self.camera.get(core.Scene)) |scene| { + if (self.camera.fetch(core.Scene)) |scene| { const vector = core.Vectorf{ .x = self.moveVector.x, .z = self.moveVector.z, .y = self.verticalMove }; scene.getPosRot().position = scene.getPosRot().position.add(vector.fmul(self.cameraSpeed * fdt)); // core.engine_log(" camera position >> {any}", .{scene.getPosRot().position});