Lint tests

This commit is contained in:
Christian Treffs 2019-09-30 20:52:24 +02:00
parent 29cd66b947
commit 5117127ee3
18 changed files with 331 additions and 412 deletions

View File

@ -1,7 +1,6 @@
included: included:
- Sources - Sources
excluded: excluded:
- Tests
- docs - docs
- build - build
identifier_name: identifier_name:

View File

@ -10,33 +10,33 @@ import FirebladeECS
class EmptyComponent: Component { } class EmptyComponent: Component { }
class Name: Component { class Name: Component {
var name: String var name: String
init(name: String) { init(name: String) {
self.name = name self.name = name
} }
} }
class Position: Component { class Position: Component {
var x: Int var x: Int
var y: Int var y: Int
init(x: Int, y: Int) { init(x: Int, y: Int) {
self.x = x self.x = x
self.y = y self.y = y
} }
} }
class Velocity: Component { class Velocity: Component {
var a: Float var a: Float
init(a: Float) { init(a: Float) {
self.a = a self.a = a
} }
} }
class Party: Component { class Party: Component {
var partying: Bool var partying: Bool
init(partying: Bool) { init(partying: Bool) {
self.partying = partying self.partying = partying
} }
} }
class Color: Component { class Color: Component {
@ -46,26 +46,21 @@ class Color: Component {
} }
class ExampleSystem { class ExampleSystem {
private let family: Family2<Position, Velocity> private let family: Family2<Position, Velocity>
init(nexus: Nexus) { init(nexus: Nexus) {
family = nexus.family(requiresAll: Position.self, Velocity.self, excludesAll: EmptyComponent.self) family = nexus.family(requiresAll: Position.self, Velocity.self, excludesAll: EmptyComponent.self)
} }
func update(deltaT: Double) { func update(deltaT: Double) {
family.forEach { (position: Position, velocity: Velocity) in family.forEach { (position: Position, velocity: Velocity) in
position.x *= 2 position.x *= 2
velocity.a *= 2 velocity.a *= 2
} }
}
}
} }
final class SingleGameState: SingleComponent { final class SingleGameState: SingleComponent {
var shouldQuit: Bool = false var shouldQuit: Bool = false
var playerHealth: Int = 67 var playerHealth: Int = 67
} }

View File

@ -9,7 +9,6 @@ import FirebladeECS
import XCTest import XCTest
class ComponentTests: XCTestCase { class ComponentTests: XCTestCase {
func testMeasureStaticComponentIdentifier() { func testMeasureStaticComponentIdentifier() {
let number: Int = 10_000 let number: Int = 10_000
measure { measure {
@ -19,7 +18,7 @@ class ComponentTests: XCTestCase {
} }
} }
} }
func testMeasureComponentIdentifier() { func testMeasureComponentIdentifier() {
let number: Int = 10_000 let number: Int = 10_000
let pos = Position(x: 1, y: 2) let pos = Position(x: 1, y: 2)

View File

@ -5,16 +5,15 @@
// Created by Christian Treffs on 14.02.19. // Created by Christian Treffs on 14.02.19.
// //
import XCTest
import FirebladeECS import FirebladeECS
import XCTest
class HashingPerformanceTests: XCTestCase { class HashingPerformanceTests: XCTestCase {
func testMeasureCombineHash() { func testMeasureCombineHash() {
let a: Set<Int> = Set<Int>([14_561_291, 26_451_562, 34_562_182, 488_972_556, 5_128_426_962, 68_211_812]) let a: Set<Int> = Set<Int>([14_561_291, 26_451_562, 34_562_182, 488_972_556, 5_128_426_962, 68_211_812])
let b: Set<Int> = Set<Int>([1_083_838, 912_312, 83_333, 71_234_555, 4_343_234]) let b: Set<Int> = Set<Int>([1_083_838, 912_312, 83_333, 71_234_555, 4_343_234])
let c: Set<Int> = Set<Int>([3_410_346_899_765, 90_000_002, 12_212_321, 71, 6_123_345_676_543]) let c: Set<Int> = Set<Int>([3_410_346_899_765, 90_000_002, 12_212_321, 71, 6_123_345_676_543])
let input: ContiguousArray<Int> = ContiguousArray<Int>(arrayLiteral: a.hashValue, b.hashValue, c.hashValue) let input: ContiguousArray<Int> = ContiguousArray<Int>(arrayLiteral: a.hashValue, b.hashValue, c.hashValue)
measure { measure {
for _ in 0..<1_000_000 { for _ in 0..<1_000_000 {
@ -23,12 +22,12 @@ class HashingPerformanceTests: XCTestCase {
} }
} }
} }
func testMeasureSetOfSetHash() { func testMeasureSetOfSetHash() {
let a: Set<Int> = Set<Int>([14_561_291, 26_451_562, 34_562_182, 488_972_556, 5_128_426_962, 68_211_812]) let a: Set<Int> = Set<Int>([14_561_291, 26_451_562, 34_562_182, 488_972_556, 5_128_426_962, 68_211_812])
let b: Set<Int> = Set<Int>([1_083_838, 912_312, 83_333, 71_234_555, 4_343_234]) let b: Set<Int> = Set<Int>([1_083_838, 912_312, 83_333, 71_234_555, 4_343_234])
let c: Set<Int> = Set<Int>([3_410_346_899_765, 90_000_002, 12_212_321, 71, 6_123_345_676_543]) let c: Set<Int> = Set<Int>([3_410_346_899_765, 90_000_002, 12_212_321, 71, 6_123_345_676_543])
let input = Set<Set<Int>>(arrayLiteral: a, b, c) let input = Set<Set<Int>>(arrayLiteral: a, b, c)
measure { measure {
for _ in 0..<1_000_000 { for _ in 0..<1_000_000 {
@ -37,6 +36,4 @@ class HashingPerformanceTests: XCTestCase {
} }
} }
} }
} }

View File

@ -9,39 +9,37 @@ import FirebladeECS
import XCTest import XCTest
class TypedFamilyPerformanceTests: XCTestCase { class TypedFamilyPerformanceTests: XCTestCase {
let numEntities: Int = 10_000 let numEntities: Int = 10_000
var nexus: Nexus! var nexus: Nexus!
override func setUp() { override func setUp() {
super.setUp() super.setUp()
nexus = Nexus() nexus = Nexus()
for i in 0..<numEntities { for i in 0..<numEntities {
nexus.createEntity().assign(Position(x: 1 + i, y: 2 + i), nexus.createEntity().assign(Position(x: 1 + i, y: 2 + i),
Name(name: "myName\(i)"), Name(name: "myName\(i)"),
Velocity(a: 3.14), Velocity(a: 3.14),
EmptyComponent(), EmptyComponent(),
Color()) Color())
} }
} }
override func tearDown() { override func tearDown() {
nexus = nil nexus = nil
super.tearDown() super.tearDown()
} }
func testMeasureTraitMatching() { func testMeasureTraitMatching() {
let a = nexus.createEntity() let a = nexus.createEntity()
a.assign(Position(x: 1, y: 2)) a.assign(Position(x: 1, y: 2))
a.assign(Name(name: "myName")) a.assign(Name(name: "myName"))
a.assign(Velocity(a: 3.14)) a.assign(Velocity(a: 3.14))
a.assign(EmptyComponent()) a.assign(EmptyComponent())
let isMatch = nexus.family(requiresAll: Position.self, Velocity.self, let isMatch = nexus.family(requiresAll: Position.self, Velocity.self,
excludesAll: Party.self) excludesAll: Party.self)
measure { measure {
for _ in 0..<10_000 { for _ in 0..<10_000 {
let success = isMatch.canBecomeMember(a) let success = isMatch.canBecomeMember(a)
@ -49,125 +47,125 @@ class TypedFamilyPerformanceTests: XCTestCase {
} }
} }
} }
func testPerformanceTypedFamilyEntities() { func testPerformanceTypedFamilyEntities() {
let family = nexus.family(requires: Position.self, excludesAll: Party.self) let family = nexus.family(requires: Position.self, excludesAll: Party.self)
XCTAssertEqual(family.count, numEntities) XCTAssertEqual(family.count, numEntities)
XCTAssertEqual(nexus.numEntities, numEntities) XCTAssertEqual(nexus.numEntities, numEntities)
XCTAssertEqual(nexus.numFamilies, 1) XCTAssertEqual(nexus.numFamilies, 1)
XCTAssertEqual(nexus.numComponents, numEntities * 5) XCTAssertEqual(nexus.numComponents, numEntities * 5)
var loopCount: Int = 0 var loopCount: Int = 0
measure { measure {
family family
.entities .entities
.forEach { (entity: Entity) in .forEach { (entity: Entity) in
_ = entity _ = entity
loopCount += 1 loopCount += 1
} }
} }
XCTAssertEqual(loopCount, family.count * 10) XCTAssertEqual(loopCount, family.count * 10)
} }
func testPerformanceArray() { func testPerformanceArray() {
let positions = [Position](repeating: Position(x: Int.random(in: 0...10), y: Int.random(in: 0...10)), count: numEntities) let positions = [Position](repeating: Position(x: Int.random(in: 0...10), y: Int.random(in: 0...10)), count: numEntities)
var loopCount: Int = 0 var loopCount: Int = 0
measure { measure {
positions positions
.forEach { (position: Position) in .forEach { (position: Position) in
_ = position _ = position
loopCount += 1 loopCount += 1
} }
} }
XCTAssertEqual(loopCount, numEntities * 10) XCTAssertEqual(loopCount, numEntities * 10)
} }
func testPerformanceTypedFamilyOneComponent() { func testPerformanceTypedFamilyOneComponent() {
let family = nexus.family(requires: Position.self, excludesAll: Party.self) let family = nexus.family(requires: Position.self, excludesAll: Party.self)
XCTAssertEqual(family.count, numEntities) XCTAssertEqual(family.count, numEntities)
XCTAssertEqual(nexus.numEntities, numEntities) XCTAssertEqual(nexus.numEntities, numEntities)
XCTAssertEqual(nexus.numFamilies, 1) XCTAssertEqual(nexus.numFamilies, 1)
XCTAssertEqual(nexus.numComponents, numEntities * 5) XCTAssertEqual(nexus.numComponents, numEntities * 5)
var loopCount: Int = 0 var loopCount: Int = 0
measure { measure {
family family
.forEach { (position: Position) in .forEach { (position: Position) in
_ = position _ = position
loopCount += 1 loopCount += 1
} }
} }
XCTAssertEqual(loopCount, family.count * 10) XCTAssertEqual(loopCount, family.count * 10)
} }
func testPerformanceTypedFamilyEntityOneComponent() { func testPerformanceTypedFamilyEntityOneComponent() {
let family = nexus.family(requires: Position.self, excludesAll: Party.self) let family = nexus.family(requires: Position.self, excludesAll: Party.self)
XCTAssertEqual(family.count, numEntities) XCTAssertEqual(family.count, numEntities)
XCTAssertEqual(nexus.numEntities, numEntities) XCTAssertEqual(nexus.numEntities, numEntities)
XCTAssertEqual(nexus.numFamilies, 1) XCTAssertEqual(nexus.numFamilies, 1)
XCTAssertEqual(nexus.numComponents, numEntities * 5) XCTAssertEqual(nexus.numComponents, numEntities * 5)
var loopCount: Int = 0 var loopCount: Int = 0
measure { measure {
family family
.entityAndComponents .entityAndComponents
.forEach { (entity: Entity, position: Position) in .forEach { (entity: Entity, position: Position) in
_ = entity _ = entity
_ = position _ = position
loopCount += 1 loopCount += 1
} }
} }
XCTAssertEqual(loopCount, family.count * 10) XCTAssertEqual(loopCount, family.count * 10)
} }
func testPerformanceTypedFamilyTwoComponents() { func testPerformanceTypedFamilyTwoComponents() {
let family = nexus.family(requiresAll: Position.self, Velocity.self, excludesAll: Party.self) let family = nexus.family(requiresAll: Position.self, Velocity.self, excludesAll: Party.self)
XCTAssertEqual(family.count, numEntities) XCTAssertEqual(family.count, numEntities)
XCTAssertEqual(nexus.numEntities, numEntities) XCTAssertEqual(nexus.numEntities, numEntities)
XCTAssertEqual(nexus.numFamilies, 1) XCTAssertEqual(nexus.numFamilies, 1)
XCTAssertEqual(nexus.numComponents, numEntities * 5) XCTAssertEqual(nexus.numComponents, numEntities * 5)
var loopCount: Int = 0 var loopCount: Int = 0
measure { measure {
family family
.forEach { (position: Position, velocity: Velocity) in .forEach { (position: Position, velocity: Velocity) in
_ = position _ = position
_ = velocity _ = velocity
loopCount += 1 loopCount += 1
} }
} }
XCTAssertEqual(loopCount, family.count * 10) XCTAssertEqual(loopCount, family.count * 10)
} }
func testPerformanceTypedFamilyEntityTwoComponents() { func testPerformanceTypedFamilyEntityTwoComponents() {
let family = nexus.family(requiresAll: Position.self, Velocity.self, excludesAll: Party.self) let family = nexus.family(requiresAll: Position.self, Velocity.self, excludesAll: Party.self)
XCTAssertEqual(family.count, numEntities) XCTAssertEqual(family.count, numEntities)
XCTAssertEqual(nexus.numEntities, numEntities) XCTAssertEqual(nexus.numEntities, numEntities)
XCTAssertEqual(nexus.numFamilies, 1) XCTAssertEqual(nexus.numFamilies, 1)
XCTAssertEqual(nexus.numComponents, numEntities * 5) XCTAssertEqual(nexus.numComponents, numEntities * 5)
var loopCount: Int = 0 var loopCount: Int = 0
measure { measure {
family family
.entityAndComponents .entityAndComponents
@ -175,48 +173,48 @@ class TypedFamilyPerformanceTests: XCTestCase {
_ = entity _ = entity
_ = position _ = position
_ = velocity _ = velocity
loopCount += 1 loopCount += 1
} }
} }
XCTAssertEqual(loopCount, family.count * 10) XCTAssertEqual(loopCount, family.count * 10)
} }
func testPerformanceTypedFamilyThreeComponents() { func testPerformanceTypedFamilyThreeComponents() {
let family = nexus.family(requiresAll: Position.self, Velocity.self, Name.self, excludesAll: Party.self) let family = nexus.family(requiresAll: Position.self, Velocity.self, Name.self, excludesAll: Party.self)
XCTAssertEqual(family.count, numEntities) XCTAssertEqual(family.count, numEntities)
XCTAssertEqual(nexus.numEntities, numEntities) XCTAssertEqual(nexus.numEntities, numEntities)
XCTAssertEqual(nexus.numFamilies, 1) XCTAssertEqual(nexus.numFamilies, 1)
XCTAssertEqual(nexus.numComponents, numEntities * 5) XCTAssertEqual(nexus.numComponents, numEntities * 5)
var loopCount: Int = 0 var loopCount: Int = 0
measure { measure {
family family
.forEach { (position: Position, velocity: Velocity, name: Name) in .forEach { (position: Position, velocity: Velocity, name: Name) in
_ = position _ = position
_ = velocity _ = velocity
_ = name _ = name
loopCount += 1 loopCount += 1
} }
} }
XCTAssertEqual(loopCount, family.count * 10) XCTAssertEqual(loopCount, family.count * 10)
} }
func testPerformanceTypedFamilyEntityThreeComponents() { func testPerformanceTypedFamilyEntityThreeComponents() {
let family = nexus.family(requiresAll: Position.self, Velocity.self, Name.self, excludesAll: Party.self) let family = nexus.family(requiresAll: Position.self, Velocity.self, Name.self, excludesAll: Party.self)
XCTAssertEqual(family.count, numEntities) XCTAssertEqual(family.count, numEntities)
XCTAssertEqual(nexus.numEntities, numEntities) XCTAssertEqual(nexus.numEntities, numEntities)
XCTAssertEqual(nexus.numFamilies, 1) XCTAssertEqual(nexus.numFamilies, 1)
XCTAssertEqual(nexus.numComponents, numEntities * 5) XCTAssertEqual(nexus.numComponents, numEntities * 5)
var loopCount: Int = 0 var loopCount: Int = 0
measure { measure {
family family
.entityAndComponents .entityAndComponents
@ -225,24 +223,24 @@ class TypedFamilyPerformanceTests: XCTestCase {
_ = position _ = position
_ = velocity _ = velocity
_ = name _ = name
loopCount += 1 loopCount += 1
} }
} }
XCTAssertEqual(loopCount, family.count * 10) XCTAssertEqual(loopCount, family.count * 10)
} }
func testPerformanceTypedFamilyFourComponents() { func testPerformanceTypedFamilyFourComponents() {
let family = nexus.family(requiresAll: Position.self, Velocity.self, Name.self, Color.self, excludesAll: Party.self) let family = nexus.family(requiresAll: Position.self, Velocity.self, Name.self, Color.self, excludesAll: Party.self)
XCTAssertEqual(family.count, numEntities) XCTAssertEqual(family.count, numEntities)
XCTAssertEqual(nexus.numEntities, numEntities) XCTAssertEqual(nexus.numEntities, numEntities)
XCTAssertEqual(nexus.numFamilies, 1) XCTAssertEqual(nexus.numFamilies, 1)
XCTAssertEqual(nexus.numComponents, numEntities * 5) XCTAssertEqual(nexus.numComponents, numEntities * 5)
var loopCount: Int = 0 var loopCount: Int = 0
measure { measure {
family family
.forEach { (position: Position, velocity: Velocity, name: Name, color: Color) in .forEach { (position: Position, velocity: Velocity, name: Name, color: Color) in
@ -250,24 +248,24 @@ class TypedFamilyPerformanceTests: XCTestCase {
_ = velocity _ = velocity
_ = name _ = name
_ = color _ = color
loopCount += 1 loopCount += 1
} }
} }
XCTAssertEqual(loopCount, family.count * 10) XCTAssertEqual(loopCount, family.count * 10)
} }
func testPerformanceTypedFamilyEntityFourComponents() { func testPerformanceTypedFamilyEntityFourComponents() {
let family = nexus.family(requiresAll: Position.self, Velocity.self, Name.self, Color.self, excludesAll: Party.self) let family = nexus.family(requiresAll: Position.self, Velocity.self, Name.self, Color.self, excludesAll: Party.self)
XCTAssertEqual(family.count, numEntities) XCTAssertEqual(family.count, numEntities)
XCTAssertEqual(nexus.numEntities, numEntities) XCTAssertEqual(nexus.numEntities, numEntities)
XCTAssertEqual(nexus.numFamilies, 1) XCTAssertEqual(nexus.numFamilies, 1)
XCTAssertEqual(nexus.numComponents, numEntities * 5) XCTAssertEqual(nexus.numComponents, numEntities * 5)
var loopCount: Int = 0 var loopCount: Int = 0
measure { measure {
family family
.entityAndComponents .entityAndComponents
@ -277,24 +275,24 @@ class TypedFamilyPerformanceTests: XCTestCase {
_ = velocity _ = velocity
_ = name _ = name
_ = color _ = color
loopCount += 1 loopCount += 1
} }
} }
XCTAssertEqual(loopCount, family.count * 10) XCTAssertEqual(loopCount, family.count * 10)
} }
func testPerformanceTypedFamilyFiveComponents() { func testPerformanceTypedFamilyFiveComponents() {
let family = nexus.family(requiresAll: Position.self, Velocity.self, Name.self, Color.self, EmptyComponent.self, excludesAll: Party.self) let family = nexus.family(requiresAll: Position.self, Velocity.self, Name.self, Color.self, EmptyComponent.self, excludesAll: Party.self)
XCTAssertEqual(family.count, numEntities) XCTAssertEqual(family.count, numEntities)
XCTAssertEqual(nexus.numEntities, numEntities) XCTAssertEqual(nexus.numEntities, numEntities)
XCTAssertEqual(nexus.numFamilies, 1) XCTAssertEqual(nexus.numFamilies, 1)
XCTAssertEqual(nexus.numComponents, numEntities * 5) XCTAssertEqual(nexus.numComponents, numEntities * 5)
var loopCount: Int = 0 var loopCount: Int = 0
measure { measure {
family.forEach { (position: Position, velocity: Velocity, name: Name, color: Color, empty: EmptyComponent) in family.forEach { (position: Position, velocity: Velocity, name: Name, color: Color, empty: EmptyComponent) in
_ = position _ = position
@ -302,24 +300,24 @@ class TypedFamilyPerformanceTests: XCTestCase {
_ = name _ = name
_ = color _ = color
_ = empty _ = empty
loopCount += 1 loopCount += 1
} }
} }
XCTAssertEqual(loopCount, family.count * 10) XCTAssertEqual(loopCount, family.count * 10)
} }
func testPerformanceTypedFamilyEntityFiveComponents() { func testPerformanceTypedFamilyEntityFiveComponents() {
let family = nexus.family(requiresAll: Position.self, Velocity.self, Name.self, Color.self, EmptyComponent.self, excludesAll: Party.self) let family = nexus.family(requiresAll: Position.self, Velocity.self, Name.self, Color.self, EmptyComponent.self, excludesAll: Party.self)
XCTAssertEqual(family.count, numEntities) XCTAssertEqual(family.count, numEntities)
XCTAssertEqual(nexus.numEntities, numEntities) XCTAssertEqual(nexus.numEntities, numEntities)
XCTAssertEqual(nexus.numFamilies, 1) XCTAssertEqual(nexus.numFamilies, 1)
XCTAssertEqual(nexus.numComponents, numEntities * 5) XCTAssertEqual(nexus.numComponents, numEntities * 5)
var loopCount: Int = 0 var loopCount: Int = 0
measure { measure {
family family
.entityAndComponents .entityAndComponents
@ -330,11 +328,11 @@ class TypedFamilyPerformanceTests: XCTestCase {
_ = name _ = name
_ = color _ = color
_ = empty _ = empty
loopCount += 1 loopCount += 1
} }
} }
XCTAssertEqual(loopCount, family.count * 10) XCTAssertEqual(loopCount, family.count * 10)
} }
} }

View File

@ -7,7 +7,7 @@ extension ComponentTests {
// to regenerate. // to regenerate.
static let __allTests__ComponentTests = [ static let __allTests__ComponentTests = [
("testMeasureComponentIdentifier", testMeasureComponentIdentifier), ("testMeasureComponentIdentifier", testMeasureComponentIdentifier),
("testMeasureStaticComponentIdentifier", testMeasureStaticComponentIdentifier), ("testMeasureStaticComponentIdentifier", testMeasureStaticComponentIdentifier)
] ]
} }
@ -17,7 +17,7 @@ extension HashingPerformanceTests {
// to regenerate. // to regenerate.
static let __allTests__HashingPerformanceTests = [ static let __allTests__HashingPerformanceTests = [
("testMeasureCombineHash", testMeasureCombineHash), ("testMeasureCombineHash", testMeasureCombineHash),
("testMeasureSetOfSetHash", testMeasureSetOfSetHash), ("testMeasureSetOfSetHash", testMeasureSetOfSetHash)
] ]
} }
@ -38,7 +38,7 @@ extension TypedFamilyPerformanceTests {
("testPerformanceTypedFamilyFourComponents", testPerformanceTypedFamilyFourComponents), ("testPerformanceTypedFamilyFourComponents", testPerformanceTypedFamilyFourComponents),
("testPerformanceTypedFamilyOneComponent", testPerformanceTypedFamilyOneComponent), ("testPerformanceTypedFamilyOneComponent", testPerformanceTypedFamilyOneComponent),
("testPerformanceTypedFamilyThreeComponents", testPerformanceTypedFamilyThreeComponents), ("testPerformanceTypedFamilyThreeComponents", testPerformanceTypedFamilyThreeComponents),
("testPerformanceTypedFamilyTwoComponents", testPerformanceTypedFamilyTwoComponents), ("testPerformanceTypedFamilyTwoComponents", testPerformanceTypedFamilyTwoComponents)
] ]
} }
@ -46,7 +46,7 @@ public func __allTests() -> [XCTestCaseEntry] {
return [ return [
testCase(ComponentTests.__allTests__ComponentTests), testCase(ComponentTests.__allTests__ComponentTests),
testCase(HashingPerformanceTests.__allTests__HashingPerformanceTests), testCase(HashingPerformanceTests.__allTests__HashingPerformanceTests),
testCase(TypedFamilyPerformanceTests.__allTests__TypedFamilyPerformanceTests), testCase(TypedFamilyPerformanceTests.__allTests__TypedFamilyPerformanceTests)
] ]
} }
#endif #endif

