bug fixes and speedup
This commit is contained in:
parent
cc92e4a225
commit
46c2af939e
@ -28,6 +28,7 @@ fn createEntities(reg: *ecs.Registry) void {
|
||||
reg.add(e1, Position{ .x = 1, .y = 1 });
|
||||
reg.add(e1, Velocity{ .x = 1, .y = 1 });
|
||||
}
|
||||
|
||||
var end = timer.lap();
|
||||
std.debug.warn("create entities: \t{d}\n", .{@intToFloat(f64, end) / 1000000000});
|
||||
}
|
||||
@ -104,11 +105,8 @@ fn owningGroup(reg: *ecs.Registry) void {
|
||||
if (index == 0) break;
|
||||
index -= 1;
|
||||
|
||||
const ent = storage.set.dense.items[index];
|
||||
const entity_index = storage.set.index(ent);
|
||||
|
||||
pos[entity_index].x += pos[entity_index].x;
|
||||
pos[entity_index].y += pos[entity_index].y;
|
||||
pos[index].x += pos[index].x;
|
||||
pos[index].y += pos[index].y;
|
||||
}
|
||||
|
||||
end = timer.lap();
|
||||
|
@ -27,8 +27,9 @@ pub fn ComponentStorage(comptime Component: type, comptime Entity: type) type {
|
||||
allocator: ?*std.mem.Allocator,
|
||||
/// doesnt really belong here...used to denote group ownership
|
||||
super: usize = 0,
|
||||
safe_deinit: fn (*Self) void,
|
||||
safe_swap: fn (*Self, Entity, Entity, bool) void,
|
||||
safeDeinit: fn (*Self) void,
|
||||
safeSwap: fn (*Self, Entity, Entity, bool) void,
|
||||
safeRemoveIfContains: fn (*Self, Entity) void,
|
||||
construction: Signal(Entity),
|
||||
update: Signal(Entity),
|
||||
destruction: Signal(Entity),
|
||||
@ -37,14 +38,14 @@ pub fn ComponentStorage(comptime Component: type, comptime Entity: type) type {
|
||||
var store = Self{
|
||||
.set = SparseSet(Entity).initPtr(allocator),
|
||||
.instances = undefined,
|
||||
.safe_deinit = struct {
|
||||
.safeDeinit = struct {
|
||||
fn deinit(self: *Self) void {
|
||||
if (!is_empty_struct) {
|
||||
self.instances.deinit();
|
||||
}
|
||||
}
|
||||
}.deinit,
|
||||
.safe_swap = struct {
|
||||
.safeSwap = struct {
|
||||
fn swap(self: *Self, lhs: Entity, rhs: Entity, instances_only: bool) void {
|
||||
if (!is_empty_struct) {
|
||||
std.mem.swap(Component, &self.instances.items[self.set.index(lhs)], &self.instances.items[self.set.index(rhs)]);
|
||||
@ -52,6 +53,13 @@ pub fn ComponentStorage(comptime Component: type, comptime Entity: type) type {
|
||||
if (!instances_only) self.set.swap(lhs, rhs);
|
||||
}
|
||||
}.swap,
|
||||
.safeRemoveIfContains = struct {
|
||||
fn removeIfContains(self: *Self, entity: Entity) void {
|
||||
if (self.contains(entity)) {
|
||||
self.remove(entity);
|
||||
}
|
||||
}
|
||||
}.removeIfContains,
|
||||
.allocator = null,
|
||||
.construction = Signal(Entity).init(allocator),
|
||||
.update = Signal(Entity).init(allocator),
|
||||
@ -78,7 +86,7 @@ pub fn ComponentStorage(comptime Component: type, comptime Entity: type) type {
|
||||
store.destruction = Signal(Entity).init(allocator);
|
||||
|
||||
// since we are stored as a pointer, we need to catpure this
|
||||
store.safe_deinit = struct {
|
||||
store.safeDeinit = struct {
|
||||
fn deinit(self: *Self) void {
|
||||
if (!is_empty_struct) {
|
||||
self.instances.deinit();
|
||||
@ -86,7 +94,7 @@ pub fn ComponentStorage(comptime Component: type, comptime Entity: type) type {
|
||||
}
|
||||
}.deinit;
|
||||
|
||||
store.safe_swap = struct {
|
||||
store.safeSwap = struct {
|
||||
fn swap(self: *Self, lhs: Entity, rhs: Entity, instances_only: bool) void {
|
||||
if (!is_empty_struct) {
|
||||
std.mem.swap(Component, &self.instances.items[self.set.index(lhs)], &self.instances.items[self.set.index(rhs)]);
|
||||
@ -95,6 +103,14 @@ pub fn ComponentStorage(comptime Component: type, comptime Entity: type) type {
|
||||
}
|
||||
}.swap;
|
||||
|
||||
store.safeRemoveIfContains = struct {
|
||||
fn removeIfContains(self: *Self, entity: Entity) void {
|
||||
if (self.contains(entity)) {
|
||||
self.remove(entity);
|
||||
}
|
||||
}
|
||||
}.removeIfContains;
|
||||
|
||||
return store;
|
||||
}
|
||||
|
||||
@ -102,7 +118,7 @@ pub fn ComponentStorage(comptime Component: type, comptime Entity: type) type {
|
||||
// great care must be taken here. Due to how Registry keeps this struct as pointers anything touching a type
|
||||
// will be wrong since it has to cast to a random struct when deiniting. Because of all that, is_empty_struct
|
||||
// will allways be false here so we have to deinit the instances no matter what.
|
||||
self.safe_deinit(self);
|
||||
self.safeDeinit(self);
|
||||
self.set.deinit();
|
||||
self.construction.deinit();
|
||||
self.update.deinit();
|
||||
@ -156,6 +172,14 @@ pub fn ComponentStorage(comptime Component: type, comptime Entity: type) type {
|
||||
return self.set.contains(entity);
|
||||
}
|
||||
|
||||
pub fn removeIfContains(self: *Self, entity: Entity) void {
|
||||
if (Component == u1) {
|
||||
self.safeRemoveIfContains(self, entity);
|
||||
} else if (self.contains(entity)) {
|
||||
self.remove(entity);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn len(self: Self) usize {
|
||||
return self.set.len();
|
||||
}
|
||||
@ -213,10 +237,10 @@ pub fn ComponentStorage(comptime Component: type, comptime Entity: type) type {
|
||||
storage: *Self,
|
||||
|
||||
pub fn swap(this: @This(), a: Entity, b: Entity) void {
|
||||
this.storage.safe_swap(this.storage, a, b, true);
|
||||
this.storage.safeSwap(this.storage, a, b, true);
|
||||
}
|
||||
};
|
||||
const swap_context = SortContext{.storage = self};
|
||||
const swap_context = SortContext{ .storage = self };
|
||||
self.set.arrange(length, context, lessThan, swap_context);
|
||||
} else {
|
||||
const SortContext = struct {
|
||||
@ -231,11 +255,11 @@ pub fn ComponentStorage(comptime Component: type, comptime Entity: type) type {
|
||||
}
|
||||
|
||||
pub fn swap(this: @This(), a: Entity, b: Entity) void {
|
||||
this.storage.safe_swap(this.storage, a, b, true);
|
||||
this.storage.safeSwap(this.storage, a, b, true);
|
||||
}
|
||||
};
|
||||
|
||||
const swap_context = SortContext{.storage = self, .wrapped_context = context, .lessThan = lessThan};
|
||||
const swap_context = SortContext{ .storage = self, .wrapped_context = context, .lessThan = lessThan };
|
||||
self.set.arrange(length, swap_context, SortContext.sort, swap_context);
|
||||
}
|
||||
}
|
||||
@ -253,7 +277,7 @@ pub fn ComponentStorage(comptime Component: type, comptime Entity: type) type {
|
||||
|
||||
/// Swaps entities and objects in the internal packed arrays
|
||||
pub fn swap(self: *Self, lhs: Entity, rhs: Entity) void {
|
||||
self.safe_swap(self, lhs, rhs, false);
|
||||
self.safeSwap(self, lhs, rhs, false);
|
||||
}
|
||||
|
||||
pub fn clear(self: *Self) void {
|
||||
|
@ -101,14 +101,11 @@ pub const OwningGroup = struct {
|
||||
if (it.index == 0) return null;
|
||||
it.index -= 1;
|
||||
|
||||
const ent = it.storage.set.dense.items[it.index];
|
||||
const entity_index = it.storage.set.index(ent);
|
||||
|
||||
// fill and return the struct
|
||||
var comps: Components = undefined;
|
||||
inline for (@typeInfo(Components).Struct.fields) |field, i| {
|
||||
const typed_ptr = @ptrCast([*]field.field_type.Child, @alignCast(@alignOf(field.field_type.Child), it.component_ptrs[i]));
|
||||
@field(comps, field.name) = &typed_ptr[entity_index];
|
||||
@field(comps, field.name) = &typed_ptr[it.index];
|
||||
}
|
||||
return comps;
|
||||
}
|
||||
@ -200,36 +197,9 @@ pub const OwningGroup = struct {
|
||||
self.validate(Components);
|
||||
|
||||
// optionally we could just use an Iterator here and pay for some slight indirection for code sharing
|
||||
// var iter = self.iterator(Components);
|
||||
// while (iter.next()) |comps| {
|
||||
// @call(.{ .modifier = .always_inline }, func, .{comps});
|
||||
// }
|
||||
|
||||
const component_info = @typeInfo(Components).Struct;
|
||||
|
||||
// get the data pointers for the requested component types
|
||||
var component_ptrs: [component_info.fields.len][*]u8 = undefined;
|
||||
inline for (component_info.fields) |field, i| {
|
||||
const storage = self.registry.assure(field.field_type.Child);
|
||||
component_ptrs[i] = @ptrCast([*]u8, storage.instances.items.ptr);
|
||||
}
|
||||
|
||||
var storage = self.firstOwnedStorage();
|
||||
var index: usize = self.group_data.current;
|
||||
while (true) {
|
||||
if (index == 0) return;
|
||||
index -= 1;
|
||||
|
||||
const ent = storage.set.dense.items[index];
|
||||
const entity_index = storage.set.index(ent);
|
||||
|
||||
var comps: Components = undefined;
|
||||
inline for (component_info.fields) |field, i| {
|
||||
const typed_ptr = @ptrCast([*]field.field_type.Child, @alignCast(@alignOf(field.field_type.Child), component_ptrs[i]));
|
||||
@field(comps, field.name) = &typed_ptr[entity_index];
|
||||
}
|
||||
|
||||
func(comps);
|
||||
var iter = self.iterator(Components);
|
||||
while (iter.next()) |comps| {
|
||||
@call(.{ .modifier = .always_inline }, func, .{comps});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -334,8 +334,9 @@ pub const Registry = struct {
|
||||
pub fn removeIfExists(self: *Registry, comptime T: type, entity: Entity) void {
|
||||
assert(self.valid(entity));
|
||||
var store = self.assure(T);
|
||||
if (store.contains(entity))
|
||||
if (store.contains(entity)) {
|
||||
store.remove(entity);
|
||||
}
|
||||
}
|
||||
|
||||
/// Removes all the components from an entity and makes it orphaned
|
||||
@ -345,8 +346,8 @@ pub const Registry = struct {
|
||||
var it = self.components.iterator();
|
||||
while (it.next()) |ptr| {
|
||||
// HACK: we dont know the Type here but we need to be able to call methods on the Storage(T)
|
||||
var store = @intToPtr(*Storage(u128), ptr.value);
|
||||
if (store.contains(entity)) store.remove(entity);
|
||||
var store = @intToPtr(*Storage(u1), ptr.value);
|
||||
store.removeIfContains(entity);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user