-
-
Notifications
You must be signed in to change notification settings - Fork 12
Expand file tree
/
Copy pathEntity.swift
More file actions
215 lines (188 loc) · 7.59 KB
/
Copy pathEntity.swift
File metadata and controls
215 lines (188 loc) · 7.59 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
//
// Entity.swift
// FirebladeECS
//
// Created by Christian Treffs on 08.10.17.
//
/// **Entity**
///
/// An entity is a general purpose object.
/// It only consists of a unique id (EntityIdentifier).
/// Components can be assigned to an entity to give it behavior or functionality.
/// An entity creates the relationship between all it's assigned components.
public struct Entity {
/// The Nexus managing this entity.
@usableFromInline unowned let nexus: Nexus
/// The unique entity identifier.
public private(set) var identifier: EntityIdentifier
/// Initializes a new entity instance.
///
/// Entities are value types that act as a handle to the data stored in the `Nexus`.
/// - Parameters:
/// - nexus: The nexus managing this entity's components.
/// - id: The unique identifier for this entity.
/// - Complexity: O(1)
init(nexus: Nexus, id: EntityIdentifier) {
self.nexus = nexus
identifier = id
}
/// Returns the number of components for this entity.
/// - Complexity: O(1)
public var numComponents: Int {
nexus.count(components: identifier)
}
/// Creates a new entity.
/// - Returns: The created entity.
/// - Complexity: O(1)
@discardableResult
public func createEntity() -> Entity {
nexus.createEntity()
}
/// Creates a new entity with the provided components.
/// - Parameter components: The components to assign to the new entity.
/// - Returns: The created entity.
/// - Complexity: O(C + M) where C is the number of components and M is the number of families.
@discardableResult
public func createEntity<each C: Component>(with components: repeat each C) -> Entity {
nexus.createEntity(with: repeat each components)
}
/// Creates a new entity with the provided components.
/// - Parameter components: The components to assign to the new entity.
/// - Returns: The created entity.
/// - Complexity: O(C + M) where C is the number of components and M is the number of families.
@discardableResult
public func createEntity(with components: some Collection<Component>) -> Entity {
nexus.createEntity(with: components)
}
/// Checks if a component with given type is assigned to this entity.
/// - Parameter type: the component type.
/// - Complexity: O(1)
public func has(_ type: (some Component).Type) -> Bool {
has(type.identifier)
}
/// Checks if a component with a given component identifier is assigned to this entity.
/// - Parameter compId: the component identifier.
/// - Complexity: O(1)
public func has(_ compId: ComponentIdentifier) -> Bool {
nexus.has(componentId: compId, entityId: identifier)
}
/// Checks if this entity has any components.
/// - Complexity: O(1)
public var hasComponents: Bool {
nexus.count(components: identifier) > 0
}
/// Add one or more components to this entity.
/// - Parameter components: one or more components.
/// - Complexity: O(M) where M is the number of families.
@discardableResult
public func assign<each C: Component>(_ components: repeat each C) -> Entity {
nexus.assign(components: repeat each components, to: self)
return self
}
/// Add a single component to this entity.
/// - Parameter component: a component.
/// - Complexity: O(M) where M is the number of families.
@discardableResult
public func assign(_ component: Component) -> Entity {
nexus.assign(component: component, to: self)
return self
}
/// Assigns a collection of components to this entity.
/// - Parameter components: The components to assign.
/// - Returns: This entity (for chaining).
/// - Complexity: O(C + M) where C is the number of components and M is the number of families.
@discardableResult
public func assign(_ components: some Collection<Component>) -> Entity {
nexus.assign(components: components, to: self)
return self
}
/// Remove a component from this entity.
/// - Parameter component: the component.
/// - Complexity: O(M) where M is the number of families.
@discardableResult
public func remove(_ component: some Component) -> Entity {
remove(component.identifier)
}
/// Remove a component by type from this entity.
/// - Parameter compType: the component type.
/// - Complexity: O(M) where M is the number of families.
@discardableResult
public func remove(_ compType: (some Component).Type) -> Entity {
remove(compType.identifier)
}
/// Remove a component by id from this entity.
/// - Parameter compId: the component id.
/// - Complexity: O(M) where M is the number of families.
@discardableResult
public func remove(_ compId: ComponentIdentifier) -> Entity {
nexus.remove(component: compId, from: identifier)
return self
}
/// Remove all components from this entity.
/// - Complexity: O(C * M) where C is the number of components and M is the number of families.
public func removeAll() {
nexus.removeAll(components: identifier)
}
/// Destroy this entity.
/// - Complexity: O(C * M) where C is the number of components and M is the number of families.
public func destroy() {
nexus.destroy(entity: self)
}
/// Returns an iterator over all components of this entity.
/// - Complexity: O(1)
@inlinable
public func makeComponentsIterator() -> ComponentsIterator {
ComponentsIterator(nexus: nexus, entityIdentifier: identifier)
}
}
extension Entity {
/// An iterator over the components of an entity.
public struct ComponentsIterator: IteratorProtocol {
private var iterator: IndexingIterator<[Component]>?
/// Creates a new iterator for the given entity.
/// - Parameters:
/// - nexus: The nexus instance.
/// - entityIdentifier: The entity identifier.
/// - Complexity: O(C) where C is the number of components.
@usableFromInline
init(nexus: Nexus, entityIdentifier: EntityIdentifier) {
iterator = nexus.get(components: entityIdentifier)?
.map { nexus.get(unsafe: $0, for: entityIdentifier) }
.makeIterator()
}
/// Advances to the next component and returns it, or `nil` if no next element exists.
/// - Returns: The next component in the sequence, or `nil`.
/// - Complexity: O(1)
public mutating func next() -> Component? {
iterator?.next()
}
}
}
extension Entity.ComponentsIterator: LazySequenceProtocol {}
extension Entity.ComponentsIterator: Sequence {}
extension Entity: Equatable {
/// Returns a Boolean value indicating whether two entities are equal.
///
/// Entities are considered equal if they belong to the same Nexus and have the same identifier.
/// - Parameters:
/// - lhs: An entity to compare.
/// - rhs: Another entity to compare.
/// - Complexity: O(1)
public static func == (lhs: Entity, rhs: Entity) -> Bool {
lhs.nexus === rhs.nexus && lhs.identifier == rhs.identifier
}
}
extension Entity: CustomStringConvertible {
/// A textual representation of the entity.
/// - Complexity: O(1)
public var description: String {
"<Entity id:\(identifier.id)>"
}
}
extension Entity: CustomDebugStringConvertible {
/// A textual representation of the entity, suitable for debugging.
public var debugDescription: String {
"<Entity id:\(identifier.id) numComponents:\(numComponents)>"
}
}
extension Entity: Sendable {}