View File

@ -1,45 +1,41 @@
// //
// AccessTests.swift // AccessTests.swift
// //
// //
// Created by Christian Treffs on 25.06.19. // Created by Christian Treffs on 25.06.19.
// //
import FirebladeECS import FirebladeECS
import XCTest import XCTest
#if swift(>=5.1) #if swift(>=5.1)
class AccessTests: XCTestCase { class AccessTests: XCTestCase {
func testReadOnly() { func testReadOnly() {
let pos = Position(x: 1, y: 2) let pos = Position(x: 1, y: 2)
let readable = ReadableOnly<Position>(pos) let readable = ReadableOnly<Position>(pos)
XCTAssertEqual(readable.x, 1) XCTAssertEqual(readable.x, 1)
XCTAssertEqual(readable.y, 2) XCTAssertEqual(readable.y, 2)
// readable.x = 3 // does not work and that's correct! // readable.x = 3 // does not work and that's correct!
} }
func testWrite() { func testWrite() {
let pos = Position(x: 1, y: 2) let pos = Position(x: 1, y: 2)
let writable = Writable<Position>(pos) let writable = Writable<Position>(pos)
XCTAssertEqual(writable.x, 1) XCTAssertEqual(writable.x, 1)
XCTAssertEqual(writable.y, 2) XCTAssertEqual(writable.y, 2)
writable.x = 3 writable.x = 3
XCTAssertEqual(writable.x, 3) XCTAssertEqual(writable.x, 3)
XCTAssertEqual(pos.x, 3) XCTAssertEqual(pos.x, 3)
XCTAssertEqual(writable.y, 2) XCTAssertEqual(writable.y, 2)
XCTAssertEqual(pos.y, 2) XCTAssertEqual(pos.y, 2)
} }
} }
#endif #endif

