cleanup sort

master
Mike 5 years ago
parent 6b34565a2a
commit 96385b6c61

@ -204,24 +204,39 @@ 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. /// 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, length: usize, 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); std.debug.assert(T == Entity or T == Component);
// we have to perform a swap after the sort for all moved entities so we make a helper struct for that. In the
// case of a Component sort we also wrap that into the struct so we can get the Component data to pass to the
// lessThan method passed in.
if (T == Entity) { 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 const SortContext = struct {
// the SparseSet and let it handle sorting. Instead, we'll use swap _without a set swap_ and do it ourselves. storage: *Self,
if (Component == u1) {
const SortContext = struct { pub fn swap(this: @This(), a: Entity, b: Entity) void {
storage: *Self, this.storage.safe_swap(this.storage, a, b, true);
}
pub fn swap(this: @This(), a: Entity, b: Entity) void { };
this.storage.safe_swap(this.storage, a, b, true); const swap_context = SortContext{.storage = self};
} self.set.arrange(length, context, lessThan, swap_context);
}; } else {
const swap_context = SortContext{.storage = self}; const SortContext = struct {
self.set.sortSwap(length, context, lessThan, swap_context); storage: *Self,
} else { wrapped_context: @TypeOf(context),
self.set.sortSub(length, context, lessThan, Component, self.instances.items); lessThan: fn (@TypeOf(context), T, T) bool,
}
} else if (T == Component) { fn sort(this: @This(), a: Entity, b: Entity) bool {
self.set.sortSubSub(length, context, Component, lessThan, self.instances.items); const real_a = this.storage.getConst(a);
const real_b = this.storage.getConst(b);
return this.lessThan(this.wrapped_context, real_a, real_b);
}
pub fn swap(this: @This(), a: Entity, b: Entity) void {
this.storage.safe_swap(this.storage, a, b, true);
}
};
const swap_context = SortContext{.storage = self, .wrapped_context = context, .lessThan = lessThan};
self.set.arrange(length, swap_context, SortContext.sort, swap_context);
} }
} }
}; };

@ -143,11 +143,6 @@ pub fn SparseSet(comptime SparseT: type) type {
std.mem.swap(SparseT, &self.dense.items[from.*], &self.dense.items[to.*]); std.mem.swap(SparseT, &self.dense.items[from.*], &self.dense.items[to.*]);
std.mem.swap(SparseT, from, to); std.mem.swap(SparseT, from, to);
// auto &from = sparse[page(lhs)][offset(lhs)];
// auto &to = sparse[page(rhs)][offset(rhs)];
// std::swap(packed[size_type(from)], packed[size_type(to)]);
// std::swap(from, to);
} }
/// Sort elements according to the given comparison function /// Sort elements according to the given comparison function
@ -155,32 +150,14 @@ pub fn SparseSet(comptime SparseT: type) type {
std.sort.insertionSort(SparseT, self.dense.items, context, lessThan); std.sort.insertionSort(SparseT, self.dense.items, context, lessThan);
for (self.dense.items) |sparse, i| { for (self.dense.items) |sparse, i| {
// sparse[page(packed[pos])][offset(packed[pos])] = entity_type(pos);
const item = @intCast(SparseT, i); const item = @intCast(SparseT, i);
self.sparse.items[self.page(self.dense.items[self.page(item)])].?[self.offset(self.dense.items[self.page(item)])] = @intCast(SparseT, i); self.sparse.items[self.page(self.dense.items[self.page(item)])].?[self.offset(self.dense.items[self.page(item)])] = @intCast(SparseT, i);
} }
} }
/// Sort elements according to the given comparison function and keeps sub_items with the same sort /// Sort elements according to the given comparison function. Use this when a data array needs to stay in sync with the SparseSet
pub fn sortSub(self: *Self, length: usize, context: var, comptime lessThan: fn (@TypeOf(context), SparseT, SparseT) bool, comptime T: type, sub_items: []T) void { /// by passing in a "swap_context" that contains a "swap" method with a sig of fn(ctx,SparseT,SparseT)void
std.sort.insertionSort(SparseT, self.dense.items[0..length], context, lessThan); pub fn arrange(self: *Self, length: usize, context: var, comptime lessThan: fn (@TypeOf(context), SparseT, SparseT) bool, swap_context: var) void {
for (self.dense.items[0..length]) |sparse, pos| {
var curr = @intCast(SparseT, pos);
var next = self.index(self.dense.items[curr]);
while (curr != next) {
std.mem.swap(T, &sub_items[self.index(self.dense.items[curr])], &sub_items[self.index(self.dense.items[next])]);
self.sparse.items[self.page(self.dense.items[curr])].?[self.offset(self.dense.items[curr])] = curr;
curr = next;
next = self.index(self.dense.items[curr]);
}
}
}
/// Sort elements according to the given comparison function and keeps sub_items with the same sort
pub fn sortSwap(self: *Self, length: usize, context: var, comptime lessThan: fn (@TypeOf(context), SparseT, SparseT) bool, swap_context: var) void {
std.sort.insertionSort(SparseT, self.dense.items[0..length], context, lessThan); std.sort.insertionSort(SparseT, self.dense.items[0..length], context, lessThan);
for (self.dense.items[0..length]) |sparse, pos| { for (self.dense.items[0..length]) |sparse, pos| {
@ -189,7 +166,6 @@ pub fn SparseSet(comptime SparseT: type) type {
while (curr != next) { while (curr != next) {
swap_context.swap(self.dense.items[curr], self.dense.items[next]); swap_context.swap(self.dense.items[curr], self.dense.items[next]);
// self.sparse.items[self.dense.items[self.page(@intCast(SparseT, curr))]] = @intCast(SparseT, curr);
self.sparse.items[self.page(self.dense.items[curr])].?[self.offset(self.dense.items[curr])] = curr; self.sparse.items[self.page(self.dense.items[curr])].?[self.offset(self.dense.items[curr])] = curr;
curr = next; curr = next;

Loading…
Cancel
Save