diff --git a/Sources/FirebladeECS/Entity+Component.swift b/Sources/FirebladeECS/Entity+Component.swift index 03aee46..99eb2ea 100644 --- a/Sources/FirebladeECS/Entity+Component.swift +++ b/Sources/FirebladeECS/Entity+Component.swift @@ -6,14 +6,17 @@ // public extension Entity { - final func get() -> C? where C: Component { + @inlinable + func get() -> C? where C: Component { return nexus.get(for: identifier) } + @inlinable func get(component compType: A.Type = A.self) -> A? where A: Component { return nexus.get(for: identifier) } + @inlinable func getComponent() -> () -> A? where A: Component { func getComponentFunc() -> A? { return get(component: A.self) @@ -21,14 +24,16 @@ public extension Entity { return getComponentFunc } + @inlinable func get(components _: A.Type, _: B.Type) -> (A?, B?) where A: Component, B: Component { let compA: A? = get(component: A.self) let compB: B? = get(component: B.self) return (compA, compB) } - // swiftlint:disable:next large_tuple - func get(components _: A.Type, _: B.Type, _: C.Type) -> (A?, B?, C?) where A: Component, B: Component, C: Component { + // swiftlint:disable large_tuple + @inlinable + func get(components _: A.Type, _: B.Type, _: C.Type) -> (A?, B?, C?) where A: Component, B: Component, C: Component { let compA: A? = get(component: A.self) let compB: B? = get(component: B.self) let compC: C? = get(component: C.self) diff --git a/Sources/FirebladeECS/Entity.swift b/Sources/FirebladeECS/Entity.swift index 75865e1..9f36180 100644 --- a/Sources/FirebladeECS/Entity.swift +++ b/Sources/FirebladeECS/Entity.swift @@ -5,10 +5,10 @@ // Created by Christian Treffs on 08.10.17. // -open class Entity: UniqueEntityIdentifiable { +public struct Entity: UniqueEntityIdentifiable { public internal(set) var identifier = EntityIdentifier.invalid public var name: String? - internal unowned let nexus: Nexus + public let nexus: Nexus internal init(nexus: Nexus, id: EntityIdentifier, name: String? = nil) { self.nexus = nexus @@ -24,22 +24,22 @@ open class Entity: UniqueEntityIdentifiable { // MARK: - number of components public extension Entity { - final var numComponents: Int { + var numComponents: Int { return nexus.count(components: identifier) } } // MARK: - has component(s) public extension Entity { - final func has(_ type: C.Type) -> Bool where C: Component { + func has(_ type: C.Type) -> Bool where C: Component { return has(type.identifier) } - final func has(_ compId: ComponentIdentifier) -> Bool { + func has(_ compId: ComponentIdentifier) -> Bool { return nexus.has(componentId: compId, entityIdx: identifier.index) } - final var hasComponents: Bool { + var hasComponents: Bool { return nexus.count(components: identifier) > 0 } } @@ -47,7 +47,7 @@ public extension Entity { // MARK: - add component(s) public extension Entity { @discardableResult - final func assign(_ components: Component...) -> Entity { + func assign(_ components: Component...) -> Entity { for component: Component in components { assign(component) } @@ -55,13 +55,13 @@ public extension Entity { } @discardableResult - final func assign(_ component: Component) -> Entity { + func assign(_ component: Component) -> Entity { nexus.assign(component: component, to: self) return self } @discardableResult - final func assign(_ component: C) -> Entity where C: Component { + func assign(_ component: C) -> Entity where C: Component { nexus.assign(component: component, to: self) return self } @@ -80,22 +80,22 @@ public extension Entity { // MARK: - remove component(s) public extension Entity { @discardableResult - final func remove(_ component: C) -> Entity where C: Component { + func remove(_ component: C) -> Entity where C: Component { return remove(component.identifier) } @discardableResult - final func remove(_ compType: C.Type) -> Entity where C: Component { + func remove(_ compType: C.Type) -> Entity where C: Component { return remove(compType.identifier) } @discardableResult - final func remove(_ compId: ComponentIdentifier) -> Entity { + func remove(_ compId: ComponentIdentifier) -> Entity { nexus.remove(component: compId, from: identifier) return self } - final func clear() { + func clear() { nexus.clear(componentes: identifier) } @@ -112,7 +112,7 @@ public extension Entity { // MARK: - destroy/deinit entity public extension Entity { - final func destroy() { + func destroy() { nexus.destroy(entity: self) } } diff --git a/Sources/FirebladeECS/TypedFamily.swift b/Sources/FirebladeECS/TypedFamily.swift index 5bbeb2a..f299db8 100644 --- a/Sources/FirebladeECS/TypedFamily.swift +++ b/Sources/FirebladeECS/TypedFamily.swift @@ -27,23 +27,25 @@ public protocol TypedFamilyProtocol: Equatable, Sequence { } public extension TypedFamilyProtocol { + @inlinable func canBecomeMember(_ entity: Entity) -> Bool { return nexus.canBecomeMember(entity, in: traits) } + @inlinable func isMember(_ entity: Entity) -> Bool { return nexus.isMember(entity, in: traits) } - var memberIds: UniformEntityIdentifiers { + @inlinable var memberIds: UniformEntityIdentifiers { return nexus.members(withFamilyTraits: traits) ?? UniformEntityIdentifiers() } - var count: Int { + @inlinable var count: Int { return memberIds.count } - var entities: FamilyEntities { + @inlinable var entities: FamilyEntities { return FamilyEntities(nexus, memberIds) } diff --git a/Tests/FirebladeECSTests/TypedFamilyPerformanceTests.swift b/Tests/FirebladeECSTests/TypedFamilyPerformanceTests.swift index 8bfdd9a..abada10 100644 --- a/Tests/FirebladeECSTests/TypedFamilyPerformanceTests.swift +++ b/Tests/FirebladeECSTests/TypedFamilyPerformanceTests.swift @@ -52,6 +52,22 @@ class TypedFamilyPerformanceTests: XCTestCase { XCTAssertEqual(loopCount, family.count * 10) } + func testPerformanceArray() { + let positions = [Position](repeating: Position(x: Int.random(in: 0...10), y: Int.random(in: 0...10)), count: numEntities) + + var loopCount: Int = 0 + + measure { + positions + .forEach { (position: Position) in + _ = position + loopCount += 1 + } + } + + XCTAssertEqual(loopCount, numEntities * 10) + } + func testPerformanceTypedFamilyOneComponent() { let family = nexus.family(requires: Position.self, excludesAll: Party.self)