From 41745a1fa761f73b6ffefff93fe1865e2277c1dd Mon Sep 17 00:00:00 2001 From: Christian Treffs Date: Sat, 21 Oct 2017 23:12:13 +0200 Subject: [PATCH] Cleanups --- Sources/FirebladeECS/Entity.swift | 82 ------------------ Sources/FirebladeECS/EventHandling.swift | 76 ----------------- Sources/FirebladeECS/EventHub.swift | 80 ----------------- Sources/FirebladeECS/Events.swift | 2 +- Sources/FirebladeECS/Family+Members.swift | 3 +- Sources/FirebladeECS/Family.swift | 99 +--------------------- Sources/FirebladeECS/FamilyTraitSet.swift | 41 --------- Sources/FirebladeECS/Logging.swift | 49 ----------- Sources/FirebladeECS/Nexus+Component.swift | 12 ++- Sources/FirebladeECS/Nexus+Family.swift | 36 +++++--- Sources/FirebladeECS/Nexus.swift | 24 +----- Sources/FirebladeECS/System.swift | 16 ---- Sources/FirebladeECS/UET.swift | 41 --------- Tests/FirebladeECSTests/FamilyTests.swift | 13 +-- 14 files changed, 44 insertions(+), 530 deletions(-) delete mode 100644 Sources/FirebladeECS/EventHandling.swift delete mode 100644 Sources/FirebladeECS/EventHub.swift delete mode 100644 Sources/FirebladeECS/Logging.swift delete mode 100644 Sources/FirebladeECS/System.swift delete mode 100644 Sources/FirebladeECS/UET.swift diff --git a/Sources/FirebladeECS/Entity.swift b/Sources/FirebladeECS/Entity.swift index 4822215..982403f 100644 --- a/Sources/FirebladeECS/Entity.swift +++ b/Sources/FirebladeECS/Entity.swift @@ -194,85 +194,3 @@ public extension Entity { return (a, b, c, d, e, f) } } - -/* - -extension Entity: EventDispatcher { - public func dispatch(_ event: E) where E: Event { - eventDispatcher.dispatch(event) - } - - fileprivate func unowned(_ closure: @escaping (Entity) -> Void) { - #if DEBUG - let preActionCount: Int = retainCount(self) - #endif - let unownedClosure = { [unowned self] in - closure(self) - } - unownedClosure() - #if DEBUG - let postActionCount: Int = retainCount(self) - assert(postActionCount == preActionCount, "retain count missmatch [\(preActionCount)] -> [\(postActionCount)]") - #endif - } - - private func notifyInit() { - unowned { - $0.dispatch(EntityCreated(entity: $0)) - } - } - - private func notify(add component: C) { - unowned { - $0.dispatch(ComponentAdded(to: $0)) - } - } - - private func notify(update newComponent: C, previous previousComponent: C) { - unowned { - $0.dispatch(ComponentUpdated(at: $0)) - } - } - - private func notify(removed component: C) { - unowned { - $0.dispatch(ComponentRemoved(from: $0)) - } - } - - private func notify(removed component) { - //unowned { /* this keeps a reference since we need it */ - dispatch(ComponentRemoved(from: self)) - //} - } - - private func notifyDestoryed() { - //unowned { - //$0.dispatch(event: EntityDestroyed(entity: $0)) - //TODO: here entity is already dead - //} - } - -} - -// MARK: - debugging and string representation - -extension Entity: CustomStringConvertible { - - fileprivate var componentsString: String { - let compTypes: [String] = componentMap.map { String(describing: $0.value.uct.type) } - return compTypes.joined(separator: ",") - } - - public var description: String { - return "Entity[\(uei)][\(numComponents):\(componentsString)]" - } - -} - -extension Entity: CustomPlaygroundQuickLookable { - public var customPlaygroundQuickLook: PlaygroundQuickLook { - return .text(self.description) - } -} -*/ diff --git a/Sources/FirebladeECS/EventHandling.swift b/Sources/FirebladeECS/EventHandling.swift deleted file mode 100644 index 1baac8c..0000000 --- a/Sources/FirebladeECS/EventHandling.swift +++ /dev/null @@ -1,76 +0,0 @@ -// -// EventHandling.swift -// FirebladeECS -// -// Created by Christian Treffs on 08.10.17. -// - -// MARK: - event -public protocol Event: UniqueEventIdentifiable { } -public extension Event { - static var uet: UET { return UET(Self.self) } - var uet: UET { return Self.uet } -} - -// MARK: - event handler -public struct EventHandlerRef { - unowned var eventHandlerClassRefUnowned: EventHandler - let eventHandler: (Event) -> Void -} - -public protocol EventHandler: class { - func subscribe(event eventHandler: @escaping (E) -> Void) - func unsubscribe(event eventHandler: @escaping (E) -> Void) - - weak var delegate: EventHub? { get set } -} - -public extension EventHandler { - - fileprivate func unowned(_ closure: @escaping (EventHandler) -> Void) { - #if DEBUG - let preActionCount: Int = retainCount(self) - #endif - let unownedClosure = { [unowned self] in - closure(self) - } - unownedClosure() - #if DEBUG - let postActionCount: Int = retainCount(self) - assert(postActionCount == preActionCount, "retain count missmatch [\(preActionCount)] -> [\(postActionCount)]") - #endif - } - - /// Subscribe with an event handler closure to receive events of type T - /// - /// - Parameter eventHandler: event handler closure - public func subscribe(event eventHandler: @escaping (E) -> Void) { - unowned { - self.delegate?.subscribe(classRef: $0, eventHandler: eventHandler) - } - } - - /// Unsubscribe from an event handler closure to stop receiving events of type T - /// - /// - Parameter eventHandler: event handler closure - public func unsubscribe(event eventHandler: @escaping (E) -> Void) { - unowned { - self.delegate?.unsubscribe(classRef: $0, eventHandler: eventHandler) - } - } - -} - -public extension ContiguousArray where Element == EventHandlerRef { - public func index(is eventHandler: EventHandler) -> Int? { // FIXME: this my be costly - return index { (eventHandlerRef: EventHandlerRef) -> Bool in - return eventHandlerRef.eventHandlerClassRefUnowned === eventHandler - } - } - -} - -// MARK: - event dispatcher -public protocol EventDispatcher: class { - func dispatch(_ event: E) -} diff --git a/Sources/FirebladeECS/EventHub.swift b/Sources/FirebladeECS/EventHub.swift deleted file mode 100644 index 9b3d71b..0000000 --- a/Sources/FirebladeECS/EventHub.swift +++ /dev/null @@ -1,80 +0,0 @@ -// -// EventHub.swift -// FirebladeECS -// -// Created by Christian Treffs on 09.10.17. -// - -public protocol EventHub: class { - func subscribe(classRef eventHandlerRefUnowned: EventHandler, eventHandler: @escaping (E) -> Void) - func unsubscribe(classRef eventHandlerRefUnowned: EventHandler, eventHandler: @escaping (E) -> Void) - - weak var sniffer: EventSniffer? { get set } -} - -public class DefaultEventHub: EventHub, EventDispatcher { - - public var sniffer: EventSniffer? - - public init() { } - - private var listeners: [UET: ContiguousArray] = [:] - - private func typeEvent(opaqueEvent: Event, eventHandler: @escaping (E) -> Void ) { - guard let typedEvent: E = opaqueEvent as? E else { - fatalError() // TODO: meaningful message - } - eventHandler(typedEvent) - } - - private func push(listener newListener: EventHandlerRef, `for` uet: UET) { - if listeners[uet] == nil { - listeners[uet] = [] - listeners.reserveCapacity(1) - } - listeners[uet]?.append(newListener) - } -} - -// MARK: - event center -extension DefaultEventHub { - - final public func subscribe(classRef unownedListenerRef: EventHandler, eventHandler handler: @escaping (E) -> Void) { - let eventListener: EventHandlerRef = EventHandlerRef(eventHandlerClassRefUnowned: unownedListenerRef, - eventHandler: { self.typeEvent(opaqueEvent: $0, eventHandler: handler) }) - - push(listener: eventListener, for: E.uet) - sniffer?.subscriber(subsribed: E.uet) - } - - final public func unsubscribe(classRef listenerRef: EventHandler, eventHandler handler: @escaping (E) -> Void) { - let uet: UET = E.uet - - if let removeIdx: Int = listeners[uet]?.index(is: listenerRef) { - let removed = listeners[uet]?.remove(at: removeIdx) - assert(removed != nil) - sniffer?.subscriber(unsubsribed: uet) - } - - } - -} - -// MARK: - event dispatcher delegate -extension DefaultEventHub { - final public func dispatch(_ event: E) { - let uet: UET = E.uet - listeners[uet]?.forEach { - $0.eventHandler(event) - } - sniffer?.dispatched(event: event) - } - -} - -// MARK: - event dumper -public protocol EventSniffer: class { - func subscriber(subsribed to: UET) - func subscriber(unsubsribed from: UET) - func dispatched(event: E) -} diff --git a/Sources/FirebladeECS/Events.swift b/Sources/FirebladeECS/Events.swift index 50e090d..db9e935 100644 --- a/Sources/FirebladeECS/Events.swift +++ b/Sources/FirebladeECS/Events.swift @@ -4,7 +4,7 @@ // // Created by Christian Treffs on 08.10.17. // - +protocol Event { } public struct EntityCreated: Event { let entityId: EntityIdentifier } diff --git a/Sources/FirebladeECS/Family+Members.swift b/Sources/FirebladeECS/Family+Members.swift index a31ca49..d5d7d87 100644 --- a/Sources/FirebladeECS/Family+Members.swift +++ b/Sources/FirebladeECS/Family+Members.swift @@ -130,7 +130,8 @@ extension Family { } } - public func iterate(_ apply: @escaping (() -> Entity, () -> A?, () -> B?, () -> C?, () -> D?, () -> E?, () -> F?) -> Void) where A: Component, B: Component, C: Component, D: Component, E: Component, F: Component { + public func iterate(_ apply: @escaping (() -> Entity, () -> A?, () -> B?, () -> C?, () -> D?, () -> E?, () -> F?) -> Void) + where A: Component, B: Component, C: Component, D: Component, E: Component, F: Component { iterateMembers { (entityId, getEntityInstance) in func getComponent() -> Z? where Z: Component { return self.nexus.get(component: Z.identifier, for: entityId) as? Z diff --git a/Sources/FirebladeECS/Family.swift b/Sources/FirebladeECS/Family.swift index 0ffde41..e473dc8 100644 --- a/Sources/FirebladeECS/Family.swift +++ b/Sources/FirebladeECS/Family.swift @@ -30,6 +30,10 @@ extension Family { return nexus.isMember(entity, in: self) } + public final func isMember(_ entityId: EntityIdentifier) -> Bool { + return nexus.isMember(entityId, in: self) + } + internal var members: LazyMapCollection>, Entity> { return nexus.members(of: self) } @@ -37,98 +41,3 @@ extension Family { return nexus.members(of: self) } } - -// MARK: - member iterator -extension Family { - /* - func makeIterator() -> AnyIterator<(Entity, A)> where A: Component { - var members = self.members.makeIterator() - return AnyIterator<(Entity, A)> { [unowned self] in - let entityId: EntityIdentifier = members.next()! - let entity: Entity = self.nexus.get(entity: entityId)! - let a: A = entity.get()! - return (entity, a) - } - } - - func makeIterator() -> AnyIterator<(Entity, A, B)> where A: Component, B: Component { - var members = self.members.makeIterator() - return AnyIterator<(Entity, A, B)> { [unowned self] in - let entityId: EntityIdentifier = members.next()! - let entity: Entity = self.nexus.get(entity: entityId)! - let a: A = entity.get()! - let b: B = entity.get()! - return (entity, a, b) - } - } - - func makeIterator() -> AnyIterator<(Entity, A, B, C)> where A: Component, B: Component, C: Component { - var members = self.members.makeIterator() - return AnyIterator<(Entity, A, B, C)> { [unowned self] in - let entityId: EntityIdentifier = members.next()! - let entity: Entity = self.nexus.get(entity: entityId)! - let a: A = entity.get()! - let b: B = entity.get()! - let c: C = entity.get()! - return (entity, a, b, c) - } - } - */ -} - -/* -// MARK: - Equatable -extension Family: Equatable { - public static func ==(lhs: Family, rhs: Family) -> Bool { - return lhs.traits == rhs.traits - } -} - -// MARK: - Hashable -extension Family: Hashable { - public var hashValue: Int { - return traits.hashValue - } -} -*/ -/* -// MARK: - event dispatcher -extension Family: EventDispatcher { - public func dispatch(_ event: E) where E: Event { - dispatcher.dispatch(event) - } - - fileprivate func notifyCreated() { - dispatch(FamilyCreated(family: traits)) - } - - fileprivate func notify(added newEntity: EntityIdentifier) { - dispatch(FamilyMemberAdded(member: newEntity, to: traits)) - } - - fileprivate func notify(removed removedEntity: EntityIdentifier) { - dispatch(FamilyMemberRemoved(member: removedEntity, from: traits)) - } - - fileprivate func notifyDestroyed() { - dispatch(FamilyDestroyed(family: traits)) - } -} - -// MARK: - event handler -extension Family: EventHandler { - - fileprivate final func handleComponentAddedToEntity(event: ComponentAdded) { - update(membership: event.to) - } - - fileprivate final func handleComponentUpdatedAtEntity(event: ComponentUpdated) { - update(membership: event.at) - } - - fileprivate final func handleComponentRemovedFromEntity(event: ComponentRemoved) { - update(membership: event.from) - } - -} -*/ diff --git a/Sources/FirebladeECS/FamilyTraitSet.swift b/Sources/FirebladeECS/FamilyTraitSet.swift index 0b939de..1fedbcf 100644 --- a/Sources/FirebladeECS/FamilyTraitSet.swift +++ b/Sources/FirebladeECS/FamilyTraitSet.swift @@ -70,47 +70,6 @@ extension FamilyTraitSet { } -extension FamilyTraitSet { - - /*/// needs to have all of the given components - fileprivate func matches(all entity: Entity) -> Bool { - var all = requiresAll - while let compId: ComponentIdentifier = all.next() { - guard entity.has(compId) else { return false } - } - return true - } - - /// needs to have none of the given (excluded) components - fileprivate func matches(none entity: Entity) -> Bool { - var none = excludesAll - while let compId: ComponentIdentifier = none.next() { - guard !entity.has(compId) else { return false } - } - return true - } - - /// needs to have at lease one of the given components - fileprivate func matches(any entity: Entity) -> Bool { - guard !isEmptyAny else { return true } - var any = needsAtLeastOne - while let compId: ComponentIdentifier = any.next() { - if entity.has(compId) { - return true - } - } - return false - } - - func isMatch(_ entity: Entity) -> Bool { - guard matches(all: entity) else { return false } - guard matches(none: entity) else { return false } - guard matches(any: entity) else { return false } - return true - }*/ - -} - // MARK: - Equatable extension FamilyTraitSet: Equatable { public static func ==(lhs: FamilyTraitSet, rhs: FamilyTraitSet) -> Bool { diff --git a/Sources/FirebladeECS/Logging.swift b/Sources/FirebladeECS/Logging.swift deleted file mode 100644 index c8e4fdd..0000000 --- a/Sources/FirebladeECS/Logging.swift +++ /dev/null @@ -1,49 +0,0 @@ -// -// Logging.swift -// FirebladeECS -// -// Created by Christian Treffs on 08.10.17. -// - -struct Log { - - private init() { } - - enum Level { - case info, debug, warn, error - - var toString: String { - switch self { - case .info: return "INFO" - case .debug: return "DEBUG" - case .warn: return "WARN" - case .error: return "ERROR" - } - } - } - - static func info(_ args: Any?...) { Log.log(level: .info, args: args) } - static func debug(_ args: Any?...) { Log.log(level: .debug, args: args) } - static func warn(_ args: Any?...) { Log.log(level: .warn, args: args) } - static func error(_ args: Any?...) { Log.log(level: .error, args: args) } - - private static func log(level: Log.Level, args: [Any?]) { - let entry: String = Log.serialize(level: level, args: args) - Swift.print(entry) - } - - private static func serialize(level: Log.Level, args: [Any?]) -> String { - let argStrings: [String] = args.flatMap { arg in - if let arg = arg { - return String(describing: arg) - } - return nil - } - - let argString: String = argStrings.joined(separator: " ") - let levelString: String = level.toString - - return ["[", levelString, "]\t", argString].joined() - } - -} diff --git a/Sources/FirebladeECS/Nexus+Component.swift b/Sources/FirebladeECS/Nexus+Component.swift index 481d51f..1a68abd 100644 --- a/Sources/FirebladeECS/Nexus+Component.swift +++ b/Sources/FirebladeECS/Nexus+Component.swift @@ -59,6 +59,12 @@ extension Nexus { // assign entity / component to index componentIndexByEntityComponentHash[hash] = newComponentIndex + // FIXME: this is costly for many families + let entityId: EntityIdentifier = entity.identifier + familiyByTraitHash.forEach { (_, family) in + update(membership: family, for: entityId) + } + notify(ComponentAdded(component: componentId, to: entity.identifier)) } @@ -79,7 +85,6 @@ extension Nexus { } fileprivate func get(_ hash: EntityComponentHash) -> C? where C: Component { - Log.info("GETTING: \(C.self)") let componentId: ComponentIdentifier = C.identifier guard let componentIdx: ComponentIndex = componentIndexByEntityComponentHash[hash] else { return nil } guard let uniformComponents: UniformComponents = componentsByType[componentId] else { return nil } @@ -136,6 +141,11 @@ extension Nexus { } } + // FIXME: this is costly for many families + familiyByTraitHash.forEach { (_, family) in + update(membership: family, for: entityId) + } + notify(ComponentRemoved(component: componentId, from: entityId)) return true } diff --git a/Sources/FirebladeECS/Nexus+Family.swift b/Sources/FirebladeECS/Nexus+Family.swift index fdbd5b2..cb1c79f 100644 --- a/Sources/FirebladeECS/Nexus+Family.swift +++ b/Sources/FirebladeECS/Nexus+Family.swift @@ -43,8 +43,12 @@ extension Nexus { } public func isMember(_ entity: Entity, in family: Family) -> Bool { + return isMember(entity.identifier, in: family) + } + + public func isMember(_ entityId: EntityIdentifier, in family: Family) -> Bool { let traitHash: FamilyTraitSetHash = family.traits.hashValue - let entityId = entity.identifier + // FIXME: this may be costly for many entities in family return familyMembersByTraitHash[traitHash]?.contains(entityId) ?? false } @@ -58,8 +62,13 @@ extension Nexus { let family = Family(self, traits: traits) let replaced = familiyByTraitHash.updateValue(family, forKey: traitHash) assert(replaced == nil, "Family with exact trait hash already exists: \(traitHash)") + + // FIXME: this is costly for many entities + entities.forEach { + update(membership: family, for: $0.identifier) + } + notify(FamilyCreated(family: traits)) - // FIXME: update memberships for prior entites return family } @@ -67,21 +76,23 @@ extension Nexus { // MARK: - update family membership - func update(membership family: Family, for entity: Entity) { - let entityIdx: EntityIndex = entity.identifier.index + func update(membership family: Family, for entityId: EntityIdentifier) { + let entityIdx: EntityIndex = entityId.index guard let componentsSet: ComponentSet = componentIdsSetByEntity[entityIdx] else { return } + let isMember: Bool = family.isMember(entityId) let isMatch: Bool = family.traits.isMatch(components: componentsSet) - switch isMatch { - case true: - add(to: family, entity: entity) - case false: - remove(from: family, entity: entity) + switch (isMatch, isMember) { + case (true, false): + add(to: family, entityId: entityId) + case (false, true): + remove(from: family, entityId: entityId) + default: + break } } - fileprivate func add(to family: Family, entity: Entity) { + fileprivate func add(to family: Family, entityId: EntityIdentifier) { let traitHash: FamilyTraitSetHash = family.traits.hashValue - let entityId: EntityIdentifier = entity.identifier if familyMembersByTraitHash[traitHash] != nil { let (inserted, _) = familyMembersByTraitHash[traitHash]!.insert(entityId) assert(inserted, "entity with id \(entityId) already in family") @@ -93,9 +104,8 @@ extension Nexus { notify(FamilyMemberAdded(member: entityId, to: family.traits)) } - fileprivate func remove(from family: Family, entity: Entity) { + fileprivate func remove(from family: Family, entityId: EntityIdentifier) { let traitHash: FamilyTraitSetHash = family.traits.hashValue - let entityId: EntityIdentifier = entity.identifier guard let removed = familyMembersByTraitHash[traitHash]?.remove(entityId) else { assert(false, "removing entity id \(entityId) that is not in family \(family)") diff --git a/Sources/FirebladeECS/Nexus.swift b/Sources/FirebladeECS/Nexus.swift index 3dd81f7..3f0c084 100644 --- a/Sources/FirebladeECS/Nexus.swift +++ b/Sources/FirebladeECS/Nexus.swift @@ -69,32 +69,10 @@ extension Nexus { func notify(_ event: Event) { //Log.debug(event) // TODO: implement + } func report(_ message: String) { - Log.warn(message) // TODO: implement } } - -/* -// MARK: - event handler -extension Nexus { - func handleEntityCreated(_ e: EntityCreated) { print(e) } - func handleEntityDestroyed(_ e: EntityDestroyed) { print(e) } - - func handleComponentAdded(_ e: ComponentAdded) { print(e) } - func handleComponentUpdated(_ e: ComponentUpdated) { print(e) } - func handleComponentRemoved(_ e: ComponentRemoved) { print(e) } - - func handleFamilyCreated(_ e: FamilyCreated) { - print(e) - let newFamily: Family = e.family - onFamilyCreated(newFamily) - - } - func handleFamilyMemberAdded(_ e: FamilyMemberAdded) { print(e) } - func handleFamilyMemberRemoved(_ e: FamilyMemberRemoved) { print(e) } - func handleFamilyDestroyed(_ e: FamilyDestroyed) { print(e) } -} -*/ diff --git a/Sources/FirebladeECS/System.swift b/Sources/FirebladeECS/System.swift deleted file mode 100644 index b79b9e0..0000000 --- a/Sources/FirebladeECS/System.swift +++ /dev/null @@ -1,16 +0,0 @@ -// -// System.swift -// FirebladeECS -// -// Created by Christian Treffs on 08.10.17. -// - -public enum SystemState { - case running, paused, inactive -} - -public protocol System: class { - //var state: SystemState { set get } - func startup() - func shutdown() -} diff --git a/Sources/FirebladeECS/UET.swift b/Sources/FirebladeECS/UET.swift deleted file mode 100644 index ac360c7..0000000 --- a/Sources/FirebladeECS/UET.swift +++ /dev/null @@ -1,41 +0,0 @@ -// -// UET.swift -// FirebladeECS -// -// Created by Christian Treffs on 09.10.17. -// - -// MARK: Unique Event Type -/// Unique Event Type -public struct UET { - let objectIdentifier: ObjectIdentifier - let type: Event.Type - - init(_ eventType: Event.Type) { - objectIdentifier = ObjectIdentifier(eventType) - type = eventType - } - - init(_ event: Event) { - let eventType: Event.Type = event.uet.type - self.init(eventType) - } -} - -extension UET: Equatable { - public static func ==(lhs: UET, rhs: UET) -> Bool { - return lhs.objectIdentifier == rhs.objectIdentifier - } -} - -extension UET: Hashable { - public var hashValue: Int { - return objectIdentifier.hashValue - } -} - -// MARK: Unique Event Identifiable -public protocol UniqueEventIdentifiable { - static var uet: UET { get } - var uet: UET { get } -} diff --git a/Tests/FirebladeECSTests/FamilyTests.swift b/Tests/FirebladeECSTests/FamilyTests.swift index d8853c8..d757335 100644 --- a/Tests/FirebladeECSTests/FamilyTests.swift +++ b/Tests/FirebladeECSTests/FamilyTests.swift @@ -67,14 +67,11 @@ class FamilyTests: XCTestCase { let nexus = Nexus() - let a = nexus.create(entity: "a").assign(Position(x: 1, y: 2), Name(name: "myName"), Velocity(a: 3.14), EmptyComponent()) - let b = nexus.create(entity: "b").assign(Position(x: 3, y: 4), Velocity(a: 5.23), EmptyComponent()) + nexus.create(entity: "a").assign(Position(x: 1, y: 2), Name(name: "myName"), Velocity(a: 3.14), EmptyComponent()) + nexus.create(entity: "b").assign(Position(x: 3, y: 4), Velocity(a: 5.23), EmptyComponent()) let family = nexus.family(requiresAll: [Position.self, Velocity.self], excludesAll: [Party.self], needsAtLeastOne: [Name.self, EmptyComponent.self]) - nexus.update(membership: family, for: a) - nexus.update(membership: family, for: b) - var index: Int = 0 family.iterate { (e: () -> Entity, p: () -> Position!, v: () -> Velocity!, n: () -> Name?) in @@ -122,8 +119,6 @@ class FamilyTests: XCTestCase { let family = nexus.family(requiresAll: [Position.self, Velocity.self], excludesAll: [Party.self], needsAtLeastOne: [Name.self, EmptyComponent.self]) - nexus.entities.forEach { nexus.update(membership: family, for: $0) } - XCTAssert(family.members.count == number) XCTAssert(family.memberIds.count == number) XCTAssert(nexus.entities.count == number) @@ -152,8 +147,6 @@ class FamilyTests: XCTestCase { let family = nexus.family(requiresAll: [Position.self, Velocity.self], excludesAll: [Party.self], needsAtLeastOne: [Name.self, EmptyComponent.self]) - nexus.entities.forEach { nexus.update(membership: family, for: $0) } - XCTAssert(family.members.count == number) XCTAssert(family.memberIds.count == number) XCTAssert(nexus.entities.count == number) @@ -182,8 +175,6 @@ class FamilyTests: XCTestCase { let family = nexus.family(requiresAll: [Position.self, Velocity.self], excludesAll: [Party.self], needsAtLeastOne: [Name.self, EmptyComponent.self]) - nexus.entities.forEach { nexus.update(membership: family, for: $0) } - measure { family.memberIds.forEach { (e) in _ = e