Introduce single

This commit is contained in:
Christian Treffs 2019-02-13 17:32:47 +01:00
parent 2be8c49bcb
commit cb248d87cf
4 changed files with 131 additions and 4 deletions

View File

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

View File

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

View File

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

View File

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