order doesnt matter anymore for types

cleanup OwningGroup
master
Mike 5 years ago
parent 088a11b840
commit 21a51a9298

@ -73,37 +73,27 @@ pub fn BasicGroup(comptime n_includes: usize, comptime n_excludes: usize) type {
}; };
} }
pub fn OwningGroup(comptime n_owned: usize, comptime n_includes: usize, comptime n_excludes: usize) type { pub const OwningGroup = struct {
return struct { registry: *Registry,
const Self = @This(); group_data: *Registry.GroupData,
super: *usize,
current: *usize,
super: *usize, pub fn init(registry: *Registry, group_data: *Registry.GroupData, super: *usize) OwningGroup {
registry: *Registry, return .{
owned_type_ids: [n_owned]u32, .registry = registry,
include_type_ids: [n_includes]u32, .group_data = group_data,
exclude_type_ids: [n_excludes]u32, .super = super,
};
pub fn init(super: *usize, current: *usize, registry: *Registry, owned_type_ids: [n_owned]u32, include_type_ids: [n_includes]u32, exclude_type_ids: [n_excludes]u32) Self { }
return Self{
.super = super,
.current = current,
.registry = registry,
.owned_type_ids = owned_type_ids,
.include_type_ids = include_type_ids,
.exclude_type_ids = exclude_type_ids,
};
}
pub fn len(self: Self) usize { pub fn len(self: OwningGroup) usize {
return self.current.*; return self.group_data.current;
} }
pub fn sortable(self: *Registry, comptime T: type) bool { pub fn sortable(self: OwningGroup, comptime T: type) bool {
return self.super.* == n_owned + n_includes + n_excludes; return self.group_data.super == self.group_data.size;
} }
}; };
}
test "BasicGroup creation" { test "BasicGroup creation" {
var reg = Registry.init(std.testing.allocator); var reg = Registry.init(std.testing.allocator);
@ -133,7 +123,7 @@ test "BasicGroup excludes" {
var reg = Registry.init(std.testing.allocator); var reg = Registry.init(std.testing.allocator);
defer reg.deinit(); defer reg.deinit();
var group = reg.group(.{}, .{ i32 }, .{ u32 }); var group = reg.group(.{}, .{i32}, .{u32});
std.testing.expectEqual(group.len(), 0); std.testing.expectEqual(group.len(), 0);
var e0 = reg.create(); var e0 = reg.create();
@ -168,7 +158,7 @@ test "OwningGroup" {
var reg = Registry.init(std.testing.allocator); var reg = Registry.init(std.testing.allocator);
defer reg.deinit(); defer reg.deinit();
var group = reg.group(.{i32, u32}, .{}, .{}); var group = reg.group(.{ i32, u32 }, .{}, .{});
var e0 = reg.create(); var e0 = reg.create();
reg.add(e0, @as(i32, 44)); reg.add(e0, @as(i32, 44));
@ -180,7 +170,7 @@ test "OwningGroup add/remove" {
var reg = Registry.init(std.testing.allocator); var reg = Registry.init(std.testing.allocator);
defer reg.deinit(); defer reg.deinit();
var group = reg.group(.{i32, u32}, .{}, .{}); var group = reg.group(.{ i32, u32 }, .{}, .{});
var e0 = reg.create(); var e0 = reg.create();
reg.add(e0, @as(i32, 44)); reg.add(e0, @as(i32, 44));
@ -203,9 +193,9 @@ test "multiple OwningGroups" {
// var group1 = reg.group(.{u64, u32}, .{}, .{}); // var group1 = reg.group(.{u64, u32}, .{}, .{});
// var group2 = reg.group(.{u64, u32, u8}, .{}, .{}); // var group2 = reg.group(.{u64, u32, u8}, .{}, .{});
var group5 = reg.group(.{Sprite, Transform}, .{Renderable, Rotation}, .{}); var group5 = reg.group(.{ Sprite, Transform }, .{ Renderable, Rotation }, .{});
var group3 = reg.group(.{Sprite}, .{Renderable}, .{}); var group3 = reg.group(.{Sprite}, .{Renderable}, .{});
var group4 = reg.group(.{Sprite, Transform}, .{Renderable}, .{}); var group4 = reg.group(.{ Sprite, Transform }, .{Renderable}, .{});
var last_size: u8 = 0; var last_size: u8 = 0;
for (reg.groups.items) |grp| { for (reg.groups.items) |grp| {

@ -37,7 +37,7 @@ pub const Registry = struct {
allocator: *std.mem.Allocator, allocator: *std.mem.Allocator,
/// internal, persistant data structure to manage the entities in a group /// internal, persistant data structure to manage the entities in a group
const GroupData = struct { pub const GroupData = struct {
hash: u64, hash: u64,
size: u8, size: u8,
/// optional. there will be an entity_set for non-owning groups and current for owning /// optional. there will be an entity_set for non-owning groups and current for owning
@ -485,9 +485,7 @@ pub const Registry = struct {
comptime const hash = comptime hashGroupTypes(owned, includes, excludes); comptime const hash = comptime hashGroupTypes(owned, includes, excludes);
for (self.groups.items) |grp| { for (self.groups.items) |grp| {
// TODO: these checks rely on owned/include/exclude to all be in the same order. fix that. if (grp.hash == hash) {
// TODO: prolly dont need the mem.eql since hash is the same damn thing
if (grp.hash == hash and std.mem.eql(u32, grp.owned, owned_arr[0..]) and std.mem.eql(u32, grp.include, includes_arr[0..]) and std.mem.eql(u32, grp.exclude, excludes_arr[0..])) {
maybe_group_data = grp; maybe_group_data = grp;
break; break;
} }
@ -500,7 +498,7 @@ pub const Registry = struct {
return BasicGroup(includes.len, excludes.len).init(&group_data.entity_set, self, includes_arr, excludes_arr); return BasicGroup(includes.len, excludes.len).init(&group_data.entity_set, self, includes_arr, excludes_arr);
} else { } else {
var first_owned = self.assure(owned[0]); var first_owned = self.assure(owned[0]);
return OwningGroup(owned.len, includes.len, excludes.len).init(&first_owned.super, &group_data.current, self, owned_arr, includes_arr, excludes_arr); return OwningGroup.init(self, group_data, &first_owned.super);
} }
} }
@ -577,7 +575,7 @@ pub const Registry = struct {
new_group_data.entity_set.add(entity); new_group_data.entity_set.add(entity);
} }
} else { } else {
// ??we cannot iterate backwards because we want to leave behind valid entities in case of owned types // ??? why not? we cannot iterate backwards because we want to leave behind valid entities in case of owned types
var first_owned_storage = self.assure(owned[0]); var first_owned_storage = self.assure(owned[0]);
for (first_owned_storage.data().*) |entity| { for (first_owned_storage.data().*) |entity| {
new_group_data.maybeValidIf(entity); new_group_data.maybeValidIf(entity);
@ -591,17 +589,18 @@ pub const Registry = struct {
return BasicGroup(includes.len, excludes.len).init(&new_group_data.entity_set, self, includes_arr, excludes_arr); return BasicGroup(includes.len, excludes.len).init(&new_group_data.entity_set, self, includes_arr, excludes_arr);
} else { } else {
var first_owned_storage = self.assure(owned[0]); var first_owned_storage = self.assure(owned[0]);
return OwningGroup(owned.len, includes.len, excludes.len).init(&first_owned_storage.super, &new_group_data.current, self, owned_arr, includes_arr, excludes_arr); return OwningGroup.init(self, new_group_data, &first_owned_storage.super);
} }
} }
/// returns the Type that a view will be based on the includes and excludes /// returns the Type that a view will be, based on the includes and excludes
fn GroupType(comptime owned: var, comptime includes: var, comptime excludes: var) type { fn GroupType(comptime owned: var, comptime includes: var, comptime excludes: var) type {
if (owned.len == 0) return BasicGroup(includes.len, excludes.len); if (owned.len == 0) return BasicGroup(includes.len, excludes.len);
return OwningGroup(owned.len, includes.len, excludes.len); return OwningGroup;
} }
/// given the 3 group Types arrays, generates a (mostly) unique u64 hash. Simultaneously ensures there are no duped types. /// given the 3 group Types arrays, generates a (mostly) unique u64 hash. Simultaneously ensures there are no duped types between
/// the 3 groups.
inline fn hashGroupTypes(comptime owned: var, comptime includes: var, comptime excludes: var) u64 { inline fn hashGroupTypes(comptime owned: var, comptime includes: var, comptime excludes: var) u64 {
comptime { comptime {
for (owned) |t1| { for (owned) |t1| {
@ -623,10 +622,24 @@ pub const Registry = struct {
} }
} }
/// expects a tuple of types. Convertes them to type names, sorts them then concatenates and returns the string.
inline fn concatTypes(comptime types: var) []const u8 { inline fn concatTypes(comptime types: var) []const u8 {
comptime { comptime {
const impl = struct {
fn asc(lhs: []const u8, rhs: []const u8) bool {
return std.mem.lessThan(u8, lhs, rhs);
}
};
var names: [types.len][]const u8 = undefined;
for (names) |*name, i| {
name.* = @typeName(types[i]);
}
std.sort.sort([]const u8, &names, impl.asc);
comptime var res: []const u8 = ""; comptime var res: []const u8 = "";
inline for (types) |t| res = res ++ @typeName(t); inline for (names) |name| res = res ++ name;
return res; return res;
} }
} }

@ -72,5 +72,5 @@ test "nested OwningGroups entity order" {
printStore(sprite_store, "Sprite"); printStore(sprite_store, "Sprite");
printStore(transform_store, "Transform"); printStore(transform_store, "Transform");
warn("group2.current: {}\n", .{group2.current.*}); warn("group2.current: {}\n", .{group2.group_data.current});
} }

Loading…
Cancel
Save