diff --git a/Sources/FirebladeECS/FamilyTraitSet.swift b/Sources/FirebladeECS/FamilyTraitSet.swift index bf7a855..1f98a9f 100644 --- a/Sources/FirebladeECS/FamilyTraitSet.swift +++ b/Sources/FirebladeECS/FamilyTraitSet.swift @@ -6,14 +6,14 @@ // public struct FamilyTraitSet { - public let requiresAll: ComponentSet - public let excludesAll: ComponentSet + public let requiresAll: Set + public let excludesAll: Set public let setHash: Int public init(requiresAll: [Component.Type], excludesAll: [Component.Type]) { - let requiresAll = ComponentSet(requiresAll.map { $0.identifier }) - let excludesAll = ComponentSet(excludesAll.map { $0.identifier }) + let requiresAll = Set(requiresAll.map { $0.identifier }) + let excludesAll = Set(excludesAll.map { $0.identifier }) let valid: Bool = FamilyTraitSet.isValid(requiresAll: requiresAll, excludesAll: excludesAll) precondition(valid, "invalid family trait created - requiresAll: \(requiresAll), excludesAll: \(excludesAll)") @@ -25,23 +25,23 @@ public struct FamilyTraitSet { // MARK: - match @inlinable - public func isMatch(components: ComponentSet) -> Bool { + public func isMatch(components: Set) -> Bool { return hasAll(components) && hasNone(components) } @inlinable - public func hasAll(_ components: ComponentSet) -> Bool { + public func hasAll(_ components: Set) -> Bool { return requiresAll.isSubset(of: components) } @inlinable - public func hasNone(_ components: ComponentSet) -> Bool { + public func hasNone(_ components: Set) -> Bool { return excludesAll.isDisjoint(with: components) } // MARK: - valid @inlinable - public static func isValid(requiresAll: ComponentSet, excludesAll: ComponentSet) -> Bool { + public static func isValid(requiresAll: Set, excludesAll: Set) -> Bool { return !requiresAll.isEmpty && requiresAll.isDisjoint(with: excludesAll) } diff --git a/Sources/FirebladeECS/Hashing.swift b/Sources/FirebladeECS/Hashing.swift index c0827e3..3e13954 100644 --- a/Sources/FirebladeECS/Hashing.swift +++ b/Sources/FirebladeECS/Hashing.swift @@ -13,6 +13,12 @@ private let kFibA: UInt = 0x9e3779b9 // = 2654435769 aka Fibonacci Hash a value #error("unsupported architecture") #endif +/// entity id ^ component identifier hash +public typealias EntityComponentHash = Int + +/// component object identifier hash value +public typealias ComponentTypeHash = Int + // MARK: - hash combine /// Calculates the combined hash of two values. This implementation is based on boost::hash_combine. /// Will always produce the same result for the same combination of seed and value during the single run of a program. diff --git a/Sources/FirebladeECS/Nexus+Component.swift b/Sources/FirebladeECS/Nexus+Component.swift index cfa1891..1d39953 100644 --- a/Sources/FirebladeECS/Nexus+Component.swift +++ b/Sources/FirebladeECS/Nexus+Component.swift @@ -11,7 +11,7 @@ public extension Nexus { } final func has(componentId: ComponentIdentifier, entityId: EntityIdentifier) -> Bool { - guard let uniforms: UniformComponents = componentsByType[componentId] else { + guard let uniforms = componentsByType[componentId] else { return false } return uniforms.contains(entityId.index) @@ -34,13 +34,13 @@ public extension Nexus { // add component instances to uniform component stores if componentsByType[componentId] == nil { - componentsByType[componentId] = UniformComponents() + componentsByType[componentId] = ManagedContiguousArray() } componentsByType[componentId]?.insert(component, at: entityId.index) // assigns the component id to the entity id if componentIdsByEntity[entityId] == nil { - componentIdsByEntity[entityId] = ComponentSet() + componentIdsByEntity[entityId] = Set() } componentIdsByEntity[entityId]?.insert(componentId) //, at: componentId.hashValue) @@ -54,14 +54,14 @@ public extension Nexus { } final func get(component componentId: ComponentIdentifier, for entityId: EntityIdentifier) -> Component? { - guard let uniformComponents: UniformComponents = componentsByType[componentId] else { + guard let uniformComponents = componentsByType[componentId] else { return nil } return uniformComponents.get(at: entityId.index) } final func get(unsafeComponent componentId: ComponentIdentifier, for entityId: EntityIdentifier) -> Component { - let uniformComponents: UniformComponents = componentsByType[componentId].unsafelyUnwrapped + let uniformComponents = componentsByType[componentId].unsafelyUnwrapped return uniformComponents.get(unsafeAt: entityId.index) } @@ -76,7 +76,7 @@ public extension Nexus { return unsafeDowncast(component, to: C.self) } - final func get(components entityId: EntityIdentifier) -> ComponentSet? { + final func get(components entityId: EntityIdentifier) -> Set? { return componentIdsByEntity[entityId] } @@ -110,7 +110,7 @@ public extension Nexus { private extension Nexus { final func get(componentId: ComponentIdentifier, entityId: EntityIdentifier) -> C? where C: Component { - guard let uniformComponents: UniformComponents = componentsByType[componentId] else { + guard let uniformComponents = componentsByType[componentId] else { return nil } return uniformComponents.get(at: entityId.index) as? C diff --git a/Sources/FirebladeECS/Nexus+Family.swift b/Sources/FirebladeECS/Nexus+Family.swift index 5fd9787..c219f27 100644 --- a/Sources/FirebladeECS/Nexus+Family.swift +++ b/Sources/FirebladeECS/Nexus+Family.swift @@ -19,8 +19,8 @@ public extension Nexus { return traits.isMatch(components: componentIds) } - func members(withFamilyTraits traits: FamilyTraitSet) -> UniformEntityIdentifiers { - return familyMembersByTraits[traits] ?? UniformEntityIdentifiers() + func members(withFamilyTraits traits: FamilyTraitSet) -> UnorderedSparseSet { + return familyMembersByTraits[traits] ?? UnorderedSparseSet() } func isMember(_ entity: Entity, in family: FamilyTraitSet) -> Bool { diff --git a/Sources/FirebladeECS/Nexus+FamilyUpdate.swift b/Sources/FirebladeECS/Nexus+FamilyUpdate.swift index ebd68e1..1954ba2 100644 --- a/Sources/FirebladeECS/Nexus+FamilyUpdate.swift +++ b/Sources/FirebladeECS/Nexus+FamilyUpdate.swift @@ -12,7 +12,7 @@ extension Nexus { return } - familyMembersByTraits[traits] = UniformEntityIdentifiers() + familyMembersByTraits[traits] = UnorderedSparseSet() update(familyMembership: traits) } diff --git a/Sources/FirebladeECS/Nexus.swift b/Sources/FirebladeECS/Nexus.swift index c379cb0..a7e5337 100644 --- a/Sources/FirebladeECS/Nexus.swift +++ b/Sources/FirebladeECS/Nexus.swift @@ -10,24 +10,23 @@ public class Nexus { /// - Index: index value matching entity identifier shifted to Int /// - Value: each element is a entity instance - @usableFromInline internal var entityStorage: Entities + @usableFromInline var entityStorage: UnorderedSparseSet /// - Key: component type identifier /// - Value: each element is a component instance of the same type (uniform). New component instances are appended. - @usableFromInline internal var componentsByType: [ComponentIdentifier: UniformComponents] + @usableFromInline internal var componentsByType: [ComponentIdentifier: ManagedContiguousArray] /// - Key: entity id as index /// - Value: each element is a component identifier associated with this entity - @usableFromInline internal var componentIdsByEntity: [EntityIdentifier: ComponentSet] + @usableFromInline internal var componentIdsByEntity: [EntityIdentifier: Set] /// - Values: entity ids that are currently not used @usableFromInline internal var freeEntities: ContiguousArray - //var familiesByTraitHash: [FamilyTraitSetHash: Family] - @usableFromInline internal var familyMembersByTraits: [FamilyTraitSet: UniformEntityIdentifiers] + @usableFromInline internal var familyMembersByTraits: [FamilyTraitSet: UnorderedSparseSet] public init() { - entityStorage = Entities() + entityStorage = UnorderedSparseSet() componentsByType = [:] componentIdsByEntity = [:] freeEntities = ContiguousArray() diff --git a/Sources/FirebladeECS/Typealiases.swift b/Sources/FirebladeECS/Typealiases.swift deleted file mode 100644 index d953b4a..0000000 --- a/Sources/FirebladeECS/Typealiases.swift +++ /dev/null @@ -1,21 +0,0 @@ -// -// Typealiases.swift -// -// -// Created by Christian Treffs on 20.08.19. -// - -/// entity id ^ component identifier hash -public typealias EntityComponentHash = Int -public typealias ComponentIdsByEntityIndex = Int -public typealias ComponentTypeHash = Int // component object identifier hash value -public typealias UniformComponents = ManagedContiguousArray -public typealias UniformEntityIdentifiers = UnorderedSparseSet -public typealias ComponentIdentifiers = ContiguousArray -public typealias ComponentSet = Set -public typealias Entities = UnorderedSparseSet -public typealias EntityIdSet = Set -public typealias FamilyTraitSetHash = Int -public typealias TraitEntityIdHash = Int -public typealias EntityIdInFamilyIndex = Int -public typealias TraitEntityIdHashSet = [TraitEntityIdHash: EntityIdInFamilyIndex] diff --git a/Sources/FirebladeECS/TypedFamily.swift b/Sources/FirebladeECS/TypedFamily.swift index a3767d0..4fa2472 100644 --- a/Sources/FirebladeECS/TypedFamily.swift +++ b/Sources/FirebladeECS/TypedFamily.swift @@ -19,7 +19,7 @@ public protocol TypedFamilyProtocol: Equatable, Sequence { var count: Int { get } var isEmpty: Bool { get } - var memberIds: UniformEntityIdentifiers { get } + var memberIds: UnorderedSparseSet { get } var entities: FamilyEntities { get } var entityAndComponents: EntityComponentsSequence { get } @@ -38,7 +38,7 @@ public extension TypedFamilyProtocol { return nexus.isMember(entity, in: traits) } - @inlinable var memberIds: UniformEntityIdentifiers { + @inlinable var memberIds: UnorderedSparseSet { return nexus.members(withFamilyTraits: traits) } @@ -79,7 +79,7 @@ public struct FamilyEntities: LazySequenceProtocol, IteratorProtocol { public let nexus: Nexus public var memberIdsIterator: UnorderedSparseSetIterator - public init(_ nexus: Nexus, _ memberIds: UniformEntityIdentifiers) { + public init(_ nexus: Nexus, _ memberIds: UnorderedSparseSet) { self.nexus = nexus memberIdsIterator = memberIds.makeIterator() }