From 52aef18b351ca2697ea6e28d21fffbc5b0f66a84 Mon Sep 17 00:00:00 2001 From: Mike Date: Fri, 12 Jun 2020 13:47:53 -0700 Subject: [PATCH] sorting a Storage works now --- zig-ecs/src/ecs/component_storage.zig | 46 ++++++++++++++------------- zig-ecs/src/ecs/sparse_set.zig | 16 +++++----- zig-ecs/tests/groups_test.zig | 22 ++++--------- 3 files changed, 39 insertions(+), 45 deletions(-) diff --git a/zig-ecs/src/ecs/component_storage.zig b/zig-ecs/src/ecs/component_storage.zig index b499a93..ede1bb6 100644 --- a/zig-ecs/src/ecs/component_storage.zig +++ b/zig-ecs/src/ecs/component_storage.zig @@ -200,26 +200,12 @@ pub fn ComponentStorage(comptime CompT: type, comptime EntityT: type) type { } /// Sort Entities or Components according to the given comparison function - pub fn sort(self: *Self, comptime T: type, comptime sortFn: fn (void, T, T) bool) void { + pub fn sort(self: *Self, comptime T: type, comptime lessThan: fn (void, T, T) bool) void { std.debug.assert(T == EntityT or T == CompT); if (T == EntityT) { - self.set.sortSub(sortFn, CompT, self.instances.items); + self.set.sortSub(lessThan, CompT, self.instances.items); } else if (T == CompT) { - // essentially need to be able to call a sort method with a bound fn. That fn would then use sortFn along - // with self.instances. - const Context = struct{ - self: *Self, - sortFn: fn (void, T, T) bool, - - fn sort(this: @This(), a: EntityT, b: EntityT) bool { - const real_a = this.self.getConst(a); - const real_b = this.self.getConst(b); - return this.sortFn({}, real_a, real_b); - } - }; - const context = Context{.self = self, .sortFn = sortFn}; - - self.set.sortSubSub(context, Context.sort, CompT, self.instances.items); + self.set.sortSubSub({}, CompT, lessThan, self.instances.items); // fn sorter(self: Self, a: T, b: T, sortFn) bool { // return sortFn(self.instances[a], self.instances[b]); // } @@ -342,9 +328,6 @@ test "signals" { store.remove(4); } -const asc_u32 = std.sort.asc(u32); -const desc_u32 = std.sort.desc(u32); - test "sort empty component" { const Empty = struct {}; @@ -355,11 +338,13 @@ test "sort empty component" { store.add(2, Empty{}); store.add(0, Empty{}); + comptime const asc_u32 = std.sort.asc(u32); store.sort(asc_u32); for (store.data()) |e, i| { std.testing.expectEqual(@intCast(u32, i), e); } + comptime const desc_u32 = std.sort.desc(u32); store.sort(desc_u32); var counter: u32 = 2; for (store.data()) |e, i| { @@ -368,5 +353,22 @@ test "sort empty component" { } } -const asc_f32 = std.sort.asc(f32); -const desc_f32 = std.sort.desc(f32); +test "sort component" { + std.debug.warn("\n", .{}); + + var store = ComponentStorage(f32, u32).initPtr(std.testing.allocator); + defer store.deinit(); + + store.add(22, @as(f32, 2.2)); + store.add(11, @as(f32, 1.1)); + store.add(33, @as(f32, 3.3)); + + comptime const desc_u32 = std.sort.desc(f32); + store.sort(f32, desc_u32); + + var compare: f32 = 5; + for (store.raw()) |val, i| { + std.testing.expect(compare > val); + compare = val; + } +} diff --git a/zig-ecs/src/ecs/sparse_set.zig b/zig-ecs/src/ecs/sparse_set.zig index a0fe045..d3e239e 100644 --- a/zig-ecs/src/ecs/sparse_set.zig +++ b/zig-ecs/src/ecs/sparse_set.zig @@ -146,9 +146,9 @@ pub fn SparseSet(comptime SparseT: type) type { pub fn sort(self: *Self, comptime sortFn: fn (void, SparseT, SparseT) bool) void { std.sort.insertionSort(SparseT, self.dense.items, {}, sortFn); - for (self.dense.items) |sparse| { + for (self.dense.items) |sparse, i| { // sparse[page(packed[pos])][offset(packed[pos])] = entity_type(pos); - self.sparse.items[self.page(sparse)] = @intCast(SparseT, sparse); + self.sparse.items[self.dense.items[self.page(@intCast(SparseT, i))]] = @intCast(SparseT, i); } } @@ -156,19 +156,19 @@ pub fn SparseSet(comptime SparseT: type) type { pub fn sortSub(self: *Self, comptime sortFn: fn (void, SparseT, SparseT) bool, comptime T: type, sub_items: []T) void { utils.sortSub(SparseT, T, self.dense.items, sub_items, sortFn); - for (self.dense.items) |sparse| { + for (self.dense.items) |sparse, i| { // sparse[page(packed[pos])][offset(packed[pos])] = entity_type(pos); - self.sparse.items[self.page(sparse)] = @intCast(SparseT, sparse); + self.sparse.items[self.dense.items[self.page(@intCast(SparseT, i))]] = @intCast(SparseT, i); } } - pub fn sortSubSub(self: *Self, context: var, comptime sortFn: fn (@TypeOf(context), SparseT, SparseT) bool, comptime T: type, sub_items: []T) void { - utils.sortSubSub(SparseT, T, self.dense.items, sub_items, context, sortFn); + /// flips the script and uses the sparse set as the subordinate and does the sorting on the items slice + pub fn sortSubSub(self: *Self, context: var, comptime T: type, comptime lessThan: fn (@TypeOf(context), T, T) bool, items: []T) void { + utils.sortSubSub(T, SparseT, items, self.dense.items, context, lessThan); for (self.dense.items) |sparse, i| { - std.debug.warn("e: {}, dense: {}, instance: {}\n", .{sparse, self.dense.items[self.page(@intCast(u32, i))], sub_items[i]}); // sparse[page(packed[pos])][offset(packed[pos])] = entity_type(pos); - self.sparse.items[self.dense.items[self.page(@intCast(u32, i))]] = @intCast(SparseT, sparse); + self.sparse.items[self.dense.items[self.page(@intCast(SparseT, i))]] = @intCast(SparseT, i); } } diff --git a/zig-ecs/tests/groups_test.zig b/zig-ecs/tests/groups_test.zig index 70af802..cdfaf05 100644 --- a/zig-ecs/tests/groups_test.zig +++ b/zig-ecs/tests/groups_test.zig @@ -22,29 +22,21 @@ fn printStore(store: var, name: []const u8) void { test "sort component" { - std.debug.warn("\n", .{}); - var store = ecs.ComponentStorage(f32, u32).initPtr(std.testing.allocator); defer store.deinit(); - store.add(33, @as(f32, 3.3)); store.add(22, @as(f32, 2.2)); store.add(11, @as(f32, 1.1)); + store.add(33, @as(f32, 3.3)); - printStore(store, "Fuckerrrr"); - - // sort by entity - // comptime const asc_u32 = std.sort.asc(u32); - // store.sort(u32, asc_u32); - - - comptime const desc_u32 = std.sort.asc(f32); + comptime const desc_u32 = std.sort.desc(f32); store.sort(f32, desc_u32); - for (store.raw()) |e, i| { - // std.testing.expectEqual(counter, e); - } - printStore(store, "Fuckerrrrr"); + var compare: f32 = 5; + for (store.raw()) |val, i| { + std.testing.expect(compare > val); + compare = val; + } } test "nested OwningGroups add/remove components" {