Optimize and cleanup Nexus

This commit is contained in:
Christian Treffs 2019-10-05 14:55:52 +02:00
parent 589a8c2ec1
commit 61d407e5db
6 changed files with 30 additions and 28 deletions

View File

@ -161,7 +161,7 @@ extension Family {
}
mutating func aggregateRelativesBreathFirst(_ parent: EntityIdentifier) {
guard let children = nexus.parentChildrenMap[parent] else {
guard let children = nexus.childrenByParentEntity[parent] else {
return
}
children

View File

@ -61,11 +61,13 @@ extension FamilyTraitSet: Hashable {
}
}
extension FamilyTraitSet: CustomStringConvertible, CustomDebugStringConvertible {
extension FamilyTraitSet: CustomStringConvertible {
@inlinable public var description: String {
return "<FamilyTraitSet [requiresAll:\(requiresAll.description) excludesAll:\(excludesAll.description)]>"
}
}
extension FamilyTraitSet: CustomDebugStringConvertible {
@inlinable public var debugDescription: String {
return "<FamilyTraitSet [requiresAll:\(requiresAll.debugDescription) excludesAll: \(excludesAll.debugDescription)]>"
}

View File

@ -34,7 +34,7 @@ extension Nexus {
// add component instances to uniform component stores
if componentsByType[componentId] == nil {
componentsByType[componentId] = ManagedContiguousArray<Component>()
componentsByType[componentId] = UnorderedSparseSet<Component>()
}
componentsByType[componentId]?.insert(component, at: entityId.id)

View File

@ -64,11 +64,11 @@ extension Nexus {
final func add(entityWithId entityId: EntityIdentifier, toFamilyWithTraits traits: FamilyTraitSet) {
precondition(familyMembersByTraits[traits] != nil)
familyMembersByTraits[traits].unsafelyUnwrapped.insert(entityId, at: entityId.id)
familyMembersByTraits[traits]!.insert(entityId, at: entityId.id)
}
final func remove(entityWithId entityId: EntityIdentifier, fromFamilyWithTraits traits: FamilyTraitSet) {
precondition(familyMembersByTraits[traits] != nil)
familyMembersByTraits[traits].unsafelyUnwrapped.remove(at: entityId.id)
familyMembersByTraits[traits]!.remove(at: entityId.id)
}
}

View File

@ -8,11 +8,11 @@
extension Nexus {
public final func addChild(_ child: Entity, to parent: Entity) -> Bool {
let inserted: Bool
if parentChildrenMap[parent.identifier] == nil {
parentChildrenMap[parent.identifier] = [child.identifier]
if childrenByParentEntity[parent.identifier] == nil {
childrenByParentEntity[parent.identifier] = [child.identifier]
inserted = true
} else {
let (isNewMember, _) = parentChildrenMap[parent.identifier]!.insert(child.identifier)
let (isNewMember, _) = childrenByParentEntity[parent.identifier]!.insert(child.identifier)
inserted = isNewMember
}
if inserted {
@ -27,7 +27,7 @@ extension Nexus {
@discardableResult
public final func removeChild(_ child: EntityIdentifier, from parent: EntityIdentifier) -> Bool {
let removed: Bool = parentChildrenMap[parent]?.remove(child) != nil
let removed: Bool = childrenByParentEntity[parent]?.remove(child) != nil
if removed {
delegate?.nexusEvent(ChildRemoved(parent: parent, child: child))
}
@ -35,11 +35,11 @@ extension Nexus {
}
public final func removeAllChildren(from parent: Entity) {
parentChildrenMap[parent.identifier]?.forEach { removeChild($0, from: parent.identifier) }
return parentChildrenMap[parent.identifier] = nil
childrenByParentEntity[parent.identifier]?.forEach { removeChild($0, from: parent.identifier) }
return childrenByParentEntity[parent.identifier] = nil
}
public final func numChildren(for entity: Entity) -> Int {
return parentChildrenMap[entity.identifier]?.count ?? 0
return childrenByParentEntity[entity.identifier]?.count ?? 0
}
}

View File

@ -6,40 +6,44 @@
//
public final class Nexus {
public final weak var delegate: NexusEventDelegate?
/// Main entity storage.
/// Entities are tightly packed by EntityIdentifier.
@usableFromInline final var entityStorage: UnorderedSparseSet<Entity>
/// Entity ids that are currently not used.
@usableFromInline final var freeEntities: [EntityIdentifier]
/// - Key: ComponentIdentifier aka component type.
/// - Value: Array of component instances of same type (uniform).
/// New component instances are appended.
@usableFromInline final var componentsByType: [ComponentIdentifier: ManagedContiguousArray<Component>]
@usableFromInline final var componentsByType: [ComponentIdentifier: UnorderedSparseSet<Component>]
/// - Key: EntityIdentifier aka entity index
/// - Value: Set of unique component types (ComponentIdentifier).
/// Each element is a component identifier associated with this entity.
@usableFromInline final var componentIdsByEntity: [EntityIdentifier: Set<ComponentIdentifier>]
/// Entity ids that are currently not used.
@usableFromInline final var freeEntities: ContiguousArray<EntityIdentifier>
/// - Key: A parent entity id.
/// - Value: Adjacency Set of all associated children.
@usableFromInline final var childrenByParentEntity: [EntityIdentifier: Set<EntityIdentifier>]
/// - Key: FamilyTraitSet aka component types that make up one distinct family.
/// - Value: Tightly packed EntityIdentifiers that represent the association of an entity to the family.
@usableFromInline final var familyMembersByTraits: [FamilyTraitSet: UnorderedSparseSet<EntityIdentifier>]
/// - Key: A parent entity id.
/// - Value: Adjacency Set of all associated children.
@usableFromInline final var parentChildrenMap: [EntityIdentifier: Set<EntityIdentifier>]
public final weak var delegate: NexusEventDelegate?
public init() {
entityStorage = UnorderedSparseSet<Entity>()
componentsByType = [:]
componentIdsByEntity = [:]
freeEntities = ContiguousArray<EntityIdentifier>()
freeEntities = []
familyMembersByTraits = [:]
parentChildrenMap = [:]
childrenByParentEntity = [:]
}
deinit {
clear()
}
public final func clear() {
@ -60,11 +64,7 @@ public final class Nexus {
componentsByType.removeAll()
componentIdsByEntity.removeAll()
familyMembersByTraits.removeAll()
parentChildrenMap.removeAll()
}
deinit {
clear()
childrenByParentEntity.removeAll()
}
}
@ -77,7 +77,7 @@ extension Nexus: Equatable {
lhs.freeEntities == rhs.freeEntities &&
lhs.familyMembersByTraits == rhs.familyMembersByTraits &&
lhs.componentsByType.keys == rhs.componentsByType.keys &&
lhs.parentChildrenMap == rhs.parentChildrenMap
lhs.childrenByParentEntity == rhs.childrenByParentEntity
// NOTE: components are not equatable (yet)
}
}