From 57767c2f9f789efada400699ac378aec88556763 Mon Sep 17 00:00:00 2001 From: Stephen Gutekanst Date: Tue, 7 May 2024 17:59:46 -0700 Subject: [PATCH] module: remove deprecated query API Signed-off-by: Stephen Gutekanst --- src/module/Archetype.zig | 31 --------- src/module/entities.zig | 75 --------------------- src/module/main.zig | 22 ------ src/module/query.zig | 142 --------------------------------------- 4 files changed, 270 deletions(-) delete mode 100644 src/module/query.zig diff --git a/src/module/Archetype.zig b/src/module/Archetype.zig index 3190a9b5..7bd8d482 100644 --- a/src/module/Archetype.zig +++ b/src/module/Archetype.zig @@ -269,34 +269,3 @@ pub inline fn debugAssertRowType(storage: *Archetype, row: anytype) void { } } } - -// TODO: comptime refactor -pub fn Slicer(comptime modules: anytype) type { - const component_types_by_name = ComponentTypesByName(modules){}; - return struct { - archetype: *Archetype, - - pub fn slice( - slicer: @This(), - // TODO: cleanup comptime - comptime namespace_name: std.meta.FieldEnum(@TypeOf(component_types_by_name)), - comptime component_name: std.meta.FieldEnum(@TypeOf(@field(component_types_by_name, @tagName(namespace_name)))), - ) []@field( - @field(component_types_by_name, @tagName(namespace_name)), - @tagName(component_name), - ).type { - // TODO: cleanup comptime - const Type = @field( - @field(component_types_by_name, @tagName(namespace_name)), - @tagName(component_name), - ).type; - if (namespace_name == .entities and component_name == .id) { - const name_id = slicer.archetype.component_names.index("entities.id").?; - return slicer.archetype.getColumnValues(name_id, Type).?[0..slicer.archetype.len]; - } - const name = @tagName(namespace_name) ++ "." ++ @tagName(component_name); - const name_id = slicer.archetype.component_names.index(name).?; - return slicer.archetype.getColumnValues(name_id, Type).?[0..slicer.archetype.len]; - } - }; -} diff --git a/src/module/entities.zig b/src/module/entities.zig index b685fdd4..4dbe7f2a 100644 --- a/src/module/entities.zig +++ b/src/module/entities.zig @@ -3,7 +3,6 @@ const Allocator = std.mem.Allocator; const testing = std.testing; const builtin = @import("builtin"); const assert = std.debug.assert; -const query_mod = @import("query.zig"); const Archetype = @import("Archetype.zig"); const StringTable = @import("StringTable.zig"); const ComponentTypesByName = @import("module.zig").ComponentTypesByName; @@ -112,10 +111,6 @@ pub fn Database(comptime modules: anytype) type { row_index: u32, }; - /// A complex query for entities matching a given criteria - pub const QueryDeprecated = query_mod.QueryDeprecated(modules); - pub const QueryTag = query_mod.QueryTag; - pub fn init(allocator: Allocator) !Self { const component_names = try allocator.create(StringTable); errdefer allocator.destroy(component_names); @@ -626,14 +621,6 @@ pub fn Database(comptime modules: anytype) type { }); } - // Queries for archetypes matching the given query. - pub fn queryDeprecated( - entities: *Self, - q: QueryDeprecated, - ) ArchetypeIterator(modules) { - return ArchetypeIterator(modules).init(entities, q); - } - /// Represents a dynamic (runtime-generated, non type safe) query. pub const QueryDynamic = union(enum) { /// Logical AND operator for query expressions @@ -869,68 +856,6 @@ pub fn Database(comptime modules: anytype) type { }; } -// TODO: move this type somewhere else -pub fn ArchetypeIterator(comptime modules: anytype) type { - const DatabaseT = Database(modules); - return struct { - entities: *DatabaseT, - query: DatabaseT.QueryDeprecated, - index: usize, - - const Self = @This(); - - pub fn init(entities: *DatabaseT, query: DatabaseT.QueryDeprecated) Self { - return Self{ - .entities = entities, - .query = query, - .index = 0, - }; - } - - // TODO: component_types_by_name is a superset of queried items, not type-safe. - 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(modules){ .archetype = archetype }; - } - return null; - } - - pub fn match(iter: *Self, consideration: *Archetype) bool { - if (consideration.len == 0) return false; - var buf: [2048]u8 = undefined; - switch (iter.query) { - .all => { - for (iter.query.all) |namespace| { - switch (namespace) { - inline else => |components| { - for (components) |component| { - if (@typeInfo(@TypeOf(component)).Enum.fields.len == 0) continue; - const name = switch (component) { - inline else => |c| std.fmt.bufPrint(&buf, "{s}.{s}", .{ @tagName(namespace), @tagName(c) }) catch break, - }; - const name_id = iter.entities.componentNameString(name); - var has_column = false; - for (consideration.columns) |column| { - if (column.name == name_id) { - has_column = true; - break; - } - } - if (!has_column) return false; - } - }, - } - } - return true; - }, - .any => @panic("TODO"), - } - } - }; -} - test { const modules = merge(.{ builtin_modules, diff --git a/src/module/main.zig b/src/module/main.zig index 5da55979..9b28d7ce 100644 --- a/src/module/main.zig +++ b/src/module/main.zig @@ -30,7 +30,6 @@ test { // std.testing.refAllDeclsRecursive(@This()); std.testing.refAllDeclsRecursive(@import("Archetype.zig")); std.testing.refAllDeclsRecursive(@import("entities.zig")); - std.testing.refAllDeclsRecursive(@import("query.zig")); std.testing.refAllDeclsRecursive(@import("StringTable.zig")); } @@ -97,27 +96,6 @@ test "entities DB" { try physics.set(player2, .id, 1002); try physics.set(player3, .id, 1003); - //------------------------------------------------------------------------- - // Querying - var iter = world.entities.queryDeprecated(.{ .all = &.{ - .{ .physics = &.{.id} }, - } }); - - var archetype = iter.next().?; - var ids = archetype.slice(.physics, .id); - try testing.expectEqual(@as(usize, 2), ids.len); - try testing.expectEqual(@as(usize, 1002), ids[0]); - try testing.expectEqual(@as(usize, 1003), ids[1]); - - archetype = iter.next().?; - ids = archetype.slice(.physics, .id); - try testing.expectEqual(@as(usize, 1), ids.len); - 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(modules) - try testing.expectEqual(iter.next(), null); - //------------------------------------------------------------------------- // Send events to modules world.mod.renderer.sendGlobal(.tick, .{}); diff --git a/src/module/query.zig b/src/module/query.zig deleted file mode 100644 index fc952321..00000000 --- a/src/module/query.zig +++ /dev/null @@ -1,142 +0,0 @@ -const std = @import("std"); -const testing = std.testing; -const ComponentTypesByName = @import("module.zig").ComponentTypesByName; -const merge = @import("main.zig").merge; -const builtin_modules = @import("main.zig").builtin_modules; - -pub const QueryTag = enum { - any, - all, -}; - -/// A complex query for entities matching a given criteria -pub fn QueryDeprecated(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` - pub const Namespace = std.meta.FieldEnum(@TypeOf(component_types_by_name)); - - // TODO: cleanup comptime - /// Enum matching a component within a namespace - /// e.g. `var a: Component(.physics2d) = .location` - pub fn Component(comptime namespace: Namespace) type { - const components = @field(component_types_by_name, @tagName(namespace)); - if (@typeInfo(@TypeOf(components)).Struct.fields.len == 0) return enum {}; - return std.meta.FieldEnum(@TypeOf(components)); - } - - // TODO: cleanup comptime - /// Slice of enums matching a component within a namespace - /// e.g. `&.{.location, .rotation}` - pub fn ComponentList(comptime namespace: Namespace) type { - return []const Component(namespace); - } - - // TODO: cleanup comptime - /// Tagged union of namespaces matching lists of components - /// e.g. `.physics2d = &.{ .location, .rotation }` - pub const NamespaceComponent = T: { - const namespaces = std.meta.fields(Namespace); - var fields: [namespaces.len]std.builtin.Type.UnionField = undefined; - for (namespaces, 0..) |namespace, i| { - const ns = stringToEnum(Namespace, namespace.name).?; - fields[i] = .{ - .name = namespace.name, - .type = ComponentList(ns), - .alignment = @alignOf(ComponentList(ns)), - }; - } - - break :T @Type(.{ .Union = .{ - .layout = .Auto, - .tag_type = Namespace, - .fields = &fields, - .decls = &.{}, - } }); - }; - - /// Matches any of these components - any: []const NamespaceComponent, - - /// Matches all of these components - all: []const NamespaceComponent, - }; -} - -// TODO: cannot use std.meta.stringToEnum for some reason; an issue with its internal comptime map and u0 values -pub fn stringToEnum(comptime T: type, str: []const u8) ?T { - inline for (@typeInfo(T).Enum.fields) |enumField| { - if (std.mem.eql(u8, str, enumField.name)) { - return @field(T, enumField.name); - } - } -} - -test "query" { - const Location = struct { - x: f32 = 0, - y: f32 = 0, - z: f32 = 0, - }; - - const Rotation = struct { degrees: f32 }; - - const modules = merge(.{ - builtin_modules, - struct { - pub const name = .game; - pub const components = .{ - .name = .{ .type = []const u8 }, - }; - }, - struct { - pub const name = .physics; - pub const components = .{ - .location = .{ .type = Location }, - .rotation = .{ .type = Rotation }, - }; - }, - struct { - pub const name = .renderer; - }, - }); - - const Q = QueryDeprecated(modules); - - // Namespace type lets us select a single namespace. - try testing.expectEqual(@as(Q.Namespace, .game), .game); - try testing.expectEqual(@as(Q.Namespace, .physics), .physics); - - // Component type lets us select a single component within a namespace. - try testing.expectEqual(@as(Q.Component(.physics), .location), .location); - try testing.expectEqual(@as(Q.Component(.game), .name), .name); - - // ComponentList type lets us select multiple components within a namespace. - const x: Q.ComponentList(.physics) = &.{ - .location, - .rotation, - }; - _ = x; - - // NamespaceComponent lets us select multiple components within multiple namespaces. - const y: []const Q.NamespaceComponent = &.{ - .{ .physics = &.{ .location, .rotation } }, - .{ .game = &.{.name} }, - }; - _ = y; - - // Query matching entities with *any* of these components - const z: Q = .{ .any = &.{ - .{ .physics = &.{ .location, .rotation } }, - .{ .game = &.{.name} }, - } }; - _ = z; - - // Query matching entities with *all* of these components. - const w: Q = .{ .all = &.{ - .{ .physics = &.{ .location, .rotation } }, - .{ .game = &.{.name} }, - } }; - _ = w; -}