diff --git a/Sources/FirebladeECS/Family.swift b/Sources/FirebladeECS/Family.swift index 27ec0e6..ac818f4 100644 --- a/Sources/FirebladeECS/Family.swift +++ b/Sources/FirebladeECS/Family.swift @@ -47,6 +47,14 @@ public struct Family where R: FamilyRequirementsManaging { public func destroyMembers() -> Bool { entities.reduce(!isEmpty) { $0 && nexus.destroy(entity: $1) } } + + /// Create a member entity with the given components assigned. + /// - Parameter builder: The family member builder. + /// - Returns: The newly created member entity. + @discardableResult + public func createMember(@FamilyMemberBuilder using builder: () -> R.Components) -> Entity { + self.createMember(with: builder()) + } } extension Family: Equatable { diff --git a/Sources/FirebladeECS/FamilyMemberBuilder.swift b/Sources/FirebladeECS/FamilyMemberBuilder.swift new file mode 100644 index 0000000..c1c79bf --- /dev/null +++ b/Sources/FirebladeECS/FamilyMemberBuilder.swift @@ -0,0 +1,10 @@ +// +// FamilyMemberBuilder.swift +// FirebladeECS +// +// Created by Christian Treffs on 07.08.20. +// + +@_functionBuilder +public enum FamilyMemberBuilderPreview where R: FamilyRequirementsManaging { } +public typealias FamilyMemberBuilder = FamilyMemberBuilderPreview where R: FamilyRequirementsManaging diff --git a/Sources/FirebladeECS/Generated/Family.generated.swift b/Sources/FirebladeECS/Generated/Family.generated.swift index 0bf19c9..daf673c 100644 --- a/Sources/FirebladeECS/Generated/Family.generated.swift +++ b/Sources/FirebladeECS/Generated/Family.generated.swift @@ -11,6 +11,10 @@ public typealias Family1 = Family> where Comp1: Component +public protocol RequiringComponents1: FamilyRequirementsManaging where Components == (Comp1) { + associatedtype Comp1: Component +} + public struct Requires1: FamilyRequirementsManaging where Comp1: Component { public let componentTypes: [Component.Type] @@ -34,6 +38,14 @@ public struct Requires1: FamilyRequirementsManaging where Comp1: Componen } } +extension Requires1: RequiringComponents1 { } + +extension FamilyMemberBuilder where R: RequiringComponents1 { + public static func buildBlock(_ comp1: R.Comp1) -> (R.Components) { + (comp1) + } +} + extension Requires1: FamilyEncoding where Comp1: Encodable { public static func encode(components: (Comp1), into container: inout KeyedEncodingContainer, using strategy: CodingStrategy) throws { try container.encode(components, forKey: strategy.codingKey(for: Comp1.self)) @@ -91,6 +103,11 @@ extension Nexus { public typealias Family2 = Family> where Comp1: Component, Comp2: Component +public protocol RequiringComponents2: FamilyRequirementsManaging where Components == (Comp1, Comp2) { + associatedtype Comp1: Component + associatedtype Comp2: Component +} + public struct Requires2: FamilyRequirementsManaging where Comp1: Component, Comp2: Component { public let componentTypes: [Component.Type] @@ -116,6 +133,14 @@ public struct Requires2: FamilyRequirementsManaging where Comp1: C } } +extension Requires2: RequiringComponents2 { } + +extension FamilyMemberBuilder where R: RequiringComponents2 { + public static func buildBlock(_ comp1: R.Comp1, _ comp2: R.Comp2) -> (R.Components) { + (comp1, comp2) + } +} + extension Requires2: FamilyEncoding where Comp1: Encodable, Comp2: Encodable { public static func encode(components: (Comp1, Comp2), into container: inout KeyedEncodingContainer, using strategy: CodingStrategy) throws { try container.encode(components.0, forKey: strategy.codingKey(for: Comp1.self)) @@ -176,6 +201,12 @@ extension Nexus { public typealias Family3 = Family> where Comp1: Component, Comp2: Component, Comp3: Component +public protocol RequiringComponents3: FamilyRequirementsManaging where Components == (Comp1, Comp2, Comp3) { + associatedtype Comp1: Component + associatedtype Comp2: Component + associatedtype Comp3: Component +} + public struct Requires3: FamilyRequirementsManaging where Comp1: Component, Comp2: Component, Comp3: Component { public let componentTypes: [Component.Type] @@ -203,6 +234,14 @@ public struct Requires3: FamilyRequirementsManaging where C } } +extension Requires3: RequiringComponents3 { } + +extension FamilyMemberBuilder where R: RequiringComponents3 { + public static func buildBlock(_ comp1: R.Comp1, _ comp2: R.Comp2, _ comp3: R.Comp3) -> (R.Components) { + (comp1, comp2, comp3) + } +} + extension Requires3: FamilyEncoding where Comp1: Encodable, Comp2: Encodable, Comp3: Encodable { public static func encode(components: (Comp1, Comp2, Comp3), into container: inout KeyedEncodingContainer, using strategy: CodingStrategy) throws { try container.encode(components.0, forKey: strategy.codingKey(for: Comp1.self)) @@ -266,6 +305,13 @@ extension Nexus { public typealias Family4 = Family> where Comp1: Component, Comp2: Component, Comp3: Component, Comp4: Component +public protocol RequiringComponents4: FamilyRequirementsManaging where Components == (Comp1, Comp2, Comp3, Comp4) { + associatedtype Comp1: Component + associatedtype Comp2: Component + associatedtype Comp3: Component + associatedtype Comp4: Component +} + public struct Requires4: FamilyRequirementsManaging where Comp1: Component, Comp2: Component, Comp3: Component, Comp4: Component { public let componentTypes: [Component.Type] @@ -295,6 +341,14 @@ public struct Requires4: FamilyRequirementsManaging } } +extension Requires4: RequiringComponents4 { } + +extension FamilyMemberBuilder where R: RequiringComponents4 { + public static func buildBlock(_ comp1: R.Comp1, _ comp2: R.Comp2, _ comp3: R.Comp3, _ comp4: R.Comp4) -> (R.Components) { + (comp1, comp2, comp3, comp4) + } +} + extension Requires4: FamilyEncoding where Comp1: Encodable, Comp2: Encodable, Comp3: Encodable, Comp4: Encodable { public static func encode(components: (Comp1, Comp2, Comp3, Comp4), into container: inout KeyedEncodingContainer, using strategy: CodingStrategy) throws { try container.encode(components.0, forKey: strategy.codingKey(for: Comp1.self)) @@ -361,6 +415,14 @@ extension Nexus { public typealias Family5 = Family> where Comp1: Component, Comp2: Component, Comp3: Component, Comp4: Component, Comp5: Component +public protocol RequiringComponents5: FamilyRequirementsManaging where Components == (Comp1, Comp2, Comp3, Comp4, Comp5) { + associatedtype Comp1: Component + associatedtype Comp2: Component + associatedtype Comp3: Component + associatedtype Comp4: Component + associatedtype Comp5: Component +} + public struct Requires5: FamilyRequirementsManaging where Comp1: Component, Comp2: Component, Comp3: Component, Comp4: Component, Comp5: Component { public let componentTypes: [Component.Type] @@ -392,6 +454,14 @@ public struct Requires5: FamilyRequirementsMa } } +extension Requires5: RequiringComponents5 { } + +extension FamilyMemberBuilder where R: RequiringComponents5 { + public static func buildBlock(_ comp1: R.Comp1, _ comp2: R.Comp2, _ comp3: R.Comp3, _ comp4: R.Comp4, _ comp5: R.Comp5) -> (R.Components) { + (comp1, comp2, comp3, comp4, comp5) + } +} + extension Requires5: FamilyEncoding where Comp1: Encodable, Comp2: Encodable, Comp3: Encodable, Comp4: Encodable, Comp5: Encodable { public static func encode(components: (Comp1, Comp2, Comp3, Comp4, Comp5), into container: inout KeyedEncodingContainer, using strategy: CodingStrategy) throws { try container.encode(components.0, forKey: strategy.codingKey(for: Comp1.self)) @@ -461,6 +531,15 @@ extension Nexus { public typealias Family6 = Family> where Comp1: Component, Comp2: Component, Comp3: Component, Comp4: Component, Comp5: Component, Comp6: Component +public protocol RequiringComponents6: FamilyRequirementsManaging where Components == (Comp1, Comp2, Comp3, Comp4, Comp5, Comp6) { + associatedtype Comp1: Component + associatedtype Comp2: Component + associatedtype Comp3: Component + associatedtype Comp4: Component + associatedtype Comp5: Component + associatedtype Comp6: Component +} + public struct Requires6: FamilyRequirementsManaging where Comp1: Component, Comp2: Component, Comp3: Component, Comp4: Component, Comp5: Component, Comp6: Component { public let componentTypes: [Component.Type] @@ -494,6 +573,14 @@ public struct Requires6: FamilyRequire } } +extension Requires6: RequiringComponents6 { } + +extension FamilyMemberBuilder where R: RequiringComponents6 { + public static func buildBlock(_ comp1: R.Comp1, _ comp2: R.Comp2, _ comp3: R.Comp3, _ comp4: R.Comp4, _ comp5: R.Comp5, _ comp6: R.Comp6) -> (R.Components) { + (comp1, comp2, comp3, comp4, comp5, comp6) + } +} + extension Requires6: FamilyEncoding where Comp1: Encodable, Comp2: Encodable, Comp3: Encodable, Comp4: Encodable, Comp5: Encodable, Comp6: Encodable { public static func encode(components: (Comp1, Comp2, Comp3, Comp4, Comp5, Comp6), into container: inout KeyedEncodingContainer, using strategy: CodingStrategy) throws { try container.encode(components.0, forKey: strategy.codingKey(for: Comp1.self)) @@ -566,6 +653,16 @@ extension Nexus { public typealias Family7 = Family> where Comp1: Component, Comp2: Component, Comp3: Component, Comp4: Component, Comp5: Component, Comp6: Component, Comp7: Component +public protocol RequiringComponents7: FamilyRequirementsManaging where Components == (Comp1, Comp2, Comp3, Comp4, Comp5, Comp6, Comp7) { + associatedtype Comp1: Component + associatedtype Comp2: Component + associatedtype Comp3: Component + associatedtype Comp4: Component + associatedtype Comp5: Component + associatedtype Comp6: Component + associatedtype Comp7: Component +} + public struct Requires7: FamilyRequirementsManaging where Comp1: Component, Comp2: Component, Comp3: Component, Comp4: Component, Comp5: Component, Comp6: Component, Comp7: Component { public let componentTypes: [Component.Type] @@ -601,6 +698,14 @@ public struct Requires7: Family } } +extension Requires7: RequiringComponents7 { } + +extension FamilyMemberBuilder where R: RequiringComponents7 { + public static func buildBlock(_ comp1: R.Comp1, _ comp2: R.Comp2, _ comp3: R.Comp3, _ comp4: R.Comp4, _ comp5: R.Comp5, _ comp6: R.Comp6, _ comp7: R.Comp7) -> (R.Components) { + (comp1, comp2, comp3, comp4, comp5, comp6, comp7) + } +} + extension Requires7: FamilyEncoding where Comp1: Encodable, Comp2: Encodable, Comp3: Encodable, Comp4: Encodable, Comp5: Encodable, Comp6: Encodable, Comp7: Encodable { public static func encode(components: (Comp1, Comp2, Comp3, Comp4, Comp5, Comp6, Comp7), into container: inout KeyedEncodingContainer, using strategy: CodingStrategy) throws { try container.encode(components.0, forKey: strategy.codingKey(for: Comp1.self)) @@ -676,6 +781,17 @@ extension Nexus { public typealias Family8 = Family> where Comp1: Component, Comp2: Component, Comp3: Component, Comp4: Component, Comp5: Component, Comp6: Component, Comp7: Component, Comp8: Component +public protocol RequiringComponents8: FamilyRequirementsManaging where Components == (Comp1, Comp2, Comp3, Comp4, Comp5, Comp6, Comp7, Comp8) { + associatedtype Comp1: Component + associatedtype Comp2: Component + associatedtype Comp3: Component + associatedtype Comp4: Component + associatedtype Comp5: Component + associatedtype Comp6: Component + associatedtype Comp7: Component + associatedtype Comp8: Component +} + public struct Requires8: FamilyRequirementsManaging where Comp1: Component, Comp2: Component, Comp3: Component, Comp4: Component, Comp5: Component, Comp6: Component, Comp7: Component, Comp8: Component { public let componentTypes: [Component.Type] @@ -713,6 +829,14 @@ public struct Requires8: } } +extension Requires8: RequiringComponents8 { } + +extension FamilyMemberBuilder where R: RequiringComponents8 { + public static func buildBlock(_ comp1: R.Comp1, _ comp2: R.Comp2, _ comp3: R.Comp3, _ comp4: R.Comp4, _ comp5: R.Comp5, _ comp6: R.Comp6, _ comp7: R.Comp7, _ comp8: R.Comp8) -> (R.Components) { + (comp1, comp2, comp3, comp4, comp5, comp6, comp7, comp8) + } +} + extension Requires8: FamilyEncoding where Comp1: Encodable, Comp2: Encodable, Comp3: Encodable, Comp4: Encodable, Comp5: Encodable, Comp6: Encodable, Comp7: Encodable, Comp8: Encodable { public static func encode(components: (Comp1, Comp2, Comp3, Comp4, Comp5, Comp6, Comp7, Comp8), into container: inout KeyedEncodingContainer, using strategy: CodingStrategy) throws { try container.encode(components.0, forKey: strategy.codingKey(for: Comp1.self)) diff --git a/Sources/FirebladeECS/Stencils/Family.stencil b/Sources/FirebladeECS/Stencils/Family.stencil index 50a1c32..252f388 100644 --- a/Sources/FirebladeECS/Stencils/Family.stencil +++ b/Sources/FirebladeECS/Stencils/Family.stencil @@ -23,12 +23,20 @@ {% map components into compsTypeParams using comp %}{% if not maploop.first %}_ {% endif %}{{ comp|lowercase }}: {{ comp }}.Type{% endmap %} {% set CompsTypeParams %}{{compsTypeParams|join: ", "}}{% endset %} {% map components into compsNamedParams using comp %}{% if not maploop.first %}_ {% endif %}{{ comp|lowercase }}: {{ comp }}{% endmap %} -{% set CompsNamedParams %}{{compsNamedParams|join: ", "}}{% endset %} +{% set CompsNamedParams %}{{compsNamedParams|join: ", "}}{% endset %} +{% map components into compsNamedRParams using comp %}_ {{ comp|lowercase }}: R.{{ comp }}{% endmap %} +{% set CompsNamedRParams %}{{compsNamedRParams|join: ", "}}{% endset %} // MARK: - Family {{ idx }} public typealias Family{{ idx }}<{{ CompParams }}> = Family> where {{ CompsWhere }} +public protocol RequiringComponents{{ idx }}: FamilyRequirementsManaging where Components == ({{ CompParams }}) { + {% for comp in components %} + associatedtype {{ comp }}: Component + {% endfor %} +} + public struct Requires{{ idx }}<{{ CompParams }}>: FamilyRequirementsManaging where {{ CompsWhere }} { public let componentTypes: [Component.Type] @@ -56,6 +64,14 @@ public struct Requires{{ idx }}<{{ CompParams }}>: FamilyRequirementsManaging wh } } +extension Requires{{ idx }}: RequiringComponents{{ idx }} { } + +extension FamilyMemberBuilder where R: RequiringComponents{{ idx }} { + public static func buildBlock({{ CompsNamedRParams }}) -> (R.Components) { + return ({{ CompsLowercased }}) + } +} + extension Requires{{ idx }}: FamilyEncoding where {{ CompsWhereEncodable }} { public static func encode(components: ({{ CompParams }}), into container: inout KeyedEncodingContainer, using strategy: CodingStrategy) throws { {% if compEncodable.count == 1 %} diff --git a/Tests/FirebladeECSTests/Generated/FamilyTests.generated.swift b/Tests/FirebladeECSTests/Generated/FamilyTests.generated.swift index a00cad9..2b6a2a8 100644 --- a/Tests/FirebladeECSTests/Generated/FamilyTests.generated.swift +++ b/Tests/FirebladeECSTests/Generated/FamilyTests.generated.swift @@ -25,6 +25,20 @@ final class Family1Tests: XCTestCase { XCTAssertEqual(entity[\Comp1.value], 0) } + func testMemberCreationBuilder() { + let family = nexus.family(requires: Comp1.self) + XCTAssertTrue(family.isEmpty) + let entity = family.createMember { + Comp1(0) + } + XCTAssertEqual(family.count, 1) + XCTAssertEqual(entity.numComponents, 1) + XCTAssertEqual(nexus.numFamilies, 1) + XCTAssertEqual(nexus.numEntities, 1) + XCTAssertEqual(nexus.numComponents, 1) + XCTAssertEqual(entity[\Comp1.value], 0) + } + func testComponentIteration() { let family = nexus.family(requires: Comp1.self) XCTAssertTrue(family.isEmpty) @@ -157,6 +171,22 @@ final class Family2Tests: XCTestCase { XCTAssertEqual(entity[\Comp2.value], 1) } + func testMemberCreationBuilder() { + let family = nexus.family(requiresAll: Comp1.self, Comp2.self) + XCTAssertTrue(family.isEmpty) + let entity = family.createMember { + Comp1(0) + Comp2(1) + } + XCTAssertEqual(family.count, 1) + XCTAssertEqual(entity.numComponents, 2) + XCTAssertEqual(nexus.numFamilies, 1) + XCTAssertEqual(nexus.numEntities, 1) + XCTAssertEqual(nexus.numComponents, 2) + XCTAssertEqual(entity[\Comp1.value], 0) + XCTAssertEqual(entity[\Comp2.value], 1) + } + func testComponentIteration() { let family = nexus.family(requiresAll: Comp1.self, Comp2.self) XCTAssertTrue(family.isEmpty) @@ -295,6 +325,24 @@ final class Family3Tests: XCTestCase { XCTAssertEqual(entity[\Comp3.value], 2) } + func testMemberCreationBuilder() { + let family = nexus.family(requiresAll: Comp1.self, Comp2.self, Comp3.self) + XCTAssertTrue(family.isEmpty) + let entity = family.createMember { + Comp1(0) + Comp2(1) + Comp3(2) + } + XCTAssertEqual(family.count, 1) + XCTAssertEqual(entity.numComponents, 3) + XCTAssertEqual(nexus.numFamilies, 1) + XCTAssertEqual(nexus.numEntities, 1) + XCTAssertEqual(nexus.numComponents, 3) + XCTAssertEqual(entity[\Comp1.value], 0) + XCTAssertEqual(entity[\Comp2.value], 1) + XCTAssertEqual(entity[\Comp3.value], 2) + } + func testComponentIteration() { let family = nexus.family(requiresAll: Comp1.self, Comp2.self, Comp3.self) XCTAssertTrue(family.isEmpty) @@ -439,6 +487,26 @@ final class Family4Tests: XCTestCase { XCTAssertEqual(entity[\Comp4.value], 3) } + func testMemberCreationBuilder() { + let family = nexus.family(requiresAll: Comp1.self, Comp2.self, Comp3.self, Comp4.self) + XCTAssertTrue(family.isEmpty) + let entity = family.createMember { + Comp1(0) + Comp2(1) + Comp3(2) + Comp4(3) + } + XCTAssertEqual(family.count, 1) + XCTAssertEqual(entity.numComponents, 4) + XCTAssertEqual(nexus.numFamilies, 1) + XCTAssertEqual(nexus.numEntities, 1) + XCTAssertEqual(nexus.numComponents, 4) + XCTAssertEqual(entity[\Comp1.value], 0) + XCTAssertEqual(entity[\Comp2.value], 1) + XCTAssertEqual(entity[\Comp3.value], 2) + XCTAssertEqual(entity[\Comp4.value], 3) + } + func testComponentIteration() { let family = nexus.family(requiresAll: Comp1.self, Comp2.self, Comp3.self, Comp4.self) XCTAssertTrue(family.isEmpty) @@ -589,6 +657,28 @@ final class Family5Tests: XCTestCase { XCTAssertEqual(entity[\Comp5.value], 4) } + func testMemberCreationBuilder() { + let family = nexus.family(requiresAll: Comp1.self, Comp2.self, Comp3.self, Comp4.self, Comp5.self) + XCTAssertTrue(family.isEmpty) + let entity = family.createMember { + Comp1(0) + Comp2(1) + Comp3(2) + Comp4(3) + Comp5(4) + } + XCTAssertEqual(family.count, 1) + XCTAssertEqual(entity.numComponents, 5) + XCTAssertEqual(nexus.numFamilies, 1) + XCTAssertEqual(nexus.numEntities, 1) + XCTAssertEqual(nexus.numComponents, 5) + XCTAssertEqual(entity[\Comp1.value], 0) + XCTAssertEqual(entity[\Comp2.value], 1) + XCTAssertEqual(entity[\Comp3.value], 2) + XCTAssertEqual(entity[\Comp4.value], 3) + XCTAssertEqual(entity[\Comp5.value], 4) + } + func testComponentIteration() { let family = nexus.family(requiresAll: Comp1.self, Comp2.self, Comp3.self, Comp4.self, Comp5.self) XCTAssertTrue(family.isEmpty) @@ -745,6 +835,30 @@ final class Family6Tests: XCTestCase { XCTAssertEqual(entity[\Comp6.value], 5) } + func testMemberCreationBuilder() { + let family = nexus.family(requiresAll: Comp1.self, Comp2.self, Comp3.self, Comp4.self, Comp5.self, Comp6.self) + XCTAssertTrue(family.isEmpty) + let entity = family.createMember { + Comp1(0) + Comp2(1) + Comp3(2) + Comp4(3) + Comp5(4) + Comp6(5) + } + XCTAssertEqual(family.count, 1) + XCTAssertEqual(entity.numComponents, 6) + XCTAssertEqual(nexus.numFamilies, 1) + XCTAssertEqual(nexus.numEntities, 1) + XCTAssertEqual(nexus.numComponents, 6) + XCTAssertEqual(entity[\Comp1.value], 0) + XCTAssertEqual(entity[\Comp2.value], 1) + XCTAssertEqual(entity[\Comp3.value], 2) + XCTAssertEqual(entity[\Comp4.value], 3) + XCTAssertEqual(entity[\Comp5.value], 4) + XCTAssertEqual(entity[\Comp6.value], 5) + } + func testComponentIteration() { let family = nexus.family(requiresAll: Comp1.self, Comp2.self, Comp3.self, Comp4.self, Comp5.self, Comp6.self) XCTAssertTrue(family.isEmpty) @@ -907,6 +1021,32 @@ final class Family7Tests: XCTestCase { XCTAssertEqual(entity[\Comp7.value], 6) } + func testMemberCreationBuilder() { + let family = nexus.family(requiresAll: Comp1.self, Comp2.self, Comp3.self, Comp4.self, Comp5.self, Comp6.self, Comp7.self) + XCTAssertTrue(family.isEmpty) + let entity = family.createMember { + Comp1(0) + Comp2(1) + Comp3(2) + Comp4(3) + Comp5(4) + Comp6(5) + Comp7(6) + } + XCTAssertEqual(family.count, 1) + XCTAssertEqual(entity.numComponents, 7) + XCTAssertEqual(nexus.numFamilies, 1) + XCTAssertEqual(nexus.numEntities, 1) + XCTAssertEqual(nexus.numComponents, 7) + XCTAssertEqual(entity[\Comp1.value], 0) + XCTAssertEqual(entity[\Comp2.value], 1) + XCTAssertEqual(entity[\Comp3.value], 2) + XCTAssertEqual(entity[\Comp4.value], 3) + XCTAssertEqual(entity[\Comp5.value], 4) + XCTAssertEqual(entity[\Comp6.value], 5) + XCTAssertEqual(entity[\Comp7.value], 6) + } + func testComponentIteration() { let family = nexus.family(requiresAll: Comp1.self, Comp2.self, Comp3.self, Comp4.self, Comp5.self, Comp6.self, Comp7.self) XCTAssertTrue(family.isEmpty) @@ -1075,6 +1215,34 @@ final class Family8Tests: XCTestCase { XCTAssertEqual(entity[\Comp8.value], 7) } + func testMemberCreationBuilder() { + let family = nexus.family(requiresAll: Comp1.self, Comp2.self, Comp3.self, Comp4.self, Comp5.self, Comp6.self, Comp7.self, Comp8.self) + XCTAssertTrue(family.isEmpty) + let entity = family.createMember { + Comp1(0) + Comp2(1) + Comp3(2) + Comp4(3) + Comp5(4) + Comp6(5) + Comp7(6) + Comp8(7) + } + XCTAssertEqual(family.count, 1) + XCTAssertEqual(entity.numComponents, 8) + XCTAssertEqual(nexus.numFamilies, 1) + XCTAssertEqual(nexus.numEntities, 1) + XCTAssertEqual(nexus.numComponents, 8) + XCTAssertEqual(entity[\Comp1.value], 0) + XCTAssertEqual(entity[\Comp2.value], 1) + XCTAssertEqual(entity[\Comp3.value], 2) + XCTAssertEqual(entity[\Comp4.value], 3) + XCTAssertEqual(entity[\Comp5.value], 4) + XCTAssertEqual(entity[\Comp6.value], 5) + XCTAssertEqual(entity[\Comp7.value], 6) + XCTAssertEqual(entity[\Comp8.value], 7) + } + func testComponentIteration() { let family = nexus.family(requiresAll: Comp1.self, Comp2.self, Comp3.self, Comp4.self, Comp5.self, Comp6.self, Comp7.self, Comp8.self) XCTAssertTrue(family.isEmpty) diff --git a/Tests/FirebladeECSTests/Stencils/FamilyTests.stencil b/Tests/FirebladeECSTests/Stencils/FamilyTests.stencil index 5e66d31..71b3622 100644 --- a/Tests/FirebladeECSTests/Stencils/FamilyTests.stencil +++ b/Tests/FirebladeECSTests/Stencils/FamilyTests.stencil @@ -49,6 +49,24 @@ final class Family{{ idx }}Tests: XCTestCase { {% endfor %} } + func testMemberCreationBuilder() { + let family = nexus.family({% if components.count == 1 %}requires{% else %}requiresAll{%endif%}: {{ CompsSelf }}) + XCTAssertTrue(family.isEmpty) + let entity = family.createMember { + {% for inst in compsInstances %} + {{ inst }} + {% endfor %} + } + XCTAssertEqual(family.count, 1) + XCTAssertEqual(entity.numComponents, {{ idx }}) + XCTAssertEqual(nexus.numFamilies, 1) + XCTAssertEqual(nexus.numEntities, 1) + XCTAssertEqual(nexus.numComponents, {{ idx }}) + {% for comp in components %} + XCTAssertEqual(entity[\{{ comp }}.value], {{ forloop.counter0 }}) + {% endfor %} + } + func testComponentIteration() { let family = nexus.family({% if components.count == 1 %}requires{% else %}requiresAll{%endif%}: {{ CompsSelf }}) XCTAssertTrue(family.isEmpty) diff --git a/Tests/FirebladeECSTests/XCTestManifests.swift b/Tests/FirebladeECSTests/XCTestManifests.swift index 60104b1..749f078 100644 --- a/Tests/FirebladeECSTests/XCTestManifests.swift +++ b/Tests/FirebladeECSTests/XCTestManifests.swift @@ -57,7 +57,8 @@ extension Family1Tests { ("testFamilyDecoding", testFamilyDecoding), ("testFamilyEncoding", testFamilyEncoding), ("testFamilyFailDecoding", testFamilyFailDecoding), - ("testMemberCreation", testMemberCreation) + ("testMemberCreation", testMemberCreation), + ("testMemberCreationBuilder", testMemberCreationBuilder) ] } @@ -72,7 +73,8 @@ extension Family2Tests { ("testFamilyDecoding", testFamilyDecoding), ("testFamilyEncoding", testFamilyEncoding), ("testFamilyFailDecoding", testFamilyFailDecoding), - ("testMemberCreation", testMemberCreation) + ("testMemberCreation", testMemberCreation), + ("testMemberCreationBuilder", testMemberCreationBuilder) ] } @@ -87,7 +89,8 @@ extension Family3Tests { ("testFamilyDecoding", testFamilyDecoding), ("testFamilyEncoding", testFamilyEncoding), ("testFamilyFailDecoding", testFamilyFailDecoding), - ("testMemberCreation", testMemberCreation) + ("testMemberCreation", testMemberCreation), + ("testMemberCreationBuilder", testMemberCreationBuilder) ] } @@ -102,7 +105,8 @@ extension Family4Tests { ("testFamilyDecoding", testFamilyDecoding), ("testFamilyEncoding", testFamilyEncoding), ("testFamilyFailDecoding", testFamilyFailDecoding), - ("testMemberCreation", testMemberCreation) + ("testMemberCreation", testMemberCreation), + ("testMemberCreationBuilder", testMemberCreationBuilder) ] } @@ -117,7 +121,8 @@ extension Family5Tests { ("testFamilyDecoding", testFamilyDecoding), ("testFamilyEncoding", testFamilyEncoding), ("testFamilyFailDecoding", testFamilyFailDecoding), - ("testMemberCreation", testMemberCreation) + ("testMemberCreation", testMemberCreation), + ("testMemberCreationBuilder", testMemberCreationBuilder) ] } @@ -132,7 +137,8 @@ extension Family6Tests { ("testFamilyDecoding", testFamilyDecoding), ("testFamilyEncoding", testFamilyEncoding), ("testFamilyFailDecoding", testFamilyFailDecoding), - ("testMemberCreation", testMemberCreation) + ("testMemberCreation", testMemberCreation), + ("testMemberCreationBuilder", testMemberCreationBuilder) ] } @@ -147,7 +153,8 @@ extension Family7Tests { ("testFamilyDecoding", testFamilyDecoding), ("testFamilyEncoding", testFamilyEncoding), ("testFamilyFailDecoding", testFamilyFailDecoding), - ("testMemberCreation", testMemberCreation) + ("testMemberCreation", testMemberCreation), + ("testMemberCreationBuilder", testMemberCreationBuilder) ] } @@ -162,7 +169,8 @@ extension Family8Tests { ("testFamilyDecoding", testFamilyDecoding), ("testFamilyEncoding", testFamilyEncoding), ("testFamilyFailDecoding", testFamilyFailDecoding), - ("testMemberCreation", testMemberCreation) + ("testMemberCreation", testMemberCreation), + ("testMemberCreationBuilder", testMemberCreationBuilder) ] }