fireblade-ecs/Sources/FirebladeECS/Nexus+Entity.swift

84 lines
2.3 KiB
Swift

//
// Nexus+Entity.swift
// FirebladeECS
//
// Created by Christian Treffs on 13.10.17.
//
extension Nexus {
fileprivate func nextEntityIdx() -> EntityIndex {
guard let nextReused: EntityIdentifier = freeEntities.popLast() else {
return entities.count
}
return nextReused.index
}
public func create(entity name: String? = nil) -> Entity {
let newEntityIndex: EntityIndex = nextEntityIdx()
let newEntityIdentifier: EntityIdentifier = newEntityIndex.identifier
if entities.count > newEntityIndex {
let reusedEntity: Entity = entities[newEntityIndex]
assert(reusedEntity.identifier == EntityIdentifier.invalid, "Stil valid entity \(reusedEntity)")
reusedEntity.identifier = newEntityIdentifier
reusedEntity.name = name
notify(EntityCreated(entityId: newEntityIdentifier))
return reusedEntity
} else {
let newEntity = Entity(nexus: self, id: newEntityIdentifier, name: name)
entities.insert(newEntity, at: newEntityIndex)
notify(EntityCreated(entityId: newEntityIdentifier))
return newEntity
}
}
/// Number of entities in nexus.
public var count: Int {
return entities.count - freeEntities.count
}
func isValid(entity: Entity) -> Bool {
return isValid(entity: entity.identifier)
}
func isValid(entity entitiyId: EntityIdentifier) -> Bool {
return entitiyId != EntityIdentifier.invalid &&
entitiyId.index >= 0 &&
entitiyId.index < entities.count
}
public func has(entity entityId: EntityIdentifier) -> Bool {
return isValid(entity: entityId)
}
public func get(entity entityId: EntityIdentifier) -> Entity? {
Log.info("GETTING ENTITY: \(entityId)")
guard has(entity: entityId) else { return nil }
return entities[entityId.index]
}
@discardableResult
public func destroy(entity: Entity) -> Bool {
let entityId: EntityIdentifier = entity.identifier
guard has(entity: entityId) else {
report("EntityRemove failure: no entity \(entityId) to remove")
return false
}
let cleared: Bool = clear(componentes: entityId)
assert(cleared, "Could not clear all components form entity \(entityId)")
entity.invalidate()
// replace with "new" invalid entity to keep capacity of array
let invalidEntity = Entity(nexus: self, id: EntityIdentifier.invalid)
entities[entityId.index] = invalidEntity
freeEntities.append(entityId)
notify(EntityDestroyed(entityId: entityId))
return true
}
}