From 2075959dad82941bad9a361f38ee67e224cdbb23 Mon Sep 17 00:00:00 2001 From: Stephen Gutekanst Date: Sat, 4 May 2024 18:45:36 -0700 Subject: [PATCH] module: refactor: pass modules through Entities comptime logic Signed-off-by: Stephen Gutekanst --- src/module/Archetype.zig | 4 +++- src/module/entities.zig | 34 +++++++++++++++++----------------- src/module/main.zig | 2 +- src/module/module.zig | 6 +++--- src/module/query.zig | 9 +++++---- 5 files changed, 29 insertions(+), 26 deletions(-) diff --git a/src/module/Archetype.zig b/src/module/Archetype.zig index 1800b90e..51741ae6 100644 --- a/src/module/Archetype.zig +++ b/src/module/Archetype.zig @@ -10,6 +10,7 @@ const testing = std.testing; const assert = std.debug.assert; const builtin = @import("builtin"); const StringTable = @import("StringTable.zig"); +const ComponentTypesByName = @import("module.zig").ComponentTypesByName; const Archetype = @This(); @@ -271,7 +272,8 @@ pub inline fn debugAssertRowType(storage: *Archetype, row: anytype) void { } // TODO: comptime refactor -pub fn Slicer(comptime component_types_by_name: anytype) type { +pub fn Slicer(comptime modules: anytype) type { + const component_types_by_name = ComponentTypesByName(modules){}; return struct { archetype: *Archetype, diff --git a/src/module/entities.zig b/src/module/entities.zig index d61540d8..e78d8f84 100644 --- a/src/module/entities.zig +++ b/src/module/entities.zig @@ -69,8 +69,8 @@ fn byTypeId(context: void, lhs: Archetype.Column, rhs: Archetype.Column) bool { /// row index, enabling entities to "move" from one archetype table to another seamlessly and /// making lookup by entity ID a few cheap array indexing operations. /// * ComponentStorage(T) is a column of data within a table for a single type of component `T`. -pub fn Entities(comptime component_types_by_name: anytype) type { - // TODO: validate component_types_by_name is a namespaced component set in the form we expect +pub fn Entities(comptime modules: anytype) type { + const component_types_by_name = ComponentTypesByName(modules){}; return struct { allocator: Allocator, @@ -107,7 +107,7 @@ pub fn Entities(comptime component_types_by_name: anytype) type { }; /// A complex query for entities matching a given criteria - pub const Query = query_mod.Query(component_types_by_name); + pub const Query = query_mod.Query(modules); pub const QueryTag = query_mod.QueryTag; pub fn init(allocator: Allocator) !Self { @@ -615,8 +615,8 @@ pub fn Entities(comptime component_types_by_name: anytype) type { pub fn query( entities: *Self, q: Query, - ) ArchetypeIterator(component_types_by_name) { - return ArchetypeIterator(component_types_by_name).init(entities, q); + ) ArchetypeIterator(modules) { + return ArchetypeIterator(modules).init(entities, q); } // TODO: queryDynamic @@ -639,8 +639,8 @@ pub fn Entities(comptime component_types_by_name: anytype) type { } // TODO: move this type somewhere else -pub fn ArchetypeIterator(comptime component_types_by_name: anytype) type { - const EntitiesT = Entities(component_types_by_name); +pub fn ArchetypeIterator(comptime modules: anytype) type { + const EntitiesT = Entities(modules); return struct { entities: *EntitiesT, query: EntitiesT.Query, @@ -657,11 +657,11 @@ pub fn ArchetypeIterator(comptime component_types_by_name: anytype) type { } // TODO: component_types_by_name is a superset of queried items, not type-safe. - pub fn next(iter: *Self) ?Archetype.Slicer(component_types_by_name) { + pub fn next(iter: *Self) ?Archetype.Slicer(modules) { while (iter.index < iter.entities.archetypes.items.len) { const archetype = &iter.entities.archetypes.items[iter.index]; iter.index += 1; - if (iter.match(archetype)) return Archetype.Slicer(component_types_by_name){ .archetype = archetype }; + if (iter.match(archetype)) return Archetype.Slicer(modules){ .archetype = archetype }; } return null; } @@ -701,9 +701,9 @@ pub fn ArchetypeIterator(comptime component_types_by_name: anytype) type { } test { - const modules = ComponentTypesByName(merge(.{ + const modules = merge(.{ builtin_modules, - })){}; + }); std.testing.refAllDeclsRecursive(Entities(modules)); } @@ -754,7 +754,7 @@ test "example" { const Rotation = struct { degrees: f32 }; - const component_types_by_name = ComponentTypesByName(merge(.{ + const modules = merge(.{ builtin_modules, struct { pub const name = .game; @@ -764,11 +764,11 @@ test "example" { .rotation = .{ .type = Rotation }, }; }, - })){}; + }); //------------------------------------------------------------------------- // Create a world. - var world = try Entities(component_types_by_name).init(allocator); + var world = try Entities(modules).init(allocator); defer world.deinit(); //------------------------------------------------------------------------- @@ -859,7 +859,7 @@ test "many entities" { const Rotation = struct { degrees: f32 }; - const component_types_by_name = ComponentTypesByName(.{ + const modules = .{ struct { pub const name = .game; pub const components = .{ @@ -868,10 +868,10 @@ test "many entities" { .rotation = .{ .type = Rotation }, }; }, - }){}; + }; // Create many entities - var world = try Entities(component_types_by_name).init(allocator); + var world = try Entities(modules).init(allocator); defer world.deinit(); for (0..8192) |_| { const player = try world.new(); diff --git a/src/module/main.zig b/src/module/main.zig index 7b4497f6..98df29c8 100644 --- a/src/module/main.zig +++ b/src/module/main.zig @@ -112,7 +112,7 @@ test "entities DB" { try testing.expectEqual(@as(usize, 1001), ids[0]); // TODO: can't write @as type here easily due to generic parameter, should be exposed - // ?Archetype.Slicer(component_types_by_name) + // ?Archetype.Slicer(modules) try testing.expectEqual(iter.next(), null); //------------------------------------------------------------------------- diff --git a/src/module/module.zig b/src/module/module.zig index 903b5cae..083b085a 100644 --- a/src/module/module.zig +++ b/src/module/module.zig @@ -200,12 +200,12 @@ pub fn Modules(comptime modules: anytype) type { events: EventQueue, mod: ModsByName(modules), // TODO: pass mods directly instead of ComponentTypesByName? - entities: Entities(component_types_by_name), + entities: Entities(modules), debug_trace: bool, pub fn init(m: *@This(), allocator: std.mem.Allocator) !void { // TODO: switch Entities to stack allocation like Modules is - var entities = try Entities(component_types_by_name).init(allocator); + var entities = try Entities(modules).init(allocator); errdefer entities.deinit(); const debug_trace_str = std.process.getEnvVarOwned( @@ -577,7 +577,7 @@ pub fn ModSet(comptime modules: anytype) type { const module_tag = M.name; const components = ComponentTypesM(M){}; return struct { - entities: *Entities(ComponentTypesByName(modules){}), + entities: *Entities(modules), /// Private/internal fields __is_initialized: bool, diff --git a/src/module/query.zig b/src/module/query.zig index 60eeec55..a9c427cd 100644 --- a/src/module/query.zig +++ b/src/module/query.zig @@ -8,7 +8,8 @@ pub const QueryTag = enum { }; /// A complex query for entities matching a given criteria -pub fn Query(comptime component_types_by_name: anytype) type { +pub fn Query(comptime modules: anytype) type { + const component_types_by_name = ComponentTypesByName(modules){}; return union(QueryTag) { // TODO: cleanup comptime /// Enum matching a namespace. e.g. `.game` or `.physics2d` @@ -79,7 +80,7 @@ test "query" { const Rotation = struct { degrees: f32 }; - const component_types_by_name = ComponentTypesByName(.{ + const modules = .{ struct { pub const name = .game; pub const components = .{ @@ -96,9 +97,9 @@ test "query" { struct { pub const name = .renderer; }, - }){}; + }; - const Q = Query(component_types_by_name); + const Q = Query(modules); // Namespace type lets us select a single namespace. try testing.expectEqual(@as(Q.Namespace, .game), .game);