From 85c7e2296bdb33e47cb021cec63201833306b4d2 Mon Sep 17 00:00:00 2001 From: Christian Treffs Date: Fri, 8 Mar 2019 17:57:47 +0100 Subject: [PATCH] Refactor sparse component identifier set out --- Sources/FirebladeECS/Nexus+Component.swift | 16 ++++++++++------ Sources/FirebladeECS/Nexus+Family.swift | 5 ++--- Sources/FirebladeECS/Nexus+FamilyUpdate.swift | 9 ++++----- Sources/FirebladeECS/Nexus.swift | 6 +++--- 4 files changed, 19 insertions(+), 17 deletions(-) diff --git a/Sources/FirebladeECS/Nexus+Component.swift b/Sources/FirebladeECS/Nexus+Component.swift index c4d2d59..f4e81d5 100644 --- a/Sources/FirebladeECS/Nexus+Component.swift +++ b/Sources/FirebladeECS/Nexus+Component.swift @@ -41,9 +41,9 @@ public extension Nexus { // assigns the component id to the entity id if componentIdsByEntity[entityIdx] == nil { - componentIdsByEntity[entityIdx] = SparseComponentIdentifierSet() + componentIdsByEntity[entityIdx] = ComponentSet() } - componentIdsByEntity[entityIdx]?.insert(componentId, at: componentId.hashValue) + componentIdsByEntity[entityIdx]?.insert(componentId) //, at: componentId.hashValue) update(familyMembership: entityId) @@ -77,7 +77,7 @@ public extension Nexus { return unsafeDowncast(component, to: C.self) } - final func get(components entityId: EntityIdentifier) -> SparseComponentIdentifierSet? { + final func get(components entityId: EntityIdentifier) -> ComponentSet? { return componentIdsByEntity[entityId.index] } @@ -88,7 +88,7 @@ public extension Nexus { // delete component instance componentsByType[componentId]?.remove(at: entityIdx) // unasign component from entity - componentIdsByEntity[entityIdx]?.remove(at: componentId.hashValue) + componentIdsByEntity[entityIdx]?.remove(componentId) //.hashValue) update(familyMembership: entityId) @@ -98,11 +98,15 @@ public extension Nexus { @discardableResult final func clear(componentes entityId: EntityIdentifier) -> Bool { - guard let allComponents: SparseComponentIdentifierSet = get(components: entityId) else { + guard let allComponents = get(components: entityId) else { report("clearing components form entity \(entityId) with no components") return false } - let removedAll: Bool = allComponents.reduce(true) { $0 && remove(component: $1, from: entityId) } + var iter = allComponents.makeIterator() + var removedAll: Bool = true + while let component = iter.next() { + removedAll = removedAll && remove(component: component, from: entityId) + } return removedAll } } diff --git a/Sources/FirebladeECS/Nexus+Family.swift b/Sources/FirebladeECS/Nexus+Family.swift index f37e469..42b6621 100644 --- a/Sources/FirebladeECS/Nexus+Family.swift +++ b/Sources/FirebladeECS/Nexus+Family.swift @@ -12,12 +12,11 @@ public extension Nexus { func canBecomeMember(_ entity: Entity, in traits: FamilyTraitSet) -> Bool { let entityIdx: EntityIndex = entity.identifier.index - guard let componentIds: SparseComponentIdentifierSet = componentIdsByEntity[entityIdx] else { + guard let componentIds = componentIdsByEntity[entityIdx] else { assertionFailure("no component set defined for entity: \(entity)") return false } - let componentSet = ComponentSet(componentIds) - return traits.isMatch(components: componentSet) + return traits.isMatch(components: componentIds) } func members(withFamilyTraits traits: FamilyTraitSet) -> UniformEntityIdentifiers { diff --git a/Sources/FirebladeECS/Nexus+FamilyUpdate.swift b/Sources/FirebladeECS/Nexus+FamilyUpdate.swift index a5bf3e4..9f5255f 100644 --- a/Sources/FirebladeECS/Nexus+FamilyUpdate.swift +++ b/Sources/FirebladeECS/Nexus+FamilyUpdate.swift @@ -18,7 +18,8 @@ extension Nexus { final func update(familyMembership traits: FamilyTraitSet) { // FIXME: iterating all entities is costly for many entities - for entity: Entity in entityStorage { + var iter = entityStorage.makeIterator() + while let entity = iter.next() { update(membership: traits, for: entity.identifier) } } @@ -32,7 +33,7 @@ extension Nexus { final func update(membership traits: FamilyTraitSet, for entityId: EntityIdentifier) { let entityIdx: EntityIndex = entityId.index - guard let componentIds: SparseComponentIdentifierSet = componentIdsByEntity[entityIdx] else { + guard let componentIds = componentIdsByEntity[entityIdx] else { // no components - so skip return } @@ -43,9 +44,7 @@ extension Nexus { return } - // TODO: get rid of set creation for comparison by conforming UnorderedSparseSet to SetAlgebra - let componentsSet = ComponentSet(componentIds) - let isMatch: Bool = traits.isMatch(components: componentsSet) + let isMatch: Bool = traits.isMatch(components: componentIds) switch (isMatch, isMember) { case (true, false): diff --git a/Sources/FirebladeECS/Nexus.swift b/Sources/FirebladeECS/Nexus.swift index 6518a8f..1b4fdde 100644 --- a/Sources/FirebladeECS/Nexus.swift +++ b/Sources/FirebladeECS/Nexus.swift @@ -19,7 +19,6 @@ public typealias FamilyTraitSetHash = Int public typealias TraitEntityIdHash = Int public typealias EntityIdInFamilyIndex = Int public typealias TraitEntityIdHashSet = [TraitEntityIdHash: EntityIdInFamilyIndex] -public typealias SparseComponentIdentifierSet = UnorderedSparseSet public protocol NexusDelegate: class { func nexusEventOccurred(_ event: ECSEvent) @@ -39,7 +38,7 @@ public class Nexus: Equatable { /// - Key: entity id as index /// - Value: each element is a component identifier associated with this entity - internal var componentIdsByEntity: [EntityIndex: SparseComponentIdentifierSet] + internal var componentIdsByEntity: [EntityIndex: ComponentSet] /// - Values: entity ids that are currently not used internal var freeEntities: ContiguousArray @@ -56,7 +55,8 @@ public class Nexus: Equatable { } public final func clear() { - for entity: Entity in entityStorage { + var iter = entityStorage.makeIterator() + while let entity = iter.next() { destroy(entity: entity) }