diff --git a/Sources/FirebladeECS/Entity.swift b/Sources/FirebladeECS/Entity.swift index 7d68fa4..02fbb6e 100644 --- a/Sources/FirebladeECS/Entity.swift +++ b/Sources/FirebladeECS/Entity.swift @@ -101,6 +101,12 @@ public struct Entity { public func destroy() { nexus.destroy(entity: self) } + + public func addChild(_ entity: Entity) { + } + + public func removeChild(_ entity: Entity) { + } } // MARK: - Equatable diff --git a/Sources/FirebladeECS/Family.swift b/Sources/FirebladeECS/Family.swift index 8d19398..e162492 100644 --- a/Sources/FirebladeECS/Family.swift +++ b/Sources/FirebladeECS/Family.swift @@ -40,6 +40,14 @@ public struct Family where R: FamilyRequirementsManaging { } } +// MARK: - Equatable +extension Family: Equatable { + public static func == (lhs: Family, rhs: Family) -> Bool { + return lhs.nexus == rhs.nexus && + lhs.traits == rhs.traits + } +} + extension Family: Sequence { __consuming public func makeIterator() -> ComponentsIterator { return ComponentsIterator(family: self) @@ -123,10 +131,30 @@ extension Family { extension Family.EntityComponentIterator: LazySequenceProtocol { } -// MARK: - Equatable -extension Family: Equatable { - public static func == (lhs: Family, rhs: Family) -> Bool { - return lhs.nexus == rhs.nexus && - lhs.traits == rhs.traits +// MARK: - relatives iterator + +extension Family { + @inlinable public var descendRelatives: RelativesIterator { + return RelativesIterator(family: self) + } + + public struct RelativesIterator: IteratorProtocol { + @usableFromInline var memberIdsIterator: UnorderedSparseSetIterator + @usableFromInline unowned let nexus: Nexus + + public init(family: Family) { + self.nexus = family.nexus + memberIdsIterator = family.memberIds.makeIterator() + } + + public mutating func next() -> R.RelativesDescending? { + guard let parentId = memberIdsIterator.next() else { + return nil + } + + fatalError("implement") + } } } + +extension Family.RelativesIterator: LazySequenceProtocol { } diff --git a/Sources/FirebladeECS/Family1.swift b/Sources/FirebladeECS/Family1.swift index 7af446a..8e0f42c 100644 --- a/Sources/FirebladeECS/Family1.swift +++ b/Sources/FirebladeECS/Family1.swift @@ -24,6 +24,12 @@ public struct Requires1: FamilyRequirementsManaging where A: Component { let compA: A = nexus.get(unsafeComponentFor: entityId) return (entity, compA) } + + public static func relativesDescending(nexus: Nexus, parentId: EntityIdentifier, childId: EntityIdentifier) -> (parent: A, child: A) { + let parentCompA: A = nexus.get(unsafeComponentFor: parentId) + let childCompA: A = nexus.get(unsafeComponentFor: childId) + return (parent: parentCompA, child: childCompA) + } } extension Nexus { diff --git a/Sources/FirebladeECS/Family2.swift b/Sources/FirebladeECS/Family2.swift index 3c69c3d..8d33200 100644 --- a/Sources/FirebladeECS/Family2.swift +++ b/Sources/FirebladeECS/Family2.swift @@ -5,6 +5,8 @@ // Created by Christian Treffs on 21.08.19. // +// swiftlint:disable large_tuple + public typealias Family2 = Family> public struct Requires2: FamilyRequirementsManaging where A: Component, B: Component { @@ -19,13 +21,20 @@ public struct Requires2: FamilyRequirementsManaging where A: Component, B: return (compA, compB) } - // swiftlint:disable:next large_tuple public static func entityAndComponents(nexus: Nexus, entityId: EntityIdentifier) -> (Entity, A, B) { let entity: Entity = nexus.get(unsafeEntity: entityId) let compA: A = nexus.get(unsafeComponentFor: entityId) let compB: B = nexus.get(unsafeComponentFor: entityId) return (entity, compA, compB) } + + public static func relativesDescending(nexus: Nexus, parentId: EntityIdentifier, childId: EntityIdentifier) -> (parent: (A, B), child: (A, B)) { + let pcA: A = nexus.get(unsafeComponentFor: parentId) + let pcB: B = nexus.get(unsafeComponentFor: parentId) + let ccA: A = nexus.get(unsafeComponentFor: childId) + let ccB: B = nexus.get(unsafeComponentFor: childId) + return (parent: (pcA, pcB), child: (ccA, ccB)) + } } extension Nexus { diff --git a/Sources/FirebladeECS/Family3.swift b/Sources/FirebladeECS/Family3.swift index 55618bb..74446e2 100644 --- a/Sources/FirebladeECS/Family3.swift +++ b/Sources/FirebladeECS/Family3.swift @@ -30,6 +30,16 @@ public struct Requires3: FamilyRequirementsManaging where A: Component, let compC: C = nexus.get(unsafeComponentFor: entityId) return (entity, compA, compB, compC) } + public static func relativesDescending(nexus: Nexus, parentId: EntityIdentifier, childId: EntityIdentifier) -> + (parent: (A, B, C), child: (A, B, C)) { + let pcA: A = nexus.get(unsafeComponentFor: parentId) + let pcB: B = nexus.get(unsafeComponentFor: parentId) + let pcC: C = nexus.get(unsafeComponentFor: parentId) + let ccA: A = nexus.get(unsafeComponentFor: childId) + let ccB: B = nexus.get(unsafeComponentFor: childId) + let ccC: C = nexus.get(unsafeComponentFor: childId) + return (parent: (pcA, pcB, pcC), child: (ccA, ccB, ccC)) + } } extension Nexus { diff --git a/Sources/FirebladeECS/Family4.swift b/Sources/FirebladeECS/Family4.swift index adc620c..88050f7 100644 --- a/Sources/FirebladeECS/Family4.swift +++ b/Sources/FirebladeECS/Family4.swift @@ -32,6 +32,19 @@ public struct Requires4: FamilyRequirementsManaging where A: Compone let compD: D = nexus.get(unsafeComponentFor: entityId) return (entity, compA, compB, compC, compD) } + + public static func relativesDescending(nexus: Nexus, parentId: EntityIdentifier, childId: EntityIdentifier) -> + (parent: (A, B, C, D), child: (A, B, C, D)) { + let pcA: A = nexus.get(unsafeComponentFor: parentId) + let pcB: B = nexus.get(unsafeComponentFor: parentId) + let pcC: C = nexus.get(unsafeComponentFor: parentId) + let pcD: D = nexus.get(unsafeComponentFor: parentId) + let ccA: A = nexus.get(unsafeComponentFor: childId) + let ccB: B = nexus.get(unsafeComponentFor: childId) + let ccC: C = nexus.get(unsafeComponentFor: childId) + let ccD: D = nexus.get(unsafeComponentFor: childId) + return (parent: (pcA, pcB, pcC, pcD), child: (ccA, ccB, ccC, ccD)) + } } extension Nexus { diff --git a/Sources/FirebladeECS/Family5.swift b/Sources/FirebladeECS/Family5.swift index 17955ae..0d76248 100644 --- a/Sources/FirebladeECS/Family5.swift +++ b/Sources/FirebladeECS/Family5.swift @@ -34,6 +34,22 @@ public struct Requires5: FamilyRequirementsManaging where A: Comp let compE: E = nexus.get(unsafeComponentFor: entityId) return (entity, compA, compB, compC, compD, compE) } + + public static func relativesDescending(nexus: Nexus, parentId: EntityIdentifier, childId: EntityIdentifier) -> + (parent: (A, B, C, D, E), child: (A, B, C, D, E)) { + let pcA: A = nexus.get(unsafeComponentFor: parentId) + let pcB: B = nexus.get(unsafeComponentFor: parentId) + let pcC: C = nexus.get(unsafeComponentFor: parentId) + let pcD: D = nexus.get(unsafeComponentFor: parentId) + let pcE: E = nexus.get(unsafeComponentFor: parentId) + let ccA: A = nexus.get(unsafeComponentFor: childId) + let ccB: B = nexus.get(unsafeComponentFor: childId) + let ccC: C = nexus.get(unsafeComponentFor: childId) + let ccD: D = nexus.get(unsafeComponentFor: childId) + let ccE: E = nexus.get(unsafeComponentFor: childId) + return (parent: (pcA, pcB, pcC, pcD, pcE), + child: (ccA, ccB, ccC, ccD, ccE)) + } } extension Nexus { diff --git a/Sources/FirebladeECS/FamilyRequirementsManaging.swift b/Sources/FirebladeECS/FamilyRequirementsManaging.swift index d248a4f..9774563 100644 --- a/Sources/FirebladeECS/FamilyRequirementsManaging.swift +++ b/Sources/FirebladeECS/FamilyRequirementsManaging.swift @@ -9,6 +9,7 @@ public protocol FamilyRequirementsManaging { associatedtype Components associatedtype ComponentTypes associatedtype EntityAndComponents + associatedtype RelativesDescending init(_ types: ComponentTypes) @@ -16,4 +17,5 @@ public protocol FamilyRequirementsManaging { static func components(nexus: Nexus, entityId: EntityIdentifier) -> Components static func entityAndComponents(nexus: Nexus, entityId: EntityIdentifier) -> EntityAndComponents + static func relativesDescending(nexus: Nexus, parentId: EntityIdentifier, childId: EntityIdentifier) -> RelativesDescending } diff --git a/Tests/FirebladeECSTests/SceneGraphTests.swift b/Tests/FirebladeECSTests/SceneGraphTests.swift new file mode 100644 index 0000000..5591744 --- /dev/null +++ b/Tests/FirebladeECSTests/SceneGraphTests.swift @@ -0,0 +1,56 @@ +// +// SceneGraphTests.swift +// FirebladeECSTests +// +// Created by Christian Treffs on 30.09.19. +// + +import XCTest +import FirebladeECS + +class SceneGraphTests: XCTestCase { + + var nexus: Nexus! + + override func setUp() { + super.setUp() + nexus = Nexus() + } + + override func tearDown() { + super.tearDown() + nexus = nil + } + + func testParent() { + let nttParrent = nexus.createEntity(with: Position(x: 1, y: 1)) + + let nttChild1 = nexus.createEntity(with: Position(x: 2, y: 2)) + let nttChild2 = nexus.createEntity(with: Position(x: 3, y: 3)) + + nttParrent.addChild(nttChild1) + nttParrent.removeChild(nttChild1) + nttParrent.addChild(nttChild1) + + let family = nexus.family(requires: Position.self) + + + family + .descendRelatives.forEach { (parent: Position, child: Position) in + + } + + let family2 = nexus.family(requiresAll: Position.self, Name.self) + + family2 + .descendRelatives + .forEach { (parent, child) in + let (pPos, pName) = parent + let (cPos, cName) = child + + + } + + } + +}