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, Position{ .x = 1, .y = 1 });
|
||||||
reg.add(e1, Velocity{ .x = 1, .y = 1 });
|
reg.add(e1, Velocity{ .x = 1, .y = 1 });
|
||||||
}
|
}
|
||||||
|
|
||||||
var end = timer.lap();
|
var end = timer.lap();
|
||||||
std.debug.warn("create entities: \t{d}\n", .{@intToFloat(f64, end) / 1000000000});
|
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;
|
if (index == 0) break;
|
||||||
index -= 1;
|
index -= 1;
|
||||||
|
|
||||||
const ent = storage.set.dense.items[index];
|
pos[index].x += pos[index].x;
|
||||||
const entity_index = storage.set.index(ent);
|
pos[index].y += pos[index].y;
|
||||||
|
|
||||||
pos[entity_index].x += pos[entity_index].x;
|
|
||||||
pos[entity_index].y += pos[entity_index].y;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
end = timer.lap();
|
end = timer.lap();
|
||||||
|
@ -27,8 +27,9 @@ pub fn ComponentStorage(comptime Component: type, comptime Entity: type) type {
|
|||||||
allocator: ?*std.mem.Allocator,
|
allocator: ?*std.mem.Allocator,
|
||||||
/// doesnt really belong here...used to denote group ownership
|
/// doesnt really belong here...used to denote group ownership
|
||||||
super: usize = 0,
|
super: usize = 0,
|
||||||
safe_deinit: fn (*Self) void,
|
safeDeinit: fn (*Self) void,
|
||||||
safe_swap: fn (*Self, Entity, Entity, bool) void,
|
safeSwap: fn (*Self, Entity, Entity, bool) void,
|
||||||
|
safeRemoveIfContains: fn (*Self, Entity) void,
|
||||||
construction: Signal(Entity),
|
construction: Signal(Entity),
|
||||||
update: Signal(Entity),
|
update: Signal(Entity),
|
||||||
destruction: Signal(Entity),
|
destruction: Signal(Entity),
|
||||||
@ -37,14 +38,14 @@ pub fn ComponentStorage(comptime Component: type, comptime Entity: type) type {
|
|||||||
var store = Self{
|
var store = Self{
|
||||||
.set = SparseSet(Entity).initPtr(allocator),
|
.set = SparseSet(Entity).initPtr(allocator),
|
||||||
.instances = undefined,
|
.instances = undefined,
|
||||||
.safe_deinit = struct {
|
.safeDeinit = struct {
|
||||||
fn deinit(self: *Self) void {
|
fn deinit(self: *Self) void {
|
||||||
if (!is_empty_struct) {
|
if (!is_empty_struct) {
|
||||||
self.instances.deinit();
|
self.instances.deinit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}.deinit,
|
}.deinit,
|
||||||
.safe_swap = struct {
|
.safeSwap = struct {
|
||||||
fn swap(self: *Self, lhs: Entity, rhs: Entity, instances_only: bool) void {
|
fn swap(self: *Self, lhs: Entity, rhs: Entity, instances_only: bool) void {
|
||||||
if (!is_empty_struct) {
|
if (!is_empty_struct) {
|
||||||
std.mem.swap(Component, &self.instances.items[self.set.index(lhs)], &self.instances.items[self.set.index(rhs)]);
|
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);
|
if (!instances_only) self.set.swap(lhs, rhs);
|
||||||
}
|
}
|
||||||
}.swap,
|
}.swap,
|
||||||
|
.safeRemoveIfContains = struct {
|
||||||
|
fn removeIfContains(self: *Self, entity: Entity) void {
|
||||||
|
if (self.contains(entity)) {
|
||||||
|
self.remove(entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.removeIfContains,
|
||||||
.allocator = null,
|
.allocator = null,
|
||||||
.construction = Signal(Entity).init(allocator),
|
.construction = Signal(Entity).init(allocator),
|
||||||
.update = 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);
|
store.destruction = Signal(Entity).init(allocator);
|
||||||
|
|
||||||
// since we are stored as a pointer, we need to catpure this
|
// since we are stored as a pointer, we need to catpure this
|
||||||
store.safe_deinit = struct {
|
store.safeDeinit = struct {
|
||||||
fn deinit(self: *Self) void {
|
fn deinit(self: *Self) void {
|
||||||
if (!is_empty_struct) {
|
if (!is_empty_struct) {
|
||||||
self.instances.deinit();
|
self.instances.deinit();
|
||||||
@ -86,7 +94,7 @@ pub fn ComponentStorage(comptime Component: type, comptime Entity: type) type {
|
|||||||
}
|
}
|
||||||
}.deinit;
|
}.deinit;
|
||||||
|
|
||||||
store.safe_swap = struct {
|
store.safeSwap = struct {
|
||||||
fn swap(self: *Self, lhs: Entity, rhs: Entity, instances_only: bool) void {
|
fn swap(self: *Self, lhs: Entity, rhs: Entity, instances_only: bool) void {
|
||||||
if (!is_empty_struct) {
|
if (!is_empty_struct) {
|
||||||
std.mem.swap(Component, &self.instances.items[self.set.index(lhs)], &self.instances.items[self.set.index(rhs)]);
|
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;
|
}.swap;
|
||||||
|
|
||||||
|
store.safeRemoveIfContains = struct {
|
||||||
|
fn removeIfContains(self: *Self, entity: Entity) void {
|
||||||
|
if (self.contains(entity)) {
|
||||||
|
self.remove(entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.removeIfContains;
|
||||||
|
|
||||||
return store;
|
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
|
// 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 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.
|
// 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.set.deinit();
|
||||||
self.construction.deinit();
|
self.construction.deinit();
|
||||||
self.update.deinit();
|
self.update.deinit();
|
||||||
@ -156,6 +172,14 @@ pub fn ComponentStorage(comptime Component: type, comptime Entity: type) type {
|
|||||||
return self.set.contains(entity);
|
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 {
|
pub fn len(self: Self) usize {
|
||||||
return self.set.len();
|
return self.set.len();
|
||||||
}
|
}
|
||||||
@ -213,10 +237,10 @@ pub fn ComponentStorage(comptime Component: type, comptime Entity: type) type {
|
|||||||
storage: *Self,
|
storage: *Self,
|
||||||
|
|
||||||
pub fn swap(this: @This(), a: Entity, b: Entity) void {
|
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);
|
self.set.arrange(length, context, lessThan, swap_context);
|
||||||
} else {
|
} else {
|
||||||
const SortContext = struct {
|
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 {
|
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);
|
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
|
/// Swaps entities and objects in the internal packed arrays
|
||||||
pub fn swap(self: *Self, lhs: Entity, rhs: Entity) void {
|
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 {
|
pub fn clear(self: *Self) void {
|
||||||
|
@ -101,14 +101,11 @@ pub const OwningGroup = struct {
|
|||||||
if (it.index == 0) return null;
|
if (it.index == 0) return null;
|
||||||
it.index -= 1;
|
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
|
// fill and return the struct
|
||||||
var comps: Components = undefined;
|
var comps: Components = undefined;
|
||||||
inline for (@typeInfo(Components).Struct.fields) |field, i| {
|
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]));
|
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;
|
return comps;
|
||||||
}
|
}
|
||||||
@ -200,36 +197,9 @@ pub const OwningGroup = struct {
|
|||||||
self.validate(Components);
|
self.validate(Components);
|
||||||
|
|
||||||
// optionally we could just use an Iterator here and pay for some slight indirection for code sharing
|
// optionally we could just use an Iterator here and pay for some slight indirection for code sharing
|
||||||
// var iter = self.iterator(Components);
|
var iter = self.iterator(Components);
|
||||||
// while (iter.next()) |comps| {
|
while (iter.next()) |comps| {
|
||||||
// @call(.{ .modifier = .always_inline }, func, .{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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -334,8 +334,9 @@ pub const Registry = struct {
|
|||||||
pub fn removeIfExists(self: *Registry, comptime T: type, entity: Entity) void {
|
pub fn removeIfExists(self: *Registry, comptime T: type, entity: Entity) void {
|
||||||
assert(self.valid(entity));
|
assert(self.valid(entity));
|
||||||
var store = self.assure(T);
|
var store = self.assure(T);
|
||||||
if (store.contains(entity))
|
if (store.contains(entity)) {
|
||||||
store.remove(entity);
|
store.remove(entity);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Removes all the components from an entity and makes it orphaned
|
/// Removes all the components from an entity and makes it orphaned
|
||||||
@ -345,8 +346,8 @@ pub const Registry = struct {
|
|||||||
var it = self.components.iterator();
|
var it = self.components.iterator();
|
||||||
while (it.next()) |ptr| {
|
while (it.next()) |ptr| {
|
||||||
// HACK: we dont know the Type here but we need to be able to call methods on the Storage(T)
|
// 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);
|
var store = @intToPtr(*Storage(u1), ptr.value);
|
||||||
if (store.contains(entity)) store.remove(entity);
|
store.removeIfContains(entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user