Modernize project (#66)
* Add Mintfile * Update Makefile * Use old swiftlint and swiftformat versions * Lint * Update SwiftLint and SwiftFormat Versions + Lint * Re-add documented make rules * Update sourcery to 2.2.5 * Update SwiftLint and Lint
This commit is contained in:
parent
a5c98c4963
commit
2c1c5885ae
|
|
@ -0,0 +1,11 @@
|
|||
# file options
|
||||
--exclude Sources/**/*.generated.swift
|
||||
--exclude Sources/FirebladeECS/Entity+Component.swift # problems with self.get { }
|
||||
--exclude Tests/**/*.swift
|
||||
|
||||
# format options
|
||||
--extensionacl on-declarations
|
||||
--stripunusedargs closure-only
|
||||
--commas inline
|
||||
--self remove
|
||||
--selfrequired get
|
||||
|
|
@ -9,23 +9,11 @@ identifier_name:
|
|||
line_length: 220
|
||||
number_separator:
|
||||
minimum_length: 5
|
||||
analyzer_rules:
|
||||
- explicit_self
|
||||
- unused_declaration
|
||||
- unused_import
|
||||
opt_in_rules:
|
||||
#- explicit_acl
|
||||
#- explicit_enum_raw_value
|
||||
#- explicit_type_interface
|
||||
#- extension_access_modifier
|
||||
#- file_name
|
||||
#- file_types_order
|
||||
#- indentation_width
|
||||
#- missing_docs
|
||||
#- multiline_arguments_brackets
|
||||
#- multiline_literal_brackets
|
||||
#- multiline_parameters_brackets
|
||||
#- no_grouping_extension
|
||||
#- required_deinit
|
||||
#- type_contents_order
|
||||
#- unowned_variable_capture
|
||||
- anyobject_protocol
|
||||
- array_init
|
||||
- attributes
|
||||
- closure_body_length
|
||||
|
|
@ -48,7 +36,6 @@ opt_in_rules:
|
|||
- enum_case_associated_values_count
|
||||
- expiring_todo
|
||||
- explicit_init
|
||||
- explicit_self
|
||||
- explicit_top_level_acl
|
||||
- fallthrough
|
||||
- fatal_error_message
|
||||
|
|
@ -109,8 +96,6 @@ opt_in_rules:
|
|||
- unavailable_function
|
||||
- unneeded_parentheses_in_closure_argument
|
||||
- untyped_error_in_catch
|
||||
- unused_declaration
|
||||
- unused_import
|
||||
- vertical_parameter_alignment_on_call
|
||||
- vertical_whitespace_between_cases
|
||||
- vertical_whitespace_closing_braces
|
||||
|
|
|
|||
108
Makefile
108
Makefile
|
|
@ -1,79 +1,61 @@
|
|||
# Version 1.0.0
|
||||
UNAME_S := $(shell uname -s)
|
||||
SWIFT_PACKAGE_VERSION := $(shell swift package tools-version)
|
||||
|
||||
# Lint
|
||||
lint:
|
||||
swiftlint autocorrect --format
|
||||
swiftlint lint --quiet
|
||||
# Lint fix and format code.
|
||||
.PHONY: lint-fix
|
||||
swiftlint:
|
||||
mint run swiftlint lint --fix --config .swiftlint.yml --format --quiet
|
||||
swiftformat:
|
||||
mint run swiftformat . --swiftversion ${SWIFT_PACKAGE_VERSION}
|
||||
lint-fix: swiftlint swiftformat
|
||||
|
||||
lintErrorOnly:
|
||||
@swiftlint autocorrect --format --quiet
|
||||
@swiftlint lint --quiet | grep error
|
||||
# Generate code
|
||||
.PHONY: generate-code
|
||||
generate-code:
|
||||
mint run sourcery --quiet --config ./.sourcery.yml
|
||||
mint run sourcery --quiet --config ./.sourceryTests.yml
|
||||
|
||||
# Git
|
||||
precommit: generateCode generateTestsCode lint genLinuxTests
|
||||
# Run pre-push tasks
|
||||
.PHONY: pre-push
|
||||
pre-push: generate-code lint-fix
|
||||
|
||||
submodule:
|
||||
git submodule init
|
||||
git submodule update --recursive
|
||||
.PHONY: precommit
|
||||
precommit: pre-push
|
||||
|
||||
# Tests
|
||||
genLinuxTests:
|
||||
swift test --generate-linuxmain
|
||||
swiftlint autocorrect --format --path Tests/
|
||||
.PHONY: setup-brew
|
||||
setup-brew:
|
||||
@which -s brew || /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
|
||||
@brew update
|
||||
|
||||
test: genLinuxTests
|
||||
swift test
|
||||
.PHONY: install-dependencies-macOS
|
||||
install-dependencies-macOS: setup-brew
|
||||
brew install mint
|
||||
mint bootstrap
|
||||
|
||||
# Package
|
||||
latest:
|
||||
swift package update
|
||||
.PHONY: setupEnvironment
|
||||
setupEnvironment: install-dependencies-macOS
|
||||
|
||||
resolve:
|
||||
swift package resolve
|
||||
# Build debug version
|
||||
.PHONY: build-debug
|
||||
build-debug:
|
||||
swift build -c debug
|
||||
|
||||
# Xcode
|
||||
genXcode:
|
||||
swift package generate-xcodeproj --enable-code-coverage --skip-extra-files
|
||||
|
||||
genXcodeOpen: genXcode
|
||||
open *.xcodeproj
|
||||
|
||||
# Clean
|
||||
clean:
|
||||
swift package reset
|
||||
-rm -rdf .swiftpm/xcode
|
||||
-rm -rdf .build/
|
||||
-rm Package.resolved
|
||||
-rm .DS_Store
|
||||
|
||||
cleanArtifacts:
|
||||
swift package clean
|
||||
# Build release version
|
||||
.PHONY: build-release
|
||||
build-release:
|
||||
swift build -c release --skip-update
|
||||
|
||||
# Test links in README
|
||||
# requires <https://github.com/tcort/markdown-link-check>
|
||||
.PHONY: testReadme
|
||||
testReadme:
|
||||
markdown-link-check -p -v ./README.md
|
||||
|
||||
generateCode:
|
||||
sourcery --config ./.sourcery.yml --verbose
|
||||
generateTestsCode:
|
||||
sourcery --config ./.sourceryTests.yml --verbose
|
||||
# Delete package build artifacts.
|
||||
.PHONY: clean
|
||||
clean: clean-sourcery
|
||||
swift package clean
|
||||
|
||||
brewInstallDeps: brewUpdate
|
||||
brew install swiftenv
|
||||
brew install swiftlint
|
||||
brew install sourcery
|
||||
|
||||
brewSetup:
|
||||
which -s brew || /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
|
||||
|
||||
brewUpdate: brewSetup
|
||||
brew update
|
||||
|
||||
setupEnvironment: brewInstallDeps
|
||||
open Package.swift
|
||||
|
||||
# lines of code
|
||||
loc: clean
|
||||
find . -name "*.swift" -print0 | xargs -0 wc -l
|
||||
# Clean sourcery cache
|
||||
.PHONY: clean-sourcery
|
||||
clean-sourcery:
|
||||
rm -rdf ${HOME}/Library/Caches/Sourcery
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
realm/SwiftLint@0.57.0
|
||||
nicklockwood/SwiftFormat@0.54.6
|
||||
krzysztofzablocki/Sourcery@2.2.5
|
||||
|
|
@ -13,6 +13,6 @@ public struct DynamicCodingKey: CodingKey {
|
|||
public var intValue: Int?
|
||||
public var stringValue: String
|
||||
|
||||
public init?(intValue: Int) { self.intValue = intValue; self.stringValue = "\(intValue)" }
|
||||
public init?(intValue: Int) { self.intValue = intValue; stringValue = "\(intValue)" }
|
||||
public init?(stringValue: String) { self.stringValue = stringValue }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,14 +14,14 @@ public struct ComponentIdentifier {
|
|||
extension ComponentIdentifier {
|
||||
@usableFromInline
|
||||
init<C>(_ componentType: C.Type) where C: Component {
|
||||
self.id = Self.makeRuntimeHash(componentType)
|
||||
id = Self.makeRuntimeHash(componentType)
|
||||
}
|
||||
|
||||
/// object identifier hash (only stable during runtime) - arbitrary hash is ok.
|
||||
internal static func makeRuntimeHash<C>(_ componentType: C.Type) -> Identifier where C: Component {
|
||||
static func makeRuntimeHash<C>(_ componentType: C.Type) -> Identifier where C: Component {
|
||||
ObjectIdentifier(componentType).hashValue
|
||||
}
|
||||
}
|
||||
|
||||
extension ComponentIdentifier: Equatable { }
|
||||
extension ComponentIdentifier: Hashable { }
|
||||
extension ComponentIdentifier: Equatable {}
|
||||
extension ComponentIdentifier: Hashable {}
|
||||
|
|
|
|||
|
|
@ -17,9 +17,9 @@ public struct Entity {
|
|||
/// The unique entity identifier.
|
||||
public private(set) var identifier: EntityIdentifier
|
||||
|
||||
internal init(nexus: Nexus, id: EntityIdentifier) {
|
||||
init(nexus: Nexus, id: EntityIdentifier) {
|
||||
self.nexus = nexus
|
||||
self.identifier = id
|
||||
identifier = id
|
||||
}
|
||||
|
||||
/// Returns the number of components for this entity.
|
||||
|
|
@ -130,7 +130,7 @@ public struct Entity {
|
|||
|
||||
extension Entity {
|
||||
public struct ComponentsIterator: IteratorProtocol {
|
||||
private var iterator: IndexingIterator<([Component])>?
|
||||
private var iterator: IndexingIterator<[Component]>?
|
||||
|
||||
@usableFromInline
|
||||
init(nexus: Nexus, entityIdentifier: EntityIdentifier) {
|
||||
|
|
@ -144,8 +144,9 @@ extension Entity {
|
|||
}
|
||||
}
|
||||
}
|
||||
extension Entity.ComponentsIterator: LazySequenceProtocol { }
|
||||
extension Entity.ComponentsIterator: Sequence { }
|
||||
|
||||
extension Entity.ComponentsIterator: LazySequenceProtocol {}
|
||||
extension Entity.ComponentsIterator: Sequence {}
|
||||
|
||||
extension Entity: Equatable {
|
||||
public static func == (lhs: Entity, rhs: Entity) -> Bool {
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@ public struct EntityIdentifier {
|
|||
}
|
||||
}
|
||||
|
||||
extension EntityIdentifier: Equatable { }
|
||||
extension EntityIdentifier: Hashable { }
|
||||
extension EntityIdentifier: Equatable {}
|
||||
extension EntityIdentifier: Hashable {}
|
||||
|
||||
extension EntityIdentifier: RawRepresentable {
|
||||
/// The entity identifier represented as a raw value.
|
||||
|
|
@ -33,7 +33,7 @@ extension EntityIdentifier: RawRepresentable {
|
|||
|
||||
@inlinable
|
||||
public init(rawValue: Identifier) {
|
||||
self.id = rawValue
|
||||
id = rawValue
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ public struct LinearIncrementingEntityIdGenerator: EntityIdentifierGenerator {
|
|||
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 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
|
||||
|
|
@ -83,12 +83,12 @@ public struct LinearIncrementingEntityIdGenerator: EntityIdentifierGenerator {
|
|||
|
||||
@inlinable
|
||||
public init<EntityIds>(startProviding initialEntityIds: EntityIds) where EntityIds: BidirectionalCollection, EntityIds.Element == EntityIdentifier {
|
||||
self.storage = Storage(startProviding: initialEntityIds)
|
||||
storage = Storage(startProviding: initialEntityIds)
|
||||
}
|
||||
|
||||
@inlinable
|
||||
public init() {
|
||||
self.storage = Storage()
|
||||
storage = Storage()
|
||||
}
|
||||
|
||||
@inline(__always)
|
||||
|
|
|
|||
|
|
@ -97,9 +97,7 @@ extension ComponentTypeProvider: ComponentProvider {
|
|||
/// This component provider always returns the same instance of the component. The instance
|
||||
/// is created when first required and is of the type passed in to the initializer.
|
||||
public final class ComponentSingletonProvider {
|
||||
private lazy var instance: Component = {
|
||||
componentType.init()
|
||||
}()
|
||||
private lazy var instance: Component = componentType.init()
|
||||
|
||||
private var componentType: ComponentInitializable.Type
|
||||
|
||||
|
|
@ -171,7 +169,7 @@ extension DynamicComponentProvider: ComponentProvider {
|
|||
/// Represents a state for an EntityStateMachine. The state contains any number of ComponentProviders which
|
||||
/// are used to add components to the entity when this state is entered.
|
||||
public class EntityState {
|
||||
internal var providers = [ComponentIdentifier: ComponentProvider]()
|
||||
var providers = [ComponentIdentifier: ComponentProvider]()
|
||||
|
||||
public init() {}
|
||||
|
||||
|
|
@ -272,7 +270,7 @@ public class StateComponentMapping {
|
|||
/// by more specific mappings if other methods are called.
|
||||
/// - Parameter creatingState: The EntityState that the mapping will belong to
|
||||
/// - Parameter type: The component type for the mapping
|
||||
internal init(creatingState: EntityState, type: ComponentInitializable.Type) {
|
||||
init(creatingState: EntityState, type: ComponentInitializable.Type) {
|
||||
self.creatingState = creatingState
|
||||
componentType = type
|
||||
provider = ComponentTypeProvider(type: type)
|
||||
|
|
@ -411,7 +409,8 @@ public class EntityStateMachine<StateIdentifier: Hashable> {
|
|||
|
||||
for (identifier, _) in currentState.providers {
|
||||
if let other = toAdd[identifier], let current = currentState.providers[identifier],
|
||||
current.identifier == other.identifier {
|
||||
current.identifier == other.identifier
|
||||
{
|
||||
toAdd[identifier] = nil
|
||||
} else {
|
||||
entity.remove(identifier)
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ extension CodingUserInfoKey {
|
|||
}
|
||||
|
||||
// MARK: - encoding
|
||||
|
||||
extension FamilyMemberContainer: Encodable where R: FamilyEncoding {
|
||||
func encode(to encoder: Encoder) throws {
|
||||
let strategy = encoder.userInfo[.nexusCodingStrategy] as? CodingStrategy ?? DefaultCodingStrategy()
|
||||
|
|
@ -50,11 +51,12 @@ extension Family where R: FamilyEncoding {
|
|||
}
|
||||
|
||||
// MARK: - decoding
|
||||
|
||||
extension FamilyMemberContainer: Decodable where R: FamilyDecoding {
|
||||
init(from decoder: Decoder) throws {
|
||||
var familyContainer = try decoder.unkeyedContainer()
|
||||
let strategy = decoder.userInfo[.nexusCodingStrategy] as? CodingStrategy ?? DefaultCodingStrategy()
|
||||
self.components = try R.decode(componentsIn: &familyContainer, using: strategy)
|
||||
components = try R.decode(componentsIn: &familyContainer, using: strategy)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ public struct Family<R> where R: FamilyRequirementsManaging {
|
|||
/// - Returns: The newly created member entity.
|
||||
@discardableResult
|
||||
public func createMember(@FamilyMemberBuilder<R> using builder: () -> R.Components) -> Entity {
|
||||
self.createMember(with: builder())
|
||||
createMember(with: builder())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -70,16 +70,17 @@ extension Family: Sequence {
|
|||
}
|
||||
}
|
||||
|
||||
extension Family: LazySequenceProtocol { }
|
||||
extension Family: LazySequenceProtocol {}
|
||||
|
||||
// MARK: - components iterator
|
||||
|
||||
extension Family {
|
||||
public struct ComponentsIterator: IteratorProtocol {
|
||||
@usableFromInline var memberIdsIterator: UnorderedSparseSet<EntityIdentifier, EntityIdentifier.Identifier>.ElementIterator
|
||||
@usableFromInline unowned let nexus: Nexus
|
||||
|
||||
public init(family: Family<R>) {
|
||||
self.nexus = family.nexus
|
||||
nexus = family.nexus
|
||||
memberIdsIterator = family.memberIds.makeIterator()
|
||||
}
|
||||
|
||||
|
|
@ -93,10 +94,11 @@ extension Family {
|
|||
}
|
||||
}
|
||||
|
||||
extension Family.ComponentsIterator: LazySequenceProtocol { }
|
||||
extension Family.ComponentsIterator: Sequence { }
|
||||
extension Family.ComponentsIterator: LazySequenceProtocol {}
|
||||
extension Family.ComponentsIterator: Sequence {}
|
||||
|
||||
// MARK: - entity iterator
|
||||
|
||||
extension Family {
|
||||
@inlinable public var entities: EntityIterator {
|
||||
EntityIterator(family: self)
|
||||
|
|
@ -107,7 +109,7 @@ extension Family {
|
|||
@usableFromInline unowned let nexus: Nexus
|
||||
|
||||
public init(family: Family<R>) {
|
||||
self.nexus = family.nexus
|
||||
nexus = family.nexus
|
||||
memberIdsIterator = family.memberIds.makeIterator()
|
||||
}
|
||||
|
||||
|
|
@ -120,10 +122,11 @@ extension Family {
|
|||
}
|
||||
}
|
||||
|
||||
extension Family.EntityIterator: LazySequenceProtocol { }
|
||||
extension Family.EntityIterator: Sequence { }
|
||||
extension Family.EntityIterator: LazySequenceProtocol {}
|
||||
extension Family.EntityIterator: Sequence {}
|
||||
|
||||
// MARK: - entity component iterator
|
||||
|
||||
extension Family {
|
||||
@inlinable public var entityAndComponents: EntityComponentIterator {
|
||||
EntityComponentIterator(family: self)
|
||||
|
|
@ -134,7 +137,7 @@ extension Family {
|
|||
@usableFromInline unowned let nexus: Nexus
|
||||
|
||||
public init(family: Family<R>) {
|
||||
self.nexus = family.nexus
|
||||
nexus = family.nexus
|
||||
memberIdsIterator = family.memberIds.makeIterator()
|
||||
}
|
||||
|
||||
|
|
@ -147,10 +150,11 @@ extension Family {
|
|||
}
|
||||
}
|
||||
|
||||
extension Family.EntityComponentIterator: LazySequenceProtocol { }
|
||||
extension Family.EntityComponentIterator: Sequence { }
|
||||
extension Family.EntityComponentIterator: LazySequenceProtocol {}
|
||||
extension Family.EntityComponentIterator: Sequence {}
|
||||
|
||||
// MARK: - member creation
|
||||
|
||||
extension Family {
|
||||
/// Create a new entity with components required by this family.
|
||||
///
|
||||
|
|
|
|||
|
|
@ -6,9 +6,9 @@
|
|||
//
|
||||
|
||||
#if swift(<5.4)
|
||||
@_functionBuilder
|
||||
public enum FamilyMemberBuilder<R> where R: FamilyRequirementsManaging { }
|
||||
@_functionBuilder
|
||||
public enum FamilyMemberBuilder<R> where R: FamilyRequirementsManaging {}
|
||||
#else
|
||||
@resultBuilder
|
||||
public enum FamilyMemberBuilder<R> where R: FamilyRequirementsManaging { }
|
||||
@resultBuilder
|
||||
public enum FamilyMemberBuilder<R> where R: FamilyRequirementsManaging {}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ public struct FamilyTraitSet {
|
|||
|
||||
self.requiresAll = requiresAll
|
||||
self.excludesAll = excludesAll
|
||||
self.setHash = FirebladeECS.hash(combine: [requiresAll, excludesAll])
|
||||
setHash = FirebladeECS.hash(combine: [requiresAll, excludesAll])
|
||||
}
|
||||
|
||||
@inlinable
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@
|
|||
//
|
||||
|
||||
#if canImport(Foundation)
|
||||
import Foundation
|
||||
import Foundation
|
||||
|
||||
extension JSONEncoder: TopLevelEncoder { }
|
||||
extension JSONDecoder: TopLevelDecoder { }
|
||||
extension JSONEncoder: TopLevelEncoder {}
|
||||
extension JSONDecoder: TopLevelDecoder {}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
// Generated using Sourcery 1.0.0 — https://github.com/krzysztofzablocki/Sourcery
|
||||
// Generated using Sourcery 2.2.5 — https://github.com/krzysztofzablocki/Sourcery
|
||||
// DO NOT EDIT
|
||||
|
||||
// swiftlint:disable file_length
|
||||
// swiftlint:disable function_parameter_count
|
||||
// swiftlint:disable large_tuple
|
||||
|
|
|
|||
|
|
@ -6,11 +6,11 @@
|
|||
//
|
||||
|
||||
#if arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x) // 64 bit
|
||||
private let kFibA: UInt = 0x9e3779b97f4a7c15 // = 11400714819323198485 aka Fibonacci Hash a value for 2^64; calculate by: 2^64 / (golden ratio)
|
||||
private let kFibA: UInt = 0x9E37_79B9_7F4A_7C15 // = 11400714819323198485 aka Fibonacci Hash a value for 2^64; calculate by: 2^64 / (golden ratio)
|
||||
#elseif arch(i386) || arch(arm) || os(watchOS) || arch(wasm32) // 32 bit
|
||||
private let kFibA: UInt = 0x9e3779b9 // = 2654435769 aka Fibonacci Hash a value for 2^32; calculate by: 2^32 / (golden ratio)
|
||||
private let kFibA: UInt = 0x9E37_79B9 // = 2654435769 aka Fibonacci Hash a value for 2^32; calculate by: 2^32 / (golden ratio)
|
||||
#else
|
||||
#error("unsupported architecture")
|
||||
#error("unsupported architecture")
|
||||
#endif
|
||||
|
||||
/// entity id ^ component identifier hash
|
||||
|
|
@ -20,6 +20,7 @@ public typealias EntityComponentHash = Int
|
|||
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.
|
||||
///
|
||||
|
|
@ -55,27 +56,29 @@ public func hash<H: Sequence>(combine hashValues: H) -> Int where H.Element: Has
|
|||
}
|
||||
|
||||
// MARK: - entity component hash
|
||||
|
||||
extension EntityComponentHash {
|
||||
internal static func compose(entityId: EntityIdentifier, componentTypeHash: ComponentTypeHash) -> EntityComponentHash {
|
||||
static func compose(entityId: EntityIdentifier, componentTypeHash: ComponentTypeHash) -> EntityComponentHash {
|
||||
let entityIdSwapped = UInt(entityId.id).byteSwapped // needs to be 64 bit
|
||||
let componentTypeHashUInt = UInt(bitPattern: componentTypeHash)
|
||||
let hashUInt: UInt = componentTypeHashUInt ^ entityIdSwapped
|
||||
return Int(bitPattern: hashUInt)
|
||||
}
|
||||
|
||||
internal static func decompose(_ hash: EntityComponentHash, with entityId: EntityIdentifier) -> ComponentTypeHash {
|
||||
static func decompose(_ hash: EntityComponentHash, with entityId: EntityIdentifier) -> ComponentTypeHash {
|
||||
let entityIdSwapped = UInt(entityId.id).byteSwapped
|
||||
let entityIdSwappedInt = Int(bitPattern: entityIdSwapped)
|
||||
return hash ^ entityIdSwappedInt
|
||||
}
|
||||
|
||||
internal static func decompose(_ hash: EntityComponentHash, with componentTypeHash: ComponentTypeHash) -> EntityIdentifier {
|
||||
static func decompose(_ hash: EntityComponentHash, with componentTypeHash: ComponentTypeHash) -> EntityIdentifier {
|
||||
let entityId: Int = (hash ^ componentTypeHash).byteSwapped
|
||||
return EntityIdentifier(UInt32(truncatingIfNeeded: entityId))
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - string hashing
|
||||
|
||||
/// <https://stackoverflow.com/a/52440609>
|
||||
public enum StringHashing {
|
||||
/// *Waren Singer djb2*
|
||||
|
|
@ -85,7 +88,7 @@ public enum StringHashing {
|
|||
var hash: UInt64 = 5381
|
||||
var iter = utf8String.unicodeScalars.makeIterator()
|
||||
while let char = iter.next() {
|
||||
hash = 127 * (hash & 0xFFFFFFFFFFFFFF) &+ UInt64(char.value)
|
||||
hash = 127 * (hash & 0xFF_FFFF_FFFF_FFFF) &+ UInt64(char.value)
|
||||
}
|
||||
return hash
|
||||
}
|
||||
|
|
|
|||
|
|
@ -92,6 +92,7 @@ public struct ManagedContiguousArray<Element> {
|
|||
}
|
||||
|
||||
// MARK: - Equatable
|
||||
|
||||
extension ManagedContiguousArray: Equatable where Element: Equatable {
|
||||
public static func == (lhs: ManagedContiguousArray<Element>, rhs: ManagedContiguousArray<Element>) -> Bool {
|
||||
lhs.store == rhs.store
|
||||
|
|
@ -99,4 +100,5 @@ extension ManagedContiguousArray: Equatable where Element: Equatable {
|
|||
}
|
||||
|
||||
// MARK: - Codable
|
||||
extension ManagedContiguousArray: Codable where Element: Codable { }
|
||||
|
||||
extension ManagedContiguousArray: Codable where Element: Codable {}
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ extension Nexus {
|
|||
return false
|
||||
}
|
||||
var iter = allComponents.makeIterator()
|
||||
var removedAll: Bool = true
|
||||
var removedAll = true
|
||||
while let component = iter.next() {
|
||||
removedAll = removedAll && remove(component: component, from: entityId)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,11 +6,11 @@
|
|||
//
|
||||
|
||||
#if swift(<5.4)
|
||||
@_functionBuilder
|
||||
public enum ComponentsBuilder { }
|
||||
@_functionBuilder
|
||||
public enum ComponentsBuilder {}
|
||||
#else
|
||||
@resultBuilder
|
||||
public enum ComponentsBuilder { }
|
||||
@resultBuilder
|
||||
public enum ComponentsBuilder {}
|
||||
#endif
|
||||
|
||||
extension ComponentsBuilder {
|
||||
|
|
@ -39,7 +39,7 @@ extension Nexus {
|
|||
/// - Returns: The newly created entity with the provided component assigned.
|
||||
@discardableResult
|
||||
public func createEntity(@ComponentsBuilder using builder: () -> Component) -> Entity {
|
||||
self.createEntity(with: builder())
|
||||
createEntity(with: builder())
|
||||
}
|
||||
|
||||
/// Create an entity assigning multiple components.
|
||||
|
|
@ -55,7 +55,7 @@ extension Nexus {
|
|||
/// - Returns: The newly created entity with the provided components assigned.
|
||||
@discardableResult
|
||||
public func createEntity(@ComponentsBuilder using builder: () -> [Component]) -> Entity {
|
||||
self.createEntity(with: builder())
|
||||
createEntity(with: builder())
|
||||
}
|
||||
|
||||
/// Create multiple entities assigning one component each.
|
||||
|
|
@ -72,7 +72,7 @@ extension Nexus {
|
|||
/// - Returns: The newly created entities with the provided component assigned.
|
||||
@discardableResult
|
||||
public func createEntities(count: Int, @ComponentsBuilder using builder: (ComponentsBuilder.Context) -> Component) -> [Entity] {
|
||||
(0..<count).map { self.createEntity(with: builder(ComponentsBuilder.Context(index: $0))) }
|
||||
(0 ..< count).map { self.createEntity(with: builder(ComponentsBuilder.Context(index: $0))) }
|
||||
}
|
||||
|
||||
/// Create multiple entities assigning multiple components each.
|
||||
|
|
@ -90,6 +90,6 @@ extension Nexus {
|
|||
/// - Returns: The newly created entities with the provided components assigned.
|
||||
@discardableResult
|
||||
public func createEntities(count: Int, @ComponentsBuilder using builder: (ComponentsBuilder.Context) -> [Component] = { _ in [] }) -> [Entity] {
|
||||
(0..<count).map { self.createEntity(with: builder(ComponentsBuilder.Context(index: $0))) }
|
||||
(0 ..< count).map { self.createEntity(with: builder(ComponentsBuilder.Context(index: $0))) }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ extension Nexus {
|
|||
|
||||
@discardableResult
|
||||
public func createEntity<C>(with components: C) -> Entity where C: Collection, C.Element == Component {
|
||||
let entity = self.createEntity()
|
||||
let entity = createEntity()
|
||||
assign(components: components, to: entity.identifier)
|
||||
return entity
|
||||
}
|
||||
|
|
@ -50,7 +50,7 @@ extension Nexus {
|
|||
|
||||
@discardableResult
|
||||
public func destroy(entity: Entity) -> Bool {
|
||||
self.destroy(entityId: entity.identifier)
|
||||
destroy(entityId: entity.identifier)
|
||||
}
|
||||
|
||||
@discardableResult
|
||||
|
|
@ -76,6 +76,7 @@ extension Nexus {
|
|||
}
|
||||
|
||||
// MARK: - entities iterator
|
||||
|
||||
extension Nexus {
|
||||
public struct EntitiesIterator: IteratorProtocol {
|
||||
private var iterator: AnyIterator<Entity>
|
||||
|
|
@ -96,5 +97,6 @@ extension Nexus {
|
|||
}
|
||||
}
|
||||
}
|
||||
extension Nexus.EntitiesIterator: LazySequenceProtocol { }
|
||||
extension Nexus.EntitiesIterator: Sequence { }
|
||||
|
||||
extension Nexus.EntitiesIterator: LazySequenceProtocol {}
|
||||
extension Nexus.EntitiesIterator: Sequence {}
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@ extension Nexus {
|
|||
}
|
||||
|
||||
let isMember: Bool = self.isMember(entity: entityId, inFamilyWithTraits: traits)
|
||||
if !exists(entity: entityId) && isMember {
|
||||
if !exists(entity: entityId), isMember {
|
||||
remove(entityWithId: entityId, fromFamilyWithTraits: traits)
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,13 +42,14 @@ public final class Nexus {
|
|||
codingStrategy: DefaultCodingStrategy())
|
||||
}
|
||||
|
||||
internal init(componentsByType: [ComponentIdentifier: ManagedContiguousArray<Component>],
|
||||
componentsByEntity: [EntityIdentifier: Set<ComponentIdentifier>],
|
||||
entityIdGenerator: EntityIdentifierGenerator,
|
||||
familyMembersByTraits: [FamilyTraitSet: UnorderedSparseSet<EntityIdentifier, EntityIdentifier.Identifier>],
|
||||
codingStrategy: CodingStrategy) {
|
||||
init(componentsByType: [ComponentIdentifier: ManagedContiguousArray<Component>],
|
||||
componentsByEntity: [EntityIdentifier: Set<ComponentIdentifier>],
|
||||
entityIdGenerator: EntityIdentifierGenerator,
|
||||
familyMembersByTraits: [FamilyTraitSet: UnorderedSparseSet<EntityIdentifier, EntityIdentifier.Identifier>],
|
||||
codingStrategy: CodingStrategy)
|
||||
{
|
||||
self.componentsByType = componentsByType
|
||||
self.componentIdsByEntity = componentsByEntity
|
||||
componentIdsByEntity = componentsByEntity
|
||||
self.familyMembersByTraits = familyMembersByTraits
|
||||
self.entityIdGenerator = entityIdGenerator
|
||||
self.codingStrategy = codingStrategy
|
||||
|
|
@ -66,6 +67,7 @@ public final class Nexus {
|
|||
}
|
||||
|
||||
// MARK: - CustomDebugStringConvertible
|
||||
|
||||
extension Nexus: CustomDebugStringConvertible {
|
||||
public var debugDescription: String {
|
||||
"<Nexus entities:\(numEntities) components:\(numComponents) families:\(numFamilies)>"
|
||||
|
|
@ -73,8 +75,9 @@ extension Nexus: CustomDebugStringConvertible {
|
|||
}
|
||||
|
||||
// MARK: - default coding strategy
|
||||
|
||||
public struct DefaultCodingStrategy: CodingStrategy {
|
||||
public init() { }
|
||||
public init() {}
|
||||
|
||||
public func codingKey<C>(for componentType: C.Type) -> DynamicCodingKey where C: Component {
|
||||
DynamicCodingKey(stringValue: "\(C.self)").unsafelyUnwrapped
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// NexusEvents.swift
|
||||
// NexusEvent.swift
|
||||
// FirebladeECS
|
||||
//
|
||||
// Created by Christian Treffs on 08.10.17.
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ extension Single where A: SingleComponent {
|
|||
}
|
||||
|
||||
public var entity: Entity {
|
||||
Entity(nexus: self.nexus, id: entityId)
|
||||
Entity(nexus: nexus, id: entityId)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ public struct UnorderedSparseSet<Element, Key: Hashable & Codable> {
|
|||
guard let denseIndex = findIndex(at: key) else {
|
||||
return nil
|
||||
}
|
||||
let entry = self.dense[denseIndex]
|
||||
let entry = dense[denseIndex]
|
||||
assert(entry.key == key, "entry.key and findIndex(at: key) must be equal!")
|
||||
return entry.element
|
||||
}
|
||||
|
|
@ -99,7 +99,7 @@ public struct UnorderedSparseSet<Element, Key: Hashable & Codable> {
|
|||
}
|
||||
|
||||
let removed = swapRemove(at: denseIndex)
|
||||
if !dense.isEmpty && denseIndex < dense.count {
|
||||
if !dense.isEmpty, denseIndex < dense.count {
|
||||
let swappedElement = dense[denseIndex]
|
||||
sparse[swappedElement.key] = denseIndex
|
||||
}
|
||||
|
|
@ -208,12 +208,14 @@ extension UnorderedSparseSet where Key == Int {
|
|||
}
|
||||
|
||||
// MARK: - Sequence
|
||||
|
||||
extension UnorderedSparseSet: Sequence {
|
||||
public func makeIterator() -> ElementIterator {
|
||||
ElementIterator(self)
|
||||
}
|
||||
|
||||
// MARK: - UnorderedSparseSetIterator
|
||||
|
||||
public struct ElementIterator: IteratorProtocol {
|
||||
var iterator: IndexingIterator<ContiguousArray<Storage.Entry>>
|
||||
|
||||
|
|
@ -226,17 +228,20 @@ extension UnorderedSparseSet: Sequence {
|
|||
}
|
||||
}
|
||||
}
|
||||
extension UnorderedSparseSet.ElementIterator: LazySequenceProtocol { }
|
||||
extension UnorderedSparseSet.ElementIterator: Sequence { }
|
||||
|
||||
extension UnorderedSparseSet.ElementIterator: LazySequenceProtocol {}
|
||||
extension UnorderedSparseSet.ElementIterator: Sequence {}
|
||||
|
||||
// MARK: - Equatable
|
||||
extension UnorderedSparseSet.Storage.Entry: Equatable where Element: Equatable { }
|
||||
|
||||
extension UnorderedSparseSet.Storage.Entry: Equatable where Element: Equatable {}
|
||||
extension UnorderedSparseSet.Storage: Equatable where Element: Equatable {
|
||||
@usableFromInline
|
||||
static func == (lhs: UnorderedSparseSet<Element, Key>.Storage, rhs: UnorderedSparseSet<Element, Key>.Storage) -> Bool {
|
||||
lhs.dense == rhs.dense && lhs.sparse == rhs.sparse
|
||||
}
|
||||
}
|
||||
|
||||
extension UnorderedSparseSet: Equatable where Element: Equatable {
|
||||
public static func == (lhs: UnorderedSparseSet<Element, Key>, rhs: UnorderedSparseSet<Element, Key>) -> Bool {
|
||||
lhs.storage == rhs.storage
|
||||
|
|
@ -244,6 +249,7 @@ extension UnorderedSparseSet: Equatable where Element: Equatable {
|
|||
}
|
||||
|
||||
// MARK: - Codable
|
||||
extension UnorderedSparseSet.Storage.Entry: Codable where Element: Codable { }
|
||||
extension UnorderedSparseSet.Storage: Codable where Element: Codable { }
|
||||
extension UnorderedSparseSet: Codable where Element: Codable { }
|
||||
|
||||
extension UnorderedSparseSet.Storage.Entry: Codable where Element: Codable {}
|
||||
extension UnorderedSparseSet.Storage: Codable where Element: Codable {}
|
||||
extension UnorderedSparseSet: Codable where Element: Codable {}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
// Generated using Sourcery 1.0.0 — https://github.com/krzysztofzablocki/Sourcery
|
||||
// Generated using Sourcery 2.2.5 — https://github.com/krzysztofzablocki/Sourcery
|
||||
// DO NOT EDIT
|
||||
|
||||
import FirebladeECS
|
||||
import XCTest
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue