This commit is contained in:
Christian Treffs 2020-04-30 20:00:19 +02:00
parent a79df79bf9
commit 66f5bfc0c6
No known key found for this signature in database
GPG Key ID: 49A4B4B460BE3ED4
15 changed files with 66 additions and 67 deletions

View File

@ -8,12 +8,12 @@
extension Entity { extension Entity {
@inlinable @inlinable
public func get<C>() -> C? where C: Component { public func get<C>() -> C? where C: Component {
return nexus.get(for: identifier) nexus.get(for: identifier)
} }
@inlinable @inlinable
public func get<A>(component compType: A.Type = A.self) -> A? where A: Component { public func get<A>(component compType: A.Type = A.self) -> A? where A: Component {
return nexus.get(for: identifier) nexus.get(for: identifier)
} }
@inlinable @inlinable

View File

@ -24,24 +24,24 @@ public struct Entity {
/// Returns the number of components for this entity. /// Returns the number of components for this entity.
public var numComponents: Int { public var numComponents: Int {
return nexus.count(components: identifier) nexus.count(components: identifier)
} }
/// Checks if a component with given type is assigned to this entity. /// Checks if a component with given type is assigned to this entity.
/// - Parameter type: the component type. /// - Parameter type: the component type.
public func has<C>(_ type: C.Type) -> Bool where C: Component { public func has<C>(_ type: C.Type) -> Bool where C: Component {
return has(type.identifier) has(type.identifier)
} }
/// Checks if a component with a given component identifier is assigned to this entity. /// Checks if a component with a given component identifier is assigned to this entity.
/// - Parameter compId: the component identifier. /// - Parameter compId: the component identifier.
public func has(_ compId: ComponentIdentifier) -> Bool { public func has(_ compId: ComponentIdentifier) -> Bool {
return nexus.has(componentId: compId, entityId: identifier) nexus.has(componentId: compId, entityId: identifier)
} }
/// Checks if this entity has any components. /// Checks if this entity has any components.
public var hasComponents: Bool { public var hasComponents: Bool {
return nexus.count(components: identifier) > 0 nexus.count(components: identifier) > 0
} }
/// Add one or more components to this entity. /// Add one or more components to this entity.
@ -74,14 +74,14 @@ public struct Entity {
/// - Parameter component: the component. /// - Parameter component: the component.
@discardableResult @discardableResult
public func remove<C>(_ component: C) -> Entity where C: Component { public func remove<C>(_ component: C) -> Entity where C: Component {
return remove(component.identifier) remove(component.identifier)
} }
/// Remove a component by type from this entity. /// Remove a component by type from this entity.
/// - Parameter compType: the component type. /// - Parameter compType: the component type.
@discardableResult @discardableResult
public func remove<C>(_ compType: C.Type) -> Entity where C: Component { public func remove<C>(_ compType: C.Type) -> Entity where C: Component {
return remove(compType.identifier) remove(compType.identifier)
} }
/// Remove a component by id from this entity. /// Remove a component by id from this entity.
@ -106,24 +106,24 @@ public struct Entity {
/// - Parameter entity: The child entity. /// - Parameter entity: The child entity.
@discardableResult @discardableResult
public func addChild(_ entity: Entity) -> Bool { public func addChild(_ entity: Entity) -> Bool {
return nexus.addChild(entity, to: self) nexus.addChild(entity, to: self)
} }
/// Remove entity as child. /// Remove entity as child.
/// - Parameter entity: The child entity. /// - Parameter entity: The child entity.
@discardableResult @discardableResult
public func removeChild(_ entity: Entity) -> Bool { public func removeChild(_ entity: Entity) -> Bool {
return nexus.removeChild(entity, from: self) nexus.removeChild(entity, from: self)
} }
/// Removes all children from this entity. /// Removes all children from this entity.
public func removeAllChildren() { public func removeAllChildren() {
return nexus.removeAllChildren(from: self) nexus.removeAllChildren(from: self)
} }
/// Returns the number of children for this entity. /// Returns the number of children for this entity.
public var numChildren: Int { public var numChildren: Int {
return nexus.numChildren(for: self) nexus.numChildren(for: self)
} }
} }

View File

@ -18,39 +18,38 @@ public struct Family<R> where R: FamilyRequirementsManaging {
} }
@inlinable public var memberIds: UnorderedSparseSet<EntityIdentifier> { @inlinable public var memberIds: UnorderedSparseSet<EntityIdentifier> {
return nexus.members(withFamilyTraits: traits) nexus.members(withFamilyTraits: traits)
} }
@inlinable public var count: Int { @inlinable public var count: Int {
return memberIds.count memberIds.count
} }
@inlinable public var isEmpty: Bool { @inlinable public var isEmpty: Bool {
return memberIds.isEmpty memberIds.isEmpty
} }
@inlinable @inlinable
public func canBecomeMember(_ entity: Entity) -> Bool { public func canBecomeMember(_ entity: Entity) -> Bool {
return nexus.canBecomeMember(entity, in: traits) nexus.canBecomeMember(entity, in: traits)
} }
@inlinable @inlinable
public func isMember(_ entity: Entity) -> Bool { public func isMember(_ entity: Entity) -> Bool {
return nexus.isMember(entity, in: traits) nexus.isMember(entity, in: traits)
} }
} }
// MARK: - Equatable
extension Family: Equatable { extension Family: Equatable {
public static func == (lhs: Family<R>, rhs: Family<R>) -> Bool { public static func == (lhs: Family<R>, rhs: Family<R>) -> Bool {
return lhs.nexus == rhs.nexus && lhs.nexus === rhs.nexus &&
lhs.traits == rhs.traits lhs.traits == rhs.traits
} }
} }
extension Family: Sequence { extension Family: Sequence {
__consuming public func makeIterator() -> ComponentsIterator { __consuming public func makeIterator() -> ComponentsIterator {
return ComponentsIterator(family: self) ComponentsIterator(family: self)
} }
} }
@ -82,7 +81,7 @@ extension Family.ComponentsIterator: LazySequenceProtocol { }
// MARK: - entity iterator // MARK: - entity iterator
extension Family { extension Family {
@inlinable public var entities: EntityIterator { @inlinable public var entities: EntityIterator {
return EntityIterator(family: self) EntityIterator(family: self)
} }
public struct EntityIterator: IteratorProtocol { public struct EntityIterator: IteratorProtocol {
@ -108,7 +107,7 @@ extension Family.EntityIterator: LazySequenceProtocol { }
// MARK: - entity component iterator // MARK: - entity component iterator
extension Family { extension Family {
@inlinable public var entityAndComponents: EntityComponentIterator { @inlinable public var entityAndComponents: EntityComponentIterator {
return EntityComponentIterator(family: self) EntityComponentIterator(family: self)
} }
public struct EntityComponentIterator: IteratorProtocol { public struct EntityComponentIterator: IteratorProtocol {
@ -136,7 +135,7 @@ extension Family.EntityComponentIterator: LazySequenceProtocol { }
extension Family { extension Family {
@inlinable @inlinable
public func descendRelatives(from root: Entity) -> RelativesIterator { public func descendRelatives(from root: Entity) -> RelativesIterator {
return RelativesIterator(family: self, root: root) RelativesIterator(family: self, root: root)
} }
public struct RelativesIterator: IteratorProtocol { public struct RelativesIterator: IteratorProtocol {

View File

@ -37,7 +37,7 @@ extension Nexus {
requires componentA: A.Type, requires componentA: A.Type,
excludesAll excludedComponents: Component.Type... excludesAll excludedComponents: Component.Type...
) -> Family1<A> where A: Component { ) -> Family1<A> where A: Component {
return Family1<A>(nexus: self, Family1<A>(nexus: self,
requiresAll: componentA, requiresAll: componentA,
excludesAll: excludedComponents) excludesAll: excludedComponents)
} }

View File

@ -43,7 +43,7 @@ extension Nexus {
_ componentB: B.Type, _ componentB: B.Type,
excludesAll excludedComponents: Component.Type... excludesAll excludedComponents: Component.Type...
) -> Family2<A, B> where A: Component, B: Component { ) -> Family2<A, B> where A: Component, B: Component {
return Family2<A, B>( Family2<A, B>(
nexus: self, nexus: self,
requiresAll: (componentA, componentB), requiresAll: (componentA, componentB),
excludesAll: excludedComponents excludesAll: excludedComponents

View File

@ -49,7 +49,7 @@ extension Nexus {
_ componentC: C.Type, _ componentC: C.Type,
excludesAll excludedComponents: Component.Type... excludesAll excludedComponents: Component.Type...
) -> Family3<A, B, C> where A: Component, B: Component, C: Component { ) -> Family3<A, B, C> where A: Component, B: Component, C: Component {
return Family3( Family3(
nexus: self, nexus: self,
requiresAll: (componentA, componentB, componentC), requiresAll: (componentA, componentB, componentC),
excludesAll: excludedComponents excludesAll: excludedComponents

View File

@ -55,7 +55,7 @@ extension Nexus {
_ componentD: D.Type, _ componentD: D.Type,
excludesAll excludedComponents: Component.Type... excludesAll excludedComponents: Component.Type...
) -> Family4<A, B, C, D> where A: Component, B: Component, C: Component, D: Component { ) -> Family4<A, B, C, D> where A: Component, B: Component, C: Component, D: Component {
return Family4( Family4(
nexus: self, nexus: self,
requiresAll: (componentA, componentB, componentC, componentD), requiresAll: (componentA, componentB, componentC, componentD),
excludesAll: excludedComponents excludesAll: excludedComponents

View File

@ -62,7 +62,7 @@ extension Nexus {
_ componentE: E.Type, _ componentE: E.Type,
excludesAll excludedComponents: Component.Type... excludesAll excludedComponents: Component.Type...
) -> Family5<A, B, C, D, E> where A: Component, B: Component, C: Component, D: Component, E: Component { ) -> Family5<A, B, C, D, E> where A: Component, B: Component, C: Component, D: Component, E: Component {
return Family5( Family5(
nexus: self, nexus: self,
requiresAll: (componentA, componentB, componentC, componentD, componentE), requiresAll: (componentA, componentB, componentC, componentD, componentE),
excludesAll: excludedComponents excludesAll: excludedComponents

View File

@ -25,29 +25,29 @@ public struct FamilyTraitSet {
@inlinable @inlinable
public func isMatch(components: Set<ComponentIdentifier>) -> Bool { public func isMatch(components: Set<ComponentIdentifier>) -> Bool {
return hasAll(components) && hasNone(components) hasAll(components) && hasNone(components)
} }
@inlinable @inlinable
public func hasAll(_ components: Set<ComponentIdentifier>) -> Bool { public func hasAll(_ components: Set<ComponentIdentifier>) -> Bool {
return requiresAll.isSubset(of: components) requiresAll.isSubset(of: components)
} }
@inlinable @inlinable
public func hasNone(_ components: Set<ComponentIdentifier>) -> Bool { public func hasNone(_ components: Set<ComponentIdentifier>) -> Bool {
return excludesAll.isDisjoint(with: components) excludesAll.isDisjoint(with: components)
} }
@inlinable @inlinable
public static func isValid(requiresAll: Set<ComponentIdentifier>, excludesAll: Set<ComponentIdentifier>) -> Bool { public static func isValid(requiresAll: Set<ComponentIdentifier>, excludesAll: Set<ComponentIdentifier>) -> Bool {
return !requiresAll.isEmpty && !requiresAll.isEmpty &&
requiresAll.isDisjoint(with: excludesAll) requiresAll.isDisjoint(with: excludesAll)
} }
} }
extension FamilyTraitSet: Equatable { extension FamilyTraitSet: Equatable {
public static func == (lhs: FamilyTraitSet, rhs: FamilyTraitSet) -> Bool { public static func == (lhs: FamilyTraitSet, rhs: FamilyTraitSet) -> Bool {
return lhs.setHash == rhs.setHash lhs.setHash == rhs.setHash
} }
} }
@ -59,12 +59,12 @@ extension FamilyTraitSet: Hashable {
extension FamilyTraitSet: CustomStringConvertible { extension FamilyTraitSet: CustomStringConvertible {
@inlinable public var description: String { @inlinable public var description: String {
return "<FamilyTraitSet [requiresAll:\(requiresAll.description) excludesAll:\(excludesAll.description)]>" "<FamilyTraitSet [requiresAll:\(requiresAll.description) excludesAll:\(excludesAll.description)]>"
} }
} }
extension FamilyTraitSet: CustomDebugStringConvertible { extension FamilyTraitSet: CustomDebugStringConvertible {
@inlinable public var debugDescription: String { @inlinable public var debugDescription: String {
return "<FamilyTraitSet [requiresAll:\(requiresAll.debugDescription) excludesAll: \(excludesAll.debugDescription)]>" "<FamilyTraitSet [requiresAll:\(requiresAll.debugDescription) excludesAll: \(excludesAll.debugDescription)]>"
} }
} }

View File

@ -7,7 +7,7 @@
extension Nexus { extension Nexus {
public final var numComponents: Int { public final var numComponents: Int {
return componentsByType.reduce(0) { $0 + $1.value.count } componentsByType.reduce(0) { $0 + $1.value.count }
} }
public final func has(componentId: ComponentIdentifier, entityId: EntityIdentifier) -> Bool { public final func has(componentId: ComponentIdentifier, entityId: EntityIdentifier) -> Bool {
@ -18,14 +18,14 @@ extension Nexus {
} }
public final func count(components entityId: EntityIdentifier) -> Int { public final func count(components entityId: EntityIdentifier) -> Int {
return componentIdsByEntity[entityId]?.count ?? 0 componentIdsByEntity[entityId]?.count ?? 0
} }
public final func assign(component: Component, to entity: Entity) { public final func assign(component: Component, to entity: Entity) {
let componentId: ComponentIdentifier = component.identifier let componentId: ComponentIdentifier = component.identifier
let entityId: EntityIdentifier = entity.identifier let entityId: EntityIdentifier = entity.identifier
/// test if component is already assigned // test if component is already assigned
guard !has(componentId: componentId, entityId: entityId) else { guard !has(componentId: componentId, entityId: entityId) else {
delegate?.nexusNonFatalError("ComponentAdd collision: \(entityId) already has a component \(component)") delegate?.nexusNonFatalError("ComponentAdd collision: \(entityId) already has a component \(component)")
assertionFailure("ComponentAdd collision: \(entityId) already has a component \(component)") assertionFailure("ComponentAdd collision: \(entityId) already has a component \(component)")
@ -76,13 +76,13 @@ extension Nexus {
@inlinable @inlinable
public final func get<C>(unsafeComponentFor entityId: EntityIdentifier) -> C where C: Component { public final func get<C>(unsafeComponentFor entityId: EntityIdentifier) -> C where C: Component {
let component: Component = get(unsafeComponent: C.identifier, for: entityId) let component: Component = get(unsafeComponent: C.identifier, for: entityId)
/// components are guaranteed to be reference tyes so unsafeDowncast is applicable here // components are guaranteed to be reference tyes so unsafeDowncast is applicable here
return unsafeDowncast(component, to: C.self) return unsafeDowncast(component, to: C.self)
} }
@inlinable @inlinable
public final func get(components entityId: EntityIdentifier) -> Set<ComponentIdentifier>? { public final func get(components entityId: EntityIdentifier) -> Set<ComponentIdentifier>? {
return componentIdsByEntity[entityId] componentIdsByEntity[entityId]
} }
@discardableResult @discardableResult

View File

@ -31,11 +31,11 @@ extension Nexus {
/// Number of entities in nexus. /// Number of entities in nexus.
public var numEntities: Int { public var numEntities: Int {
return entityStorage.count entityStorage.count
} }
public func exists(entity entityId: EntityIdentifier) -> Bool { public func exists(entity entityId: EntityIdentifier) -> Bool {
return entityStorage.contains(entityId.id) entityStorage.contains(entityId.id)
} }
public func get(entity entityId: EntityIdentifier) -> Entity? { public func get(entity entityId: EntityIdentifier) -> Entity? {
@ -46,12 +46,12 @@ extension Nexus {
} }
public func get(unsafeEntity entityId: EntityIdentifier) -> Entity { public func get(unsafeEntity entityId: EntityIdentifier) -> Entity {
return Entity(nexus: self, id: entityStorage.get(unsafeAt: entityId.id)) Entity(nexus: self, id: entityStorage.get(unsafeAt: entityId.id))
} }
@discardableResult @discardableResult
public func destroy(entity: Entity) -> Bool { public func destroy(entity: Entity) -> Bool {
return self.destroy(entityId: entity.identifier) self.destroy(entityId: entity.identifier)
} }
@discardableResult @discardableResult

View File

@ -7,7 +7,7 @@
extension Nexus { extension Nexus {
public final var numFamilies: Int { public final var numFamilies: Int {
return familyMembersByTraits.keys.count familyMembersByTraits.keys.count
} }
public func canBecomeMember(_ entity: Entity, in traits: FamilyTraitSet) -> Bool { public func canBecomeMember(_ entity: Entity, in traits: FamilyTraitSet) -> Bool {
@ -19,18 +19,18 @@ extension Nexus {
} }
public func members(withFamilyTraits traits: FamilyTraitSet) -> UnorderedSparseSet<EntityIdentifier> { public func members(withFamilyTraits traits: FamilyTraitSet) -> UnorderedSparseSet<EntityIdentifier> {
return familyMembersByTraits[traits] ?? UnorderedSparseSet<EntityIdentifier>() familyMembersByTraits[traits] ?? UnorderedSparseSet<EntityIdentifier>()
} }
public func isMember(_ entity: Entity, in family: FamilyTraitSet) -> Bool { public func isMember(_ entity: Entity, in family: FamilyTraitSet) -> Bool {
return isMember(entity.identifier, in: family) isMember(entity.identifier, in: family)
} }
public func isMember(_ entityId: EntityIdentifier, in family: FamilyTraitSet) -> Bool { public func isMember(_ entityId: EntityIdentifier, in family: FamilyTraitSet) -> Bool {
return isMember(entity: entityId, inFamilyWithTraits: family) isMember(entity: entityId, inFamilyWithTraits: family)
} }
public func isMember(entity entityId: EntityIdentifier, inFamilyWithTraits traits: FamilyTraitSet) -> Bool { public func isMember(entity entityId: EntityIdentifier, inFamilyWithTraits traits: FamilyTraitSet) -> Bool {
return members(withFamilyTraits: traits).contains(entityId.id) members(withFamilyTraits: traits).contains(entityId.id)
} }
} }

View File

@ -22,7 +22,7 @@ extension Nexus {
} }
public final func removeChild(_ child: Entity, from parent: Entity) -> Bool { public final func removeChild(_ child: Entity, from parent: Entity) -> Bool {
return removeChild(child.identifier, from: parent.identifier) removeChild(child.identifier, from: parent.identifier)
} }
@discardableResult @discardableResult
@ -44,6 +44,6 @@ extension Nexus {
} }
public final func numChildren(for entity: Entity) -> Int { public final func numChildren(for entity: Entity) -> Int {
return childrenByParentEntity[entity.identifier]?.count ?? 0 childrenByParentEntity[entity.identifier]?.count ?? 0
} }
} }

View File

@ -39,13 +39,13 @@ extension Single: Equatable {
extension Single where A: SingleComponent { extension Single where A: SingleComponent {
@inlinable public var component: A { @inlinable public var component: A {
/// Since we guarantee that the component will always be present by managing the complete lifecycle of the entity // Since we guarantee that the component will always be present by managing the complete lifecycle of the entity
/// and component assignment we may unsafelyUnwrap here. // and component assignment we may unsafelyUnwrap here.
/// Since components will allways be of reference type (class) we may use unsafeDowncast here for performance reasons. // Since components will allways be of reference type (class) we may use unsafeDowncast here for performance reasons.
return nexus.get(unsafeComponentFor: entityId) return nexus.get(unsafeComponentFor: entityId)
} }
public var entity: Entity { public var entity: Entity {
return nexus.get(entity: entityId).unsafelyUnwrapped nexus.get(entity: entityId).unsafelyUnwrapped
} }
} }

View File

@ -26,12 +26,12 @@ public struct UnorderedSparseSet<Element> {
self.dense = dense self.dense = dense
} }
public var count: Int { return dense.count } public var count: Int { dense.count }
public var isEmpty: Bool { return dense.isEmpty } public var isEmpty: Bool { dense.isEmpty }
@inlinable @inlinable
public func contains(_ key: Key) -> Bool { public func contains(_ key: Key) -> Bool {
return find(at: key) != nil find(at: key) != nil
} }
/// Inset an element for a given key into the set in O(1). /// Inset an element for a given key into the set in O(1).
@ -69,7 +69,7 @@ public struct UnorderedSparseSet<Element> {
@inlinable @inlinable
public func get(unsafeAt key: Key) -> Element { public func get(unsafeAt key: Key) -> Element {
return find(at: key).unsafelyUnwrapped.1 find(at: key).unsafelyUnwrapped.1
} }
/// Removes the element entry for given key in O(1). /// Removes the element entry for given key in O(1).
@ -123,7 +123,7 @@ public struct UnorderedSparseSet<Element> {
@inlinable @inlinable
public subscript(position: Index) -> Element { public subscript(position: Index) -> Element {
get { get {
return get(unsafeAt: position) get(unsafeAt: position)
} }
set(newValue) { set(newValue) {
@ -132,18 +132,18 @@ public struct UnorderedSparseSet<Element> {
} }
@inlinable public var first: Element? { @inlinable public var first: Element? {
return dense.first?.element dense.first?.element
} }
@inlinable public var last: Element? { @inlinable public var last: Element? {
return dense.last?.element dense.last?.element
} }
} }
// MARK: - Sequence // MARK: - Sequence
extension UnorderedSparseSet: Sequence { extension UnorderedSparseSet: Sequence {
public __consuming func makeIterator() -> ElementIterator { public __consuming func makeIterator() -> ElementIterator {
return ElementIterator(self) ElementIterator(self)
} }
// MARK: - UnorderedSparseSetIterator // MARK: - UnorderedSparseSetIterator
@ -155,7 +155,7 @@ extension UnorderedSparseSet: Sequence {
} }
public mutating func next() -> Element? { public mutating func next() -> Element? {
return iterator.next()?.element iterator.next()?.element
} }
} }
} }
@ -164,7 +164,7 @@ extension UnorderedSparseSet: Sequence {
extension UnorderedSparseSet.Entry: Equatable where Element: Equatable { } extension UnorderedSparseSet.Entry: Equatable where Element: Equatable { }
extension UnorderedSparseSet: Equatable where Element: Equatable { extension UnorderedSparseSet: Equatable where Element: Equatable {
public static func == (lhs: UnorderedSparseSet<Element>, rhs: UnorderedSparseSet<Element>) -> Bool { public static func == (lhs: UnorderedSparseSet<Element>, rhs: UnorderedSparseSet<Element>) -> Bool {
return lhs.dense == rhs.dense && lhs.sparse == rhs.sparse lhs.dense == rhs.dense && lhs.sparse == rhs.sparse
} }
} }