Add basic scene graph API
This commit is contained in:
parent
d4b8ffbf0c
commit
dbf82389e0
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -40,6 +40,14 @@ public struct Family<R> where R: FamilyRequirementsManaging {
|
|||
}
|
||||
}
|
||||
|
||||
// MARK: - Equatable
|
||||
extension Family: Equatable {
|
||||
public static func == (lhs: Family<R>, rhs: Family<R>) -> 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<R>, rhs: Family<R>) -> 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<EntityIdentifier>
|
||||
@usableFromInline unowned let nexus: Nexus
|
||||
|
||||
public init(family: Family<R>) {
|
||||
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 { }
|
||||
|
|
|
|||
|
|
@ -24,6 +24,12 @@ public struct Requires1<A>: 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 {
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@
|
|||
// Created by Christian Treffs on 21.08.19.
|
||||
//
|
||||
|
||||
// swiftlint:disable large_tuple
|
||||
|
||||
public typealias Family2<A: Component, B: Component> = Family<Requires2<A, B>>
|
||||
|
||||
public struct Requires2<A, B>: FamilyRequirementsManaging where A: Component, B: Component {
|
||||
|
|
@ -19,13 +21,20 @@ public struct Requires2<A, B>: 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 {
|
||||
|
|
|
|||
|
|
@ -30,6 +30,16 @@ public struct Requires3<A, B, C>: 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 {
|
||||
|
|
|
|||
|
|
@ -32,6 +32,19 @@ public struct Requires4<A, B, C, D>: 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 {
|
||||
|
|
|
|||
|
|
@ -34,6 +34,22 @@ public struct Requires5<A, B, C, D, E>: 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 {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue