Remove unused entity storage

This commit is contained in:
Christian Treffs 2020-08-21 16:28:30 +02:00
parent 37618d5b4f
commit d2cc6c1115
No known key found for this signature in database
GPG Key ID: 49A4B4B460BE3ED4
8 changed files with 31 additions and 51 deletions

View File

@ -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)
}
}
}

View File

@ -28,7 +28,7 @@ public struct Requires1<Comp1>: 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<Comp1, Comp2>: 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<Comp1, Comp2, Comp3>: 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<Comp1, Comp2, Comp3, Comp4>: 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<Comp1, Comp2, Comp3, Comp4, Comp5>: 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<Comp1, Comp2, Comp3, Comp4, Comp5, Comp6>: 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<Comp1, Comp2, Comp3, Comp4, Comp5, Comp6, Comp7>: 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<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.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)

View File

@ -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))

View File

@ -56,19 +56,11 @@ extension Nexus {
}
func assign(_ componentId: ComponentIdentifier, _ entityId: EntityIdentifier) {
if componentIdsByEntity[entityId] == nil {
componentIdsByEntity[entityId] = Set<ComponentIdentifier>(arrayLiteral: componentId)
} else {
componentIdsByEntity[entityId]?.insert(componentId)
}
componentIdsByEntity[entityId]!.insert(componentId)
}
func assign(_ componentIds: Set<ComponentIdentifier>, _ 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)
}

View File

@ -6,10 +6,6 @@
//
public final class Nexus {
/// Main entity storage.
/// Entities are tightly packed by EntityIdentifier.
@usableFromInline final var entityStorage: UnorderedSparseSet<EntityIdentifier, EntityIdentifier.Identifier>
/// - 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<EntityIdentifier, EntityIdentifier.Identifier>(),
componentsByType: [:],
self.init(componentsByType: [:],
componentsByEntity: [:],
entityIdGenerator: DefaultEntityIdGenerator(),
familyMembersByTraits: [:],
codingStrategy: DefaultCodingStrategy())
}
internal init(entityStorage: UnorderedSparseSet<EntityIdentifier, EntityIdentifier.Identifier>,
componentsByType: [ComponentIdentifier: ManagedContiguousArray<Component>],
internal init(componentsByType: [ComponentIdentifier: ManagedContiguousArray<Component>],
componentsByEntity: [EntityIdentifier: Set<ComponentIdentifier>],
entityIdGenerator: EntityIdentifierGenerator,
familyMembersByTraits: [FamilyTraitSet: UnorderedSparseSet<EntityIdentifier, EntityIdentifier.Identifier>],
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()

View File

@ -32,7 +32,7 @@ extension Single where A: SingleComponent {
}
public var entity: Entity {
nexus.get(entity: entityId).unsafelyUnwrapped
Entity(nexus: self.nexus, id: entityId)
}
}

View File

@ -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 %}

View File

@ -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)