diff --git a/Sources/FirebladeECS/Entity.swift b/Sources/FirebladeECS/Entity.swift index 99fe8a1..dec663d 100644 --- a/Sources/FirebladeECS/Entity.swift +++ b/Sources/FirebladeECS/Entity.swift @@ -10,7 +10,7 @@ public final class Entity: UniqueEntityIdentifiable { fileprivate var eventDispatcher: EventDispatcher - fileprivate var componentMap: [UCT:Component] + public private(set) var componentMap: [UCT:Component] init(uei: UEI, dispatcher: EventDispatcher) { self.uei = uei @@ -109,7 +109,6 @@ public extension Entity { } } - // MARK: - remove component(s) public extension Entity { @@ -212,8 +211,8 @@ extension Entity: EventDispatcher { private func notifyDestoryed() { //unowned { - //$0.dispatch(event: EntityDestroyed(entity: $0)) - //TODO: here entity is already dead + //$0.dispatch(event: EntityDestroyed(entity: $0)) + //TODO: here entity is already dead //} } @@ -239,3 +238,85 @@ extension Entity: CustomPlaygroundQuickLookable { return .text(self.description) } } + +// MARK: - component tuple access +public extension Entity { + + public func component(_: A.Type) -> A { + guard let a: A = componentMap[A.uct] as? A else { + fatalError("Component Mapping Error: '\(A.self)' component was not found in entity '\(self)'") + } + return a + + } + public func components(_: A.Type, _: B.Type) -> (A, B) { + let a: A = component(A.self) + let b: B = component(B.self) + return (a, b) + } + public func components(_: A.Type, _: B.Type, _: C.Type) -> (A, B, C) { + let a: A = component(A.self) + let b: B = component(B.self) + let c: C = component(C.self) + return (a, b, c) + } + public func components(_: A.Type, _: B.Type, _: C.Type, _: D.Type) -> (A, B, C, D) { + let a: A = component(A.self) + let b: B = component(B.self) + let c: C = component(C.self) + let d: D = component(D.self) + return (a, b, c, d) + } + public func components(_: A.Type, _: B.Type, _: C.Type, _: D.Type, _: E.Type) -> (A, B, C, D, E) { + let a: A = component(A.self) + let b: B = component(B.self) + let c: C = component(C.self) + let d: D = component(D.self) + let e: E = component(E.self) + return (a, b, c, d, e) + } + public func components(_: A.Type, _: B.Type, _: C.Type, _: D.Type, _: E.Type, _: F.Type) -> (A, B, C, D, E, F) { + let a: A = component(A.self) + let b: B = component(B.self) + let c: C = component(C.self) + let d: D = component(D.self) + let e: E = component(E.self) + let f: F = component(F.self) + return (a, b, c, d, e, f) + } +} + +// MARK: - component closure access +public extension Entity { + + public func component(_ closure: (A) -> R) -> R { return closure(component(A.self)) } + public func components(_ closure: (A, B) -> R) -> R { + return closure(component(A.self), component(B.self)) + } + public func components(_ closure: (A, B, C) -> R) -> R { + return closure(component(A.self), component(B.self), component(C.self)) + } + public func components(_ closure: (A, B, C, D) -> R) -> R { + return closure(component(A.self), + component(B.self), + component(C.self), + component(D.self)) + } + + public func components(_ closure: (A, B, C, D, E) -> R) -> R { + return closure(component(A.self), + component(B.self), + component(C.self), + component(D.self), + component(E.self)) + } + + public func components(_ closure: (A, B, C, D, E, F) -> R) -> R { + return closure(component(A.self), + component(B.self), + component(C.self), + component(D.self), + component(E.self), + component(F.self) ) + } +} diff --git a/Sources/FirebladeECS/Family.swift b/Sources/FirebladeECS/Family.swift index 2342a18..7634368 100644 --- a/Sources/FirebladeECS/Family.swift +++ b/Sources/FirebladeECS/Family.swift @@ -90,6 +90,25 @@ extension Family { } } +// MARK: - Iterator +extension Family { + + func forEach(_ body: (Entity) -> Void ) { + members.forEach(body) + } + + func reduce(_ initialResult: Result, _ nextPartialResult: (Result, Entity) throws -> Result) rethrows -> Result { + return try members.reduce(initialResult, nextPartialResult) + } + + func zip(_ componentTypes: Component.Type) { + + let a = members.map { $0.componentMap.values } + + } + +} + // MARK: - Equatable extension Family: Equatable { public static func ==(lhs: Family, rhs: Family) -> Bool { diff --git a/Tests/FirebladeECSTests/Base.swift b/Tests/FirebladeECSTests/Base.swift index acc7108..1c841a4 100644 --- a/Tests/FirebladeECSTests/Base.swift +++ b/Tests/FirebladeECSTests/Base.swift @@ -9,6 +9,10 @@ import FirebladeECS struct EmptyComponent: Component { } +struct Name: Component { + let name: String +} + class DebugEventHandler: EventHandler { let eventHub = DefaultEventHub() diff --git a/Tests/FirebladeECSTests/FamilyTests.swift b/Tests/FirebladeECSTests/FamilyTests.swift index e30ca0f..040e5bf 100644 --- a/Tests/FirebladeECSTests/FamilyTests.swift +++ b/Tests/FirebladeECSTests/FamilyTests.swift @@ -18,10 +18,17 @@ class FamilyTests: XCTestCase { e1 += EmptyComponent() let e2 = entityHub.createEntity() e2 += EmptyComponent() + e1 += Name(name: "Sarah") + + let (empty, name) = e1.components(EmptyComponent.self, Name.self) + + e1.components { (empty: EmptyComponent, name: Name) in + print(empty, name) + } let traits = FamilyTraits(hasAll: [EmptyComponent.uct], hasAny: [], hasNone: []) - let (new, _) = entityHub.family(with: traits) + let (new, family) = entityHub.family(with: traits) XCTAssert(new == true) let (new2, _) = entityHub.family(with: traits)