Introduce single
This commit is contained in:
parent
2be8c49bcb
commit
cb248d87cf
|
|
@ -13,15 +13,18 @@ extension Nexus {
|
||||||
return nextReused.index
|
return nextReused.index
|
||||||
}
|
}
|
||||||
|
|
||||||
public func create(entity name: String? = nil) -> Entity {
|
// swiftlint:disable function_default_parameter_at_end
|
||||||
|
@discardableResult
|
||||||
|
public func create(entity name: String? = nil, with assignedComponents: Component...) -> Entity {
|
||||||
let newEntityIndex: EntityIndex = nextEntityIdx()
|
let newEntityIndex: EntityIndex = nextEntityIdx()
|
||||||
let newEntityIdentifier: EntityIdentifier = newEntityIndex.identifier
|
let newEntityIdentifier: EntityIdentifier = newEntityIndex.identifier
|
||||||
|
|
||||||
let newEntity = Entity(nexus: self, id: newEntityIdentifier, name: name)
|
let newEntity = Entity(nexus: self, id: newEntityIdentifier, name: name)
|
||||||
entityStorage.insert(newEntity, at: newEntityIndex)
|
entityStorage.insert(newEntity, at: newEntityIndex)
|
||||||
notify(EntityCreated(entityId: newEntityIdentifier))
|
notify(EntityCreated(entityId: newEntityIdentifier))
|
||||||
|
assignedComponents.forEach { newEntity.assign($0) }
|
||||||
return newEntity
|
return newEntity
|
||||||
}
|
}
|
||||||
|
// swiftlint:enable function_default_parameter_at_end
|
||||||
|
|
||||||
/// Number of entities in nexus.
|
/// Number of entities in nexus.
|
||||||
public var numEntities: Int {
|
public var numEntities: Int {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
//
|
||||||
|
// Nexus+TypedSingle.swift
|
||||||
|
// FirebladeECS
|
||||||
|
//
|
||||||
|
// Created by Christian Treffs on 13.02.19.
|
||||||
|
//
|
||||||
|
|
||||||
|
public extension Nexus {
|
||||||
|
func single<A>(
|
||||||
|
requires componentA: A.Type,
|
||||||
|
excludesAll excludedComponents: Component.Type...
|
||||||
|
) -> TypedSingle1<A> where A: Component {
|
||||||
|
return TypedSingle1(
|
||||||
|
self,
|
||||||
|
requires: componentA,
|
||||||
|
excludesAll: excludedComponents
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
//
|
||||||
|
// TypedSingle.swift
|
||||||
|
// FirebladeECS
|
||||||
|
//
|
||||||
|
// Created by Christian Treffs on 13.02.19.
|
||||||
|
//
|
||||||
|
|
||||||
|
public struct TypedSingle1<A>: Equatable where A: Component {
|
||||||
|
public let nexus: Nexus
|
||||||
|
public let traits: FamilyTraitSet
|
||||||
|
|
||||||
|
public init(_ nexus: Nexus, requires compA: A.Type, excludesAll: [Component.Type]) {
|
||||||
|
self.nexus = nexus
|
||||||
|
traits = FamilyTraitSet(requiresAll: [compA], excludesAll: excludesAll)
|
||||||
|
nexus.onFamilyInit(traits: traits)
|
||||||
|
}
|
||||||
|
|
||||||
|
@inlinable public var entityId: EntityIdentifier? {
|
||||||
|
guard let members = nexus.members(withFamilyTraits: traits) else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
guard let singleMemberId: EntityIdentifier = members.first else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return singleMemberId
|
||||||
|
}
|
||||||
|
|
||||||
|
@inlinable public var entity: Entity? {
|
||||||
|
guard let entityId = entityId else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return nexus.get(entity: entityId)
|
||||||
|
}
|
||||||
|
|
||||||
|
@inlinable public var component: A? {
|
||||||
|
return entity?.get(component: A.self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,67 @@
|
||||||
|
//
|
||||||
|
// SingleTests.swift
|
||||||
|
// FirebladeECSTests
|
||||||
|
//
|
||||||
|
// Created by Christian Treffs on 13.02.19.
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
@testable import FirebladeECS
|
||||||
|
import XCTest
|
||||||
|
|
||||||
|
class SingleTests: XCTestCase {
|
||||||
|
var nexus: Nexus!
|
||||||
|
|
||||||
|
override func setUp() {
|
||||||
|
super.setUp()
|
||||||
|
nexus = Nexus()
|
||||||
|
}
|
||||||
|
|
||||||
|
override func tearDown() {
|
||||||
|
nexus = nil
|
||||||
|
super.tearDown()
|
||||||
|
}
|
||||||
|
|
||||||
|
func testSingleCreation() {
|
||||||
|
let single = nexus.single(requires: Position.self,
|
||||||
|
excludesAll: Name.self)
|
||||||
|
XCTAssertEqual(single.nexus, self.nexus)
|
||||||
|
XCTAssertTrue(single.nexus === self.nexus)
|
||||||
|
XCTAssertEqual(single.traits.requiresAll.count, 1)
|
||||||
|
XCTAssertEqual(single.traits.excludesAll.count, 1)
|
||||||
|
|
||||||
|
XCTAssertEqual(nexus.familyMembersByTraits.keys.count, 1)
|
||||||
|
XCTAssertEqual(nexus.familyMembersByTraits.values.count, 1)
|
||||||
|
|
||||||
|
let traits = FamilyTraitSet(requiresAll: [Position.self], excludesAll: [Name.self])
|
||||||
|
XCTAssertEqual(single.traits, traits)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testSingleReuse() {
|
||||||
|
let singleA = nexus.single(requires: Position.self,
|
||||||
|
excludesAll: Name.self)
|
||||||
|
|
||||||
|
let singleB = nexus.single(requires: Position.self,
|
||||||
|
excludesAll: Name.self)
|
||||||
|
|
||||||
|
XCTAssertEqual(nexus.familyMembersByTraits.keys.count, 1)
|
||||||
|
XCTAssertEqual(nexus.familyMembersByTraits.values.count, 1)
|
||||||
|
|
||||||
|
XCTAssertEqual(singleA, singleB)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func testSingleEntityAndComponentCreation() {
|
||||||
|
let single = nexus.single(requires: Position.self,
|
||||||
|
excludesAll: Name.self)
|
||||||
|
XCTAssertNil(single.entity)
|
||||||
|
XCTAssertNil(single.component)
|
||||||
|
let pos = Position(x: 1, y: 2)
|
||||||
|
nexus.create(with: pos)
|
||||||
|
XCTAssertNotNil(single.entity)
|
||||||
|
XCTAssertNotNil(single.component)
|
||||||
|
XCTAssertEqual(single.component?.x, pos.x)
|
||||||
|
XCTAssertEqual(single.component?.y, pos.y)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue