From 735830994fa5b2240461b885fa17279fe2137738 Mon Sep 17 00:00:00 2001 From: Mike Date: Fri, 12 Jun 2020 23:37:09 -0700 Subject: [PATCH] add len to all sorts for owned groups --- zig-ecs/src/ecs/component_storage.zig | 16 ++++++------ zig-ecs/src/ecs/groups.zig | 13 +++------- zig-ecs/tests/groups_test.zig | 36 ++++++++++++++++++++++++++- 3 files changed, 47 insertions(+), 18 deletions(-) diff --git a/zig-ecs/src/ecs/component_storage.zig b/zig-ecs/src/ecs/component_storage.zig index 6624f99..d50870e 100644 --- a/zig-ecs/src/ecs/component_storage.zig +++ b/zig-ecs/src/ecs/component_storage.zig @@ -202,7 +202,7 @@ pub fn ComponentStorage(comptime Component: type, comptime Entity: type) type { } /// Sort Entities or Components according to the given comparison function. Valid types for T are Entity or Component. - pub fn sort(self: *Self, comptime T: type, context: var, comptime lessThan: fn (@TypeOf(context), T, T) bool) void { + pub fn sort(self: *Self, comptime T: type, length: usize, context: var, comptime lessThan: fn (@TypeOf(context), T, T) bool) void { std.debug.assert(T == Entity or T == Component); if (T == Entity) { // wtf? When an OwningGroup calls us we are gonna be fake-typed and if we are fake-typed its not safe to pass our slice to @@ -216,12 +216,12 @@ pub fn ComponentStorage(comptime Component: type, comptime Entity: type) type { } }; const swap_context = SortContext{.storage = self}; - self.set.sortSwap(context, lessThan, swap_context); + self.set.sortSwap(length, context, lessThan, swap_context); } else { - self.set.sortSub(context, lessThan, Component, self.instances.items); + self.set.sortSub(length, context, lessThan, Component, self.instances.items); } } else if (T == Component) { - self.set.sortSubSub(context, Component, lessThan, self.instances.items); + self.set.sortSubSub(length, context, Component, lessThan, self.instances.items); } } }; @@ -256,7 +256,9 @@ test "add/try-get/remove/clear" { store.add(3, 66.45); std.testing.expectEqual(store.tryGetConst(3).?, 66.45); - if (store.tryGet(3)) |found| std.testing.expectEqual(@as(f32, 66.45), found.*); + if (store.tryGet(3)) |found| { + std.testing.expectEqual(@as(f32, 66.45), found.*); + } store.remove(3); @@ -385,7 +387,7 @@ test "sort by entity" { } }; const context = SortContext{ .store = store }; - store.sort(u32, context, SortContext.sort); + store.sort(u32, store.len(), context, SortContext.sort); var compare: f32 = 5; for (store.raw()) |val, i| { @@ -405,7 +407,7 @@ test "sort by component" { store.add(33, @as(f32, 3.3)); comptime const desc_f32 = std.sort.desc(f32); - store.sort(f32, {}, desc_f32); + store.sort(f32, store.len(), {}, desc_f32); var compare: f32 = 5; for (store.raw()) |val, i| { diff --git a/zig-ecs/src/ecs/groups.zig b/zig-ecs/src/ecs/groups.zig index 4d3880b..b2aee4e 100644 --- a/zig-ecs/src/ecs/groups.zig +++ b/zig-ecs/src/ecs/groups.zig @@ -267,7 +267,7 @@ pub const OwningGroup = struct { if (T == Entity) { // only sort up to self.group_data.current - first_storage.sort(Entity, context, lessThan); + first_storage.sort(Entity, self.group_data.current, context, lessThan); } else { // TODO: in debug mode, validate that T is present in the group const SortContext = struct { @@ -282,17 +282,10 @@ pub const OwningGroup = struct { } }; const wrapper = SortContext{ .group = self, .wrapped_context = context, .lessThan = lessThan }; - first_storage.sort(Entity, wrapper, SortContext.sort); + first_storage.sort(Entity, self.group_data.current, wrapper, SortContext.sort); } - // sync up the rest of the owned components. First get our Storages in - // var tmp_storages: [20]*Storage(u1) = undefined; - // for (self.group_data.owned[1..]) |type_id, i| { - // var other_ptr = self.registry.components.getValue(type_id).?; - // tmp_storages[i] = @intToPtr(*Storage(u1), other_ptr); - // } - // var storages = tmp_storages[0 .. self.group_data.owned.len - 1]; - + // sync up the rest of the owned components var next: usize = self.group_data.current; while (true) : (next -= 1) { if (next == 0) break; diff --git a/zig-ecs/tests/groups_test.zig b/zig-ecs/tests/groups_test.zig index b8371c7..ec71bf3 100644 --- a/zig-ecs/tests/groups_test.zig +++ b/zig-ecs/tests/groups_test.zig @@ -3,6 +3,7 @@ const warn = std.debug.warn; const ecs = @import("ecs"); const Registry = @import("ecs").Registry; const BasicGroup = @import("ecs").BasicGroup; +const OwningGroup = @import("ecs").OwningGroup; const Velocity = struct { x: f32 = 0, y: f32 = 0 }; const Position = struct { x: f32 = 0, y: f32 = 0 }; @@ -83,6 +84,40 @@ test "sort BasicGroup by Component" { } } +test "sort OwningGroup by Entity" { + std.debug.warn("\n", .{}); + var reg = Registry.init(std.testing.allocator); + defer reg.deinit(); + + var group = reg.group(.{ Sprite, Renderable }, .{}, .{}); + + var i: usize = 0; + while (i < 5) : (i += 1) { + var e = reg.create(); + reg.add(e, Sprite{ .x = @intToFloat(f32, i) }); + reg.add(e, Renderable{ .x = @intToFloat(f32, i) }); + } + + const SortContext = struct { + group: OwningGroup, + + fn sort(this: @This(), a: ecs.Entity, b: ecs.Entity) bool { + const sprite_a = this.group.getConst(Sprite, a); + const sprite_b = this.group.getConst(Sprite, b); + return sprite_a.x > sprite_b.x; + } + }; + const context = SortContext{.group = group}; + group.sort(ecs.Entity, context, SortContext.sort); + + var val: f32 = 0; + var iter = group.iterator(struct {s: *Sprite, r: *Renderable}); + while (iter.next()) |entity| { + std.testing.expectEqual(val, entity.s.*.x); + val += 1; + } +} + test "sort OwningGroup by Component" { std.debug.warn("\n", .{}); var reg = Registry.init(std.testing.allocator); @@ -107,7 +142,6 @@ test "sort OwningGroup by Component" { var val: f32 = 0; var iter = group.iterator(struct {s: *Sprite, r: *Renderable}); while (iter.next()) |entity| { - std.debug.warn("e{}: {d}\n", .{iter.entity(), entity}); std.testing.expectEqual(val, entity.s.*.x); val += 1; }