diff --git a/Sources/FirebladeECS/Nexus+Component.swift b/Sources/FirebladeECS/Nexus+Component.swift index cc33ddd..7a953ba 100644 --- a/Sources/FirebladeECS/Nexus+Component.swift +++ b/Sources/FirebladeECS/Nexus+Component.swift @@ -103,7 +103,7 @@ public extension Nexus { } private extension Nexus { - func get(componentId: ComponentIdentifier, entityIdx: EntityIndex) -> C? where C: Component { + final func get(componentId: ComponentIdentifier, entityIdx: EntityIndex) -> C? where C: Component { guard let uniformComponents: UniformComponents = componentsByType[componentId] else { return nil } diff --git a/Sources/FirebladeECS/TypedFamily.swift b/Sources/FirebladeECS/TypedFamily.swift index 5bf286b..5cdfe85 100644 --- a/Sources/FirebladeECS/TypedFamily.swift +++ b/Sources/FirebladeECS/TypedFamily.swift @@ -38,29 +38,8 @@ public protocol FamilyMembersProtocol: LazySequenceProtocol { public protocol ComponentIteratorProtocol: IteratorProtocol { associatedtype TypedFamily: TypedFamilyProtocol - var memberIds: UniformEntityIdentifiers { get } + var memberIdsIterator: UnorderedSparseSetIterator { get } var nexus: Nexus? { get } - var index: Int { get set } init(_ nexus: Nexus?, _ family: TypedFamily) } - -internal extension ComponentIteratorProtocol { - internal mutating func nextIndex() -> Int? { - let nextIndex: Int = memberIds.index(after: index) - guard nextIndex < memberIds.endIndex else { - return nil - } - - index = nextIndex - return nextIndex - } - - internal mutating func nextEntityId() -> EntityIdentifier? { - guard let index: Int = nextIndex() else { - return nil - } - - return memberIds[index] - } -} diff --git a/Sources/FirebladeECS/TypedFamily1.swift b/Sources/FirebladeECS/TypedFamily1.swift index ca40f59..2e43ca7 100644 --- a/Sources/FirebladeECS/TypedFamily1.swift +++ b/Sources/FirebladeECS/TypedFamily1.swift @@ -39,26 +39,19 @@ public struct FamilyMembers1: FamilyMembersProtocol where A: Component { public struct ComponentIterator1: ComponentIteratorProtocol where A: Component { public private(set) weak var nexus: Nexus? - public let memberIds: UniformEntityIdentifiers - public var index: Int = -1 + public var memberIdsIterator: UnorderedSparseSetIterator public init(_ nexus: Nexus?, _ family: TypedFamily1) { self.nexus = nexus - memberIds = family.memberIds + memberIdsIterator = family.memberIds.makeIterator() } public mutating func next() -> A? { - guard let entityId: EntityIdentifier = nextEntityId() else { + guard let entityId = memberIdsIterator.next() else { return nil } - guard - let compA: A = nexus?.get(for: entityId) - else { - return nil - } - - return compA + return nexus?.get(for: entityId) } } diff --git a/Sources/FirebladeECS/TypedFamily2.swift b/Sources/FirebladeECS/TypedFamily2.swift index 7ca7d94..f7c3bf4 100644 --- a/Sources/FirebladeECS/TypedFamily2.swift +++ b/Sources/FirebladeECS/TypedFamily2.swift @@ -39,16 +39,15 @@ public struct FamilyMembers2: FamilyMembersProtocol where A: Component, B: public struct ComponentIterator2: ComponentIteratorProtocol where A: Component, B: Component { public private(set) weak var nexus: Nexus? - public let memberIds: UniformEntityIdentifiers - public var index: Int = -1 + public var memberIdsIterator: UnorderedSparseSetIterator public init(_ nexus: Nexus?, _ family: TypedFamily2) { self.nexus = nexus - memberIds = family.memberIds + memberIdsIterator = family.memberIds.makeIterator() } public mutating func next() -> (A, B)? { - guard let entityId: EntityIdentifier = nextEntityId() else { + guard let entityId: EntityIdentifier = memberIdsIterator.next() else { return nil } diff --git a/Sources/FirebladeECS/TypedFamily3.swift b/Sources/FirebladeECS/TypedFamily3.swift index 654ae3e..7488b95 100644 --- a/Sources/FirebladeECS/TypedFamily3.swift +++ b/Sources/FirebladeECS/TypedFamily3.swift @@ -40,16 +40,15 @@ public struct FamilyMembers3: FamilyMembersProtocol where A: 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 = -1 + public var memberIdsIterator: UnorderedSparseSetIterator public init(_ nexus: Nexus?, _ family: TypedFamily3) { self.nexus = nexus - memberIds = family.memberIds + memberIdsIterator = family.memberIds.makeIterator() } public mutating func next() -> (A, B, C)? { - guard let entityId: EntityIdentifier = nextEntityId() else { + guard let entityId: EntityIdentifier = memberIdsIterator.next() else { return nil } diff --git a/Sources/FirebladeECS/TypedFamily4.swift b/Sources/FirebladeECS/TypedFamily4.swift index 4a54fdd..613cb60 100644 --- a/Sources/FirebladeECS/TypedFamily4.swift +++ b/Sources/FirebladeECS/TypedFamily4.swift @@ -40,16 +40,15 @@ public struct FamilyMembers4: FamilyMembersProtocol where A: Compone public struct ComponentIterator4: ComponentIteratorProtocol where A: Component, B: Component, C: Component, D: Component { public private(set) weak var nexus: Nexus? - public let memberIds: UniformEntityIdentifiers - public var index: Int = -1 + public var memberIdsIterator: UnorderedSparseSetIterator public init(_ nexus: Nexus?, _ family: TypedFamily4) { self.nexus = nexus - memberIds = family.memberIds + memberIdsIterator = family.memberIds.makeIterator() } public mutating func next() -> (A, B, C, D)? { - guard let entityId: EntityIdentifier = nextEntityId() else { + guard let entityId: EntityIdentifier = memberIdsIterator.next() else { return nil } diff --git a/Sources/FirebladeECS/TypedFamily5.swift b/Sources/FirebladeECS/TypedFamily5.swift index 812ccf0..df077a0 100644 --- a/Sources/FirebladeECS/TypedFamily5.swift +++ b/Sources/FirebladeECS/TypedFamily5.swift @@ -40,16 +40,15 @@ public struct FamilyMembers5: FamilyMembersProtocol where A: Comp public struct ComponentIterator5: ComponentIteratorProtocol where A: Component, B: Component, C: Component, D: Component, E: Component { public private(set) weak var nexus: Nexus? - public let memberIds: UniformEntityIdentifiers - public var index: Int = -1 + public var memberIdsIterator: UnorderedSparseSetIterator public init(_ nexus: Nexus?, _ family: TypedFamily5) { self.nexus = nexus - memberIds = family.memberIds + memberIdsIterator = family.memberIds.makeIterator() } public mutating func next() -> (A, B, C, D, E)? { - guard let entityId: EntityIdentifier = nextEntityId() else { + guard let entityId: EntityIdentifier = memberIdsIterator.next() else { return nil } diff --git a/Sources/FirebladeECS/UnorderedSparseSet.swift b/Sources/FirebladeECS/UnorderedSparseSet.swift index acb95fb..5a3d2b9 100644 --- a/Sources/FirebladeECS/UnorderedSparseSet.swift +++ b/Sources/FirebladeECS/UnorderedSparseSet.swift @@ -120,19 +120,19 @@ public class UnorderedSparseSet { return (denseIndex, entry.element) } - // MARK: - UnorderedSparseSetIterator +} - public struct UnorderedSparseSetIterator: IteratorProtocol { +// MARK: - UnorderedSparseSetIterator +public struct UnorderedSparseSetIterator: IteratorProtocol { - public private(set) var iterator: IndexingIterator.Entry>> + public private(set) var iterator: IndexingIterator.Entry>> - public init(_ sparseSet: UnorderedSparseSet) { - iterator = sparseSet.dense.makeIterator() - } + public init(_ sparseSet: UnorderedSparseSet) { + iterator = sparseSet.dense.makeIterator() + } - public mutating func next() -> Element? { - return iterator.next()?.element - } + public mutating func next() -> Element? { + return iterator.next()?.element } } diff --git a/Tests/FirebladeECSTests/FamilyPerformanceTests.swift b/Tests/FirebladeECSTests/FamilyPerformanceTests.swift index d41f103..16c8f08 100644 --- a/Tests/FirebladeECSTests/FamilyPerformanceTests.swift +++ b/Tests/FirebladeECSTests/FamilyPerformanceTests.swift @@ -9,82 +9,154 @@ import FirebladeECS import XCTest class FamilyPerformanceTests: XCTestCase { - + + let numEntities: Int = 10_000 var nexus: Nexus! - + override func setUp() { super.setUp() nexus = Nexus() + + for i in 0..