|
|
@ -55,7 +55,7 @@ pub const Registry = struct {
|
|
|
|
// std.debug.assert(std.mem.indexOfAny(u32, include, exclude) == null);
|
|
|
|
// std.debug.assert(std.mem.indexOfAny(u32, include, exclude) == null);
|
|
|
|
var group_data = allocator.create(GroupData) catch unreachable;
|
|
|
|
var group_data = allocator.create(GroupData) catch unreachable;
|
|
|
|
group_data.hash = hash;
|
|
|
|
group_data.hash = hash;
|
|
|
|
group_data.size = @intCast(u8, owned.len + include.len + exclude.len);
|
|
|
|
group_data.size = @as(u8, @intCast(owned.len + include.len + exclude.len));
|
|
|
|
if (owned.len == 0) {
|
|
|
|
if (owned.len == 0) {
|
|
|
|
group_data.entity_set = SparseSet(Entity).init(allocator);
|
|
|
|
group_data.entity_set = SparseSet(Entity).init(allocator);
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -83,19 +83,19 @@ pub const Registry = struct {
|
|
|
|
const isValid: bool = blk: {
|
|
|
|
const isValid: bool = blk: {
|
|
|
|
for (self.owned) |tid| {
|
|
|
|
for (self.owned) |tid| {
|
|
|
|
const ptr = self.registry.components.get(tid).?;
|
|
|
|
const ptr = self.registry.components.get(tid).?;
|
|
|
|
if (!@ptrFromInt(*Storage(u1), ptr).contains(entity))
|
|
|
|
if (!@as(*Storage(u1), @ptrFromInt(ptr)).contains(entity))
|
|
|
|
break :blk false;
|
|
|
|
break :blk false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for (self.include) |tid| {
|
|
|
|
for (self.include) |tid| {
|
|
|
|
const ptr = self.registry.components.get(tid).?;
|
|
|
|
const ptr = self.registry.components.get(tid).?;
|
|
|
|
if (!@ptrFromInt(*Storage(u1), ptr).contains(entity))
|
|
|
|
if (!@as(*Storage(u1), @ptrFromInt(ptr)).contains(entity))
|
|
|
|
break :blk false;
|
|
|
|
break :blk false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for (self.exclude) |tid| {
|
|
|
|
for (self.exclude) |tid| {
|
|
|
|
const ptr = self.registry.components.get(tid).?;
|
|
|
|
const ptr = self.registry.components.get(tid).?;
|
|
|
|
if (@ptrFromInt(*Storage(u1), ptr).contains(entity))
|
|
|
|
if (@as(*Storage(u1), @ptrFromInt(ptr)).contains(entity))
|
|
|
|
break :blk false;
|
|
|
|
break :blk false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break :blk true;
|
|
|
|
break :blk true;
|
|
|
@ -108,11 +108,11 @@ pub const Registry = struct {
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
if (isValid) {
|
|
|
|
if (isValid) {
|
|
|
|
const ptr = self.registry.components.get(self.owned[0]).?;
|
|
|
|
const ptr = self.registry.components.get(self.owned[0]).?;
|
|
|
|
if (!(@ptrFromInt(*Storage(u1), ptr).set.index(entity) < self.current)) {
|
|
|
|
if (!(@as(*Storage(u1), @ptrFromInt(ptr)).set.index(entity) < self.current)) {
|
|
|
|
for (self.owned) |tid| {
|
|
|
|
for (self.owned) |tid| {
|
|
|
|
// store.swap hides a safe version that types it correctly
|
|
|
|
// store.swap hides a safe version that types it correctly
|
|
|
|
const store_ptr = self.registry.components.get(tid).?;
|
|
|
|
const store_ptr = self.registry.components.get(tid).?;
|
|
|
|
var store = @ptrFromInt(*Storage(u1), store_ptr);
|
|
|
|
var store = @as(*Storage(u1), @ptrFromInt(store_ptr));
|
|
|
|
store.swap(store.data()[self.current], entity);
|
|
|
|
store.swap(store.data()[self.current], entity);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
self.current += 1;
|
|
|
|
self.current += 1;
|
|
|
@ -129,12 +129,12 @@ pub const Registry = struct {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
const ptr = self.registry.components.get(self.owned[0]).?;
|
|
|
|
const ptr = self.registry.components.get(self.owned[0]).?;
|
|
|
|
var store = @ptrFromInt(*Storage(u1), ptr);
|
|
|
|
var store = @as(*Storage(u1), @ptrFromInt(ptr));
|
|
|
|
if (store.contains(entity) and store.set.index(entity) < self.current) {
|
|
|
|
if (store.contains(entity) and store.set.index(entity) < self.current) {
|
|
|
|
self.current -= 1;
|
|
|
|
self.current -= 1;
|
|
|
|
for (self.owned) |tid| {
|
|
|
|
for (self.owned) |tid| {
|
|
|
|
const store_ptr = self.registry.components.get(tid).?;
|
|
|
|
const store_ptr = self.registry.components.get(tid).?;
|
|
|
|
store = @ptrFromInt(*Storage(u1), store_ptr);
|
|
|
|
store = @as(*Storage(u1), @ptrFromInt(store_ptr));
|
|
|
|
store.swap(store.data()[self.current], entity);
|
|
|
|
store.swap(store.data()[self.current], entity);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -199,7 +199,7 @@ pub const Registry = struct {
|
|
|
|
var iter = self.components.valueIterator();
|
|
|
|
var iter = self.components.valueIterator();
|
|
|
|
while (iter.next()) |ptr| {
|
|
|
|
while (iter.next()) |ptr| {
|
|
|
|
// HACK: we dont know the Type here but we need to call deinit
|
|
|
|
// HACK: we dont know the Type here but we need to call deinit
|
|
|
|
var storage = @ptrFromInt(*Storage(u1), ptr.*);
|
|
|
|
var storage = @as(*Storage(u1), @ptrFromInt(ptr.*));
|
|
|
|
storage.deinit();
|
|
|
|
storage.deinit();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -217,7 +217,7 @@ pub const Registry = struct {
|
|
|
|
pub fn assure(self: *Registry, comptime T: type) *Storage(T) {
|
|
|
|
pub fn assure(self: *Registry, comptime T: type) *Storage(T) {
|
|
|
|
var type_id = utils.typeId(T);
|
|
|
|
var type_id = utils.typeId(T);
|
|
|
|
if (self.components.getEntry(type_id)) |kv| {
|
|
|
|
if (self.components.getEntry(type_id)) |kv| {
|
|
|
|
return @ptrFromInt(*Storage(T), kv.value_ptr.*);
|
|
|
|
return @as(*Storage(T), @ptrFromInt(kv.value_ptr.*));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var comp_set = Storage(T).initPtr(self.allocator);
|
|
|
|
var comp_set = Storage(T).initPtr(self.allocator);
|
|
|
@ -262,7 +262,7 @@ pub const Registry = struct {
|
|
|
|
|
|
|
|
|
|
|
|
/// Returns the version stored along with an entity identifier
|
|
|
|
/// Returns the version stored along with an entity identifier
|
|
|
|
pub fn version(_: *Registry, entity: Entity) entity_traits.version_type {
|
|
|
|
pub fn version(_: *Registry, entity: Entity) entity_traits.version_type {
|
|
|
|
return @truncate(entity_traits.version_type, entity >> entity_traits.entity_shift);
|
|
|
|
return @as(entity_traits.version_type, @truncate(entity >> entity_traits.entity_shift));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Creates a new entity and returns it
|
|
|
|
/// Creates a new entity and returns it
|
|
|
@ -316,6 +316,7 @@ pub const Registry = struct {
|
|
|
|
const store = self.assure(@TypeOf(value));
|
|
|
|
const store = self.assure(@TypeOf(value));
|
|
|
|
if (store.tryGet(entity)) |found| {
|
|
|
|
if (store.tryGet(entity)) |found| {
|
|
|
|
found.* = value;
|
|
|
|
found.* = value;
|
|
|
|
|
|
|
|
store.update.publish(entity);
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
store.add(entity, value);
|
|
|
|
store.add(entity, value);
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -347,7 +348,7 @@ pub const Registry = struct {
|
|
|
|
var iter = self.components.valueIterator();
|
|
|
|
var iter = self.components.valueIterator();
|
|
|
|
while (iter.next()) |value| {
|
|
|
|
while (iter.next()) |value| {
|
|
|
|
// 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 = @ptrFromInt(*Storage(u1), value.*);
|
|
|
|
var store = @as(*Storage(u1), @ptrFromInt(value.*));
|
|
|
|
store.removeIfContains(entity);
|
|
|
|
store.removeIfContains(entity);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -369,9 +370,10 @@ pub const Registry = struct {
|
|
|
|
|
|
|
|
|
|
|
|
/// Returns a reference to the given component for an entity creating it if necessary
|
|
|
|
/// Returns a reference to the given component for an entity creating it if necessary
|
|
|
|
pub fn getOrAdd(self: *Registry, comptime T: type, entity: Entity) *T {
|
|
|
|
pub fn getOrAdd(self: *Registry, comptime T: type, entity: Entity) *T {
|
|
|
|
if (self.has(T, entity)) return self.get(T, entity);
|
|
|
|
if (!self.has(T, entity)) {
|
|
|
|
self.add(T, entity, std.mem.zeros(T));
|
|
|
|
self.addTyped(T, entity, .{});
|
|
|
|
return self.get(T, type);
|
|
|
|
}
|
|
|
|
|
|
|
|
return self.get(T, entity);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub fn tryGet(self: *Registry, comptime T: type, entity: Entity) ?*T {
|
|
|
|
pub fn tryGet(self: *Registry, comptime T: type, entity: Entity) ?*T {
|
|
|
@ -412,7 +414,7 @@ pub const Registry = struct {
|
|
|
|
std.debug.assert(@typeInfo(T) != .Pointer);
|
|
|
|
std.debug.assert(@typeInfo(T) != .Pointer);
|
|
|
|
|
|
|
|
|
|
|
|
return if (self.contexts.get(utils.typeId(T))) |ptr|
|
|
|
|
return if (self.contexts.get(utils.typeId(T))) |ptr|
|
|
|
|
return if (ptr > 0) @ptrFromInt(*T, ptr) else null
|
|
|
|
return if (ptr > 0) @as(*T, @ptrFromInt(ptr)) else null
|
|
|
|
else
|
|
|
|
else
|
|
|
|
null;
|
|
|
|
null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|