From d2cc6c1115e24e1bf18cd44e30258164db26f122 Mon Sep 17 00:00:00 2001 From: Christian Treffs Date: Fri, 21 Aug 2020 16:28:30 +0200 Subject: [PATCH] Remove unused entity storage --- Sources/FirebladeECS/Family.swift | 2 +- .../Generated/Family.generated.swift | 16 ++++++------- Sources/FirebladeECS/Nexus+Entity.swift | 23 ++++++++----------- Sources/FirebladeECS/Nexus+Internal.swift | 14 +++-------- Sources/FirebladeECS/Nexus.swift | 13 ++--------- Sources/FirebladeECS/Single.swift | 2 +- Sources/FirebladeECS/Stencils/Family.stencil | 2 +- Tests/FirebladeECSTests/NexusTests.swift | 10 ++++---- 8 files changed, 31 insertions(+), 51 deletions(-) diff --git a/Sources/FirebladeECS/Family.swift b/Sources/FirebladeECS/Family.swift index ca0804a..c97289e 100644 --- a/Sources/FirebladeECS/Family.swift +++ b/Sources/FirebladeECS/Family.swift @@ -114,7 +114,7 @@ extension Family { guard let entityId = memberIdsIterator.next() else { return nil } - return nexus.get(unsafeEntity: entityId) + return Entity(nexus: nexus, id: entityId) } } } diff --git a/Sources/FirebladeECS/Generated/Family.generated.swift b/Sources/FirebladeECS/Generated/Family.generated.swift index a5ae33c..a128a3b 100644 --- a/Sources/FirebladeECS/Generated/Family.generated.swift +++ b/Sources/FirebladeECS/Generated/Family.generated.swift @@ -28,7 +28,7 @@ public struct Requires1: FamilyRequirementsManaging where Comp1: Componen } public static func entityAndComponents(nexus: Nexus, entityId: EntityIdentifier) -> (Entity, Comp1) { - let entity: Entity = nexus.get(unsafeEntity: entityId) + let entity = Entity(nexus: nexus, id: entityId) let comp1: Comp1 = nexus.get(unsafeComponentFor: entityId) return (entity, comp1) } @@ -122,7 +122,7 @@ public struct Requires2: FamilyRequirementsManaging where Comp1: C } public static func entityAndComponents(nexus: Nexus, entityId: EntityIdentifier) -> (Entity, Comp1, Comp2) { - let entity: Entity = nexus.get(unsafeEntity: entityId) + let entity = Entity(nexus: nexus, id: entityId) let comp1: Comp1 = nexus.get(unsafeComponentFor: entityId) let comp2: Comp2 = nexus.get(unsafeComponentFor: entityId) return (entity, comp1, comp2) @@ -222,7 +222,7 @@ public struct Requires3: FamilyRequirementsManaging where C } public static func entityAndComponents(nexus: Nexus, entityId: EntityIdentifier) -> (Entity, Comp1, Comp2, Comp3) { - let entity: Entity = nexus.get(unsafeEntity: entityId) + 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) @@ -328,7 +328,7 @@ public struct Requires4: FamilyRequirementsManaging } public static func entityAndComponents(nexus: Nexus, entityId: EntityIdentifier) -> (Entity, Comp1, Comp2, Comp3, Comp4) { - let entity: Entity = nexus.get(unsafeEntity: entityId) + 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) @@ -440,7 +440,7 @@ public struct Requires5: FamilyRequirementsMa } public static func entityAndComponents(nexus: Nexus, entityId: EntityIdentifier) -> (Entity, Comp1, Comp2, Comp3, Comp4, Comp5) { - let entity: Entity = nexus.get(unsafeEntity: entityId) + 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) @@ -558,7 +558,7 @@ public struct Requires6: FamilyRequire } public static func entityAndComponents(nexus: Nexus, entityId: EntityIdentifier) -> (Entity, Comp1, Comp2, Comp3, Comp4, Comp5, Comp6) { - let entity: Entity = nexus.get(unsafeEntity: entityId) + 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) @@ -682,7 +682,7 @@ public struct Requires7: Family } public static func entityAndComponents(nexus: Nexus, entityId: EntityIdentifier) -> (Entity, Comp1, Comp2, Comp3, Comp4, Comp5, Comp6, Comp7) { - let entity: Entity = nexus.get(unsafeEntity: entityId) + 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) @@ -812,7 +812,7 @@ public struct Requires8: } public static func entityAndComponents(nexus: Nexus, entityId: EntityIdentifier) -> (Entity, Comp1, Comp2, Comp3, Comp4, Comp5, Comp6, Comp7, Comp8) { - let entity: Entity = nexus.get(unsafeEntity: entityId) + 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) diff --git a/Sources/FirebladeECS/Nexus+Entity.swift b/Sources/FirebladeECS/Nexus+Entity.swift index a8279e8..772da3e 100644 --- a/Sources/FirebladeECS/Nexus+Entity.swift +++ b/Sources/FirebladeECS/Nexus+Entity.swift @@ -9,7 +9,7 @@ extension Nexus { @discardableResult public func createEntity() -> Entity { let entityId: EntityIdentifier = entityIdGenerator.nextId() - entityStorage.insert(entityId, at: entityId.id) + componentIdsByEntity[entityId] = [] delegate?.nexusEvent(EntityCreated(entityId: entityId)) return Entity(nexus: self, id: entityId) } @@ -30,22 +30,15 @@ extension Nexus { /// Number of entities in nexus. public var numEntities: Int { - entityStorage.count + componentIdsByEntity.keys.count } public func exists(entity entityId: EntityIdentifier) -> Bool { - entityStorage.contains(entityId.id) + componentIdsByEntity.keys.contains(entityId) } - public func get(entity entityId: EntityIdentifier) -> Entity? { - guard let id = entityStorage.get(at: entityId.id) else { - return nil - } - return Entity(nexus: self, id: id) - } - - public func get(unsafeEntity entityId: EntityIdentifier) -> Entity { - Entity(nexus: self, id: entityStorage.get(unsafeAt: entityId.id)) + public func entity(from entityId: EntityIdentifier) -> Entity { + Entity(nexus: self, id: entityId) } @discardableResult @@ -55,7 +48,7 @@ extension Nexus { @discardableResult public func destroy(entityId: EntityIdentifier) -> Bool { - guard entityStorage.remove(at: entityId.id) != nil else { + guard componentIdsByEntity.keys.contains(entityId) else { delegate?.nexusNonFatalError("EntityRemove failure: no entity \(entityId) to remove") return false } @@ -64,6 +57,10 @@ extension Nexus { update(familyMembership: entityId) } + if let index = componentIdsByEntity.index(forKey: entityId) { + componentIdsByEntity.remove(at: index) + } + entityIdGenerator.markUnused(entityId: entityId) delegate?.nexusEvent(EntityDestroyed(entityId: entityId)) diff --git a/Sources/FirebladeECS/Nexus+Internal.swift b/Sources/FirebladeECS/Nexus+Internal.swift index 43bd5d2..cc6df19 100644 --- a/Sources/FirebladeECS/Nexus+Internal.swift +++ b/Sources/FirebladeECS/Nexus+Internal.swift @@ -56,19 +56,11 @@ extension Nexus { } func assign(_ componentId: ComponentIdentifier, _ entityId: EntityIdentifier) { - if componentIdsByEntity[entityId] == nil { - componentIdsByEntity[entityId] = Set(arrayLiteral: componentId) - } else { - componentIdsByEntity[entityId]?.insert(componentId) - } + componentIdsByEntity[entityId]!.insert(componentId) } func assign(_ componentIds: Set, _ entityId: EntityIdentifier) { - if componentIdsByEntity[entityId] == nil { - componentIdsByEntity[entityId] = componentIds - } else { - componentIdsByEntity[entityId]?.formUnion(componentIds) - } + componentIdsByEntity[entityId]!.formUnion(componentIds) } func update(familyMembership entityId: EntityIdentifier) { @@ -92,7 +84,7 @@ extension Nexus { func update(familyMembership traits: FamilyTraitSet) { // FIXME: iterating all entities is costly for many entities - var iter = entityStorage.makeIterator() + var iter = componentIdsByEntity.keys.makeIterator() while let entityId = iter.next() { update(membership: traits, for: entityId) } diff --git a/Sources/FirebladeECS/Nexus.swift b/Sources/FirebladeECS/Nexus.swift index 948a7a5..8f7c7f3 100644 --- a/Sources/FirebladeECS/Nexus.swift +++ b/Sources/FirebladeECS/Nexus.swift @@ -6,10 +6,6 @@ // public final class Nexus { - /// Main entity storage. - /// Entities are tightly packed by EntityIdentifier. - @usableFromInline final var entityStorage: UnorderedSparseSet - /// - Key: ComponentIdentifier aka component type. /// - Value: Array of component instances of same type (uniform). /// New component instances are appended. @@ -39,21 +35,18 @@ public final class Nexus { public final weak var delegate: NexusEventDelegate? public convenience init() { - self.init(entityStorage: UnorderedSparseSet(), - componentsByType: [:], + self.init(componentsByType: [:], componentsByEntity: [:], entityIdGenerator: DefaultEntityIdGenerator(), familyMembersByTraits: [:], codingStrategy: DefaultCodingStrategy()) } - internal init(entityStorage: UnorderedSparseSet, - componentsByType: [ComponentIdentifier: ManagedContiguousArray], + internal init(componentsByType: [ComponentIdentifier: ManagedContiguousArray], componentsByEntity: [EntityIdentifier: Set], entityIdGenerator: EntityIdentifierGenerator, familyMembersByTraits: [FamilyTraitSet: UnorderedSparseSet], codingStrategy: CodingStrategy) { - self.entityStorage = entityStorage self.componentsByType = componentsByType self.componentIdsByEntity = componentsByEntity self.familyMembersByTraits = familyMembersByTraits @@ -66,8 +59,6 @@ public final class Nexus { } public final func clear() { - entityStorage.forEach { destroy(entityId: $0) } - entityStorage.removeAll() componentsByType.removeAll() componentIdsByEntity.removeAll() familyMembersByTraits.removeAll() diff --git a/Sources/FirebladeECS/Single.swift b/Sources/FirebladeECS/Single.swift index 88aeb55..399d1ef 100644 --- a/Sources/FirebladeECS/Single.swift +++ b/Sources/FirebladeECS/Single.swift @@ -32,7 +32,7 @@ extension Single where A: SingleComponent { } public var entity: Entity { - nexus.get(entity: entityId).unsafelyUnwrapped + Entity(nexus: self.nexus, id: entityId) } } diff --git a/Sources/FirebladeECS/Stencils/Family.stencil b/Sources/FirebladeECS/Stencils/Family.stencil index 252f388..548a093 100644 --- a/Sources/FirebladeECS/Stencils/Family.stencil +++ b/Sources/FirebladeECS/Stencils/Family.stencil @@ -52,7 +52,7 @@ public struct Requires{{ idx }}<{{ CompParams }}>: FamilyRequirementsManaging wh } public static func entityAndComponents(nexus: Nexus, entityId: EntityIdentifier) -> (Entity, {{ CompParams }}) { - let entity: Entity = nexus.get(unsafeEntity: entityId) + let entity: Entity = Entity(nexus: nexus, id: entityId) {% for comp in components %} let {{ comp|lowercase }}: {{ comp }} = nexus.get(unsafeComponentFor: entityId) {% endfor %} diff --git a/Tests/FirebladeECSTests/NexusTests.swift b/Tests/FirebladeECSTests/NexusTests.swift index 35b7ea6..c86c30e 100644 --- a/Tests/FirebladeECSTests/NexusTests.swift +++ b/Tests/FirebladeECSTests/NexusTests.swift @@ -39,16 +39,16 @@ class NexusTests: XCTestCase { testEntityCreate() XCTAssertEqual(nexus.numEntities, 2) - let e1: Entity = nexus.get(entity: EntityIdentifier(1))! + let e1 = nexus.entity(from: EntityIdentifier(1)) + XCTAssertTrue(nexus.exists(entity: EntityIdentifier(1))) XCTAssertEqual(e1.identifier.id, 1) XCTAssertTrue(nexus.destroy(entity: e1)) XCTAssertFalse(nexus.destroy(entity: e1)) - XCTAssertEqual(nexus.numEntities, 1) + XCTAssertFalse(nexus.exists(entity: EntityIdentifier(1))) - let e1Again: Entity? = nexus.get(entity: EntityIdentifier(1)) - XCTAssertNil(e1Again) + XCTAssertEqual(nexus.numEntities, 1) XCTAssertEqual(nexus.numEntities, 1) @@ -78,7 +78,7 @@ class NexusTests: XCTestCase { func testComponentDeletion() { let identifier: EntityIdentifier = nexus.createEntity().identifier - let e0 = nexus.get(entity: identifier)! + let e0 = nexus.entity(from: identifier) XCTAssert(e0.numComponents == 0) e0.remove(Position.self)