From 8821648d7f6ddaeff509dd0afe8749f491745793 Mon Sep 17 00:00:00 2001 From: Christian Treffs Date: Mon, 19 Oct 2020 17:33:53 +0200 Subject: [PATCH] Refine component getter and setter --- Sources/FirebladeECS/Entity+Component.swift | 9 +- Sources/FirebladeECS/Entity.swift | 2 +- .../Generated/Family.generated.swift | 144 +++++++++--------- Sources/FirebladeECS/Nexus+Component.swift | 25 ++- Sources/FirebladeECS/Single.swift | 2 +- Sources/FirebladeECS/Stencils/Family.stencil | 4 +- Tests/FirebladeECSTests/EntityTests.swift | 3 +- 7 files changed, 92 insertions(+), 97 deletions(-) diff --git a/Sources/FirebladeECS/Entity+Component.swift b/Sources/FirebladeECS/Entity+Component.swift index 3ef5327..5b1e99e 100644 --- a/Sources/FirebladeECS/Entity+Component.swift +++ b/Sources/FirebladeECS/Entity+Component.swift @@ -8,12 +8,12 @@ extension Entity { @inlinable public func get() -> C? where C: Component { - nexus.get(for: identifier) + nexus.get(safe: identifier) } @inlinable public func get(component compType: A.Type = A.self) -> A? where A: Component { - nexus.get(for: identifier) + nexus.get(safe: identifier) } @inlinable @@ -33,7 +33,7 @@ extension Entity { } /// Get or set component instance by type via subscript. - /// + /// /// **Behavior:** /// - If `Comp` is a component type that is currently *not* assigned to this entity, /// the new instance will be assigned to this entity. @@ -57,7 +57,6 @@ extension Entity { /// Get the value of a component using the key Path to the property in the component. /// - Parameter componentKeyPath: The `KeyPath` to the property of the given component. - /// - Returns: If `Comp` is assigned to this entity the value at the given `KeyPath` is returned, nil otherwise. @inlinable public func get(valueAt componentKeyPath: KeyPath) -> Value where Comp: Component { self.get(component: Comp.self)![keyPath: componentKeyPath] @@ -88,7 +87,7 @@ extension Entity { return nexus.assign(component: newInstance, entityId: identifier) } - get(component: Comp.self).unsafelyUnwrapped[keyPath: componentKeyPath] = newValue + get(component: Comp.self)![keyPath: componentKeyPath] = newValue return true } diff --git a/Sources/FirebladeECS/Entity.swift b/Sources/FirebladeECS/Entity.swift index add53f0..35e7766 100644 --- a/Sources/FirebladeECS/Entity.swift +++ b/Sources/FirebladeECS/Entity.swift @@ -122,7 +122,7 @@ extension Entity { @usableFromInline init(nexus: Nexus, entityIdentifier: EntityIdentifier) { if let comps = nexus.get(components: entityIdentifier) { - iterator = AnyIterator(comps.compactMap { nexus.get(component: $0, for: entityIdentifier) }.makeIterator()) + iterator = AnyIterator(comps.compactMap { nexus.get(unsafe: $0, for: entityIdentifier) }.makeIterator()) } else { iterator = AnyIterator { nil } } diff --git a/Sources/FirebladeECS/Generated/Family.generated.swift b/Sources/FirebladeECS/Generated/Family.generated.swift index a128a3b..caa2ff2 100644 --- a/Sources/FirebladeECS/Generated/Family.generated.swift +++ b/Sources/FirebladeECS/Generated/Family.generated.swift @@ -23,13 +23,13 @@ public struct Requires1: FamilyRequirementsManaging where Comp1: Componen } public static func components(nexus: Nexus, entityId: EntityIdentifier) -> (Comp1) { - let comp1: Comp1 = nexus.get(unsafeComponentFor: entityId) + let comp1: Comp1 = nexus.get(unsafe: entityId) return (comp1) } public static func entityAndComponents(nexus: Nexus, entityId: EntityIdentifier) -> (Entity, Comp1) { let entity = Entity(nexus: nexus, id: entityId) - let comp1: Comp1 = nexus.get(unsafeComponentFor: entityId) + let comp1: Comp1 = nexus.get(unsafe: entityId) return (entity, comp1) } @@ -116,15 +116,15 @@ public struct Requires2: FamilyRequirementsManaging where Comp1: C } public static func components(nexus: Nexus, entityId: EntityIdentifier) -> (Comp1, Comp2) { - let comp1: Comp1 = nexus.get(unsafeComponentFor: entityId) - let comp2: Comp2 = nexus.get(unsafeComponentFor: entityId) + let comp1: Comp1 = nexus.get(unsafe: entityId) + let comp2: Comp2 = nexus.get(unsafe: entityId) return (comp1, comp2) } public static func entityAndComponents(nexus: Nexus, entityId: EntityIdentifier) -> (Entity, Comp1, Comp2) { let entity = Entity(nexus: nexus, id: entityId) - let comp1: Comp1 = nexus.get(unsafeComponentFor: entityId) - let comp2: Comp2 = nexus.get(unsafeComponentFor: entityId) + let comp1: Comp1 = nexus.get(unsafe: entityId) + let comp2: Comp2 = nexus.get(unsafe: entityId) return (entity, comp1, comp2) } @@ -215,17 +215,17 @@ public struct Requires3: FamilyRequirementsManaging where C } public static func components(nexus: Nexus, entityId: EntityIdentifier) -> (Comp1, Comp2, Comp3) { - let comp1: Comp1 = nexus.get(unsafeComponentFor: entityId) - let comp2: Comp2 = nexus.get(unsafeComponentFor: entityId) - let comp3: Comp3 = nexus.get(unsafeComponentFor: entityId) + let comp1: Comp1 = nexus.get(unsafe: entityId) + let comp2: Comp2 = nexus.get(unsafe: entityId) + let comp3: Comp3 = nexus.get(unsafe: entityId) return (comp1, comp2, comp3) } public static func entityAndComponents(nexus: Nexus, entityId: EntityIdentifier) -> (Entity, Comp1, Comp2, Comp3) { let entity = Entity(nexus: nexus, id: entityId) - let comp1: Comp1 = nexus.get(unsafeComponentFor: entityId) - let comp2: Comp2 = nexus.get(unsafeComponentFor: entityId) - let comp3: Comp3 = nexus.get(unsafeComponentFor: entityId) + let comp1: Comp1 = nexus.get(unsafe: entityId) + let comp2: Comp2 = nexus.get(unsafe: entityId) + let comp3: Comp3 = nexus.get(unsafe: entityId) return (entity, comp1, comp2, comp3) } @@ -320,19 +320,19 @@ public struct Requires4: FamilyRequirementsManaging } public static func components(nexus: Nexus, entityId: EntityIdentifier) -> (Comp1, Comp2, Comp3, Comp4) { - let comp1: Comp1 = nexus.get(unsafeComponentFor: entityId) - let comp2: Comp2 = nexus.get(unsafeComponentFor: entityId) - let comp3: Comp3 = nexus.get(unsafeComponentFor: entityId) - let comp4: Comp4 = nexus.get(unsafeComponentFor: entityId) + let comp1: Comp1 = nexus.get(unsafe: entityId) + let comp2: Comp2 = nexus.get(unsafe: entityId) + let comp3: Comp3 = nexus.get(unsafe: entityId) + let comp4: Comp4 = nexus.get(unsafe: entityId) return (comp1, comp2, comp3, comp4) } public static func entityAndComponents(nexus: Nexus, entityId: EntityIdentifier) -> (Entity, Comp1, Comp2, Comp3, Comp4) { let entity = Entity(nexus: nexus, id: entityId) - let comp1: Comp1 = nexus.get(unsafeComponentFor: entityId) - let comp2: Comp2 = nexus.get(unsafeComponentFor: entityId) - let comp3: Comp3 = nexus.get(unsafeComponentFor: entityId) - let comp4: Comp4 = nexus.get(unsafeComponentFor: entityId) + let comp1: Comp1 = nexus.get(unsafe: entityId) + let comp2: Comp2 = nexus.get(unsafe: entityId) + let comp3: Comp3 = nexus.get(unsafe: entityId) + let comp4: Comp4 = nexus.get(unsafe: entityId) return (entity, comp1, comp2, comp3, comp4) } @@ -431,21 +431,21 @@ public struct Requires5: FamilyRequirementsMa } public static func components(nexus: Nexus, entityId: EntityIdentifier) -> (Comp1, Comp2, Comp3, Comp4, Comp5) { - let comp1: Comp1 = nexus.get(unsafeComponentFor: entityId) - let comp2: Comp2 = nexus.get(unsafeComponentFor: entityId) - let comp3: Comp3 = nexus.get(unsafeComponentFor: entityId) - let comp4: Comp4 = nexus.get(unsafeComponentFor: entityId) - let comp5: Comp5 = nexus.get(unsafeComponentFor: entityId) + let comp1: Comp1 = nexus.get(unsafe: entityId) + let comp2: Comp2 = nexus.get(unsafe: entityId) + let comp3: Comp3 = nexus.get(unsafe: entityId) + let comp4: Comp4 = nexus.get(unsafe: entityId) + let comp5: Comp5 = nexus.get(unsafe: entityId) return (comp1, comp2, comp3, comp4, comp5) } public static func entityAndComponents(nexus: Nexus, entityId: EntityIdentifier) -> (Entity, Comp1, Comp2, Comp3, Comp4, Comp5) { let entity = Entity(nexus: nexus, id: entityId) - let comp1: Comp1 = nexus.get(unsafeComponentFor: entityId) - let comp2: Comp2 = nexus.get(unsafeComponentFor: entityId) - let comp3: Comp3 = nexus.get(unsafeComponentFor: entityId) - let comp4: Comp4 = nexus.get(unsafeComponentFor: entityId) - let comp5: Comp5 = nexus.get(unsafeComponentFor: entityId) + let comp1: Comp1 = nexus.get(unsafe: entityId) + let comp2: Comp2 = nexus.get(unsafe: entityId) + let comp3: Comp3 = nexus.get(unsafe: entityId) + let comp4: Comp4 = nexus.get(unsafe: entityId) + let comp5: Comp5 = nexus.get(unsafe: entityId) return (entity, comp1, comp2, comp3, comp4, comp5) } @@ -548,23 +548,23 @@ public struct Requires6: FamilyRequire } public static func components(nexus: Nexus, entityId: EntityIdentifier) -> (Comp1, Comp2, Comp3, Comp4, Comp5, Comp6) { - let comp1: Comp1 = nexus.get(unsafeComponentFor: entityId) - let comp2: Comp2 = nexus.get(unsafeComponentFor: entityId) - let comp3: Comp3 = nexus.get(unsafeComponentFor: entityId) - let comp4: Comp4 = nexus.get(unsafeComponentFor: entityId) - let comp5: Comp5 = nexus.get(unsafeComponentFor: entityId) - let comp6: Comp6 = nexus.get(unsafeComponentFor: entityId) + let comp1: Comp1 = nexus.get(unsafe: entityId) + let comp2: Comp2 = nexus.get(unsafe: entityId) + let comp3: Comp3 = nexus.get(unsafe: entityId) + let comp4: Comp4 = nexus.get(unsafe: entityId) + let comp5: Comp5 = nexus.get(unsafe: entityId) + let comp6: Comp6 = nexus.get(unsafe: entityId) return (comp1, comp2, comp3, comp4, comp5, comp6) } public static func entityAndComponents(nexus: Nexus, entityId: EntityIdentifier) -> (Entity, Comp1, Comp2, Comp3, Comp4, Comp5, Comp6) { let entity = Entity(nexus: nexus, id: entityId) - let comp1: Comp1 = nexus.get(unsafeComponentFor: entityId) - let comp2: Comp2 = nexus.get(unsafeComponentFor: entityId) - let comp3: Comp3 = nexus.get(unsafeComponentFor: entityId) - let comp4: Comp4 = nexus.get(unsafeComponentFor: entityId) - let comp5: Comp5 = nexus.get(unsafeComponentFor: entityId) - let comp6: Comp6 = nexus.get(unsafeComponentFor: entityId) + let comp1: Comp1 = nexus.get(unsafe: entityId) + let comp2: Comp2 = nexus.get(unsafe: entityId) + let comp3: Comp3 = nexus.get(unsafe: entityId) + let comp4: Comp4 = nexus.get(unsafe: entityId) + let comp5: Comp5 = nexus.get(unsafe: entityId) + let comp6: Comp6 = nexus.get(unsafe: entityId) return (entity, comp1, comp2, comp3, comp4, comp5, comp6) } @@ -671,25 +671,25 @@ public struct Requires7: Family } public static func components(nexus: Nexus, entityId: EntityIdentifier) -> (Comp1, Comp2, Comp3, Comp4, Comp5, Comp6, Comp7) { - let comp1: Comp1 = nexus.get(unsafeComponentFor: entityId) - let comp2: Comp2 = nexus.get(unsafeComponentFor: entityId) - let comp3: Comp3 = nexus.get(unsafeComponentFor: entityId) - let comp4: Comp4 = nexus.get(unsafeComponentFor: entityId) - let comp5: Comp5 = nexus.get(unsafeComponentFor: entityId) - let comp6: Comp6 = nexus.get(unsafeComponentFor: entityId) - let comp7: Comp7 = nexus.get(unsafeComponentFor: entityId) + let comp1: Comp1 = nexus.get(unsafe: entityId) + let comp2: Comp2 = nexus.get(unsafe: entityId) + let comp3: Comp3 = nexus.get(unsafe: entityId) + let comp4: Comp4 = nexus.get(unsafe: entityId) + let comp5: Comp5 = nexus.get(unsafe: entityId) + let comp6: Comp6 = nexus.get(unsafe: entityId) + let comp7: Comp7 = nexus.get(unsafe: entityId) return (comp1, comp2, comp3, comp4, comp5, comp6, comp7) } public static func entityAndComponents(nexus: Nexus, entityId: EntityIdentifier) -> (Entity, Comp1, Comp2, Comp3, Comp4, Comp5, Comp6, Comp7) { let entity = Entity(nexus: nexus, id: entityId) - let comp1: Comp1 = nexus.get(unsafeComponentFor: entityId) - let comp2: Comp2 = nexus.get(unsafeComponentFor: entityId) - let comp3: Comp3 = nexus.get(unsafeComponentFor: entityId) - let comp4: Comp4 = nexus.get(unsafeComponentFor: entityId) - let comp5: Comp5 = nexus.get(unsafeComponentFor: entityId) - let comp6: Comp6 = nexus.get(unsafeComponentFor: entityId) - let comp7: Comp7 = nexus.get(unsafeComponentFor: entityId) + let comp1: Comp1 = nexus.get(unsafe: entityId) + let comp2: Comp2 = nexus.get(unsafe: entityId) + let comp3: Comp3 = nexus.get(unsafe: entityId) + let comp4: Comp4 = nexus.get(unsafe: entityId) + let comp5: Comp5 = nexus.get(unsafe: entityId) + let comp6: Comp6 = nexus.get(unsafe: entityId) + let comp7: Comp7 = nexus.get(unsafe: entityId) return (entity, comp1, comp2, comp3, comp4, comp5, comp6, comp7) } @@ -800,27 +800,27 @@ public struct Requires8: } public static func components(nexus: Nexus, entityId: EntityIdentifier) -> (Comp1, Comp2, Comp3, Comp4, Comp5, Comp6, Comp7, Comp8) { - let comp1: Comp1 = nexus.get(unsafeComponentFor: entityId) - let comp2: Comp2 = nexus.get(unsafeComponentFor: entityId) - let comp3: Comp3 = nexus.get(unsafeComponentFor: entityId) - let comp4: Comp4 = nexus.get(unsafeComponentFor: entityId) - let comp5: Comp5 = nexus.get(unsafeComponentFor: entityId) - let comp6: Comp6 = nexus.get(unsafeComponentFor: entityId) - let comp7: Comp7 = nexus.get(unsafeComponentFor: entityId) - let comp8: Comp8 = nexus.get(unsafeComponentFor: entityId) + let comp1: Comp1 = nexus.get(unsafe: entityId) + let comp2: Comp2 = nexus.get(unsafe: entityId) + let comp3: Comp3 = nexus.get(unsafe: entityId) + let comp4: Comp4 = nexus.get(unsafe: entityId) + let comp5: Comp5 = nexus.get(unsafe: entityId) + let comp6: Comp6 = nexus.get(unsafe: entityId) + let comp7: Comp7 = nexus.get(unsafe: entityId) + let comp8: Comp8 = nexus.get(unsafe: entityId) return (comp1, comp2, comp3, comp4, comp5, comp6, comp7, comp8) } public static func entityAndComponents(nexus: Nexus, entityId: EntityIdentifier) -> (Entity, Comp1, Comp2, Comp3, Comp4, Comp5, Comp6, Comp7, Comp8) { let entity = Entity(nexus: nexus, id: entityId) - let comp1: Comp1 = nexus.get(unsafeComponentFor: entityId) - let comp2: Comp2 = nexus.get(unsafeComponentFor: entityId) - let comp3: Comp3 = nexus.get(unsafeComponentFor: entityId) - let comp4: Comp4 = nexus.get(unsafeComponentFor: entityId) - let comp5: Comp5 = nexus.get(unsafeComponentFor: entityId) - let comp6: Comp6 = nexus.get(unsafeComponentFor: entityId) - let comp7: Comp7 = nexus.get(unsafeComponentFor: entityId) - let comp8: Comp8 = nexus.get(unsafeComponentFor: entityId) + let comp1: Comp1 = nexus.get(unsafe: entityId) + let comp2: Comp2 = nexus.get(unsafe: entityId) + let comp3: Comp3 = nexus.get(unsafe: entityId) + let comp4: Comp4 = nexus.get(unsafe: entityId) + let comp5: Comp5 = nexus.get(unsafe: entityId) + let comp6: Comp6 = nexus.get(unsafe: entityId) + let comp7: Comp7 = nexus.get(unsafe: entityId) + let comp8: Comp8 = nexus.get(unsafe: entityId) return (entity, comp1, comp2, comp3, comp4, comp5, comp6, comp7, comp8) } diff --git a/Sources/FirebladeECS/Nexus+Component.swift b/Sources/FirebladeECS/Nexus+Component.swift index 0bac1e0..44b58fc 100644 --- a/Sources/FirebladeECS/Nexus+Component.swift +++ b/Sources/FirebladeECS/Nexus+Component.swift @@ -34,33 +34,32 @@ extension Nexus { } @inlinable - public final func get(component componentId: ComponentIdentifier, for entityId: EntityIdentifier) -> Component? { + public final func get(safe componentId: ComponentIdentifier, for entityId: EntityIdentifier) -> Component? { guard let uniformComponents = componentsByType[componentId], uniformComponents.contains(entityId.index) else { return nil } return uniformComponents.get(at: entityId.index) } - - @inlinable - public final func get(componentId: ComponentIdentifier, entityId: EntityIdentifier) -> C? where C: Component { - get(component: componentId, for: entityId) as? C - } @inlinable - public final func get(unsafeComponent componentId: ComponentIdentifier, for entityId: EntityIdentifier) -> Component { + public final func get(unsafe componentId: ComponentIdentifier, for entityId: EntityIdentifier) -> Component { let uniformComponents = componentsByType[componentId].unsafelyUnwrapped return uniformComponents.get(unsafeAt: entityId.index) } @inlinable - public final func get(for entityId: EntityIdentifier) -> C? where C: Component { - let componentId: ComponentIdentifier = C.identifier - return get(componentId: componentId, entityId: entityId) + public final func get(safe componentId: ComponentIdentifier, for entityId: EntityIdentifier) -> C? where C: Component { + get(safe: componentId, for: entityId) as? C } @inlinable - public final func get(unsafeComponentFor entityId: EntityIdentifier) -> C where C: Component { - let component: Component = get(unsafeComponent: C.identifier, for: entityId) + public final func get(safe entityId: EntityIdentifier) -> C? where C: Component { + get(safe: C.identifier, for: entityId) + } + + @inlinable + public final func get(unsafe entityId: EntityIdentifier) -> C where C: Component { + let component: Component = get(unsafe: C.identifier, for: entityId) // components are guaranteed to be reference types so unsafeDowncast is applicable here return unsafeDowncast(component, to: C.self) } @@ -96,6 +95,4 @@ extension Nexus { } return removedAll } - - } diff --git a/Sources/FirebladeECS/Single.swift b/Sources/FirebladeECS/Single.swift index 399d1ef..36d2c8e 100644 --- a/Sources/FirebladeECS/Single.swift +++ b/Sources/FirebladeECS/Single.swift @@ -28,7 +28,7 @@ extension Single where A: SingleComponent { // Since we guarantee that the component will always be present by managing the complete lifecycle of the entity // and component assignment we may unsafelyUnwrap here. // Since components will always be of reference type (class) we may use unsafeDowncast here for performance reasons. - nexus.get(unsafeComponentFor: entityId) + nexus.get(unsafe: entityId) } public var entity: Entity { diff --git a/Sources/FirebladeECS/Stencils/Family.stencil b/Sources/FirebladeECS/Stencils/Family.stencil index 548a093..d26dbdf 100644 --- a/Sources/FirebladeECS/Stencils/Family.stencil +++ b/Sources/FirebladeECS/Stencils/Family.stencil @@ -46,7 +46,7 @@ public struct Requires{{ idx }}<{{ CompParams }}>: FamilyRequirementsManaging wh public static func components(nexus: Nexus, entityId: EntityIdentifier) -> ({{ CompParams }}) { {% for comp in components %} - let {{ comp|lowercase }}: {{ comp }} = nexus.get(unsafeComponentFor: entityId) + let {{ comp|lowercase }}: {{ comp }} = nexus.get(unsafe: entityId) {% endfor %} return ({{ CompsLowercased }}) } @@ -54,7 +54,7 @@ public struct Requires{{ idx }}<{{ CompParams }}>: FamilyRequirementsManaging wh public static func entityAndComponents(nexus: Nexus, entityId: EntityIdentifier) -> (Entity, {{ CompParams }}) { let entity: Entity = Entity(nexus: nexus, id: entityId) {% for comp in components %} - let {{ comp|lowercase }}: {{ comp }} = nexus.get(unsafeComponentFor: entityId) + let {{ comp|lowercase }}: {{ comp }} = nexus.get(unsafe: entityId) {% endfor %} return (entity, {{ CompsLowercased }}) } diff --git a/Tests/FirebladeECSTests/EntityTests.swift b/Tests/FirebladeECSTests/EntityTests.swift index 922b93a..b1e7223 100644 --- a/Tests/FirebladeECSTests/EntityTests.swift +++ b/Tests/FirebladeECSTests/EntityTests.swift @@ -107,7 +107,6 @@ class EntityTests: XCTestCase { XCTAssertEqual(entity[Position.self]?.x, 1234) XCTAssertEqual(entity[Velocity.self]?.a, 123.0) - // remove position component entity[Position.self] = nil XCTAssertNil(entity[Position.self]) @@ -117,7 +116,7 @@ class EntityTests: XCTestCase { XCTAssertTrue(entity[Position.self] === pos) entity[Position.self] = nil // remove position component XCTAssertNil(entity[Position.self]) - + } }