diff --git a/Sources/FirebladeECS/Nexus+TypedFamily.swift b/Sources/FirebladeECS/Nexus+TypedFamily.swift index 4051420..96ed1b4 100644 --- a/Sources/FirebladeECS/Nexus+TypedFamily.swift +++ b/Sources/FirebladeECS/Nexus+TypedFamily.swift @@ -7,15 +7,31 @@ public extension Nexus { + func family(requires componentA: A.Type, + excludesAll excludedComponents: Component.Type...) -> TypedFamily1 where A: Component { + return TypedFamily1(self, + requiresAll: componentA, + excludesAll: excludedComponents) + } + + func family(requiresAll componentA: A.Type, + _ componentB: B.Type, + excludesAll excludedComponents: Component.Type...) -> TypedFamily2 where A: Component, B: Component { + return TypedFamily2(self, + requiresAll: componentA, + componentB, + excludesAll: excludedComponents) + } + func family(requiresAll componentA: A.Type, _ componentB: B.Type, _ componentC: C.Type, - excludesAll excludedComponents: Component.Type...) -> TypedFamily where A: Component, B: Component, C: Component { - return TypedFamily(self, - requiresAll: componentA, - componentB, - componentC, - excludesAll: excludedComponents) + excludesAll excludedComponents: Component.Type...) -> TypedFamily3 where A: Component, B: Component, C: Component { + return TypedFamily3(self, + requiresAll: componentA, + componentB, + componentC, + excludesAll: excludedComponents) } } diff --git a/Sources/FirebladeECS/TypedFamily.swift b/Sources/FirebladeECS/TypedFamily.swift index 6ac5eeb..ed44732 100644 --- a/Sources/FirebladeECS/TypedFamily.swift +++ b/Sources/FirebladeECS/TypedFamily.swift @@ -6,9 +6,12 @@ // public protocol TypedFamilyProtocol: AnyObject { + associatedtype Members: FamilyMembersProtocol + var traits: FamilyTraitSet { get } var nexus: Nexus? { get } var memberIds: UniformEntityIdentifiers { get } + var members: Members { get set } } public extension TypedFamilyProtocol { @@ -17,14 +20,23 @@ public extension TypedFamilyProtocol { } } +public protocol FamilyMembersProtocol: LazySequenceProtocol { + associatedtype TypedFamily: TypedFamilyProtocol + + var nexus: Nexus? { get } + var family: TypedFamily { get } + + init(_ nexus: Nexus?, _ family: TypedFamily) +} + public protocol ComponentIteratorProtocol: IteratorProtocol { + associatedtype TypedFamily: TypedFamilyProtocol + var memberIds: UniformEntityIdentifiers { get } var nexus: Nexus? { get } var index: Int { get set } -} -public protocol FamilyMembersProtocol: LazySequenceProtocol { - var nexus: Nexus? { get } + init(_ nexus: Nexus?, _ family: TypedFamily) } internal extension ComponentIteratorProtocol { diff --git a/Sources/FirebladeECS/TypedFamily1.swift b/Sources/FirebladeECS/TypedFamily1.swift new file mode 100644 index 0000000..6657555 --- /dev/null +++ b/Sources/FirebladeECS/TypedFamily1.swift @@ -0,0 +1,65 @@ +// +// TypedFamily1.swift +// FirebladeECS +// +// Created by Christian Treffs on 29.09.18. +// + +public final class TypedFamily1: TypedFamilyProtocol where A: Component { + + public private(set) weak var nexus: Nexus? + public let traits: FamilyTraitSet + public lazy var members: FamilyMembers1 = FamilyMembers1(nexus, self) + + public init(_ nexus: Nexus, requiresAll compA: A.Type, excludesAll: [Component.Type]) { + self.nexus = nexus + traits = FamilyTraitSet(requiresAll: [compA], excludesAll: excludesAll) + defer { + nexus.onFamilyInit(traits: traits) + } + } + +} + +public struct FamilyMembers1: FamilyMembersProtocol where A: Component { + + public private(set) weak var nexus: Nexus? + public let family: TypedFamily1 + + public init(_ nexus: Nexus?, _ family: TypedFamily1) { + self.nexus = nexus + self.family = family + } + + public func makeIterator() -> ComponentIterator1 { + return ComponentIterator1(nexus, family) + } +} + +public struct ComponentIterator1: ComponentIteratorProtocol where A: Component { + + public private(set) weak var nexus: Nexus? + public let memberIds: UniformEntityIdentifiers + public var index: Int + + public init(_ nexus: Nexus?, _ family: TypedFamily1) { + self.nexus = nexus + memberIds = family.memberIds + index = memberIds.index(before: memberIds.startIndex) + } + + public mutating func next() -> A? { + guard let entityId: EntityIdentifier = nextEntityId() else { + return nil + } + + guard + let compA: A = nexus?.get(for: entityId) + else { + return nil + } + + return compA + } + +} diff --git a/Sources/FirebladeECS/TypedFamily2.swift b/Sources/FirebladeECS/TypedFamily2.swift new file mode 100644 index 0000000..8a22134 --- /dev/null +++ b/Sources/FirebladeECS/TypedFamily2.swift @@ -0,0 +1,66 @@ +// +// TypedFamily2.swift +// FirebladeECS +// +// Created by Christian Treffs on 29.09.18. +// + +public final class TypedFamily2: TypedFamilyProtocol where A: Component, B: Component { + + public private(set) weak var nexus: Nexus? + public let traits: FamilyTraitSet + public lazy var members: FamilyMembers2 = FamilyMembers2(nexus, self) + + public init(_ nexus: Nexus, requiresAll compA: A.Type, _ compB: B.Type, excludesAll: [Component.Type]) { + self.nexus = nexus + traits = FamilyTraitSet(requiresAll: [compA, compB], excludesAll: excludesAll) + defer { + nexus.onFamilyInit(traits: traits) + } + } + +} + +public struct FamilyMembers2: FamilyMembersProtocol where A: Component, B: Component { + + public private(set) weak var nexus: Nexus? + public let family: TypedFamily2 + + public init(_ nexus: Nexus?, _ family: TypedFamily2) { + self.nexus = nexus + self.family = family + } + + public func makeIterator() -> ComponentIterator2 { + return ComponentIterator2(nexus, family) + } +} + +public struct ComponentIterator2: ComponentIteratorProtocol where A: Component, B: Component { + + public private(set) weak var nexus: Nexus? + public let memberIds: UniformEntityIdentifiers + public var index: Int + + public init(_ nexus: Nexus?, _ family: TypedFamily2) { + self.nexus = nexus + memberIds = family.memberIds + index = memberIds.index(before: memberIds.startIndex) + } + + public mutating func next() -> (A, B)? { + guard let entityId: EntityIdentifier = nextEntityId() else { + return nil + } + + guard + let compA: A = nexus?.get(for: entityId), + let compB: B = nexus?.get(for: entityId) + else { + return nil + } + + return (compA, compB) + } + +} diff --git a/Sources/FirebladeECS/TypedFamily3.swift b/Sources/FirebladeECS/TypedFamily3.swift index aaf6ca8..da76dae 100644 --- a/Sources/FirebladeECS/TypedFamily3.swift +++ b/Sources/FirebladeECS/TypedFamily3.swift @@ -7,11 +7,10 @@ // swiftlint:disable large_tuple -public final class TypedFamily: TypedFamilyProtocol where A: Component, B: Component, C: Component { - +public final class TypedFamily3: TypedFamilyProtocol where A: Component, B: Component, C: Component { public private(set) weak var nexus: Nexus? public let traits: FamilyTraitSet - public private(set) lazy var members: FamilyMembers = FamilyMembers(nexus, self) + public lazy var members: FamilyMembers3 = FamilyMembers3(nexus, self) public init(_ nexus: Nexus, requiresAll compA: A.Type, _ compB: B.Type, _ compC: C.Type, excludesAll: [Component.Type]) { self.nexus = nexus @@ -23,28 +22,28 @@ public final class TypedFamily: TypedFamilyProtocol where A: Component, } -public struct FamilyMembers: FamilyMembersProtocol where A: Component, B: Component, C: Component { +public struct FamilyMembers3: FamilyMembersProtocol where A: Component, B: Component, C: Component { public private(set) weak var nexus: Nexus? - public let family: TypedFamily + public let family: TypedFamily3 - public init(_ nexus: Nexus?, _ family: TypedFamily) { + public init(_ nexus: Nexus?, _ family: TypedFamily3) { self.nexus = nexus self.family = family } - public func makeIterator() -> ComponentIterator { - return ComponentIterator(nexus, family) + public func makeIterator() -> ComponentIterator3 { + return ComponentIterator3(nexus, family) } } -public struct ComponentIterator: ComponentIteratorProtocol where A: Component, B: Component, C: Component { +public struct ComponentIterator3: ComponentIteratorProtocol where A: Component, B: Component, C: Component { public private(set) weak var nexus: Nexus? public let memberIds: UniformEntityIdentifiers public var index: Int - public init(_ nexus: Nexus?, _ family: TypedFamily) { + public init(_ nexus: Nexus?, _ family: TypedFamily3) { self.nexus = nexus memberIds = family.memberIds index = memberIds.index(before: memberIds.startIndex)