diff --git a/zig-ecs/.vscode/tasks.json b/zig-ecs/.vscode/tasks.json index 425f970..dce0dbc 100644 --- a/zig-ecs/.vscode/tasks.json +++ b/zig-ecs/.vscode/tasks.json @@ -21,6 +21,39 @@ "group": { "kind": "build", "isDefault": true + }, + "presentation": { + "clear": true + } + }, + { + "label": "Build and Run Project (release-fast)", + "type": "shell", + "command": "zig build run -Drelease-fast", + "problemMatcher": [ + "$gcc" + ], + "group": { + "kind": "build", + "isDefault": true + }, + "presentation": { + "clear": true + } + }, + { + "label": "Build and Run Project (release-small)", + "type": "shell", + "command": "zig build run -Drelease-small", + "problemMatcher": [ + "$gcc" + ], + "group": { + "kind": "build", + "isDefault": true + }, + "presentation": { + "clear": true } }, { diff --git a/zig-ecs/build.zig b/zig-ecs/build.zig index f3d58d0..de4d04e 100644 --- a/zig-ecs/build.zig +++ b/zig-ecs/build.zig @@ -5,8 +5,8 @@ pub fn build(b: *Builder) void { const buildMode = b.standardReleaseOptions(); const examples = [_][2][]const u8{ + [_][]const u8{ "view_vs_group", "examples/view_vs_group.zig" }, [_][]const u8{ "simple", "examples/simple.zig" }, - // [_][]const u8{ "mesh", "examples/mesh.zig" }, }; for (examples) |example, i| { diff --git a/zig-ecs/examples/view_vs_group.zig b/zig-ecs/examples/view_vs_group.zig new file mode 100644 index 0000000..59a753a --- /dev/null +++ b/zig-ecs/examples/view_vs_group.zig @@ -0,0 +1,63 @@ +const std = @import("std"); +const ecs = @import("ecs"); + +// override the EntityTraits used by ecs +pub const EntityTraits = ecs.EntityTraitsType(.medium); + +pub const Velocity = struct { x: f32, y: f32 }; +pub const Position = struct { x: f32, y: f32 }; + +/// logs the timing for views vs groups with 1,000,000 entities +pub fn main() !void { + var reg = ecs.Registry.init(std.heap.c_allocator); + defer reg.deinit(); + + var timer = try std.time.Timer.start(); + var i: usize = 0; + while (i < 1000000) : (i += 1) { + var e1 = reg.create(); + reg.add(e1, Position{ .x = 1, .y = 1 }); + reg.add(e1, Velocity{ .x = 1, .y = 1 }); + } + var end = timer.lap(); + std.debug.warn("create: \t{d}\n", .{@intToFloat(f64, end) / 1000000000}); + + var view = reg.view(.{ Velocity, Position }, .{}); + + timer.reset(); + var iter = view.iterator(); + while (iter.next()) |entity| { + var pos = view.get(Position, entity); + const vel = view.getConst(Velocity, entity); + + pos.*.x += vel.x; + pos.*.y += vel.y; + } + + end = timer.lap(); + std.debug.warn("view (iter): \t{d}\n", .{@intToFloat(f64, end) / 1000000000}); + + var group = reg.group(.{ Velocity, Position }, .{}, .{}); + end = timer.lap(); + std.debug.warn("group (create): {d}\n", .{@intToFloat(f64, end) / 1000000000}); + + timer.reset(); + var group_iter = group.iterator(struct { vel: *Velocity, pos: *Position }); + while (group_iter.next()) |e| { + e.pos.*.x += e.vel.x; + e.pos.*.y += e.vel.y; + } + + end = timer.lap(); + std.debug.warn("group (iter): \t{d}\n", .{@intToFloat(f64, end) / 1000000000}); + + timer.reset(); + group.each(each); + end = timer.read(); + std.debug.warn("group (each): \t{d}\n", .{@intToFloat(f64, end) / 1000000000}); +} + +fn each(e: struct { vel: *Velocity, pos: *Position }) void { + e.pos.*.x += e.vel.x; + e.pos.*.y += e.vel.y; +} diff --git a/zig-ecs/src/ecs/groups.zig b/zig-ecs/src/ecs/groups.zig index 64b2132..ef55d71 100644 --- a/zig-ecs/src/ecs/groups.zig +++ b/zig-ecs/src/ecs/groups.zig @@ -229,7 +229,7 @@ pub const OwningGroup = struct { @field(comps, field.name) = &typed_ptr[entity_index]; } - @call(.{ .modifier = .always_inline }, func, .{comps}); + func(comps); } }