Refactor sparse component identifier set out

This commit is contained in:
Christian Treffs 2019-03-08 17:57:47 +01:00
parent 209c19fa2f
commit 85c7e2296b
4 changed files with 19 additions and 17 deletions

View File

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

View File

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

View File

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

View File

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