View File

@ -45,78 +45,67 @@ class Color: Component {
var b: UInt8 = 0 var b: UInt8 = 0
} }
final class SingleGameState: SingleComponent { final class SingleGameState: SingleComponent {
var shouldQuit: Bool = false var shouldQuit: Bool = false
var playerHealth: Int = 67 var playerHealth: Int = 67
} }
class ExampleSystem { class ExampleSystem {
private let family: Family2<Position, Velocity> private let family: Family2<Position, Velocity>
init(nexus: Nexus) { init(nexus: Nexus) {
family = nexus.family(requiresAll: Position.self, Velocity.self, excludesAll: EmptyComponent.self) family = nexus.family(requiresAll: Position.self, Velocity.self, excludesAll: EmptyComponent.self)
} }
func update(deltaT: Double) { func update(deltaT: Double) {
family.forEach { (position: Position, velocity: Velocity) in family.forEach { (position: Position, velocity: Velocity) in
position.x *= 2 position.x *= 2
velocity.a *= 2 velocity.a *= 2
} }
} }
} }
class ColorSystem { class ColorSystem {
let nexus: Nexus let nexus: Nexus
lazy var colors = nexus.family(requires: Color.self) lazy var colors = nexus.family(requires: Color.self)
init(nexus: Nexus) { init(nexus: Nexus) {
self.nexus = nexus self.nexus = nexus
} }
func update() { func update() {
colors colors
.forEach { (color: Color) in .forEach { (color: Color) in
color.r = 1 color.r = 1
color.g = 2 color.g = 2
color.b = 3 color.b = 3
} }
} }
} }
class PositionSystem { class PositionSystem {
let positions: Family1<Position> let positions: Family1<Position>
var velocity: Double = 4.0 var velocity: Double = 4.0
init(nexus: Nexus) { init(nexus: Nexus) {
positions = nexus.family(requires: Position.self) positions = nexus.family(requires: Position.self)
} }
func randNorm() -> Double { func randNorm() -> Double {
return 4.0 return 4.0
} }
func update() { func update() {
positions positions
.forEach { [unowned self](pos: Position) in .forEach { [unowned self](pos: Position) in
let deltaX: Double = self.velocity * ((self.randNorm() * 2) - 1) let deltaX: Double = self.velocity * ((self.randNorm() * 2) - 1)
let deltaY: Double = self.velocity * ((self.randNorm() * 2) - 1) let deltaY: Double = self.velocity * ((self.randNorm() * 2) - 1)
let x = pos.x + Int(deltaX) let x = pos.x + Int(deltaX)
let y = pos.y + Int(deltaY) let y = pos.y + Int(deltaY)
pos.x = x pos.x = x
pos.y = y pos.y = y
} }
} }
} }

