Mike 4 years ago
parent ac17a79631
commit 8235f3dc7f

@ -200,13 +200,26 @@ 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 sortFn: 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);
} 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);
// fn sorter(self: Self, a: T, b: T, sortFn) bool {
// return sortFn(self.instances[a], self.instances[b]);
// }
@ -357,25 +370,3 @@ 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(1, @as(f32, 1.1));
store.add(2, @as(f32, 2.2));
store.add(0, @as(f32, 0.0));
store.sort(f32, asc_f32);
for (store.raw()) |e, i| {
// std.debug.warn("{}: {}\n", .{i, e});
// std.testing.expectEqual(@intCast(u32, i), e);
}
store.sort(f32, desc_f32);
for (store.raw()) |e, i| {
// std.testing.expectEqual(counter, e);
}
}

@ -95,8 +95,9 @@ pub fn SparseSet(comptime SparseT: type) type {
pub fn contains(self: Self, sparse: SparseT) bool {
const curr = self.page(sparse);
if (curr >= self.sparse.items.len)
if (curr >= self.sparse.items.len) {
return false;
}
// testing against maxInt permits to avoid accessing the packed array
return curr < self.sparse.items.len and self.sparse.items[curr] != std.math.maxInt(SparseT);
@ -146,7 +147,7 @@ pub fn SparseSet(comptime SparseT: type) type {
std.sort.insertionSort(SparseT, self.dense.items, {}, sortFn);
for (self.dense.items) |sparse| {
// self.assure(self.page(sparse))[self.offset(sparse)] = @intCast(SparseT, sparse);
// sparse[page(packed[pos])][offset(packed[pos])] = entity_type(pos);
self.sparse.items[self.page(sparse)] = @intCast(SparseT, sparse);
}
}
@ -156,11 +157,21 @@ pub fn SparseSet(comptime SparseT: type) type {
utils.sortSub(SparseT, T, self.dense.items, sub_items, sortFn);
for (self.dense.items) |sparse| {
// self.assure(self.page(sparse))[self.offset(sparse)] = @intCast(SparseT, sparse);
// sparse[page(packed[pos])][offset(packed[pos])] = entity_type(pos);
self.sparse.items[self.page(sparse)] = @intCast(SparseT, sparse);
}
}
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);
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);
}
}
/// Sort entities according to their order in another sparse set. Other is the master in this case.
pub fn respect(self: *Self, other: *Self) void {
var pos = @as(SparseT, 0);

@ -64,6 +64,21 @@ pub fn sortSub(comptime T1: type, comptime T2: type, items: []T1, sub_items: []T
}
}
pub fn sortSubSub(comptime T1: type, comptime T2: type, items: []T1, sub_items: []T2, context: var, comptime lessThan: fn (@TypeOf(context), lhs: T1, rhs: T1) bool) void {
var i: usize = 1;
while (i < items.len) : (i += 1) {
const x = items[i];
const y = sub_items[i];
var j: usize = i;
while (j > 0 and lessThan(context, x, items[j - 1])) : (j -= 1) {
items[j] = items[j - 1];
sub_items[j] = sub_items[j - 1];
}
items[j] = x;
sub_items[j] = y;
}
}
/// comptime string hashing for the type names
pub fn typeId(comptime T: type) u32 {
comptime return hashStringFnv(u32, @typeName(T));

@ -14,14 +14,12 @@ const Rotation = struct { x: f32 = 0 };
fn printStore(store: var, name: []const u8) void {
warn("--- {} ---\n", .{name});
for (store.set.dense.items) |e, i| {
warn("[{}] {}", .{e, store.set.sparse.items[store.set.page(store.set.dense.items[i])]});
warn("e[{}] s[{}]{}", .{e, store.set.page(store.set.dense.items[i]), store.set.sparse.items[store.set.page(store.set.dense.items[i])]});
warn(" ({d:.2}) ", .{store.instances.items[i]});
}
warn("\n", .{});
}
const asc_u32 = std.sort.asc(u32);
const desc_u32 = std.sort.desc(f32);
test "sort component" {
std.debug.warn("\n", .{});
@ -29,24 +27,24 @@ test "sort component" {
var store = ecs.ComponentStorage(f32, u32).initPtr(std.testing.allocator);
defer store.deinit();
store.add(1, @as(f32, 1.1));
store.add(2, @as(f32, 2.2));
store.add(0, @as(f32, 0.0));
store.add(33, @as(f32, 3.3));
store.add(22, @as(f32, 2.2));
store.add(11, @as(f32, 1.1));
printStore(store, "Fucker");
printStore(store, "Fuckerrrr");
store.sort(u32, asc_u32);
for (store.raw()) |e, i| {
// std.debug.warn("{}: {}\n", .{i, e});
// std.testing.expectEqual(@intCast(u32, i), e);
}
// sort by entity
// comptime const asc_u32 = std.sort.asc(u32);
// store.sort(u32, asc_u32);
printStore(store, "Fucker");
comptime const desc_u32 = std.sort.asc(f32);
store.sort(f32, desc_u32);
for (store.raw()) |e, i| {
// std.testing.expectEqual(counter, e);
}
printStore(store, "Fuckerrrrr");
}
test "nested OwningGroups add/remove components" {

Loading…
Cancel
Save