diff --git a/Sources/FirebladeECS/TypedFamily.swift b/Sources/FirebladeECS/TypedFamily.swift index ef3d076..4940102 100644 --- a/Sources/FirebladeECS/TypedFamily.swift +++ b/Sources/FirebladeECS/TypedFamily.swift @@ -6,11 +6,15 @@ // public protocol TypedFamilyProtocol: AnyObject, Equatable, LazySequenceProtocol { + associatedtype EntityComponentsSequence: EntityComponentsSequenceProtocol var traits: FamilyTraitSet { get } var nexus: Nexus? { get } var count: Int { get } + + var entities: FamilyEntities { get } + var entityAndComponents: EntityComponentsSequence { get } } public extension TypedFamilyProtocol { @@ -22,9 +26,14 @@ public extension TypedFamilyProtocol { return memberIds.count } + var entities: FamilyEntities { + return FamilyEntities(nexus, memberIds) + } + static func == (lhs: Self, rhs: Other) -> Bool where Other: TypedFamilyProtocol { return lhs.traits == rhs.traits && lhs.nexus == rhs.nexus } + } public protocol ComponentIteratorProtocol: IteratorProtocol { @@ -35,3 +44,31 @@ public protocol ComponentIteratorProtocol: IteratorProtocol { init(_ nexus: Nexus?, _ family: TypedFamily) } + +public protocol EntityComponentsSequenceProtocol: LazySequenceProtocol, IteratorProtocol { + associatedtype TypedFamily: TypedFamilyProtocol + + var memberIdsIterator: UnorderedSparseSetIterator { get } + var nexus: Nexus? { get } + + init(_ nexus: Nexus?, _ family: TypedFamily) +} + +public struct FamilyEntities: LazySequenceProtocol, IteratorProtocol { + public private(set) weak var nexus: Nexus? + public var memberIdsIterator: UnorderedSparseSetIterator + + public init(_ nexus: Nexus?, _ memberIds: UniformEntityIdentifiers) { + self.nexus = nexus + memberIdsIterator = memberIds.makeIterator() + } + + public mutating func next() -> Entity? { + guard let entityId = memberIdsIterator.next() else { + return nil + } + + return nexus?.get(entity: entityId) + } + +} diff --git a/Sources/FirebladeECS/TypedFamily1.swift b/Sources/FirebladeECS/TypedFamily1.swift index 762e967..570665a 100644 --- a/Sources/FirebladeECS/TypedFamily1.swift +++ b/Sources/FirebladeECS/TypedFamily1.swift @@ -22,6 +22,9 @@ public final class TypedFamily1: TypedFamilyProtocol where A: Component { return ComponentIterator1(nexus, self) } + public var entityAndComponents: FamilyEntitiesAndComponents1 { + return FamilyEntitiesAndComponents1(nexus, self) + } } public struct ComponentIterator1: ComponentIteratorProtocol where A: Component { @@ -43,3 +46,28 @@ public struct ComponentIterator1: ComponentIteratorProtocol where A: Componen } } + +public struct FamilyEntitiesAndComponents1: EntityComponentsSequenceProtocol where A: Component { + public private(set) weak var nexus: Nexus? + public var memberIdsIterator: UnorderedSparseSetIterator + + public init(_ nexus: Nexus?, _ family: TypedFamily1) { + self.nexus = nexus + memberIdsIterator = family.memberIds.makeIterator() + } + + public mutating func next() -> (Entity, A)? { + guard let entityId = memberIdsIterator.next() else { + return nil + } + + guard + let entity = nexus?.get(entity: entityId), + let compA: A = nexus?.get(for: entityId) + else { + return nil + } + + return (entity, compA) + } +} diff --git a/Sources/FirebladeECS/TypedFamily2.swift b/Sources/FirebladeECS/TypedFamily2.swift index 3d41abf..7ee23ba 100644 --- a/Sources/FirebladeECS/TypedFamily2.swift +++ b/Sources/FirebladeECS/TypedFamily2.swift @@ -5,6 +5,8 @@ // Created by Christian Treffs on 29.09.18. // +// swiftlint:disable large_tuple + public final class TypedFamily2: TypedFamilyProtocol where A: Component, B: Component { public private(set) weak var nexus: Nexus? @@ -22,6 +24,10 @@ public final class TypedFamily2: TypedFamilyProtocol where A: Component, B return ComponentIterator2(nexus, self) } + public var entityAndComponents: FamilyEntitiesAndComponents2 { + return FamilyEntitiesAndComponents2(nexus, self) + } + } public struct ComponentIterator2: ComponentIteratorProtocol where A: Component, B: Component { @@ -50,3 +56,29 @@ public struct ComponentIterator2: ComponentIteratorProtocol where A: Compo } } + +public struct FamilyEntitiesAndComponents2: EntityComponentsSequenceProtocol where A: Component, B: Component { + public private(set) weak var nexus: Nexus? + public var memberIdsIterator: UnorderedSparseSetIterator + + public init(_ nexus: Nexus?, _ family: TypedFamily2) { + self.nexus = nexus + memberIdsIterator = family.memberIds.makeIterator() + } + + public mutating func next() -> (Entity, A, B)? { + guard let entityId = memberIdsIterator.next() else { + return nil + } + + guard + let entity = nexus?.get(entity: entityId), + let compA: A = nexus?.get(for: entityId), + let compB: B = nexus?.get(for: entityId) + else { + return nil + } + + return (entity, compA, compB) + } +} diff --git a/Sources/FirebladeECS/TypedFamily3.swift b/Sources/FirebladeECS/TypedFamily3.swift index dd69203..2bc0d72 100644 --- a/Sources/FirebladeECS/TypedFamily3.swift +++ b/Sources/FirebladeECS/TypedFamily3.swift @@ -23,6 +23,10 @@ public final class TypedFamily3: TypedFamilyProtocol where A: Component return ComponentIterator3(nexus, self) } + public var entityAndComponents: FamilyEntitiesAndComponents3 { + return FamilyEntitiesAndComponents3(nexus, self) + } + } public struct ComponentIterator3: ComponentIteratorProtocol where A: Component, B: Component, C: Component { @@ -52,3 +56,30 @@ public struct ComponentIterator3: ComponentIteratorProtocol where A: Co } } + +public struct FamilyEntitiesAndComponents3: EntityComponentsSequenceProtocol where A: Component, B: Component, C: Component { + public private(set) weak var nexus: Nexus? + public var memberIdsIterator: UnorderedSparseSetIterator + + public init(_ nexus: Nexus?, _ family: TypedFamily3) { + self.nexus = nexus + memberIdsIterator = family.memberIds.makeIterator() + } + + public mutating func next() -> (Entity, A, B, C)? { + guard let entityId = memberIdsIterator.next() else { + return nil + } + + guard + let entity = nexus?.get(entity: entityId), + let compA: A = nexus?.get(for: entityId), + let compB: B = nexus?.get(for: entityId), + let compC: C = nexus?.get(for: entityId) + else { + return nil + } + + return (entity, compA, compB, compC) + } +} diff --git a/Sources/FirebladeECS/TypedFamily4.swift b/Sources/FirebladeECS/TypedFamily4.swift index beabfb5..b28d1de 100644 --- a/Sources/FirebladeECS/TypedFamily4.swift +++ b/Sources/FirebladeECS/TypedFamily4.swift @@ -23,6 +23,9 @@ public final class TypedFamily4: TypedFamilyProtocol where A: Compon return ComponentIterator4(nexus, self) } + public var entityAndComponents: FamilyEntitiesAndComponents4 { + return FamilyEntitiesAndComponents4(nexus, self) + } } public struct ComponentIterator4: ComponentIteratorProtocol where A: Component, B: Component, C: Component, D: Component { @@ -53,3 +56,31 @@ public struct ComponentIterator4: ComponentIteratorProtocol where A: } } + +public struct FamilyEntitiesAndComponents4: EntityComponentsSequenceProtocol where A: Component, B: Component, C: Component, D: Component { + public private(set) weak var nexus: Nexus? + public var memberIdsIterator: UnorderedSparseSetIterator + + public init(_ nexus: Nexus?, _ family: TypedFamily4) { + self.nexus = nexus + memberIdsIterator = family.memberIds.makeIterator() + } + + public mutating func next() -> (Entity, A, B, C, D)? { + guard let entityId = memberIdsIterator.next() else { + return nil + } + + guard + let entity = nexus?.get(entity: entityId), + let compA: A = nexus?.get(for: entityId), + let compB: B = nexus?.get(for: entityId), + let compC: C = nexus?.get(for: entityId), + let compD: D = nexus?.get(for: entityId) + else { + return nil + } + + return (entity, compA, compB, compC, compD) + } +} diff --git a/Sources/FirebladeECS/TypedFamily5.swift b/Sources/FirebladeECS/TypedFamily5.swift index 0aaa191..3522796 100644 --- a/Sources/FirebladeECS/TypedFamily5.swift +++ b/Sources/FirebladeECS/TypedFamily5.swift @@ -23,6 +23,10 @@ public final class TypedFamily5: TypedFamilyProtocol where A: Com return ComponentIterator5(nexus, self) } + public var entityAndComponents: FamilyEntitiesAndComponents5 { + return FamilyEntitiesAndComponents5(nexus, self) + } + } public struct ComponentIterator5: ComponentIteratorProtocol where A: Component, B: Component, C: Component, D: Component, E: Component { @@ -54,3 +58,32 @@ public struct ComponentIterator5: ComponentIteratorProtocol where } } + +public struct FamilyEntitiesAndComponents5: EntityComponentsSequenceProtocol where A: Component, B: Component, C: Component, D: Component, E: Component { + public private(set) weak var nexus: Nexus? + public var memberIdsIterator: UnorderedSparseSetIterator + + public init(_ nexus: Nexus?, _ family: TypedFamily5) { + self.nexus = nexus + memberIdsIterator = family.memberIds.makeIterator() + } + + public mutating func next() -> (Entity, A, B, C, D, E)? { + guard let entityId = memberIdsIterator.next() else { + return nil + } + + guard + let entity = nexus?.get(entity: entityId), + let compA: A = nexus?.get(for: entityId), + let compB: B = nexus?.get(for: entityId), + let compC: C = nexus?.get(for: entityId), + let compD: D = nexus?.get(for: entityId), + let compE: E = nexus?.get(for: entityId) + else { + return nil + } + + return (entity, compA, compB, compC, compD, compE) + } +}