View File

@ -9,19 +9,15 @@ import FirebladeECS
import XCTest import XCTest
class ComponentTests: XCTestCase { class ComponentTests: XCTestCase {
func testComponentIdentifier() {
func testComponentIdentifier() { XCTAssertEqual(Position.identifier, Position.identifier)
XCTAssertEqual(Position.identifier, Position.identifier) XCTAssertEqual(Velocity.identifier, Velocity.identifier)
XCTAssertEqual(Velocity.identifier, Velocity.identifier)
XCTAssertNotEqual(Velocity.identifier, Position.identifier) XCTAssertNotEqual(Velocity.identifier, Position.identifier)
let p1 = Position(x: 1, y: 2) let p1 = Position(x: 1, y: 2)
let v1 = Velocity(a: 3.14) let v1 = Velocity(a: 3.14)
XCTAssertEqual(p1.identifier, Position.identifier) XCTAssertEqual(p1.identifier, Position.identifier)
XCTAssertEqual(v1.identifier, Velocity.identifier) XCTAssertEqual(v1.identifier, Velocity.identifier)
XCTAssertNotEqual(v1.identifier, p1.identifier) XCTAssertNotEqual(v1.identifier, p1.identifier)
}
}
} }

View File

@ -9,20 +9,16 @@ import FirebladeECS
import XCTest import XCTest
class EntityTests: XCTestCase { class EntityTests: XCTestCase {
func testEntityIdentifierAndIndex() {
func testEntityIdentifierAndIndex() { let min = EntityIdentifier(.min)
XCTAssertEqual(min.index, Int(UInt32.min))
let min = EntityIdentifier(.min)
XCTAssertEqual(min.index, Int(UInt32.min))
let uRand = UInt32.random(in: UInt32.min...UInt32.max) let uRand = UInt32.random(in: UInt32.min...UInt32.max)
let rand = EntityIdentifier(uRand) let rand = EntityIdentifier(uRand)
XCTAssertEqual(rand.index, Int(uRand)) XCTAssertEqual(rand.index, Int(uRand))
let max = EntityIdentifier(.max) let max = EntityIdentifier(.max)
XCTAssertEqual(max, EntityIdentifier.invalid) XCTAssertEqual(max, EntityIdentifier.invalid)
XCTAssertEqual(max.index, Int(UInt32.max)) XCTAssertEqual(max.index, Int(UInt32.max))
}
}
} }

View File

