Add basic scene graph API

This commit is contained in:
Christian Treffs 2019-09-30 21:54:19 +02:00
parent d4b8ffbf0c
commit dbf82389e0
9 changed files with 152 additions and 6 deletions

View File

@ -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

View File

@ -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 { }

View File

@ -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 {

View File

@ -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 {

View File

@ -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 {

View File

@ -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 {

View File

@ -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 {

View File

@ -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
}

View File

@ -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
}
}
}