Fix entity id default generation + add tests
This commit is contained in:
parent
fcf5f4eaf3
commit
bb02f301c8
|
|
@ -17,7 +17,7 @@ public protocol EntityIdentifierGenerator {
|
|||
/// Entity ids provided should be passed to `nextId()` in last out order up until the collection is empty.
|
||||
/// The default is an empty collection.
|
||||
/// - Parameter initialEntityIds: The entity ids to start providing up until the collection is empty (in last out order).
|
||||
init<EntityIds>(startProviding initialEntityIds: EntityIds) where EntityIds: BidirectionalCollection, EntityIds.Element == EntityIdentifier
|
||||
init<EntityIds>(startProviding initialEntityIds: EntityIds) where EntityIds: BidirectionalCollection & MutableCollection, EntityIds.Element == EntityIdentifier
|
||||
|
||||
/// Provides the next unused entity identifier.
|
||||
///
|
||||
|
|
@ -41,8 +41,19 @@ public struct DefaultEntityIdGenerator: EntityIdentifierGenerator {
|
|||
@usableFromInline var count: Int { stack.count }
|
||||
|
||||
@usableFromInline
|
||||
init<EntityIds>(startProviding initialEntityIds: EntityIds) where EntityIds: BidirectionalCollection, EntityIds.Element == EntityIdentifier {
|
||||
stack = initialEntityIds.map { $0.id }
|
||||
init<EntityIds>(startProviding initialEntityIds: EntityIds) where EntityIds: BidirectionalCollection & MutableCollection, EntityIds.Element == EntityIdentifier {
|
||||
let initialInUse: [EntityIdentifier.Identifier] = initialEntityIds.map { $0.id }
|
||||
let maxInUseValue = initialInUse.max() ?? 0
|
||||
let inUseSet = Set(initialInUse) // a set of all eIds in use
|
||||
let allSet = Set(0...maxInUseValue) // all eIds from 0 to including maxInUseValue
|
||||
let freeSet = allSet.subtracting(inUseSet) // all "holes" / unused / free eIds
|
||||
let initialFree = Array(freeSet).sorted().reversed() // order them to provide them linear increasing after all initially used are provided.
|
||||
stack = initialFree + initialInUse
|
||||
}
|
||||
|
||||
@usableFromInline
|
||||
init() {
|
||||
stack = [0]
|
||||
}
|
||||
|
||||
@usableFromInline
|
||||
|
|
@ -65,16 +76,16 @@ public struct DefaultEntityIdGenerator: EntityIdentifierGenerator {
|
|||
@usableFromInline var count: Int { storage.count }
|
||||
|
||||
@inlinable
|
||||
public init<EntityIds>(startProviding initialEntityIds: EntityIds) where EntityIds: BidirectionalCollection, EntityIds.Element == EntityIdentifier {
|
||||
public init<EntityIds>(startProviding initialEntityIds: EntityIds) where EntityIds: BidirectionalCollection & MutableCollection, EntityIds.Element == EntityIdentifier {
|
||||
self.storage = Storage(startProviding: initialEntityIds)
|
||||
}
|
||||
|
||||
@inlinable
|
||||
public init() {
|
||||
self.init(startProviding: [EntityIdentifier(0)])
|
||||
self.storage = Storage()
|
||||
}
|
||||
|
||||
@inline(__always)
|
||||
//@inline(__always)
|
||||
public func nextId() -> EntityIdentifier {
|
||||
storage.nextId()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,76 @@
|
|||
//
|
||||
// EntityIdGenTests.swift
|
||||
//
|
||||
//
|
||||
// Created by Christian Treffs on 21.08.20.
|
||||
//
|
||||
|
||||
import FirebladeECS
|
||||
import XCTest
|
||||
|
||||
final class EntityIdGenTests: XCTestCase {
|
||||
var gen: EntityIdentifierGenerator!
|
||||
|
||||
override func setUp() {
|
||||
super.setUp()
|
||||
gen = DefaultEntityIdGenerator()
|
||||
}
|
||||
|
||||
func testGeneratorDefaultInit() {
|
||||
XCTAssertEqual(gen.nextId(), 0)
|
||||
}
|
||||
|
||||
func testLinearIncrement() {
|
||||
for i in 0..<1_000_000 {
|
||||
XCTAssertEqual(gen.nextId(), EntityIdentifier(EntityIdentifier.Identifier(i)))
|
||||
}
|
||||
}
|
||||
|
||||
func testGenerateWithInitialIds() {
|
||||
let initialIds: [EntityIdentifier] = [2, 4, 11, 3, 0, 304]
|
||||
gen = DefaultEntityIdGenerator(startProviding: initialIds)
|
||||
|
||||
let generatedIds: [EntityIdentifier] = (0..<initialIds.count).map { _ in gen.nextId() }.reversed()
|
||||
XCTAssertEqual(initialIds, generatedIds)
|
||||
XCTAssertEqual(gen.nextId(), 1)
|
||||
XCTAssertEqual(gen.nextId(), 5)
|
||||
XCTAssertEqual(gen.nextId(), 6)
|
||||
XCTAssertEqual(gen.nextId(), 7)
|
||||
XCTAssertEqual(gen.nextId(), 8)
|
||||
XCTAssertEqual(gen.nextId(), 9)
|
||||
XCTAssertEqual(gen.nextId(), 10)
|
||||
XCTAssertEqual(gen.nextId(), 12)
|
||||
|
||||
for i in 13...304 {
|
||||
XCTAssertEqual(gen.nextId(), EntityIdentifier(EntityIdentifier.Identifier(i)))
|
||||
}
|
||||
|
||||
XCTAssertEqual(gen.nextId(), 305)
|
||||
}
|
||||
|
||||
func testGeneratorMarkUnused() {
|
||||
XCTAssertEqual(gen.nextId(), 0)
|
||||
XCTAssertEqual(gen.nextId(), 1)
|
||||
XCTAssertEqual(gen.nextId(), 2)
|
||||
|
||||
gen.markUnused(entityId: EntityIdentifier(1))
|
||||
|
||||
XCTAssertEqual(gen.nextId(), 1)
|
||||
XCTAssertEqual(gen.nextId(), 3)
|
||||
XCTAssertEqual(gen.nextId(), 4)
|
||||
|
||||
gen.markUnused(entityId: 3)
|
||||
gen.markUnused(entityId: 0)
|
||||
|
||||
XCTAssertEqual(gen.nextId(), 0)
|
||||
XCTAssertEqual(gen.nextId(), 3)
|
||||
|
||||
gen.markUnused(entityId: 3)
|
||||
|
||||
XCTAssertEqual(gen.nextId(), 3)
|
||||
XCTAssertEqual(gen.nextId(), 5)
|
||||
XCTAssertEqual(gen.nextId(), 6)
|
||||
XCTAssertEqual(gen.nextId(), 7)
|
||||
XCTAssertEqual(gen.nextId(), 8)
|
||||
}
|
||||
}
|
||||
|
|
@ -32,6 +32,18 @@ extension EntityCreationTests {
|
|||
]
|
||||
}
|
||||
|
||||
extension EntityIdGenTests {
|
||||
// DO NOT MODIFY: This is autogenerated, use:
|
||||
// `swift test --generate-linuxmain`
|
||||
// to regenerate.
|
||||
static let __allTests__EntityIdGenTests = [
|
||||
("testGenerateWithInitialIds", testGenerateWithInitialIds),
|
||||
("testGeneratorDefaultInit", testGeneratorDefaultInit),
|
||||
("testGeneratorMarkUnused", testGeneratorMarkUnused),
|
||||
("testLinearIncrement", testLinearIncrement)
|
||||
]
|
||||
}
|
||||
|
||||
extension EntityTests {
|
||||
// DO NOT MODIFY: This is autogenerated, use:
|
||||
// `swift test --generate-linuxmain`
|
||||
|
|
@ -292,6 +304,7 @@ public func __allTests() -> [XCTestCaseEntry] {
|
|||
testCase(ComponentIdentifierTests.__allTests__ComponentIdentifierTests),
|
||||
testCase(ComponentTests.__allTests__ComponentTests),
|
||||
testCase(EntityCreationTests.__allTests__EntityCreationTests),
|
||||
testCase(EntityIdGenTests.__allTests__EntityIdGenTests),
|
||||
testCase(EntityTests.__allTests__EntityTests),
|
||||
testCase(Family1Tests.__allTests__Family1Tests),
|
||||
testCase(Family2Tests.__allTests__Family2Tests),
|
||||
|
|
|
|||
Loading…
Reference in New Issue