Implement entity and component lookup for different family sizes
This commit is contained in:
parent
af3864701e
commit
c4d213a4e2
|
|
@ -14,10 +14,16 @@ public struct Components1<A>: ComponentsProviding where A: Component {
|
|||
componentTypes = [A.self]
|
||||
}
|
||||
|
||||
public static func getComponents(nexus: Nexus, entityId: EntityIdentifier) -> (A) {
|
||||
public static func components(nexus: Nexus, entityId: EntityIdentifier) -> (A) {
|
||||
let compA: A = nexus.get(unsafeComponentFor: entityId)
|
||||
return (compA)
|
||||
}
|
||||
|
||||
public static func entityAndComponents(nexus: Nexus, entityId: EntityIdentifier) -> (Entity, A) {
|
||||
let entity: Entity = nexus.get(unsafeEntity: entityId)
|
||||
let compA: A = nexus.get(unsafeComponentFor: entityId)
|
||||
return (entity, compA)
|
||||
}
|
||||
}
|
||||
|
||||
extension Nexus {
|
||||
|
|
|
|||
|
|
@ -13,11 +13,18 @@ public struct Components2<A, B>: ComponentsProviding where A: Component, B: Comp
|
|||
public init(_ components: (A.Type, B.Type)) {
|
||||
componentTypes = [ A.self, B.self]
|
||||
}
|
||||
public static func getComponents(nexus: Nexus, entityId: EntityIdentifier) -> (A, B) {
|
||||
public static func components(nexus: Nexus, entityId: EntityIdentifier) -> (A, B) {
|
||||
let compA: A = nexus.get(unsafeComponentFor: entityId)
|
||||
let compB: B = nexus.get(unsafeComponentFor: entityId)
|
||||
return (compA, compB)
|
||||
}
|
||||
|
||||
public static func entityAndComponents(nexus: Nexus, entityId: EntityIdentifier) -> (Entity, A, B) {
|
||||
let entity: Entity = nexus.get(unsafeEntity: entityId)
|
||||
let compA: A = nexus.get(unsafeComponentFor: entityId)
|
||||
let compB: B = nexus.get(unsafeComponentFor: entityId)
|
||||
return (entity, compA, compB)
|
||||
}
|
||||
}
|
||||
|
||||
extension Nexus {
|
||||
|
|
|
|||
|
|
@ -13,12 +13,20 @@ public struct Components3<A, B, C>: ComponentsProviding where A: Component, B: C
|
|||
componentTypes = [A.self, B.self, C.self]
|
||||
}
|
||||
|
||||
public static func getComponents(nexus: Nexus, entityId: EntityIdentifier) -> (A, B, C) {
|
||||
public static func components(nexus: Nexus, entityId: EntityIdentifier) -> (A, B, C) {
|
||||
let compA: A = nexus.get(unsafeComponentFor: entityId)
|
||||
let compB: B = nexus.get(unsafeComponentFor: entityId)
|
||||
let compC: C = nexus.get(unsafeComponentFor: entityId)
|
||||
return (compA, compB, compC)
|
||||
}
|
||||
|
||||
public static func entityAndComponents(nexus: Nexus, entityId: EntityIdentifier) -> (Entity, A, B, C) {
|
||||
let entity: Entity = nexus.get(unsafeEntity: entityId)
|
||||
let compA: A = nexus.get(unsafeComponentFor: entityId)
|
||||
let compB: B = nexus.get(unsafeComponentFor: entityId)
|
||||
let compC: C = nexus.get(unsafeComponentFor: entityId)
|
||||
return (entity, compA, compB, compC)
|
||||
}
|
||||
}
|
||||
|
||||
extension Nexus {
|
||||
|
|
|
|||
|
|
@ -13,13 +13,22 @@ public struct Components4<A, B, C, D>: ComponentsProviding where A: Component, B
|
|||
componentTypes = [A.self, B.self, C.self, D.self]
|
||||
}
|
||||
|
||||
public static func getComponents(nexus: Nexus, entityId: EntityIdentifier) -> (A, B, C, D) {
|
||||
public static func components(nexus: Nexus, entityId: EntityIdentifier) -> (A, B, C, D) {
|
||||
let compA: A = nexus.get(unsafeComponentFor: entityId)
|
||||
let compB: B = nexus.get(unsafeComponentFor: entityId)
|
||||
let compC: C = nexus.get(unsafeComponentFor: entityId)
|
||||
let compD: D = nexus.get(unsafeComponentFor: entityId)
|
||||
return (compA, compB, compC, compD)
|
||||
}
|
||||
|
||||
public static func entityAndComponents(nexus: Nexus, entityId: EntityIdentifier) -> (Entity, A, B, C, D) {
|
||||
let entity: Entity = nexus.get(unsafeEntity: entityId)
|
||||
let compA: A = nexus.get(unsafeComponentFor: entityId)
|
||||
let compB: B = nexus.get(unsafeComponentFor: entityId)
|
||||
let compC: C = nexus.get(unsafeComponentFor: entityId)
|
||||
let compD: D = nexus.get(unsafeComponentFor: entityId)
|
||||
return (entity, compA, compB, compC, compD)
|
||||
}
|
||||
}
|
||||
|
||||
extension Nexus {
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ public struct Components5<A, B, C, D, E>: ComponentsProviding where A: Component
|
|||
componentTypes = [A.self, B.self, C.self, D.self, E.self]
|
||||
}
|
||||
|
||||
public static func getComponents(nexus: Nexus, entityId: EntityIdentifier) -> (A, B, C, D, E) {
|
||||
public static func components(nexus: Nexus, entityId: EntityIdentifier) -> (A, B, C, D, E) {
|
||||
let compA: A = nexus.get(unsafeComponentFor: entityId)
|
||||
let compB: B = nexus.get(unsafeComponentFor: entityId)
|
||||
let compC: C = nexus.get(unsafeComponentFor: entityId)
|
||||
|
|
@ -21,6 +21,16 @@ public struct Components5<A, B, C, D, E>: ComponentsProviding where A: Component
|
|||
let compE: E = nexus.get(unsafeComponentFor: entityId)
|
||||
return (compA, compB, compC, compD, compE)
|
||||
}
|
||||
|
||||
public static func entityAndComponents(nexus: Nexus, entityId: EntityIdentifier) -> (Entity, A, B, C, D, E) {
|
||||
let entity = nexus.get(unsafeEntity: entityId)
|
||||
let compA: A = nexus.get(unsafeComponentFor: entityId)
|
||||
let compB: B = nexus.get(unsafeComponentFor: entityId)
|
||||
let compC: C = nexus.get(unsafeComponentFor: entityId)
|
||||
let compD: D = nexus.get(unsafeComponentFor: entityId)
|
||||
let compE: E = nexus.get(unsafeComponentFor: entityId)
|
||||
return (entity, compA, compB, compC, compD, compE)
|
||||
}
|
||||
}
|
||||
|
||||
extension Nexus {
|
||||
|
|
|
|||
|
|
@ -8,7 +8,9 @@
|
|||
public protocol ComponentsProviding {
|
||||
associatedtype Components
|
||||
associatedtype ComponentTypes
|
||||
associatedtype EntityAndComponents
|
||||
init(_ types: ComponentTypes)
|
||||
var componentTypes: [Component.Type] { get }
|
||||
static func getComponents(nexus: Nexus, entityId: EntityIdentifier) -> Components
|
||||
static func components(nexus: Nexus, entityId: EntityIdentifier) -> Components
|
||||
static func entityAndComponents(nexus: Nexus, entityId: EntityIdentifier) -> EntityAndComponents
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,14 +12,16 @@ public struct Family<R> where R: ComponentsProviding {
|
|||
public init(nexus: Nexus, requiresAll: @autoclosure () -> (R.ComponentTypes), excludesAll: [Component.Type]) {
|
||||
let required = R(requiresAll())
|
||||
self.nexus = nexus
|
||||
traits = FamilyTraitSet(requiresAll: required.componentTypes, excludesAll: excludesAll)
|
||||
let traits = FamilyTraitSet(requiresAll: required.componentTypes, excludesAll: excludesAll)
|
||||
self.traits = traits
|
||||
nexus.onFamilyInit(traits: traits)
|
||||
}
|
||||
|
||||
@inlinable public var memberIds: UnorderedSparseSet<EntityIdentifier> {
|
||||
return nexus.members(withFamilyTraits: traits)
|
||||
}
|
||||
|
||||
@inlinable public var count: Int {
|
||||
@inlinable public var count: Int {
|
||||
return memberIds.count
|
||||
}
|
||||
|
||||
|
|
@ -27,10 +29,6 @@ public struct Family<R> where R: ComponentsProviding {
|
|||
return memberIds.isEmpty
|
||||
}
|
||||
|
||||
@inlinable public var entities: FamilyEntities {
|
||||
return FamilyEntities(nexus, memberIds)
|
||||
}
|
||||
|
||||
@inlinable
|
||||
public func canBecomeMember(_ entity: Entity) -> Bool {
|
||||
return nexus.canBecomeMember(entity, in: traits)
|
||||
|
|
@ -42,8 +40,17 @@ public struct Family<R> where R: ComponentsProviding {
|
|||
}
|
||||
}
|
||||
|
||||
extension Family: Sequence {
|
||||
__consuming public func makeIterator() -> ComponentsIterator {
|
||||
return ComponentsIterator(family: self)
|
||||
}
|
||||
}
|
||||
|
||||
extension Family: LazySequenceProtocol { }
|
||||
|
||||
// MARK: - components iterator
|
||||
extension Family {
|
||||
public struct FamilyIterator: IteratorProtocol {
|
||||
public struct ComponentsIterator: IteratorProtocol {
|
||||
@usableFromInline var memberIdsIterator: UnorderedSparseSetIterator<EntityIdentifier>
|
||||
@usableFromInline unowned let nexus: Nexus
|
||||
|
||||
|
|
@ -57,13 +64,64 @@ extension Family {
|
|||
return nil
|
||||
}
|
||||
|
||||
return R.getComponents(nexus: nexus, entityId: entityId)
|
||||
return R.components(nexus: nexus, entityId: entityId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension Family: Sequence {
|
||||
__consuming public func makeIterator() -> FamilyIterator {
|
||||
return FamilyIterator(family: self)
|
||||
extension Family.ComponentsIterator: LazySequenceProtocol { }
|
||||
|
||||
// MARK: - entity iterator
|
||||
extension Family {
|
||||
@inlinable public var entities: EntityIterator {
|
||||
return EntityIterator(family: self)
|
||||
}
|
||||
|
||||
public struct EntityIterator: IteratorProtocol {
|
||||
@usableFromInline var memberIdsIterator: UnorderedSparseSetIterator<EntityIdentifier>
|
||||
@usableFromInline unowned let nexus: Nexus
|
||||
|
||||
public init(family: Family<R>) {
|
||||
self.nexus = family.nexus
|
||||
memberIdsIterator = family.memberIds.makeIterator()
|
||||
}
|
||||
|
||||
public mutating func next() -> Entity? {
|
||||
guard let entityId = memberIdsIterator.next() else {
|
||||
return nil
|
||||
}
|
||||
return nexus.get(unsafeEntity: entityId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension Family.EntityIterator: LazySequenceProtocol { }
|
||||
|
||||
// MARK: - entity component iterator
|
||||
extension Family {
|
||||
@inlinable public var entityAndComponents: EntityComponentIterator {
|
||||
return EntityComponentIterator(family: self)
|
||||
}
|
||||
|
||||
public struct EntityComponentIterator: IteratorProtocol {
|
||||
@usableFromInline var memberIdsIterator: UnorderedSparseSetIterator<EntityIdentifier>
|
||||
@usableFromInline unowned let nexus: Nexus
|
||||
|
||||
public init(family: Family<R>) {
|
||||
self.nexus = family.nexus
|
||||
memberIdsIterator = family.memberIds.makeIterator()
|
||||
}
|
||||
|
||||
public mutating func next() -> R.EntityAndComponents? {
|
||||
guard let entityId = memberIdsIterator.next() else {
|
||||
return nil
|
||||
}
|
||||
return R.entityAndComponents(nexus: nexus, entityId: entityId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension Family.EntityComponentIterator: LazySequenceProtocol { }
|
||||
|
||||
// MARK: - Equatable
|
||||
extension Family: Equatable { }
|
||||
|
|
|
|||
|
|
@ -1,30 +0,0 @@
|
|||
//
|
||||
// FamilyEntities.swift
|
||||
//
|
||||
//
|
||||
// Created by Christian Treffs on 21.08.19.
|
||||
//
|
||||
|
||||
public struct FamilyEntities {
|
||||
public let nexus: Nexus
|
||||
public var memberIdsIterator: UnorderedSparseSetIterator<EntityIdentifier>
|
||||
|
||||
public init(_ nexus: Nexus, _ memberIds: UnorderedSparseSet<EntityIdentifier>) {
|
||||
self.nexus = nexus
|
||||
memberIdsIterator = memberIds.makeIterator()
|
||||
}
|
||||
}
|
||||
|
||||
extension FamilyEntities: IteratorProtocol {
|
||||
public mutating func next() -> Entity? {
|
||||
guard let entityId = memberIdsIterator.next() else {
|
||||
return nil
|
||||
}
|
||||
|
||||
return nexus.get(entity: entityId)
|
||||
}
|
||||
}
|
||||
|
||||
extension FamilyEntities: LazySequenceProtocol { }
|
||||
|
||||
// TODO: extension FamilyEntities: Equatable { }
|
||||
|
|
@ -5,7 +5,7 @@
|
|||
// Created by Christian Treffs on 09.10.17.
|
||||
//
|
||||
|
||||
import FirebladeECS
|
||||
@testable import FirebladeECS
|
||||
import XCTest
|
||||
|
||||
class FamilyTests: XCTestCase {
|
||||
|
|
|
|||
Loading…
Reference in New Issue