@ -9,54 +9,51 @@
import XCTest import XCTest
class FamilyTests: XCTestCase { class FamilyTests: XCTestCase {
var nexus: Nexus! var nexus: Nexus!
override func setUp() { override func setUp() {
super.setUp() super.setUp()
nexus = Nexus() nexus = Nexus()
} }
override func tearDown() { override func tearDown() {
nexus = nil nexus = nil
super.tearDown() super.tearDown()
} }
func createDefaultEntity() { func createDefaultEntity() {
let e = nexus.createEntity() let e = nexus.createEntity()
e.assign(Position(x: 1, y: 2)) e.assign(Position(x: 1, y: 2))
e.assign(Color()) e.assign(Color())
} }
func testFamilyCreation() { func testFamilyCreation() {
let family = nexus.family(requires: Position.self, let family = nexus.family(requires: Position.self,
excludesAll: Name.self) excludesAll: Name.self)
XCTAssertEqual(family.nexus, self.nexus) XCTAssertEqual(family.nexus, self.nexus)
XCTAssertTrue(family.nexus === self.nexus) XCTAssertTrue(family.nexus === self.nexus)
XCTAssertEqual(nexus.numFamilies, 1) XCTAssertEqual(nexus.numFamilies, 1)
XCTAssertEqual(nexus.numComponents, 0) XCTAssertEqual(nexus.numComponents, 0)
XCTAssertEqual(nexus.numEntities, 0) XCTAssertEqual(nexus.numEntities, 0)
let traits = FamilyTraitSet(requiresAll: [Position.self], excludesAll: [Name.self]) let traits = FamilyTraitSet(requiresAll: [Position.self], excludesAll: [Name.self])
XCTAssertEqual(family.traits, traits) XCTAssertEqual(family.traits, traits)
} }
func testFamilyReuse() { func testFamilyReuse() {
let familyA = nexus.family(requires: Position.self, let familyA = nexus.family(requires: Position.self,
excludesAll: Name.self) excludesAll: Name.self)
let familyB = nexus.family(requires: Position.self, let familyB = nexus.family(requires: Position.self,
excludesAll: Name.self) excludesAll: Name.self)
XCTAssertEqual(nexus.numFamilies, 1) XCTAssertEqual(nexus.numFamilies, 1)
XCTAssertEqual(nexus.numComponents, 0) XCTAssertEqual(nexus.numComponents, 0)
XCTAssertEqual(familyA, familyB) XCTAssertEqual(familyA, familyB)
} }
func testFamilyAbandoned() { func testFamilyAbandoned() {
XCTAssertEqual(nexus.numFamilies, 0) XCTAssertEqual(nexus.numFamilies, 0)
XCTAssertEqual(nexus.numComponents, 0) XCTAssertEqual(nexus.numComponents, 0)
@ -83,9 +80,8 @@ class FamilyTests: XCTestCase {
XCTAssertEqual(nexus.numFamilies, 1) XCTAssertEqual(nexus.numFamilies, 1)
XCTAssertEqual(nexus.numComponents, 0) XCTAssertEqual(nexus.numComponents, 0)
XCTAssertEqual(nexus.numEntities, 0) XCTAssertEqual(nexus.numEntities, 0)
} }
func testFamilyLateMember() { func testFamilyLateMember() {
let eEarly = nexus.createEntity(with: Position(x: 1, y: 2)) let eEarly = nexus.createEntity(with: Position(x: 1, y: 2))
XCTAssertEqual(nexus.numFamilies, 0) XCTAssertEqual(nexus.numFamilies, 0)
@ -102,95 +98,91 @@ class FamilyTests: XCTestCase {
XCTAssertTrue(family.isMember(eEarly)) XCTAssertTrue(family.isMember(eEarly))
XCTAssertTrue(family.isMember(eLate)) XCTAssertTrue(family.isMember(eLate))
} }
func testFamilyExchange() { func testFamilyExchange() {
let number: Int = 10 let number: Int = 10
for i in 0..<number { for i in 0..<number {
nexus.createEntity(with: Position(x: i + 1, y: i + 2)) nexus.createEntity(with: Position(x: i + 1, y: i + 2))
} }
let familyA = nexus.family(requires: Position.self, let familyA = nexus.family(requires: Position.self,
excludesAll: Velocity.self) excludesAll: Velocity.self)
let familyB = nexus.family(requires: Velocity.self, let familyB = nexus.family(requires: Velocity.self,
excludesAll: Position.self) excludesAll: Position.self)
XCTAssertEqual(familyA.count, 10) XCTAssertEqual(familyA.count, 10)
XCTAssertEqual(familyB.count, 0) XCTAssertEqual(familyB.count, 0)
familyA familyA
.entityAndComponents .entityAndComponents
.forEach { (entity: Entity, position: Position) in .forEach { (entity: Entity, _: Position) in
entity.assign(Velocity(a: 3.14)) entity.assign(Velocity(a: 3.14))
entity.remove(Position.self) entity.remove(Position.self)
} }
XCTAssertEqual(familyA.count, 0) XCTAssertEqual(familyA.count, 0)
XCTAssertEqual(familyB.count, 10) XCTAssertEqual(familyB.count, 10)
familyB familyB
.entityAndComponents .entityAndComponents
.forEach { (entity: Entity, velocity: Velocity) in .forEach { (entity: Entity, velocity: Velocity) in
entity.assign(Position(x: 1, y: 2)) entity.assign(Position(x: 1, y: 2))
entity.remove(velocity) entity.remove(velocity)
} }
XCTAssertEqual(familyA.count, 10) XCTAssertEqual(familyA.count, 10)
XCTAssertEqual(familyB.count, 0) XCTAssertEqual(familyB.count, 0)
} }
func testFamilyMemberBasicIteration() { func testFamilyMemberBasicIteration() {
for i in 0..<1000 { for i in 0..<1000 {
nexus.createEntity(with: Position(x: i + 1, y: i + 2)) nexus.createEntity(with: Position(x: i + 1, y: i + 2))
nexus.createEntity(with: Velocity(a: Float(i))) nexus.createEntity(with: Velocity(a: Float(i)))
} }
let familyA = nexus.family(requires: Position.self, let familyA = nexus.family(requires: Position.self,
excludesAll: Velocity.self) excludesAll: Velocity.self)
let familyB = nexus.family(requires: Velocity.self, let familyB = nexus.family(requires: Velocity.self,
excludesAll: Position.self) excludesAll: Position.self)
familyA.forEach { (pos: Position?) in familyA.forEach { (pos: Position?) in
XCTAssertNotNil(pos) XCTAssertNotNil(pos)
} }
familyB.forEach { (vel: Velocity?) in familyB.forEach { (vel: Velocity?) in
XCTAssertNotNil(vel) XCTAssertNotNil(vel)
} }
} }
func testFamilyBulkDestroy() { func testFamilyBulkDestroy() {
let count = 10_000 let count = 10_000
for _ in 0..<count { for _ in 0..<count {
createDefaultEntity() createDefaultEntity()
} }
let family = nexus.family(requires: Position.self) let family = nexus.family(requires: Position.self)
XCTAssertEqual(family.memberIds.count, count) XCTAssertEqual(family.memberIds.count, count)
let currentCount: Int = (count / 2) let currentCount: Int = (count / 2)
family family
.entities .entities
.prefix(currentCount) .prefix(currentCount)
.forEach { (entity: Entity) in .forEach { (entity: Entity) in
entity.destroy() entity.destroy()
}
}
XCTAssertEqual(family.memberIds.count, (count / 2)) XCTAssertEqual(family.memberIds.count, (count / 2))
for _ in 0..<count { for _ in 0..<count {
createDefaultEntity() createDefaultEntity()
} }
XCTAssertEqual(family.memberIds.count, count + (count / 2)) XCTAssertEqual(family.memberIds.count, count + (count / 2))
} }
} }

View File

@ -9,7 +9,6 @@ import FirebladeECS
import XCTest import XCTest
class FamilyTraitsTests: XCTestCase { class FamilyTraitsTests: XCTestCase {
var nexus: Nexus! var nexus: Nexus!
override func setUp() { override func setUp() {
@ -23,7 +22,6 @@ class FamilyTraitsTests: XCTestCase {
} }
func testTraitCommutativity() { func testTraitCommutativity() {
let t1 = FamilyTraitSet(requiresAll: [Position.self, Velocity.self], let t1 = FamilyTraitSet(requiresAll: [Position.self, Velocity.self],
excludesAll: [Name.self]) excludesAll: [Name.self])
let t2 = FamilyTraitSet(requiresAll: [Velocity.self, Position.self], let t2 = FamilyTraitSet(requiresAll: [Velocity.self, Position.self],
@ -31,11 +29,9 @@ class FamilyTraitsTests: XCTestCase {
XCTAssertEqual(t1, t2) XCTAssertEqual(t1, t2)
XCTAssertEqual(t1.hashValue, t2.hashValue) XCTAssertEqual(t1.hashValue, t2.hashValue)
} }
func testTraitMatching() { func testTraitMatching() {
let a = nexus.createEntity() let a = nexus.createEntity()
a.assign(Position(x: 1, y: 2)) a.assign(Position(x: 1, y: 2))
a.assign(Name(name: "myName")) a.assign(Name(name: "myName"))
@ -49,7 +45,5 @@ class FamilyTraitsTests: XCTestCase {
XCTAssertFalse(noMatch.canBecomeMember(a)) XCTAssertFalse(noMatch.canBecomeMember(a))
XCTAssertTrue(isMatch.canBecomeMember(a)) XCTAssertTrue(isMatch.canBecomeMember(a))
} }
} }

View File

@ -9,7 +9,6 @@
import XCTest import XCTest
class HashingTests: XCTestCase { class HashingTests: XCTestCase {
func makeComponent() -> Int { func makeComponent() -> Int {
let upperBound: Int = 44 let upperBound: Int = 44
let range = UInt32.min...UInt32.max let range = UInt32.min...UInt32.max
@ -23,35 +22,32 @@ class HashingTests: XCTestCase {
let cH = Int(bitPattern: rand) let cH = Int(bitPattern: rand)
return cH return cH
} }
func testCollisionsInCritialRange() { func testCollisionsInCritialRange() {
var hashSet: Set<Int> = Set<Int>() var hashSet: Set<Int> = Set<Int>()
var range: CountableRange<UInt32> = 0 ..< 1_000_000 var range: CountableRange<UInt32> = 0 ..< 1_000_000
let maxComponents: Int = 1000 let maxComponents: Int = 1000
let components: [Int] = (0..<maxComponents).map { _ in makeComponent() } let components: [Int] = (0..<maxComponents).map { _ in makeComponent() }
var index: Int = 0 var index: Int = 0
while let idx: UInt32 = range.popLast() { while let idx: UInt32 = range.popLast() {
let eId = EntityIdentifier(idx) let eId = EntityIdentifier(idx)
let entityId: EntityIdentifier = eId let entityId: EntityIdentifier = eId
let c = (index % maxComponents) let c = (index % maxComponents)
index += 1 index += 1
let cH: ComponentTypeHash = components[c] let cH: ComponentTypeHash = components[c]
let h: Int = EntityComponentHash.compose(entityId: entityId, componentTypeHash: cH) let h: Int = EntityComponentHash.compose(entityId: entityId, componentTypeHash: cH)
let (collisionFree, _) = hashSet.insert(h) let (collisionFree, _) = hashSet.insert(h)
XCTAssert(collisionFree) XCTAssert(collisionFree)
XCTAssert(EntityComponentHash.decompose(h, with: cH) == entityId) XCTAssert(EntityComponentHash.decompose(h, with: cH) == entityId)
XCTAssert(EntityComponentHash.decompose(h, with: entityId) == cH) XCTAssert(EntityComponentHash.decompose(h, with: entityId) == cH)
} }
} }
} }

View File

@ -9,25 +9,24 @@ import FirebladeECS
import XCTest import XCTest
class NexusTests: XCTestCase { class NexusTests: XCTestCase {
var nexus: Nexus! var nexus: Nexus!
override func setUp() { override func setUp() {
super.setUp() super.setUp()
nexus = Nexus() nexus = Nexus()
} }
override func tearDown() { override func tearDown() {
nexus = nil nexus = nil
super.tearDown() super.tearDown()
} }
func testEntityCreate() { func testEntityCreate() {
XCTAssertEqual(nexus.numEntities, 0) XCTAssertEqual(nexus.numEntities, 0)
let e0 = nexus.createEntity() let e0 = nexus.createEntity()
XCTAssertEqual(e0.identifier.index, 0) XCTAssertEqual(e0.identifier.index, 0)
XCTAssertEqual(nexus.numEntities, 1) XCTAssertEqual(nexus.numEntities, 1)
let e1 = nexus.createEntity(with: Name(name: "Entity 1")) let e1 = nexus.createEntity(with: Name(name: "Entity 1"))
@ -37,7 +36,7 @@ class NexusTests: XCTestCase {
//FIXME: XCTAssertNil(e0.name) //FIXME: XCTAssertNil(e0.name)
//FIXME: XCTAssertEqual(e1.name, "Entity 1") //FIXME: XCTAssertEqual(e1.name, "Entity 1")
} }
func testEntityDestroy() { func testEntityDestroy() {
testEntityCreate() testEntityCreate()
@ -61,108 +60,101 @@ class NexusTests: XCTestCase {
XCTAssertEqual(nexus.numEntities, 0) XCTAssertEqual(nexus.numEntities, 0)
} }
func testComponentCreation() { func testComponentCreation() {
XCTAssert(nexus.numEntities == 0)
XCTAssert(nexus.numEntities == 0) let e0: Entity = nexus.createEntity()
let e0: Entity = nexus.createEntity() let p0 = Position(x: 1, y: 2)
let p0 = Position(x: 1, y: 2) e0.assign(p0)
e0.assign(p0)
// component collision: e0.assign(p0) // component collision: e0.assign(p0)
XCTAssert(e0.hasComponents) XCTAssert(e0.hasComponents)
XCTAssert(e0.numComponents == 1) XCTAssert(e0.numComponents == 1)
let rP0: Position = e0.get(component: Position.self)! let rP0: Position = e0.get(component: Position.self)!
XCTAssert(rP0.x == 1) XCTAssert(rP0.x == 1)
XCTAssert(rP0.y == 2) XCTAssert(rP0.y == 2)
} }
func testComponentDeletion() { func testComponentDeletion() {
let identifier: EntityIdentifier = nexus.createEntity().identifier
let identifier: EntityIdentifier = nexus.createEntity().identifier let e0 = nexus.get(entity: identifier)!
let e0 = nexus.get(entity: identifier)! XCTAssert(e0.numComponents == 0)
e0.remove(Position.self)
XCTAssert(e0.numComponents == 0)
XCTAssert(e0.numComponents == 0) let n0 = Name(name: "myName")
e0.remove(Position.self) let p0 = Position(x: 99, y: 111)
XCTAssert(e0.numComponents == 0)
let n0 = Name(name: "myName") e0.assign(n0)
let p0 = Position(x: 99, y: 111) XCTAssert(e0.numComponents == 1)
XCTAssert(e0.hasComponents)
e0.assign(n0) e0.remove(Name.self)
XCTAssert(e0.numComponents == 1)
XCTAssert(e0.hasComponents)
e0.remove(Name.self) XCTAssert(e0.numComponents == 0)
XCTAssert(!e0.hasComponents)
XCTAssert(e0.numComponents == 0) e0.assign(p0)
XCTAssert(!e0.hasComponents)
e0.assign(p0) XCTAssert(e0.numComponents == 1)
XCTAssert(e0.hasComponents)
XCTAssert(e0.numComponents == 1) e0.remove(p0)
XCTAssert(e0.hasComponents)
e0.remove(p0) XCTAssert(e0.numComponents == 0)
XCTAssert(!e0.hasComponents)
XCTAssert(e0.numComponents == 0) e0.assign(n0)
XCTAssert(!e0.hasComponents) e0.assign(p0)
e0.assign(n0) XCTAssert(e0.numComponents == 2)
e0.assign(p0) let (name, position) = e0.get(components: Name.self, Position.self)
XCTAssert(e0.numComponents == 2) XCTAssert(name?.name == "myName")
let (name, position) = e0.get(components: Name.self, Position.self) XCTAssert(position?.x == 99)
XCTAssert(position?.y == 111)
XCTAssert(name?.name == "myName") e0.destroy()
XCTAssert(position?.x == 99)
XCTAssert(position?.y == 111)
e0.destroy() XCTAssert(e0.numComponents == 0)
}
XCTAssert(e0.numComponents == 0)
}
func testComponentRetrieval() { func testComponentRetrieval() {
let pos = Position(x: 1, y: 2) let pos = Position(x: 1, y: 2)
let name = Name(name: "myName") let name = Name(name: "myName")
let vel = Velocity(a: 3) let vel = Velocity(a: 3)
let entity = nexus.createEntity(with: pos, name, vel) let entity = nexus.createEntity(with: pos, name, vel)
let (rPos, rName, rVel) = entity.get(components: Position.self, Name.self, Velocity.self) let (rPos, rName, rVel) = entity.get(components: Position.self, Name.self, Velocity.self)
XCTAssertTrue(rPos === pos) XCTAssertTrue(rPos === pos)
XCTAssertTrue(rName === name) XCTAssertTrue(rName === name)
XCTAssertTrue(rVel === vel) XCTAssertTrue(rVel === vel)
} }
func testComponentUniqueness() { func testComponentUniqueness() {
let a = nexus.createEntity() let a = nexus.createEntity()
let b = nexus.createEntity() let b = nexus.createEntity()
let c = nexus.createEntity() let c = nexus.createEntity()
XCTAssert(nexus.numEntities == 3) XCTAssert(nexus.numEntities == 3)
a.assign(Position(x: 0, y: 0)) a.assign(Position(x: 0, y: 0))
b.assign(Position(x: 0, y: 0)) b.assign(Position(x: 0, y: 0))
c.assign(Position(x: 0, y: 0)) c.assign(Position(x: 0, y: 0))
let pA: Position = a.get()! let pA: Position = a.get()!
let pB: Position = b.get()! let pB: Position = b.get()!
pA.x = 23 pA.x = 23
pA.y = 32 pA.y = 32
XCTAssert(pB.x != pA.x)
XCTAssert(pB.y != pA.y)
}
XCTAssert(pB.x != pA.x)
XCTAssert(pB.y != pA.y)
}
} }

View File

@ -10,43 +10,42 @@ import XCTest
class SingleTests: XCTestCase { class SingleTests: XCTestCase {
var nexus: Nexus! var nexus: Nexus!
override func setUp() { override func setUp() {
super.setUp() super.setUp()
nexus = Nexus() nexus = Nexus()
} }
override func tearDown() { override func tearDown() {
nexus = nil nexus = nil
super.tearDown() super.tearDown()
} }
func testSingleCreation() { func testSingleCreation() {
let single = nexus.single(SingleGameState.self) let single = nexus.single(SingleGameState.self)
XCTAssertEqual(single.nexus, self.nexus) XCTAssertEqual(single.nexus, self.nexus)
XCTAssertTrue(single.nexus === self.nexus) XCTAssertTrue(single.nexus === self.nexus)
XCTAssertEqual(single.traits.requiresAll.count, 1) XCTAssertEqual(single.traits.requiresAll.count, 1)
XCTAssertEqual(single.traits.excludesAll.count, 0) XCTAssertEqual(single.traits.excludesAll.count, 0)
XCTAssertEqual(nexus.familyMembersByTraits.keys.count, 1) XCTAssertEqual(nexus.familyMembersByTraits.keys.count, 1)
XCTAssertEqual(nexus.familyMembersByTraits.values.count, 1) XCTAssertEqual(nexus.familyMembersByTraits.values.count, 1)
let traits = FamilyTraitSet(requiresAll: [SingleGameState.self], excludesAll: []) let traits = FamilyTraitSet(requiresAll: [SingleGameState.self], excludesAll: [])
XCTAssertEqual(single.traits, traits) XCTAssertEqual(single.traits, traits)
} }
func testSingleReuse() { func testSingleReuse() {
let singleA = nexus.single(SingleGameState.self) let singleA = nexus.single(SingleGameState.self)
let singleB = nexus.single(SingleGameState.self) let singleB = nexus.single(SingleGameState.self)
XCTAssertEqual(nexus.familyMembersByTraits.keys.count, 1) XCTAssertEqual(nexus.familyMembersByTraits.keys.count, 1)
XCTAssertEqual(nexus.familyMembersByTraits.values.count, 1) XCTAssertEqual(nexus.familyMembersByTraits.values.count, 1)
XCTAssertEqual(singleA, singleB) XCTAssertEqual(singleA, singleB)
} }
func testSingleEntityAndComponentCreation() { func testSingleEntityAndComponentCreation() {
let single = nexus.single(SingleGameState.self) let single = nexus.single(SingleGameState.self)
let gameState = SingleGameState() let gameState = SingleGameState()
@ -54,9 +53,8 @@ class SingleTests: XCTestCase {
XCTAssertNotNil(single.component) XCTAssertNotNil(single.component)
XCTAssertEqual(single.component.shouldQuit, gameState.shouldQuit) XCTAssertEqual(single.component.shouldQuit, gameState.shouldQuit)
XCTAssertEqual(single.component.playerHealth, gameState.playerHealth) XCTAssertEqual(single.component.playerHealth, gameState.playerHealth)
} }
func testSingleCreationOnExistingFamilyMember() { func testSingleCreationOnExistingFamilyMember() {
_ = nexus.createEntity(with: Position(x: 1, y: 2)) _ = nexus.createEntity(with: Position(x: 1, y: 2))
let singleGame = SingleGameState() let singleGame = SingleGameState()

View File

@ -9,7 +9,6 @@
import XCTest import XCTest
class SparseSetTests: XCTestCase { class SparseSetTests: XCTestCase {
var set: UnorderedSparseSet<Position>! var set: UnorderedSparseSet<Position>!
override func setUp() { override func setUp() {
@ -23,7 +22,6 @@ class SparseSetTests: XCTestCase {
} }
func testSparseSetAdd() { func testSparseSetAdd() {
let num: Int = 100 let num: Int = 100
for idx in 0..<num { for idx in 0..<num {
@ -47,7 +45,6 @@ class SparseSetTests: XCTestCase {
} }
func testSparseSetAddAndReplace() { func testSparseSetAddAndReplace() {
let p1 = Position(x: 1, y: 1) let p1 = Position(x: 1, y: 1)
let p2 = Position(x: 2, y: 2) let p2 = Position(x: 2, y: 2)
@ -60,11 +57,9 @@ class SparseSetTests: XCTestCase {
XCTAssertEqual(set.get(at: 10)?.x, p2.x) XCTAssertEqual(set.get(at: 10)?.x, p2.x)
XCTAssertEqual(set.count, 1) XCTAssertEqual(set.count, 1)
} }
func testSparseSetGet() { func testSparseSetGet() {
let p1 = Position(x: 1, y: 1) let p1 = Position(x: 1, y: 1)
set.insert(p1, at: 10) set.insert(p1, at: 10)
@ -79,7 +74,6 @@ class SparseSetTests: XCTestCase {
} }
func testSparseSetRemove() { func testSparseSetRemove() {
let num: Int = 7 let num: Int = 7
for idx in 0..<num { for idx in 0..<num {
@ -358,7 +352,6 @@ class SparseSetTests: XCTestCase {
XCTAssertEqual(set.sparse[5], nil) XCTAssertEqual(set.sparse[5], nil)
XCTAssertEqual(set.sparse[6], nil) XCTAssertEqual(set.sparse[6], nil)
XCTAssertEqual(set.sparse[7], nil) XCTAssertEqual(set.sparse[7], nil)
} }
func testSparseSetRemoveAndAdd() { func testSparseSetRemoveAndAdd() {
@ -384,11 +377,9 @@ class SparseSetTests: XCTestCase {
XCTAssertEqual(set.get(at: 56)?.x, 56) XCTAssertEqual(set.get(at: 56)?.x, 56)
XCTAssertEqual(set.get(at: 99)?.x, 99) XCTAssertEqual(set.get(at: 99)?.x, 99)
XCTAssertEqual(set.get(at: 3)?.x, 3) XCTAssertEqual(set.get(at: 3)?.x, 3)
} }
func testSparseSetRemoveNonPresent() { func testSparseSetRemoveNonPresent() {
XCTAssertTrue(set.isEmpty) XCTAssertTrue(set.isEmpty)
XCTAssertNil(set.remove(at: 100)) XCTAssertNil(set.remove(at: 100))
XCTAssertTrue(set.isEmpty) XCTAssertTrue(set.isEmpty)
@ -427,11 +418,9 @@ class SparseSetTests: XCTestCase {
XCTAssertTrue(set.get(at: 0) === a) XCTAssertTrue(set.get(at: 0) === a)
XCTAssertEqual(set.count, 1) XCTAssertEqual(set.count, 1)
} }
func testSparseSetNonCongiuousData() { func testSparseSetNonCongiuousData() {
var indices: Set<Int> = [0, 30, 1, 21, 78, 56, 99, 3] var indices: Set<Int> = [0, 30, 1, 21, 78, 56, 99, 3]
for idx in indices { for idx in indices {
@ -462,7 +451,6 @@ class SparseSetTests: XCTestCase {
} }
func testSparseSetClear() { func testSparseSetClear() {
let num: Int = 100 let num: Int = 100
XCTAssertEqual(set.count, 0) XCTAssertEqual(set.count, 0)
@ -506,27 +494,26 @@ class SparseSetTests: XCTestCase {
// NOTE: this tests only dense insertion order, this is no guarantee for the real ordering. // NOTE: this tests only dense insertion order, this is no guarantee for the real ordering.
XCTAssertEqual(string, "Hello World") XCTAssertEqual(string, "Hello World")
} }
func testSubscript() { func testSubscript() {
let characters = UnorderedSparseSet<Character>() let characters = UnorderedSparseSet<Character>()
characters[4] = "H" characters[4] = "H"
characters[13] = "e" characters[13] = "e"
characters[44] = "l" characters[44] = "l"
characters[123] = "l" characters[123] = "l"
characters[89] = "o" characters[89] = "o"
characters[66] = " " characters[66] = " "
characters[77] = "W" characters[77] = "W"
characters[55] = "o" characters[55] = "o"
characters[90] = "r" characters[90] = "r"
characters[34] = "l" characters[34] = "l"
characters[140] = "d" characters[140] = "d"
XCTAssertEqual(characters.count, 11) XCTAssertEqual(characters.count, 11)
XCTAssertEqual(characters[4], "H") XCTAssertEqual(characters[4], "H")
XCTAssertEqual(characters[13], "e") XCTAssertEqual(characters[13], "e")
XCTAssertEqual(characters[44], "l") XCTAssertEqual(characters[44], "l")
@ -539,17 +526,16 @@ class SparseSetTests: XCTestCase {
XCTAssertEqual(characters[34], "l") XCTAssertEqual(characters[34], "l")
XCTAssertEqual(characters[140], "d") XCTAssertEqual(characters[140], "d")
} }
func testStartEndIndex() { func testStartEndIndex() {
let set = UnorderedSparseSet<Character>() let set = UnorderedSparseSet<Character>()
set.insert("C", at: 33) set.insert("C", at: 33)
set.insert("A", at: 11) set.insert("A", at: 11)
set.insert("B", at: 22) set.insert("B", at: 22)
let mapped = set.dense.map { $0.element } let mapped = set.dense.map { $0.element }
XCTAssertEqual(mapped, ["C", "A", "B"]) XCTAssertEqual(mapped, ["C", "A", "B"])
} }
} }

View File

@ -9,122 +9,118 @@
import XCTest import XCTest
class SystemsTests: XCTestCase { class SystemsTests: XCTestCase {
var nexus: Nexus! var nexus: Nexus!
var colorSystem: ColorSystem! var colorSystem: ColorSystem!
var positionSystem: PositionSystem! var positionSystem: PositionSystem!
override func setUp() { override func setUp() {
super.setUp() super.setUp()
nexus = Nexus() nexus = Nexus()
colorSystem = ColorSystem(nexus: nexus) colorSystem = ColorSystem(nexus: nexus)
positionSystem = PositionSystem(nexus: nexus) positionSystem = PositionSystem(nexus: nexus)
} }
override func tearDown() { override func tearDown() {
colorSystem = nil colorSystem = nil
positionSystem = nil positionSystem = nil
nexus = nil nexus = nil
super.tearDown() super.tearDown()
} }
func testSystemsUpdate() { func testSystemsUpdate() {
let num: Int = 10_000 let num: Int = 10_000
colorSystem.update() colorSystem.update()
positionSystem.update() positionSystem.update()
let posTraits = positionSystem.positions.traits let posTraits = positionSystem.positions.traits
XCTAssertEqual(nexus.numEntities, 0) XCTAssertEqual(nexus.numEntities, 0)
XCTAssertEqual(colorSystem.colors.memberIds.count, 0) XCTAssertEqual(colorSystem.colors.memberIds.count, 0)
XCTAssertEqual(positionSystem.positions.memberIds.count, 0) XCTAssertEqual(positionSystem.positions.memberIds.count, 0)
XCTAssertEqual(nexus.freeEntities.count, 0) XCTAssertEqual(nexus.freeEntities.count, 0)
XCTAssertEqual(nexus.familyMembersByTraits[posTraits]?.count, 0) XCTAssertEqual(nexus.familyMembersByTraits[posTraits]?.count, 0)
batchCreateEntities(count: num) batchCreateEntities(count: num)
XCTAssertEqual(nexus.numEntities, num) XCTAssertEqual(nexus.numEntities, num)
XCTAssertEqual(nexus.familyMembersByTraits[posTraits]?.count, num) XCTAssertEqual(nexus.familyMembersByTraits[posTraits]?.count, num)
XCTAssertEqual(colorSystem.colors.memberIds.count, num) XCTAssertEqual(colorSystem.colors.memberIds.count, num)
XCTAssertEqual(positionSystem.positions.memberIds.count, num) XCTAssertEqual(positionSystem.positions.memberIds.count, num)
XCTAssertEqual(nexus.freeEntities.count, 0) XCTAssertEqual(nexus.freeEntities.count, 0)
colorSystem.update() colorSystem.update()
positionSystem.update() positionSystem.update()
XCTAssertEqual(nexus.numEntities, num) XCTAssertEqual(nexus.numEntities, num)
XCTAssertEqual(nexus.familyMembersByTraits[posTraits]?.count, num) XCTAssertEqual(nexus.familyMembersByTraits[posTraits]?.count, num)
XCTAssertEqual(colorSystem.colors.memberIds.count, num) XCTAssertEqual(colorSystem.colors.memberIds.count, num)
XCTAssertEqual(positionSystem.positions.memberIds.count, num) XCTAssertEqual(positionSystem.positions.memberIds.count, num)
XCTAssertEqual(nexus.freeEntities.count, 0) XCTAssertEqual(nexus.freeEntities.count, 0)
batchCreateEntities(count: num) batchCreateEntities(count: num)
XCTAssertEqual(nexus.numEntities, num * 2) XCTAssertEqual(nexus.numEntities, num * 2)
XCTAssertEqual(nexus.familyMembersByTraits[posTraits]?.count, num * 2) XCTAssertEqual(nexus.familyMembersByTraits[posTraits]?.count, num * 2)
XCTAssertEqual(colorSystem.colors.memberIds.count, num * 2) XCTAssertEqual(colorSystem.colors.memberIds.count, num * 2)
XCTAssertEqual(positionSystem.positions.memberIds.count, num * 2) XCTAssertEqual(positionSystem.positions.memberIds.count, num * 2)
XCTAssertEqual(nexus.freeEntities.count, 0) XCTAssertEqual(nexus.freeEntities.count, 0)
colorSystem.update() colorSystem.update()
positionSystem.update() positionSystem.update()
XCTAssertEqual(nexus.numEntities, num * 2) XCTAssertEqual(nexus.numEntities, num * 2)
XCTAssertEqual(nexus.familyMembersByTraits[posTraits]?.count, num * 2) XCTAssertEqual(nexus.familyMembersByTraits[posTraits]?.count, num * 2)
XCTAssertEqual(colorSystem.colors.memberIds.count, num * 2) XCTAssertEqual(colorSystem.colors.memberIds.count, num * 2)
XCTAssertEqual(positionSystem.positions.memberIds.count, num * 2) XCTAssertEqual(positionSystem.positions.memberIds.count, num * 2)
XCTAssertEqual(nexus.freeEntities.count, 0) XCTAssertEqual(nexus.freeEntities.count, 0)
batchDestroyEntities(count: num) batchDestroyEntities(count: num)
XCTAssertEqual(nexus.familyMembersByTraits[posTraits]?.count, num) XCTAssertEqual(nexus.familyMembersByTraits[posTraits]?.count, num)
XCTAssertEqual(nexus.freeEntities.count, num) XCTAssertEqual(nexus.freeEntities.count, num)
XCTAssertEqual(nexus.numEntities, num) XCTAssertEqual(nexus.numEntities, num)
XCTAssertEqual(colorSystem.colors.memberIds.count, num) XCTAssertEqual(colorSystem.colors.memberIds.count, num)
XCTAssertEqual(positionSystem.positions.memberIds.count, num) XCTAssertEqual(positionSystem.positions.memberIds.count, num)
colorSystem.update() colorSystem.update()
positionSystem.update() positionSystem.update()
XCTAssertEqual(nexus.familyMembersByTraits[posTraits]?.count, num) XCTAssertEqual(nexus.familyMembersByTraits[posTraits]?.count, num)
XCTAssertEqual(nexus.numEntities, num) XCTAssertEqual(nexus.numEntities, num)
XCTAssertEqual(colorSystem.colors.memberIds.count, num) XCTAssertEqual(colorSystem.colors.memberIds.count, num)
XCTAssertEqual(positionSystem.positions.memberIds.count, num) XCTAssertEqual(positionSystem.positions.memberIds.count, num)
XCTAssertEqual(nexus.freeEntities.count, num) XCTAssertEqual(nexus.freeEntities.count, num)
batchCreateEntities(count: num) batchCreateEntities(count: num)
XCTAssertEqual(nexus.familyMembersByTraits[posTraits]?.count, num * 2) XCTAssertEqual(nexus.familyMembersByTraits[posTraits]?.count, num * 2)
XCTAssertEqual(nexus.numEntities, num * 2) XCTAssertEqual(nexus.numEntities, num * 2)
XCTAssertEqual(colorSystem.colors.memberIds.count, num * 2) XCTAssertEqual(colorSystem.colors.memberIds.count, num * 2)
XCTAssertEqual(positionSystem.positions.memberIds.count, num * 2) XCTAssertEqual(positionSystem.positions.memberIds.count, num * 2)
XCTAssertEqual(nexus.freeEntities.count, 0) XCTAssertEqual(nexus.freeEntities.count, 0)
} }
func createDefaultEntity() { func createDefaultEntity() {
let e = nexus.createEntity() let e = nexus.createEntity()
e.assign(Position(x: 1, y: 2)) e.assign(Position(x: 1, y: 2))
e.assign(Color()) e.assign(Color())
} }
func batchCreateEntities(count: Int) { func batchCreateEntities(count: Int) {
for _ in 0..<count { for _ in 0..<count {
createDefaultEntity() createDefaultEntity()
} }
} }
func batchDestroyEntities(count: Int) { func batchDestroyEntities(count: Int) {
let family = nexus.family(requires: Position.self) let family = nexus.family(requires: Position.self)
family family
.entities .entities
.prefix(count) .prefix(count)
.forEach { (entity: Entity) in .forEach { (entity: Entity) in
entity.destroy() entity.destroy()
} }
} }
} }

View File

@ -6,7 +6,7 @@ extension ComponentTests {
// `swift test --generate-linuxmain` // `swift test --generate-linuxmain`
// to regenerate. // to regenerate.
static let __allTests__ComponentTests = [ static let __allTests__ComponentTests = [
("testComponentIdentifier", testComponentIdentifier), ("testComponentIdentifier", testComponentIdentifier)
] ]
} }
@ -15,7 +15,7 @@ extension EntityTests {
// `swift test --generate-linuxmain` // `swift test --generate-linuxmain`
// to regenerate. // to regenerate.
static let __allTests__EntityTests = [ static let __allTests__EntityTests = [
("testEntityIdentifierAndIndex", testEntityIdentifierAndIndex), ("testEntityIdentifierAndIndex", testEntityIdentifierAndIndex)
] ]
} }
@ -30,7 +30,7 @@ extension FamilyTests {
("testFamilyExchange", testFamilyExchange), ("testFamilyExchange", testFamilyExchange),
("testFamilyLateMember", testFamilyLateMember), ("testFamilyLateMember", testFamilyLateMember),
("testFamilyMemberBasicIteration", testFamilyMemberBasicIteration), ("testFamilyMemberBasicIteration", testFamilyMemberBasicIteration),
("testFamilyReuse", testFamilyReuse), ("testFamilyReuse", testFamilyReuse)
] ]
} }
@ -40,7 +40,7 @@ extension FamilyTraitsTests {
// to regenerate. // to regenerate.
static let __allTests__FamilyTraitsTests = [ static let __allTests__FamilyTraitsTests = [
("testTraitCommutativity", testTraitCommutativity), ("testTraitCommutativity", testTraitCommutativity),
("testTraitMatching", testTraitMatching), ("testTraitMatching", testTraitMatching)
] ]
} }
@ -49,7 +49,7 @@ extension HashingTests {
// `swift test --generate-linuxmain` // `swift test --generate-linuxmain`
// to regenerate. // to regenerate.
static let __allTests__HashingTests = [ static let __allTests__HashingTests = [
("testCollisionsInCritialRange", testCollisionsInCritialRange), ("testCollisionsInCritialRange", testCollisionsInCritialRange)
] ]
} }
@ -63,7 +63,7 @@ extension NexusTests {
("testComponentRetrieval", testComponentRetrieval), ("testComponentRetrieval", testComponentRetrieval),
("testComponentUniqueness", testComponentUniqueness), ("testComponentUniqueness", testComponentUniqueness),
("testEntityCreate", testEntityCreate), ("testEntityCreate", testEntityCreate),
("testEntityDestroy", testEntityDestroy), ("testEntityDestroy", testEntityDestroy)
] ]
} }
@ -75,7 +75,7 @@ extension SingleTests {
("testSingleCreation", testSingleCreation), ("testSingleCreation", testSingleCreation),
("testSingleCreationOnExistingFamilyMember", testSingleCreationOnExistingFamilyMember), ("testSingleCreationOnExistingFamilyMember", testSingleCreationOnExistingFamilyMember),
("testSingleEntityAndComponentCreation", testSingleEntityAndComponentCreation), ("testSingleEntityAndComponentCreation", testSingleEntityAndComponentCreation),
("testSingleReuse", testSingleReuse), ("testSingleReuse", testSingleReuse)
] ]
} }
@ -95,7 +95,7 @@ extension SparseSetTests {
("testSparseSetRemoveAndAdd", testSparseSetRemoveAndAdd), ("testSparseSetRemoveAndAdd", testSparseSetRemoveAndAdd),
("testSparseSetRemoveNonPresent", testSparseSetRemoveNonPresent), ("testSparseSetRemoveNonPresent", testSparseSetRemoveNonPresent),
("testStartEndIndex", testStartEndIndex), ("testStartEndIndex", testStartEndIndex),
("testSubscript", testSubscript), ("testSubscript", testSubscript)
] ]
} }
@ -104,7 +104,7 @@ extension SystemsTests {
// `swift test --generate-linuxmain` // `swift test --generate-linuxmain`
// to regenerate. // to regenerate.
static let __allTests__SystemsTests = [ static let __allTests__SystemsTests = [
("testSystemsUpdate", testSystemsUpdate), ("testSystemsUpdate", testSystemsUpdate)
] ]
} }
@ -118,7 +118,7 @@ public func __allTests() -> [XCTestCaseEntry] {
testCase(NexusTests.__allTests__NexusTests), testCase(NexusTests.__allTests__NexusTests),
testCase(SingleTests.__allTests__SingleTests), testCase(SingleTests.__allTests__SingleTests),
testCase(SparseSetTests.__allTests__SparseSetTests), testCase(SparseSetTests.__allTests__SparseSetTests),
testCase(SystemsTests.__allTests__SystemsTests), testCase(SystemsTests.__allTests__SystemsTests)
] ]
} }
#endif #endif