diff --git a/Sources/FirebladeECS/Nexus+Entity.swift b/Sources/FirebladeECS/Nexus+Entity.swift
index 0238c31..c56fb18 100644
--- a/Sources/FirebladeECS/Nexus+Entity.swift
+++ b/Sources/FirebladeECS/Nexus+Entity.swift
@@ -13,15 +13,18 @@ extension Nexus {
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 newEntityIdentifier: EntityIdentifier = newEntityIndex.identifier
-
let newEntity = Entity(nexus: self, id: newEntityIdentifier, name: name)
entityStorage.insert(newEntity, at: newEntityIndex)
notify(EntityCreated(entityId: newEntityIdentifier))
- return newEntity
- }
+ assignedComponents.forEach { newEntity.assign($0) }
+ return newEntity
+ }
+ // swiftlint:enable function_default_parameter_at_end
/// Number of entities in nexus.
public var numEntities: Int {
diff --git a/Sources/FirebladeECS/Nexus+TypedSingle.swift b/Sources/FirebladeECS/Nexus+TypedSingle.swift
new file mode 100644
index 0000000..7ddd63d
--- /dev/null
+++ b/Sources/FirebladeECS/Nexus+TypedSingle.swift
@@ -0,0 +1,19 @@
+//
+// Nexus+TypedSingle.swift
+// FirebladeECS
+//
+// Created by Christian Treffs on 13.02.19.
+//
+
+public extension Nexus {
+ func single(
+ requires componentA: A.Type,
+ excludesAll excludedComponents: Component.Type...
+ ) -> TypedSingle1 where A: Component {
+ return TypedSingle1(
+ self,
+ requires: componentA,
+ excludesAll: excludedComponents
+ )
+ }
+}
diff --git a/Sources/FirebladeECS/TypedSingle.swift b/Sources/FirebladeECS/TypedSingle.swift
new file mode 100644
index 0000000..af8b795
--- /dev/null
+++ b/Sources/FirebladeECS/TypedSingle.swift
@@ -0,0 +1,38 @@
+//
+// TypedSingle.swift
+// FirebladeECS
+//
+// Created by Christian Treffs on 13.02.19.
+//
+
+public struct TypedSingle1: 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)
+ }
+}
diff --git a/Tests/FirebladeECSTests/SingleTests.swift b/Tests/FirebladeECSTests/SingleTests.swift
new file mode 100644
index 0000000..4c52f23
--- /dev/null
+++ b/Tests/FirebladeECSTests/SingleTests.swift
@@ -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)
+
+ }
+}