Finish basic scene graph implementation
This commit is contained in:
parent
8958d96687
commit
71a319fe27
|
|
@ -134,25 +134,52 @@ extension Family.EntityComponentIterator: LazySequenceProtocol { }
|
||||||
// MARK: - relatives iterator
|
// MARK: - relatives iterator
|
||||||
|
|
||||||
extension Family {
|
extension Family {
|
||||||
@inlinable public var descendRelatives: RelativesIterator {
|
@inlinable
|
||||||
return RelativesIterator(family: self)
|
public func descendRelatives(from root: Entity) -> RelativesIterator {
|
||||||
|
return RelativesIterator(family: self, root: root)
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct RelativesIterator: IteratorProtocol {
|
public struct RelativesIterator: IteratorProtocol {
|
||||||
@usableFromInline var memberIdsIterator: UnorderedSparseSetIterator<EntityIdentifier>
|
|
||||||
@usableFromInline unowned let nexus: Nexus
|
@usableFromInline unowned let nexus: Nexus
|
||||||
|
@usableFromInline let familyTraits: FamilyTraitSet
|
||||||
|
|
||||||
public init(family: Family<R>) {
|
@usableFromInline var relatives: [(EntityIdentifier, EntityIdentifier)]
|
||||||
|
|
||||||
|
public init(family: Family<R>, root: Entity) {
|
||||||
self.nexus = family.nexus
|
self.nexus = family.nexus
|
||||||
memberIdsIterator = family.memberIds.makeIterator()
|
self.familyTraits = family.traits
|
||||||
|
|
||||||
|
// FIXME: this is not the most efficient way to aggregate all parent child tuples
|
||||||
|
// Problems:
|
||||||
|
// - allocates new memory
|
||||||
|
// - needs to be build on every iteration
|
||||||
|
// - relies on isMember check
|
||||||
|
self.relatives = []
|
||||||
|
self.relatives.reserveCapacity(family.memberIds.count)
|
||||||
|
aggregateRelativesBreathFirst(root.identifier)
|
||||||
|
relatives.reverse()
|
||||||
|
}
|
||||||
|
|
||||||
|
mutating func aggregateRelativesBreathFirst(_ parent: EntityIdentifier) {
|
||||||
|
guard let children = nexus.parentChildrenMap[parent] else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
children
|
||||||
|
.compactMap { child in
|
||||||
|
guard nexus.isMember(child, in: familyTraits) else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
relatives.append((parent, child))
|
||||||
|
return child
|
||||||
|
}
|
||||||
|
.forEach { aggregateRelativesBreathFirst($0) }
|
||||||
}
|
}
|
||||||
|
|
||||||
public mutating func next() -> R.RelativesDescending? {
|
public mutating func next() -> R.RelativesDescending? {
|
||||||
guard let parentId = memberIdsIterator.next() else {
|
guard let (parentId, childId) = relatives.popLast() else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
return R.relativesDescending(nexus: nexus, parentId: parentId, childId: childId)
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue