• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mlange-42 / ark / 13618572525

02 Mar 2025 07:23PM CUT coverage: 96.93% (-0.5%) from 97.422%
13618572525

Pull #91

github

web-flow
Merge a19dd6549 into a609eb208
Pull Request #91: Batch operations

511 of 550 new or added lines in 6 files covered. (92.91%)

14 existing lines in 1 file now uncovered.

4389 of 4528 relevant lines covered (96.93%)

40787.75 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.8
/ecs/maps_gen.go
1
package ecs
2

3
// Code generated by go generate; DO NOT EDIT.
4

5
import "unsafe"
6

7
// Map1 is a mapper to access 1 components of an entity.
8
type Map1[A any] struct {
9
        world     *World
10
        ids       []ID
11
        storageA  *componentStorage
12
        relations []RelationID
13
}
14

15
// NewMap1 creates a new [Map1].
16
func NewMap1[A any](world *World) Map1[A] {
28✔
17
        ids := []ID{
28✔
18
                ComponentID[A](world),
28✔
19
        }
28✔
20
        return Map1[A]{
28✔
21
                world:    world,
28✔
22
                ids:      ids,
28✔
23
                storageA: &world.storage.components[ids[0].id],
28✔
24
        }
28✔
25
}
28✔
26

27
// NewEntity creates a new entity with the mapped components.
28
func (m *Map1[A]) NewEntity(a *A, rel ...RelationIndex) Entity {
97✔
29
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
97✔
30
        return m.world.newEntityWith(m.ids, []unsafe.Pointer{
97✔
31
                unsafe.Pointer(a),
97✔
32
        }, m.relations)
97✔
33
}
97✔
34

35
// NewBatch creates a batch of new entities with the mapped components.
36
func (m *Map1[A]) NewBatch(count int, a *A, rel ...RelationIndex) {
1✔
37
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
1✔
38
        m.world.newEntitiesWith(count, m.ids, []unsafe.Pointer{
1✔
39
                unsafe.Pointer(a),
1✔
40
        }, m.relations)
1✔
41
}
1✔
42

43
// NewBatchFn creates a batch of new entities with the mapped components, running the given initializer function on each.
44
// The initializer function can be nil.
45
func (m *Map1[A]) NewBatchFn(count int, fn func(entity Entity, a *A), rel ...RelationIndex) {
17✔
46
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
17✔
47
        tableID, start := m.world.newEntities(count, m.ids, m.relations)
17✔
48
        if fn == nil {
17✔
49
                return
×
50
        }
×
51

52
        table := &m.world.storage.tables[tableID]
17✔
53
        columnA := m.storageA.columns[tableID]
17✔
54

17✔
55
        lock := m.world.lock()
17✔
56
        for i := range count {
233✔
57
                index := uintptr(start + i)
216✔
58
                fn(
216✔
59
                        table.GetEntity(index),
216✔
60
                        (*A)(columnA.Get(index)),
216✔
61
                )
216✔
62
        }
216✔
63
        m.world.unlock(lock)
17✔
64
}
65

66
// Get returns the mapped components for the given entity.
67
func (m *Map1[A]) Get(entity Entity) *A {
409✔
68
        if !m.world.Alive(entity) {
410✔
69
                panic("can't get components of a dead entity")
1✔
70
        }
71
        return m.GetUnchecked(entity)
408✔
72
}
73

74
// GetUnchecked returns the mapped components for the given entity.
75
// In contrast to [Map1.Get], it does not check whether the entity is alive.
76
// Can be used as an optimization when it is certain that the entity is alive.
77
func (m *Map1[A]) GetUnchecked(entity Entity) *A {
408✔
78
        m.world.storage.checkHasComponent(entity, m.ids[0])
408✔
79

408✔
80
        index := m.world.storage.entities[entity.id]
408✔
81
        row := uintptr(index.row)
408✔
82

408✔
83
        return (*A)(m.storageA.columns[index.table].Get(row))
408✔
84
}
408✔
85

86
// HasAll return whether the given entity has all mapped components.
87
func (m *Map1[A]) HasAll(entity Entity) bool {
54✔
88
        if !m.world.Alive(entity) {
55✔
89
                panic("can't check components of a dead entity")
1✔
90
        }
91
        index := m.world.storage.entities[entity.id]
53✔
92
        return m.storageA.columns[index.table] != nil
53✔
93
}
94

95
// Add the mapped components to the given entity.
96
func (m *Map1[A]) Add(entity Entity, a *A, rel ...RelationIndex) {
14✔
97
        if !m.world.Alive(entity) {
15✔
98
                panic("can't add components to a dead entity")
1✔
99
        }
100
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
13✔
101
        m.world.exchange(entity, m.ids, nil, []unsafe.Pointer{
13✔
102
                unsafe.Pointer(a),
13✔
103
        }, m.relations)
13✔
104
}
105

106
// AddBatch adds the mapped components to all entities matching the given batch filter.
107
func (m *Map1[A]) AddBatch(batch *Batch, a *A, rel ...RelationIndex) {
1✔
108
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
1✔
109
        m.world.exchangeBatch(batch, m.ids, nil, []unsafe.Pointer{
1✔
110
                unsafe.Pointer(a),
1✔
111
        }, m.relations, nil)
1✔
112
}
1✔
113

114
// AddBatchFn adds the mapped components to all entities matching the given batch filter,
115
// running the given function on each. The function can be nil.
116
func (m *Map1[A]) AddBatchFn(batch *Batch, fn func(entity Entity, a *A), rel ...RelationIndex) {
1✔
117
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
1✔
118

1✔
119
        var process func(tableID tableID, start, len int)
1✔
120
        if fn != nil {
2✔
121
                process = func(tableID tableID, start, len int) {
3✔
122
                        table := &m.world.storage.tables[tableID]
2✔
123
                        columnA := m.storageA.columns[tableID]
2✔
124

2✔
125
                        lock := m.world.lock()
2✔
126
                        for i := range len {
26✔
127
                                index := uintptr(start + i)
24✔
128
                                fn(
24✔
129
                                        table.GetEntity(index),
24✔
130
                                        (*A)(columnA.Get(index)),
24✔
131
                                )
24✔
132
                        }
24✔
133
                        m.world.unlock(lock)
2✔
134
                }
135
        }
136
        m.world.exchangeBatch(batch, m.ids, nil, nil, m.relations, process)
1✔
137
}
138

139
// Remove the mapped components from the given entity.
140
func (m *Map1[A]) Remove(entity Entity) {
25✔
141
        if !m.world.Alive(entity) {
26✔
142
                panic("can't remove components from a dead entity")
1✔
143
        }
144
        m.world.exchange(entity, nil, m.ids, nil, nil)
24✔
145
}
146

147
// RemoveBatch removes the mapped components from all entities matching the given batch filter.
148
func (m *Map1[A]) RemoveBatch(batch *Batch) {
1✔
149
        m.world.exchangeBatch(batch, nil, m.ids, nil, nil, nil)
1✔
150
}
1✔
151

152
// RemoveBatchFn removes the mapped components from all entities matching the given batch filter,
153
// running the given function on each. The function can be nil.
154
func (m *Map1[A]) RemoveBatchFn(batch *Batch, fn func(entity Entity)) {
1✔
155
        var process func(tableID tableID, start, len int)
1✔
156
        if fn != nil {
2✔
157
                process = func(tableID tableID, start, len int) {
3✔
158
                        table := &m.world.storage.tables[tableID]
2✔
159

2✔
160
                        lock := m.world.lock()
2✔
161
                        for i := range len {
26✔
162
                                index := uintptr(start + i)
24✔
163
                                fn(table.GetEntity(index))
24✔
164
                        }
24✔
165
                        m.world.unlock(lock)
2✔
166
                }
167
        }
168
        m.world.exchangeBatch(batch, nil, m.ids, nil, nil, process)
1✔
169
}
170

171
// GetRelation returns the relation target of an entity for the component at the given index.
172
func (m *Map1[A]) GetRelation(entity Entity, index int) Entity {
3✔
173
        if !m.world.Alive(entity) {
4✔
174
                panic("can't get entity relation target for a dead entity")
1✔
175
        }
176
        return m.GetRelationUnchecked(entity, index)
2✔
177
}
178

179
// GetRelationUnchecked returns the relation target of an entity for the component at the given index.
180
// In contrast to [Map1.GetRelation], it does not check whether the entity is alive.
181
// Can be used as an optimization when it is certain that the entity is alive.
182
func (m *Map1[A]) GetRelationUnchecked(entity Entity, index int) Entity {
3✔
183
        return m.world.storage.getRelation(entity, m.ids[index])
3✔
184
}
3✔
185

186
// SetRelations sets relation targets for the given entity.
187
func (m *Map1[A]) SetRelations(entity Entity, rel ...RelationIndex) {
2✔
188
        if !m.world.Alive(entity) {
3✔
189
                panic("can't set entity relation targets for a dead entity")
1✔
190
        }
191
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
1✔
192
        m.world.setRelations(entity, m.relations)
1✔
193
}
194

195
// Map2 is a mapper to access 2 components of an entity.
196
type Map2[A any, B any] struct {
197
        world     *World
198
        ids       []ID
199
        storageA  *componentStorage
200
        storageB  *componentStorage
201
        relations []RelationID
202
}
203

204
// NewMap2 creates a new [Map2].
205
func NewMap2[A any, B any](world *World) Map2[A, B] {
54✔
206
        ids := []ID{
54✔
207
                ComponentID[A](world),
54✔
208
                ComponentID[B](world),
54✔
209
        }
54✔
210
        return Map2[A, B]{
54✔
211
                world:    world,
54✔
212
                ids:      ids,
54✔
213
                storageA: &world.storage.components[ids[0].id],
54✔
214
                storageB: &world.storage.components[ids[1].id],
54✔
215
        }
54✔
216
}
54✔
217

218
// NewEntity creates a new entity with the mapped components.
219
func (m *Map2[A, B]) NewEntity(a *A, b *B, rel ...RelationIndex) Entity {
255✔
220
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
255✔
221
        return m.world.newEntityWith(m.ids, []unsafe.Pointer{
255✔
222
                unsafe.Pointer(a),
255✔
223
                unsafe.Pointer(b),
255✔
224
        }, m.relations)
255✔
225
}
255✔
226

227
// NewBatch creates a batch of new entities with the mapped components.
228
func (m *Map2[A, B]) NewBatch(count int, a *A, b *B, rel ...RelationIndex) {
1✔
229
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
1✔
230
        m.world.newEntitiesWith(count, m.ids, []unsafe.Pointer{
1✔
231
                unsafe.Pointer(a),
1✔
232
                unsafe.Pointer(b),
1✔
233
        }, m.relations)
1✔
234
}
1✔
235

236
// NewBatchFn creates a batch of new entities with the mapped components, running the given initializer function on each.
237
// The initializer function can be nil.
238
func (m *Map2[A, B]) NewBatchFn(count int, fn func(entity Entity, a *A, b *B), rel ...RelationIndex) {
17✔
239
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
17✔
240
        tableID, start := m.world.newEntities(count, m.ids, m.relations)
17✔
241
        if fn == nil {
17✔
UNCOV
242
                return
×
UNCOV
243
        }
×
244

245
        table := &m.world.storage.tables[tableID]
17✔
246
        columnA := m.storageA.columns[tableID]
17✔
247
        columnB := m.storageB.columns[tableID]
17✔
248

17✔
249
        lock := m.world.lock()
17✔
250
        for i := range count {
233✔
251
                index := uintptr(start + i)
216✔
252
                fn(
216✔
253
                        table.GetEntity(index),
216✔
254
                        (*A)(columnA.Get(index)),
216✔
255
                        (*B)(columnB.Get(index)),
216✔
256
                )
216✔
257
        }
216✔
258
        m.world.unlock(lock)
17✔
259
}
260

261
// Get returns the mapped components for the given entity.
262
func (m *Map2[A, B]) Get(entity Entity) (*A, *B) {
25✔
263
        if !m.world.Alive(entity) {
26✔
264
                panic("can't get components of a dead entity")
1✔
265
        }
266
        return m.GetUnchecked(entity)
24✔
267
}
268

269
// GetUnchecked returns the mapped components for the given entity.
270
// In contrast to [Map2.Get], it does not check whether the entity is alive.
271
// Can be used as an optimization when it is certain that the entity is alive.
272
func (m *Map2[A, B]) GetUnchecked(entity Entity) (*A, *B) {
24✔
273
        m.world.storage.checkHasComponent(entity, m.ids[0])
24✔
274
        m.world.storage.checkHasComponent(entity, m.ids[1])
24✔
275

24✔
276
        index := m.world.storage.entities[entity.id]
24✔
277
        row := uintptr(index.row)
24✔
278

24✔
279
        return (*A)(m.storageA.columns[index.table].Get(row)),
24✔
280
                (*B)(m.storageB.columns[index.table].Get(row))
24✔
281
}
24✔
282

283
// HasAll return whether the given entity has all mapped components.
284
func (m *Map2[A, B]) HasAll(entity Entity) bool {
78✔
285
        if !m.world.Alive(entity) {
79✔
286
                panic("can't check components of a dead entity")
1✔
287
        }
288
        index := m.world.storage.entities[entity.id]
77✔
289
        return m.storageA.columns[index.table] != nil &&
77✔
290
                m.storageB.columns[index.table] != nil
77✔
291
}
292

293
// Add the mapped components to the given entity.
294
func (m *Map2[A, B]) Add(entity Entity, a *A, b *B, rel ...RelationIndex) {
13✔
295
        if !m.world.Alive(entity) {
14✔
296
                panic("can't add components to a dead entity")
1✔
297
        }
298
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
12✔
299
        m.world.exchange(entity, m.ids, nil, []unsafe.Pointer{
12✔
300
                unsafe.Pointer(a),
12✔
301
                unsafe.Pointer(b),
12✔
302
        }, m.relations)
12✔
303
}
304

305
// AddBatch adds the mapped components to all entities matching the given batch filter.
306
func (m *Map2[A, B]) AddBatch(batch *Batch, a *A, b *B, rel ...RelationIndex) {
1✔
307
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
1✔
308
        m.world.exchangeBatch(batch, m.ids, nil, []unsafe.Pointer{
1✔
309
                unsafe.Pointer(a),
1✔
310
                unsafe.Pointer(b),
1✔
311
        }, m.relations, nil)
1✔
312
}
1✔
313

314
// AddBatchFn adds the mapped components to all entities matching the given batch filter,
315
// running the given function on each. The function can be nil.
316
func (m *Map2[A, B]) AddBatchFn(batch *Batch, fn func(entity Entity, a *A, b *B), rel ...RelationIndex) {
1✔
317
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
1✔
318

1✔
319
        var process func(tableID tableID, start, len int)
1✔
320
        if fn != nil {
2✔
321
                process = func(tableID tableID, start, len int) {
3✔
322
                        table := &m.world.storage.tables[tableID]
2✔
323
                        columnA := m.storageA.columns[tableID]
2✔
324
                        columnB := m.storageB.columns[tableID]
2✔
325

2✔
326
                        lock := m.world.lock()
2✔
327
                        for i := range len {
26✔
328
                                index := uintptr(start + i)
24✔
329
                                fn(
24✔
330
                                        table.GetEntity(index),
24✔
331
                                        (*A)(columnA.Get(index)),
24✔
332
                                        (*B)(columnB.Get(index)),
24✔
333
                                )
24✔
334
                        }
24✔
335
                        m.world.unlock(lock)
2✔
336
                }
337
        }
338
        m.world.exchangeBatch(batch, m.ids, nil, nil, m.relations, process)
1✔
339
}
340

341
// Remove the mapped components from the given entity.
342
func (m *Map2[A, B]) Remove(entity Entity) {
25✔
343
        if !m.world.Alive(entity) {
26✔
344
                panic("can't remove components from a dead entity")
1✔
345
        }
346
        m.world.exchange(entity, nil, m.ids, nil, nil)
24✔
347
}
348

349
// RemoveBatch removes the mapped components from all entities matching the given batch filter.
350
func (m *Map2[A, B]) RemoveBatch(batch *Batch) {
1✔
351
        m.world.exchangeBatch(batch, nil, m.ids, nil, nil, nil)
1✔
352
}
1✔
353

354
// RemoveBatchFn removes the mapped components from all entities matching the given batch filter,
355
// running the given function on each. The function can be nil.
356
func (m *Map2[A, B]) RemoveBatchFn(batch *Batch, fn func(entity Entity)) {
1✔
357
        var process func(tableID tableID, start, len int)
1✔
358
        if fn != nil {
2✔
359
                process = func(tableID tableID, start, len int) {
3✔
360
                        table := &m.world.storage.tables[tableID]
2✔
361

2✔
362
                        lock := m.world.lock()
2✔
363
                        for i := range len {
26✔
364
                                index := uintptr(start + i)
24✔
365
                                fn(table.GetEntity(index))
24✔
366
                        }
24✔
367
                        m.world.unlock(lock)
2✔
368
                }
369
        }
370
        m.world.exchangeBatch(batch, nil, m.ids, nil, nil, process)
1✔
371
}
372

373
// GetRelation returns the relation target of an entity for the component at the given index.
374
func (m *Map2[A, B]) GetRelation(entity Entity, index int) Entity {
3✔
375
        if !m.world.Alive(entity) {
4✔
376
                panic("can't get entity relation target for a dead entity")
1✔
377
        }
378
        return m.GetRelationUnchecked(entity, index)
2✔
379
}
380

381
// GetRelationUnchecked returns the relation target of an entity for the component at the given index.
382
// In contrast to [Map2.GetRelation], it does not check whether the entity is alive.
383
// Can be used as an optimization when it is certain that the entity is alive.
384
func (m *Map2[A, B]) GetRelationUnchecked(entity Entity, index int) Entity {
3✔
385
        return m.world.storage.getRelation(entity, m.ids[index])
3✔
386
}
3✔
387

388
// SetRelations sets relation targets for the given entity.
389
func (m *Map2[A, B]) SetRelations(entity Entity, rel ...RelationIndex) {
2✔
390
        if !m.world.Alive(entity) {
3✔
391
                panic("can't set entity relation targets for a dead entity")
1✔
392
        }
393
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
1✔
394
        m.world.setRelations(entity, m.relations)
1✔
395
}
396

397
// Map3 is a mapper to access 3 components of an entity.
398
type Map3[A any, B any, C any] struct {
399
        world     *World
400
        ids       []ID
401
        storageA  *componentStorage
402
        storageB  *componentStorage
403
        storageC  *componentStorage
404
        relations []RelationID
405
}
406

407
// NewMap3 creates a new [Map3].
408
func NewMap3[A any, B any, C any](world *World) Map3[A, B, C] {
12✔
409
        ids := []ID{
12✔
410
                ComponentID[A](world),
12✔
411
                ComponentID[B](world),
12✔
412
                ComponentID[C](world),
12✔
413
        }
12✔
414
        return Map3[A, B, C]{
12✔
415
                world:    world,
12✔
416
                ids:      ids,
12✔
417
                storageA: &world.storage.components[ids[0].id],
12✔
418
                storageB: &world.storage.components[ids[1].id],
12✔
419
                storageC: &world.storage.components[ids[2].id],
12✔
420
        }
12✔
421
}
12✔
422

423
// NewEntity creates a new entity with the mapped components.
424
func (m *Map3[A, B, C]) NewEntity(a *A, b *B, c *C, rel ...RelationIndex) Entity {
137✔
425
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
137✔
426
        return m.world.newEntityWith(m.ids, []unsafe.Pointer{
137✔
427
                unsafe.Pointer(a),
137✔
428
                unsafe.Pointer(b),
137✔
429
                unsafe.Pointer(c),
137✔
430
        }, m.relations)
137✔
431
}
137✔
432

433
// NewBatch creates a batch of new entities with the mapped components.
434
func (m *Map3[A, B, C]) NewBatch(count int, a *A, b *B, c *C, rel ...RelationIndex) {
1✔
435
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
1✔
436
        m.world.newEntitiesWith(count, m.ids, []unsafe.Pointer{
1✔
437
                unsafe.Pointer(a),
1✔
438
                unsafe.Pointer(b),
1✔
439
                unsafe.Pointer(c),
1✔
440
        }, m.relations)
1✔
441
}
1✔
442

443
// NewBatchFn creates a batch of new entities with the mapped components, running the given initializer function on each.
444
// The initializer function can be nil.
445
func (m *Map3[A, B, C]) NewBatchFn(count int, fn func(entity Entity, a *A, b *B, c *C), rel ...RelationIndex) {
1✔
446
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
1✔
447
        tableID, start := m.world.newEntities(count, m.ids, m.relations)
1✔
448
        if fn == nil {
1✔
UNCOV
449
                return
×
UNCOV
450
        }
×
451

452
        table := &m.world.storage.tables[tableID]
1✔
453
        columnA := m.storageA.columns[tableID]
1✔
454
        columnB := m.storageB.columns[tableID]
1✔
455
        columnC := m.storageC.columns[tableID]
1✔
456

1✔
457
        lock := m.world.lock()
1✔
458
        for i := range count {
25✔
459
                index := uintptr(start + i)
24✔
460
                fn(
24✔
461
                        table.GetEntity(index),
24✔
462
                        (*A)(columnA.Get(index)),
24✔
463
                        (*B)(columnB.Get(index)),
24✔
464
                        (*C)(columnC.Get(index)),
24✔
465
                )
24✔
466
        }
24✔
467
        m.world.unlock(lock)
1✔
468
}
469

470
// Get returns the mapped components for the given entity.
471
func (m *Map3[A, B, C]) Get(entity Entity) (*A, *B, *C) {
25✔
472
        if !m.world.Alive(entity) {
26✔
473
                panic("can't get components of a dead entity")
1✔
474
        }
475
        return m.GetUnchecked(entity)
24✔
476
}
477

478
// GetUnchecked returns the mapped components for the given entity.
479
// In contrast to [Map3.Get], it does not check whether the entity is alive.
480
// Can be used as an optimization when it is certain that the entity is alive.
481
func (m *Map3[A, B, C]) GetUnchecked(entity Entity) (*A, *B, *C) {
24✔
482
        m.world.storage.checkHasComponent(entity, m.ids[0])
24✔
483
        m.world.storage.checkHasComponent(entity, m.ids[1])
24✔
484
        m.world.storage.checkHasComponent(entity, m.ids[2])
24✔
485

24✔
486
        index := m.world.storage.entities[entity.id]
24✔
487
        row := uintptr(index.row)
24✔
488

24✔
489
        return (*A)(m.storageA.columns[index.table].Get(row)),
24✔
490
                (*B)(m.storageB.columns[index.table].Get(row)),
24✔
491
                (*C)(m.storageC.columns[index.table].Get(row))
24✔
492
}
24✔
493

494
// HasAll return whether the given entity has all mapped components.
495
func (m *Map3[A, B, C]) HasAll(entity Entity) bool {
54✔
496
        if !m.world.Alive(entity) {
55✔
497
                panic("can't check components of a dead entity")
1✔
498
        }
499
        index := m.world.storage.entities[entity.id]
53✔
500
        return m.storageA.columns[index.table] != nil &&
53✔
501
                m.storageB.columns[index.table] != nil &&
53✔
502
                m.storageC.columns[index.table] != nil
53✔
503
}
504

505
// Add the mapped components to the given entity.
506
func (m *Map3[A, B, C]) Add(entity Entity, a *A, b *B, c *C, rel ...RelationIndex) {
13✔
507
        if !m.world.Alive(entity) {
14✔
508
                panic("can't add components to a dead entity")
1✔
509
        }
510
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
12✔
511
        m.world.exchange(entity, m.ids, nil, []unsafe.Pointer{
12✔
512
                unsafe.Pointer(a),
12✔
513
                unsafe.Pointer(b),
12✔
514
                unsafe.Pointer(c),
12✔
515
        }, m.relations)
12✔
516
}
517

518
// AddBatch adds the mapped components to all entities matching the given batch filter.
519
func (m *Map3[A, B, C]) AddBatch(batch *Batch, a *A, b *B, c *C, rel ...RelationIndex) {
1✔
520
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
1✔
521
        m.world.exchangeBatch(batch, m.ids, nil, []unsafe.Pointer{
1✔
522
                unsafe.Pointer(a),
1✔
523
                unsafe.Pointer(b),
1✔
524
                unsafe.Pointer(c),
1✔
525
        }, m.relations, nil)
1✔
526
}
1✔
527

528
// AddBatchFn adds the mapped components to all entities matching the given batch filter,
529
// running the given function on each. The function can be nil.
530
func (m *Map3[A, B, C]) AddBatchFn(batch *Batch, fn func(entity Entity, a *A, b *B, c *C), rel ...RelationIndex) {
1✔
531
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
1✔
532

1✔
533
        var process func(tableID tableID, start, len int)
1✔
534
        if fn != nil {
2✔
535
                process = func(tableID tableID, start, len int) {
3✔
536
                        table := &m.world.storage.tables[tableID]
2✔
537
                        columnA := m.storageA.columns[tableID]
2✔
538
                        columnB := m.storageB.columns[tableID]
2✔
539
                        columnC := m.storageC.columns[tableID]
2✔
540

2✔
541
                        lock := m.world.lock()
2✔
542
                        for i := range len {
26✔
543
                                index := uintptr(start + i)
24✔
544
                                fn(
24✔
545
                                        table.GetEntity(index),
24✔
546
                                        (*A)(columnA.Get(index)),
24✔
547
                                        (*B)(columnB.Get(index)),
24✔
548
                                        (*C)(columnC.Get(index)),
24✔
549
                                )
24✔
550
                        }
24✔
551
                        m.world.unlock(lock)
2✔
552
                }
553
        }
554
        m.world.exchangeBatch(batch, m.ids, nil, nil, m.relations, process)
1✔
555
}
556

557
// Remove the mapped components from the given entity.
558
func (m *Map3[A, B, C]) Remove(entity Entity) {
25✔
559
        if !m.world.Alive(entity) {
26✔
560
                panic("can't remove components from a dead entity")
1✔
561
        }
562
        m.world.exchange(entity, nil, m.ids, nil, nil)
24✔
563
}
564

565
// RemoveBatch removes the mapped components from all entities matching the given batch filter.
566
func (m *Map3[A, B, C]) RemoveBatch(batch *Batch) {
1✔
567
        m.world.exchangeBatch(batch, nil, m.ids, nil, nil, nil)
1✔
568
}
1✔
569

570
// RemoveBatchFn removes the mapped components from all entities matching the given batch filter,
571
// running the given function on each. The function can be nil.
572
func (m *Map3[A, B, C]) RemoveBatchFn(batch *Batch, fn func(entity Entity)) {
1✔
573
        var process func(tableID tableID, start, len int)
1✔
574
        if fn != nil {
2✔
575
                process = func(tableID tableID, start, len int) {
3✔
576
                        table := &m.world.storage.tables[tableID]
2✔
577

2✔
578
                        lock := m.world.lock()
2✔
579
                        for i := range len {
26✔
580
                                index := uintptr(start + i)
24✔
581
                                fn(table.GetEntity(index))
24✔
582
                        }
24✔
583
                        m.world.unlock(lock)
2✔
584
                }
585
        }
586
        m.world.exchangeBatch(batch, nil, m.ids, nil, nil, process)
1✔
587
}
588

589
// GetRelation returns the relation target of an entity for the component at the given index.
590
func (m *Map3[A, B, C]) GetRelation(entity Entity, index int) Entity {
3✔
591
        if !m.world.Alive(entity) {
4✔
592
                panic("can't get entity relation target for a dead entity")
1✔
593
        }
594
        return m.GetRelationUnchecked(entity, index)
2✔
595
}
596

597
// GetRelationUnchecked returns the relation target of an entity for the component at the given index.
598
// In contrast to [Map3.GetRelation], it does not check whether the entity is alive.
599
// Can be used as an optimization when it is certain that the entity is alive.
600
func (m *Map3[A, B, C]) GetRelationUnchecked(entity Entity, index int) Entity {
3✔
601
        return m.world.storage.getRelation(entity, m.ids[index])
3✔
602
}
3✔
603

604
// SetRelations sets relation targets for the given entity.
605
func (m *Map3[A, B, C]) SetRelations(entity Entity, rel ...RelationIndex) {
2✔
606
        if !m.world.Alive(entity) {
3✔
607
                panic("can't set entity relation targets for a dead entity")
1✔
608
        }
609
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
1✔
610
        m.world.setRelations(entity, m.relations)
1✔
611
}
612

613
// Map4 is a mapper to access 4 components of an entity.
614
type Map4[A any, B any, C any, D any] struct {
615
        world     *World
616
        ids       []ID
617
        storageA  *componentStorage
618
        storageB  *componentStorage
619
        storageC  *componentStorage
620
        storageD  *componentStorage
621
        relations []RelationID
622
}
623

624
// NewMap4 creates a new [Map4].
625
func NewMap4[A any, B any, C any, D any](world *World) Map4[A, B, C, D] {
11✔
626
        ids := []ID{
11✔
627
                ComponentID[A](world),
11✔
628
                ComponentID[B](world),
11✔
629
                ComponentID[C](world),
11✔
630
                ComponentID[D](world),
11✔
631
        }
11✔
632
        return Map4[A, B, C, D]{
11✔
633
                world:    world,
11✔
634
                ids:      ids,
11✔
635
                storageA: &world.storage.components[ids[0].id],
11✔
636
                storageB: &world.storage.components[ids[1].id],
11✔
637
                storageC: &world.storage.components[ids[2].id],
11✔
638
                storageD: &world.storage.components[ids[3].id],
11✔
639
        }
11✔
640
}
11✔
641

642
// NewEntity creates a new entity with the mapped components.
643
func (m *Map4[A, B, C, D]) NewEntity(a *A, b *B, c *C, d *D, rel ...RelationIndex) Entity {
97✔
644
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
97✔
645
        return m.world.newEntityWith(m.ids, []unsafe.Pointer{
97✔
646
                unsafe.Pointer(a),
97✔
647
                unsafe.Pointer(b),
97✔
648
                unsafe.Pointer(c),
97✔
649
                unsafe.Pointer(d),
97✔
650
        }, m.relations)
97✔
651
}
97✔
652

653
// NewBatch creates a batch of new entities with the mapped components.
654
func (m *Map4[A, B, C, D]) NewBatch(count int, a *A, b *B, c *C, d *D, rel ...RelationIndex) {
1✔
655
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
1✔
656
        m.world.newEntitiesWith(count, m.ids, []unsafe.Pointer{
1✔
657
                unsafe.Pointer(a),
1✔
658
                unsafe.Pointer(b),
1✔
659
                unsafe.Pointer(c),
1✔
660
                unsafe.Pointer(d),
1✔
661
        }, m.relations)
1✔
662
}
1✔
663

664
// NewBatchFn creates a batch of new entities with the mapped components, running the given initializer function on each.
665
// The initializer function can be nil.
666
func (m *Map4[A, B, C, D]) NewBatchFn(count int, fn func(entity Entity, a *A, b *B, c *C, d *D), rel ...RelationIndex) {
1✔
667
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
1✔
668
        tableID, start := m.world.newEntities(count, m.ids, m.relations)
1✔
669
        if fn == nil {
1✔
UNCOV
670
                return
×
UNCOV
671
        }
×
672

673
        table := &m.world.storage.tables[tableID]
1✔
674
        columnA := m.storageA.columns[tableID]
1✔
675
        columnB := m.storageB.columns[tableID]
1✔
676
        columnC := m.storageC.columns[tableID]
1✔
677
        columnD := m.storageD.columns[tableID]
1✔
678

1✔
679
        lock := m.world.lock()
1✔
680
        for i := range count {
25✔
681
                index := uintptr(start + i)
24✔
682
                fn(
24✔
683
                        table.GetEntity(index),
24✔
684
                        (*A)(columnA.Get(index)),
24✔
685
                        (*B)(columnB.Get(index)),
24✔
686
                        (*C)(columnC.Get(index)),
24✔
687
                        (*D)(columnD.Get(index)),
24✔
688
                )
24✔
689
        }
24✔
690
        m.world.unlock(lock)
1✔
691
}
692

693
// Get returns the mapped components for the given entity.
694
func (m *Map4[A, B, C, D]) Get(entity Entity) (*A, *B, *C, *D) {
25✔
695
        if !m.world.Alive(entity) {
26✔
696
                panic("can't get components of a dead entity")
1✔
697
        }
698
        return m.GetUnchecked(entity)
24✔
699
}
700

701
// GetUnchecked returns the mapped components for the given entity.
702
// In contrast to [Map4.Get], it does not check whether the entity is alive.
703
// Can be used as an optimization when it is certain that the entity is alive.
704
func (m *Map4[A, B, C, D]) GetUnchecked(entity Entity) (*A, *B, *C, *D) {
24✔
705
        m.world.storage.checkHasComponent(entity, m.ids[0])
24✔
706
        m.world.storage.checkHasComponent(entity, m.ids[1])
24✔
707
        m.world.storage.checkHasComponent(entity, m.ids[2])
24✔
708
        m.world.storage.checkHasComponent(entity, m.ids[3])
24✔
709

24✔
710
        index := m.world.storage.entities[entity.id]
24✔
711
        row := uintptr(index.row)
24✔
712

24✔
713
        return (*A)(m.storageA.columns[index.table].Get(row)),
24✔
714
                (*B)(m.storageB.columns[index.table].Get(row)),
24✔
715
                (*C)(m.storageC.columns[index.table].Get(row)),
24✔
716
                (*D)(m.storageD.columns[index.table].Get(row))
24✔
717
}
24✔
718

719
// HasAll return whether the given entity has all mapped components.
720
func (m *Map4[A, B, C, D]) HasAll(entity Entity) bool {
54✔
721
        if !m.world.Alive(entity) {
55✔
722
                panic("can't check components of a dead entity")
1✔
723
        }
724
        index := m.world.storage.entities[entity.id]
53✔
725
        return m.storageA.columns[index.table] != nil &&
53✔
726
                m.storageB.columns[index.table] != nil &&
53✔
727
                m.storageC.columns[index.table] != nil &&
53✔
728
                m.storageD.columns[index.table] != nil
53✔
729
}
730

731
// Add the mapped components to the given entity.
732
func (m *Map4[A, B, C, D]) Add(entity Entity, a *A, b *B, c *C, d *D, rel ...RelationIndex) {
13✔
733
        if !m.world.Alive(entity) {
14✔
734
                panic("can't add components to a dead entity")
1✔
735
        }
736
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
12✔
737
        m.world.exchange(entity, m.ids, nil, []unsafe.Pointer{
12✔
738
                unsafe.Pointer(a),
12✔
739
                unsafe.Pointer(b),
12✔
740
                unsafe.Pointer(c),
12✔
741
                unsafe.Pointer(d),
12✔
742
        }, m.relations)
12✔
743
}
744

745
// AddBatch adds the mapped components to all entities matching the given batch filter.
746
func (m *Map4[A, B, C, D]) AddBatch(batch *Batch, a *A, b *B, c *C, d *D, rel ...RelationIndex) {
1✔
747
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
1✔
748
        m.world.exchangeBatch(batch, m.ids, nil, []unsafe.Pointer{
1✔
749
                unsafe.Pointer(a),
1✔
750
                unsafe.Pointer(b),
1✔
751
                unsafe.Pointer(c),
1✔
752
                unsafe.Pointer(d),
1✔
753
        }, m.relations, nil)
1✔
754
}
1✔
755

756
// AddBatchFn adds the mapped components to all entities matching the given batch filter,
757
// running the given function on each. The function can be nil.
758
func (m *Map4[A, B, C, D]) AddBatchFn(batch *Batch, fn func(entity Entity, a *A, b *B, c *C, d *D), rel ...RelationIndex) {
1✔
759
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
1✔
760

1✔
761
        var process func(tableID tableID, start, len int)
1✔
762
        if fn != nil {
2✔
763
                process = func(tableID tableID, start, len int) {
3✔
764
                        table := &m.world.storage.tables[tableID]
2✔
765
                        columnA := m.storageA.columns[tableID]
2✔
766
                        columnB := m.storageB.columns[tableID]
2✔
767
                        columnC := m.storageC.columns[tableID]
2✔
768
                        columnD := m.storageD.columns[tableID]
2✔
769

2✔
770
                        lock := m.world.lock()
2✔
771
                        for i := range len {
26✔
772
                                index := uintptr(start + i)
24✔
773
                                fn(
24✔
774
                                        table.GetEntity(index),
24✔
775
                                        (*A)(columnA.Get(index)),
24✔
776
                                        (*B)(columnB.Get(index)),
24✔
777
                                        (*C)(columnC.Get(index)),
24✔
778
                                        (*D)(columnD.Get(index)),
24✔
779
                                )
24✔
780
                        }
24✔
781
                        m.world.unlock(lock)
2✔
782
                }
783
        }
784
        m.world.exchangeBatch(batch, m.ids, nil, nil, m.relations, process)
1✔
785
}
786

787
// Remove the mapped components from the given entity.
788
func (m *Map4[A, B, C, D]) Remove(entity Entity) {
25✔
789
        if !m.world.Alive(entity) {
26✔
790
                panic("can't remove components from a dead entity")
1✔
791
        }
792
        m.world.exchange(entity, nil, m.ids, nil, nil)
24✔
793
}
794

795
// RemoveBatch removes the mapped components from all entities matching the given batch filter.
796
func (m *Map4[A, B, C, D]) RemoveBatch(batch *Batch) {
1✔
797
        m.world.exchangeBatch(batch, nil, m.ids, nil, nil, nil)
1✔
798
}
1✔
799

800
// RemoveBatchFn removes the mapped components from all entities matching the given batch filter,
801
// running the given function on each. The function can be nil.
802
func (m *Map4[A, B, C, D]) RemoveBatchFn(batch *Batch, fn func(entity Entity)) {
1✔
803
        var process func(tableID tableID, start, len int)
1✔
804
        if fn != nil {
2✔
805
                process = func(tableID tableID, start, len int) {
3✔
806
                        table := &m.world.storage.tables[tableID]
2✔
807

2✔
808
                        lock := m.world.lock()
2✔
809
                        for i := range len {
26✔
810
                                index := uintptr(start + i)
24✔
811
                                fn(table.GetEntity(index))
24✔
812
                        }
24✔
813
                        m.world.unlock(lock)
2✔
814
                }
815
        }
816
        m.world.exchangeBatch(batch, nil, m.ids, nil, nil, process)
1✔
817
}
818

819
// GetRelation returns the relation target of an entity for the component at the given index.
820
func (m *Map4[A, B, C, D]) GetRelation(entity Entity, index int) Entity {
3✔
821
        if !m.world.Alive(entity) {
4✔
822
                panic("can't get entity relation target for a dead entity")
1✔
823
        }
824
        return m.GetRelationUnchecked(entity, index)
2✔
825
}
826

827
// GetRelationUnchecked returns the relation target of an entity for the component at the given index.
828
// In contrast to [Map4.GetRelation], it does not check whether the entity is alive.
829
// Can be used as an optimization when it is certain that the entity is alive.
830
func (m *Map4[A, B, C, D]) GetRelationUnchecked(entity Entity, index int) Entity {
3✔
831
        return m.world.storage.getRelation(entity, m.ids[index])
3✔
832
}
3✔
833

834
// SetRelations sets relation targets for the given entity.
835
func (m *Map4[A, B, C, D]) SetRelations(entity Entity, rel ...RelationIndex) {
2✔
836
        if !m.world.Alive(entity) {
3✔
837
                panic("can't set entity relation targets for a dead entity")
1✔
838
        }
839
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
1✔
840
        m.world.setRelations(entity, m.relations)
1✔
841
}
842

843
// Map5 is a mapper to access 5 components of an entity.
844
type Map5[A any, B any, C any, D any, E any] struct {
845
        world     *World
846
        ids       []ID
847
        storageA  *componentStorage
848
        storageB  *componentStorage
849
        storageC  *componentStorage
850
        storageD  *componentStorage
851
        storageE  *componentStorage
852
        relations []RelationID
853
}
854

855
// NewMap5 creates a new [Map5].
856
func NewMap5[A any, B any, C any, D any, E any](world *World) Map5[A, B, C, D, E] {
11✔
857
        ids := []ID{
11✔
858
                ComponentID[A](world),
11✔
859
                ComponentID[B](world),
11✔
860
                ComponentID[C](world),
11✔
861
                ComponentID[D](world),
11✔
862
                ComponentID[E](world),
11✔
863
        }
11✔
864
        return Map5[A, B, C, D, E]{
11✔
865
                world:    world,
11✔
866
                ids:      ids,
11✔
867
                storageA: &world.storage.components[ids[0].id],
11✔
868
                storageB: &world.storage.components[ids[1].id],
11✔
869
                storageC: &world.storage.components[ids[2].id],
11✔
870
                storageD: &world.storage.components[ids[3].id],
11✔
871
                storageE: &world.storage.components[ids[4].id],
11✔
872
        }
11✔
873
}
11✔
874

875
// NewEntity creates a new entity with the mapped components.
876
func (m *Map5[A, B, C, D, E]) NewEntity(a *A, b *B, c *C, d *D, e *E, rel ...RelationIndex) Entity {
97✔
877
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
97✔
878
        return m.world.newEntityWith(m.ids, []unsafe.Pointer{
97✔
879
                unsafe.Pointer(a),
97✔
880
                unsafe.Pointer(b),
97✔
881
                unsafe.Pointer(c),
97✔
882
                unsafe.Pointer(d),
97✔
883
                unsafe.Pointer(e),
97✔
884
        }, m.relations)
97✔
885
}
97✔
886

887
// NewBatch creates a batch of new entities with the mapped components.
888
func (m *Map5[A, B, C, D, E]) NewBatch(count int, a *A, b *B, c *C, d *D, e *E, rel ...RelationIndex) {
1✔
889
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
1✔
890
        m.world.newEntitiesWith(count, m.ids, []unsafe.Pointer{
1✔
891
                unsafe.Pointer(a),
1✔
892
                unsafe.Pointer(b),
1✔
893
                unsafe.Pointer(c),
1✔
894
                unsafe.Pointer(d),
1✔
895
                unsafe.Pointer(e),
1✔
896
        }, m.relations)
1✔
897
}
1✔
898

899
// NewBatchFn creates a batch of new entities with the mapped components, running the given initializer function on each.
900
// The initializer function can be nil.
901
func (m *Map5[A, B, C, D, E]) NewBatchFn(count int, fn func(entity Entity, a *A, b *B, c *C, d *D, e *E), rel ...RelationIndex) {
1✔
902
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
1✔
903
        tableID, start := m.world.newEntities(count, m.ids, m.relations)
1✔
904
        if fn == nil {
1✔
UNCOV
905
                return
×
UNCOV
906
        }
×
907

908
        table := &m.world.storage.tables[tableID]
1✔
909
        columnA := m.storageA.columns[tableID]
1✔
910
        columnB := m.storageB.columns[tableID]
1✔
911
        columnC := m.storageC.columns[tableID]
1✔
912
        columnD := m.storageD.columns[tableID]
1✔
913
        columnE := m.storageE.columns[tableID]
1✔
914

1✔
915
        lock := m.world.lock()
1✔
916
        for i := range count {
25✔
917
                index := uintptr(start + i)
24✔
918
                fn(
24✔
919
                        table.GetEntity(index),
24✔
920
                        (*A)(columnA.Get(index)),
24✔
921
                        (*B)(columnB.Get(index)),
24✔
922
                        (*C)(columnC.Get(index)),
24✔
923
                        (*D)(columnD.Get(index)),
24✔
924
                        (*E)(columnE.Get(index)),
24✔
925
                )
24✔
926
        }
24✔
927
        m.world.unlock(lock)
1✔
928
}
929

930
// Get returns the mapped components for the given entity.
931
func (m *Map5[A, B, C, D, E]) Get(entity Entity) (*A, *B, *C, *D, *E) {
25✔
932
        if !m.world.Alive(entity) {
26✔
933
                panic("can't get components of a dead entity")
1✔
934
        }
935
        return m.GetUnchecked(entity)
24✔
936
}
937

938
// GetUnchecked returns the mapped components for the given entity.
939
// In contrast to [Map5.Get], it does not check whether the entity is alive.
940
// Can be used as an optimization when it is certain that the entity is alive.
941
func (m *Map5[A, B, C, D, E]) GetUnchecked(entity Entity) (*A, *B, *C, *D, *E) {
24✔
942
        m.world.storage.checkHasComponent(entity, m.ids[0])
24✔
943
        m.world.storage.checkHasComponent(entity, m.ids[1])
24✔
944
        m.world.storage.checkHasComponent(entity, m.ids[2])
24✔
945
        m.world.storage.checkHasComponent(entity, m.ids[3])
24✔
946
        m.world.storage.checkHasComponent(entity, m.ids[4])
24✔
947

24✔
948
        index := m.world.storage.entities[entity.id]
24✔
949
        row := uintptr(index.row)
24✔
950

24✔
951
        return (*A)(m.storageA.columns[index.table].Get(row)),
24✔
952
                (*B)(m.storageB.columns[index.table].Get(row)),
24✔
953
                (*C)(m.storageC.columns[index.table].Get(row)),
24✔
954
                (*D)(m.storageD.columns[index.table].Get(row)),
24✔
955
                (*E)(m.storageE.columns[index.table].Get(row))
24✔
956
}
24✔
957

958
// HasAll return whether the given entity has all mapped components.
959
func (m *Map5[A, B, C, D, E]) HasAll(entity Entity) bool {
54✔
960
        if !m.world.Alive(entity) {
55✔
961
                panic("can't check components of a dead entity")
1✔
962
        }
963
        index := m.world.storage.entities[entity.id]
53✔
964
        return m.storageA.columns[index.table] != nil &&
53✔
965
                m.storageB.columns[index.table] != nil &&
53✔
966
                m.storageC.columns[index.table] != nil &&
53✔
967
                m.storageD.columns[index.table] != nil &&
53✔
968
                m.storageE.columns[index.table] != nil
53✔
969
}
970

971
// Add the mapped components to the given entity.
972
func (m *Map5[A, B, C, D, E]) Add(entity Entity, a *A, b *B, c *C, d *D, e *E, rel ...RelationIndex) {
13✔
973
        if !m.world.Alive(entity) {
14✔
974
                panic("can't add components to a dead entity")
1✔
975
        }
976
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
12✔
977
        m.world.exchange(entity, m.ids, nil, []unsafe.Pointer{
12✔
978
                unsafe.Pointer(a),
12✔
979
                unsafe.Pointer(b),
12✔
980
                unsafe.Pointer(c),
12✔
981
                unsafe.Pointer(d),
12✔
982
                unsafe.Pointer(e),
12✔
983
        }, m.relations)
12✔
984
}
985

986
// AddBatch adds the mapped components to all entities matching the given batch filter.
987
func (m *Map5[A, B, C, D, E]) AddBatch(batch *Batch, a *A, b *B, c *C, d *D, e *E, rel ...RelationIndex) {
1✔
988
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
1✔
989
        m.world.exchangeBatch(batch, m.ids, nil, []unsafe.Pointer{
1✔
990
                unsafe.Pointer(a),
1✔
991
                unsafe.Pointer(b),
1✔
992
                unsafe.Pointer(c),
1✔
993
                unsafe.Pointer(d),
1✔
994
                unsafe.Pointer(e),
1✔
995
        }, m.relations, nil)
1✔
996
}
1✔
997

998
// AddBatchFn adds the mapped components to all entities matching the given batch filter,
999
// running the given function on each. The function can be nil.
1000
func (m *Map5[A, B, C, D, E]) AddBatchFn(batch *Batch, fn func(entity Entity, a *A, b *B, c *C, d *D, e *E), rel ...RelationIndex) {
1✔
1001
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
1✔
1002

1✔
1003
        var process func(tableID tableID, start, len int)
1✔
1004
        if fn != nil {
2✔
1005
                process = func(tableID tableID, start, len int) {
3✔
1006
                        table := &m.world.storage.tables[tableID]
2✔
1007
                        columnA := m.storageA.columns[tableID]
2✔
1008
                        columnB := m.storageB.columns[tableID]
2✔
1009
                        columnC := m.storageC.columns[tableID]
2✔
1010
                        columnD := m.storageD.columns[tableID]
2✔
1011
                        columnE := m.storageE.columns[tableID]
2✔
1012

2✔
1013
                        lock := m.world.lock()
2✔
1014
                        for i := range len {
26✔
1015
                                index := uintptr(start + i)
24✔
1016
                                fn(
24✔
1017
                                        table.GetEntity(index),
24✔
1018
                                        (*A)(columnA.Get(index)),
24✔
1019
                                        (*B)(columnB.Get(index)),
24✔
1020
                                        (*C)(columnC.Get(index)),
24✔
1021
                                        (*D)(columnD.Get(index)),
24✔
1022
                                        (*E)(columnE.Get(index)),
24✔
1023
                                )
24✔
1024
                        }
24✔
1025
                        m.world.unlock(lock)
2✔
1026
                }
1027
        }
1028
        m.world.exchangeBatch(batch, m.ids, nil, nil, m.relations, process)
1✔
1029
}
1030

1031
// Remove the mapped components from the given entity.
1032
func (m *Map5[A, B, C, D, E]) Remove(entity Entity) {
25✔
1033
        if !m.world.Alive(entity) {
26✔
1034
                panic("can't remove components from a dead entity")
1✔
1035
        }
1036
        m.world.exchange(entity, nil, m.ids, nil, nil)
24✔
1037
}
1038

1039
// RemoveBatch removes the mapped components from all entities matching the given batch filter.
1040
func (m *Map5[A, B, C, D, E]) RemoveBatch(batch *Batch) {
1✔
1041
        m.world.exchangeBatch(batch, nil, m.ids, nil, nil, nil)
1✔
1042
}
1✔
1043

1044
// RemoveBatchFn removes the mapped components from all entities matching the given batch filter,
1045
// running the given function on each. The function can be nil.
1046
func (m *Map5[A, B, C, D, E]) RemoveBatchFn(batch *Batch, fn func(entity Entity)) {
1✔
1047
        var process func(tableID tableID, start, len int)
1✔
1048
        if fn != nil {
2✔
1049
                process = func(tableID tableID, start, len int) {
3✔
1050
                        table := &m.world.storage.tables[tableID]
2✔
1051

2✔
1052
                        lock := m.world.lock()
2✔
1053
                        for i := range len {
26✔
1054
                                index := uintptr(start + i)
24✔
1055
                                fn(table.GetEntity(index))
24✔
1056
                        }
24✔
1057
                        m.world.unlock(lock)
2✔
1058
                }
1059
        }
1060
        m.world.exchangeBatch(batch, nil, m.ids, nil, nil, process)
1✔
1061
}
1062

1063
// GetRelation returns the relation target of an entity for the component at the given index.
1064
func (m *Map5[A, B, C, D, E]) GetRelation(entity Entity, index int) Entity {
3✔
1065
        if !m.world.Alive(entity) {
4✔
1066
                panic("can't get entity relation target for a dead entity")
1✔
1067
        }
1068
        return m.GetRelationUnchecked(entity, index)
2✔
1069
}
1070

1071
// GetRelationUnchecked returns the relation target of an entity for the component at the given index.
1072
// In contrast to [Map5.GetRelation], it does not check whether the entity is alive.
1073
// Can be used as an optimization when it is certain that the entity is alive.
1074
func (m *Map5[A, B, C, D, E]) GetRelationUnchecked(entity Entity, index int) Entity {
3✔
1075
        return m.world.storage.getRelation(entity, m.ids[index])
3✔
1076
}
3✔
1077

1078
// SetRelations sets relation targets for the given entity.
1079
func (m *Map5[A, B, C, D, E]) SetRelations(entity Entity, rel ...RelationIndex) {
2✔
1080
        if !m.world.Alive(entity) {
3✔
1081
                panic("can't set entity relation targets for a dead entity")
1✔
1082
        }
1083
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
1✔
1084
        m.world.setRelations(entity, m.relations)
1✔
1085
}
1086

1087
// Map6 is a mapper to access 6 components of an entity.
1088
type Map6[A any, B any, C any, D any, E any, F any] struct {
1089
        world     *World
1090
        ids       []ID
1091
        storageA  *componentStorage
1092
        storageB  *componentStorage
1093
        storageC  *componentStorage
1094
        storageD  *componentStorage
1095
        storageE  *componentStorage
1096
        storageF  *componentStorage
1097
        relations []RelationID
1098
}
1099

1100
// NewMap6 creates a new [Map6].
1101
func NewMap6[A any, B any, C any, D any, E any, F any](world *World) Map6[A, B, C, D, E, F] {
11✔
1102
        ids := []ID{
11✔
1103
                ComponentID[A](world),
11✔
1104
                ComponentID[B](world),
11✔
1105
                ComponentID[C](world),
11✔
1106
                ComponentID[D](world),
11✔
1107
                ComponentID[E](world),
11✔
1108
                ComponentID[F](world),
11✔
1109
        }
11✔
1110
        return Map6[A, B, C, D, E, F]{
11✔
1111
                world:    world,
11✔
1112
                ids:      ids,
11✔
1113
                storageA: &world.storage.components[ids[0].id],
11✔
1114
                storageB: &world.storage.components[ids[1].id],
11✔
1115
                storageC: &world.storage.components[ids[2].id],
11✔
1116
                storageD: &world.storage.components[ids[3].id],
11✔
1117
                storageE: &world.storage.components[ids[4].id],
11✔
1118
                storageF: &world.storage.components[ids[5].id],
11✔
1119
        }
11✔
1120
}
11✔
1121

1122
// NewEntity creates a new entity with the mapped components.
1123
func (m *Map6[A, B, C, D, E, F]) NewEntity(a *A, b *B, c *C, d *D, e *E, f *F, rel ...RelationIndex) Entity {
97✔
1124
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
97✔
1125
        return m.world.newEntityWith(m.ids, []unsafe.Pointer{
97✔
1126
                unsafe.Pointer(a),
97✔
1127
                unsafe.Pointer(b),
97✔
1128
                unsafe.Pointer(c),
97✔
1129
                unsafe.Pointer(d),
97✔
1130
                unsafe.Pointer(e),
97✔
1131
                unsafe.Pointer(f),
97✔
1132
        }, m.relations)
97✔
1133
}
97✔
1134

1135
// NewBatch creates a batch of new entities with the mapped components.
1136
func (m *Map6[A, B, C, D, E, F]) NewBatch(count int, a *A, b *B, c *C, d *D, e *E, f *F, rel ...RelationIndex) {
1✔
1137
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
1✔
1138
        m.world.newEntitiesWith(count, m.ids, []unsafe.Pointer{
1✔
1139
                unsafe.Pointer(a),
1✔
1140
                unsafe.Pointer(b),
1✔
1141
                unsafe.Pointer(c),
1✔
1142
                unsafe.Pointer(d),
1✔
1143
                unsafe.Pointer(e),
1✔
1144
                unsafe.Pointer(f),
1✔
1145
        }, m.relations)
1✔
1146
}
1✔
1147

1148
// NewBatchFn creates a batch of new entities with the mapped components, running the given initializer function on each.
1149
// The initializer function can be nil.
1150
func (m *Map6[A, B, C, D, E, F]) NewBatchFn(count int, fn func(entity Entity, a *A, b *B, c *C, d *D, e *E, f *F), rel ...RelationIndex) {
1✔
1151
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
1✔
1152
        tableID, start := m.world.newEntities(count, m.ids, m.relations)
1✔
1153
        if fn == nil {
1✔
UNCOV
1154
                return
×
UNCOV
1155
        }
×
1156

1157
        table := &m.world.storage.tables[tableID]
1✔
1158
        columnA := m.storageA.columns[tableID]
1✔
1159
        columnB := m.storageB.columns[tableID]
1✔
1160
        columnC := m.storageC.columns[tableID]
1✔
1161
        columnD := m.storageD.columns[tableID]
1✔
1162
        columnE := m.storageE.columns[tableID]
1✔
1163
        columnF := m.storageF.columns[tableID]
1✔
1164

1✔
1165
        lock := m.world.lock()
1✔
1166
        for i := range count {
25✔
1167
                index := uintptr(start + i)
24✔
1168
                fn(
24✔
1169
                        table.GetEntity(index),
24✔
1170
                        (*A)(columnA.Get(index)),
24✔
1171
                        (*B)(columnB.Get(index)),
24✔
1172
                        (*C)(columnC.Get(index)),
24✔
1173
                        (*D)(columnD.Get(index)),
24✔
1174
                        (*E)(columnE.Get(index)),
24✔
1175
                        (*F)(columnF.Get(index)),
24✔
1176
                )
24✔
1177
        }
24✔
1178
        m.world.unlock(lock)
1✔
1179
}
1180

1181
// Get returns the mapped components for the given entity.
1182
func (m *Map6[A, B, C, D, E, F]) Get(entity Entity) (*A, *B, *C, *D, *E, *F) {
25✔
1183
        if !m.world.Alive(entity) {
26✔
1184
                panic("can't get components of a dead entity")
1✔
1185
        }
1186
        return m.GetUnchecked(entity)
24✔
1187
}
1188

1189
// GetUnchecked returns the mapped components for the given entity.
1190
// In contrast to [Map6.Get], it does not check whether the entity is alive.
1191
// Can be used as an optimization when it is certain that the entity is alive.
1192
func (m *Map6[A, B, C, D, E, F]) GetUnchecked(entity Entity) (*A, *B, *C, *D, *E, *F) {
24✔
1193
        m.world.storage.checkHasComponent(entity, m.ids[0])
24✔
1194
        m.world.storage.checkHasComponent(entity, m.ids[1])
24✔
1195
        m.world.storage.checkHasComponent(entity, m.ids[2])
24✔
1196
        m.world.storage.checkHasComponent(entity, m.ids[3])
24✔
1197
        m.world.storage.checkHasComponent(entity, m.ids[4])
24✔
1198
        m.world.storage.checkHasComponent(entity, m.ids[5])
24✔
1199

24✔
1200
        index := m.world.storage.entities[entity.id]
24✔
1201
        row := uintptr(index.row)
24✔
1202

24✔
1203
        return (*A)(m.storageA.columns[index.table].Get(row)),
24✔
1204
                (*B)(m.storageB.columns[index.table].Get(row)),
24✔
1205
                (*C)(m.storageC.columns[index.table].Get(row)),
24✔
1206
                (*D)(m.storageD.columns[index.table].Get(row)),
24✔
1207
                (*E)(m.storageE.columns[index.table].Get(row)),
24✔
1208
                (*F)(m.storageF.columns[index.table].Get(row))
24✔
1209
}
24✔
1210

1211
// HasAll return whether the given entity has all mapped components.
1212
func (m *Map6[A, B, C, D, E, F]) HasAll(entity Entity) bool {
54✔
1213
        if !m.world.Alive(entity) {
55✔
1214
                panic("can't check components of a dead entity")
1✔
1215
        }
1216
        index := m.world.storage.entities[entity.id]
53✔
1217
        return m.storageA.columns[index.table] != nil &&
53✔
1218
                m.storageB.columns[index.table] != nil &&
53✔
1219
                m.storageC.columns[index.table] != nil &&
53✔
1220
                m.storageD.columns[index.table] != nil &&
53✔
1221
                m.storageE.columns[index.table] != nil &&
53✔
1222
                m.storageF.columns[index.table] != nil
53✔
1223
}
1224

1225
// Add the mapped components to the given entity.
1226
func (m *Map6[A, B, C, D, E, F]) Add(entity Entity, a *A, b *B, c *C, d *D, e *E, f *F, rel ...RelationIndex) {
13✔
1227
        if !m.world.Alive(entity) {
14✔
1228
                panic("can't add components to a dead entity")
1✔
1229
        }
1230
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
12✔
1231
        m.world.exchange(entity, m.ids, nil, []unsafe.Pointer{
12✔
1232
                unsafe.Pointer(a),
12✔
1233
                unsafe.Pointer(b),
12✔
1234
                unsafe.Pointer(c),
12✔
1235
                unsafe.Pointer(d),
12✔
1236
                unsafe.Pointer(e),
12✔
1237
                unsafe.Pointer(f),
12✔
1238
        }, m.relations)
12✔
1239
}
1240

1241
// AddBatch adds the mapped components to all entities matching the given batch filter.
1242
func (m *Map6[A, B, C, D, E, F]) AddBatch(batch *Batch, a *A, b *B, c *C, d *D, e *E, f *F, rel ...RelationIndex) {
1✔
1243
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
1✔
1244
        m.world.exchangeBatch(batch, m.ids, nil, []unsafe.Pointer{
1✔
1245
                unsafe.Pointer(a),
1✔
1246
                unsafe.Pointer(b),
1✔
1247
                unsafe.Pointer(c),
1✔
1248
                unsafe.Pointer(d),
1✔
1249
                unsafe.Pointer(e),
1✔
1250
                unsafe.Pointer(f),
1✔
1251
        }, m.relations, nil)
1✔
1252
}
1✔
1253

1254
// AddBatchFn adds the mapped components to all entities matching the given batch filter,
1255
// running the given function on each. The function can be nil.
1256
func (m *Map6[A, B, C, D, E, F]) AddBatchFn(batch *Batch, fn func(entity Entity, a *A, b *B, c *C, d *D, e *E, f *F), rel ...RelationIndex) {
1✔
1257
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
1✔
1258

1✔
1259
        var process func(tableID tableID, start, len int)
1✔
1260
        if fn != nil {
2✔
1261
                process = func(tableID tableID, start, len int) {
3✔
1262
                        table := &m.world.storage.tables[tableID]
2✔
1263
                        columnA := m.storageA.columns[tableID]
2✔
1264
                        columnB := m.storageB.columns[tableID]
2✔
1265
                        columnC := m.storageC.columns[tableID]
2✔
1266
                        columnD := m.storageD.columns[tableID]
2✔
1267
                        columnE := m.storageE.columns[tableID]
2✔
1268
                        columnF := m.storageF.columns[tableID]
2✔
1269

2✔
1270
                        lock := m.world.lock()
2✔
1271
                        for i := range len {
26✔
1272
                                index := uintptr(start + i)
24✔
1273
                                fn(
24✔
1274
                                        table.GetEntity(index),
24✔
1275
                                        (*A)(columnA.Get(index)),
24✔
1276
                                        (*B)(columnB.Get(index)),
24✔
1277
                                        (*C)(columnC.Get(index)),
24✔
1278
                                        (*D)(columnD.Get(index)),
24✔
1279
                                        (*E)(columnE.Get(index)),
24✔
1280
                                        (*F)(columnF.Get(index)),
24✔
1281
                                )
24✔
1282
                        }
24✔
1283
                        m.world.unlock(lock)
2✔
1284
                }
1285
        }
1286
        m.world.exchangeBatch(batch, m.ids, nil, nil, m.relations, process)
1✔
1287
}
1288

1289
// Remove the mapped components from the given entity.
1290
func (m *Map6[A, B, C, D, E, F]) Remove(entity Entity) {
25✔
1291
        if !m.world.Alive(entity) {
26✔
1292
                panic("can't remove components from a dead entity")
1✔
1293
        }
1294
        m.world.exchange(entity, nil, m.ids, nil, nil)
24✔
1295
}
1296

1297
// RemoveBatch removes the mapped components from all entities matching the given batch filter.
1298
func (m *Map6[A, B, C, D, E, F]) RemoveBatch(batch *Batch) {
1✔
1299
        m.world.exchangeBatch(batch, nil, m.ids, nil, nil, nil)
1✔
1300
}
1✔
1301

1302
// RemoveBatchFn removes the mapped components from all entities matching the given batch filter,
1303
// running the given function on each. The function can be nil.
1304
func (m *Map6[A, B, C, D, E, F]) RemoveBatchFn(batch *Batch, fn func(entity Entity)) {
1✔
1305
        var process func(tableID tableID, start, len int)
1✔
1306
        if fn != nil {
2✔
1307
                process = func(tableID tableID, start, len int) {
3✔
1308
                        table := &m.world.storage.tables[tableID]
2✔
1309

2✔
1310
                        lock := m.world.lock()
2✔
1311
                        for i := range len {
26✔
1312
                                index := uintptr(start + i)
24✔
1313
                                fn(table.GetEntity(index))
24✔
1314
                        }
24✔
1315
                        m.world.unlock(lock)
2✔
1316
                }
1317
        }
1318
        m.world.exchangeBatch(batch, nil, m.ids, nil, nil, process)
1✔
1319
}
1320

1321
// GetRelation returns the relation target of an entity for the component at the given index.
1322
func (m *Map6[A, B, C, D, E, F]) GetRelation(entity Entity, index int) Entity {
3✔
1323
        if !m.world.Alive(entity) {
4✔
1324
                panic("can't get entity relation target for a dead entity")
1✔
1325
        }
1326
        return m.GetRelationUnchecked(entity, index)
2✔
1327
}
1328

1329
// GetRelationUnchecked returns the relation target of an entity for the component at the given index.
1330
// In contrast to [Map6.GetRelation], it does not check whether the entity is alive.
1331
// Can be used as an optimization when it is certain that the entity is alive.
1332
func (m *Map6[A, B, C, D, E, F]) GetRelationUnchecked(entity Entity, index int) Entity {
3✔
1333
        return m.world.storage.getRelation(entity, m.ids[index])
3✔
1334
}
3✔
1335

1336
// SetRelations sets relation targets for the given entity.
1337
func (m *Map6[A, B, C, D, E, F]) SetRelations(entity Entity, rel ...RelationIndex) {
2✔
1338
        if !m.world.Alive(entity) {
3✔
1339
                panic("can't set entity relation targets for a dead entity")
1✔
1340
        }
1341
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
1✔
1342
        m.world.setRelations(entity, m.relations)
1✔
1343
}
1344

1345
// Map7 is a mapper to access 7 components of an entity.
1346
type Map7[A any, B any, C any, D any, E any, F any, G any] struct {
1347
        world     *World
1348
        ids       []ID
1349
        storageA  *componentStorage
1350
        storageB  *componentStorage
1351
        storageC  *componentStorage
1352
        storageD  *componentStorage
1353
        storageE  *componentStorage
1354
        storageF  *componentStorage
1355
        storageG  *componentStorage
1356
        relations []RelationID
1357
}
1358

1359
// NewMap7 creates a new [Map7].
1360
func NewMap7[A any, B any, C any, D any, E any, F any, G any](world *World) Map7[A, B, C, D, E, F, G] {
11✔
1361
        ids := []ID{
11✔
1362
                ComponentID[A](world),
11✔
1363
                ComponentID[B](world),
11✔
1364
                ComponentID[C](world),
11✔
1365
                ComponentID[D](world),
11✔
1366
                ComponentID[E](world),
11✔
1367
                ComponentID[F](world),
11✔
1368
                ComponentID[G](world),
11✔
1369
        }
11✔
1370
        return Map7[A, B, C, D, E, F, G]{
11✔
1371
                world:    world,
11✔
1372
                ids:      ids,
11✔
1373
                storageA: &world.storage.components[ids[0].id],
11✔
1374
                storageB: &world.storage.components[ids[1].id],
11✔
1375
                storageC: &world.storage.components[ids[2].id],
11✔
1376
                storageD: &world.storage.components[ids[3].id],
11✔
1377
                storageE: &world.storage.components[ids[4].id],
11✔
1378
                storageF: &world.storage.components[ids[5].id],
11✔
1379
                storageG: &world.storage.components[ids[6].id],
11✔
1380
        }
11✔
1381
}
11✔
1382

1383
// NewEntity creates a new entity with the mapped components.
1384
func (m *Map7[A, B, C, D, E, F, G]) NewEntity(a *A, b *B, c *C, d *D, e *E, f *F, g *G, rel ...RelationIndex) Entity {
97✔
1385
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
97✔
1386
        return m.world.newEntityWith(m.ids, []unsafe.Pointer{
97✔
1387
                unsafe.Pointer(a),
97✔
1388
                unsafe.Pointer(b),
97✔
1389
                unsafe.Pointer(c),
97✔
1390
                unsafe.Pointer(d),
97✔
1391
                unsafe.Pointer(e),
97✔
1392
                unsafe.Pointer(f),
97✔
1393
                unsafe.Pointer(g),
97✔
1394
        }, m.relations)
97✔
1395
}
97✔
1396

1397
// NewBatch creates a batch of new entities with the mapped components.
1398
func (m *Map7[A, B, C, D, E, F, G]) NewBatch(count int, a *A, b *B, c *C, d *D, e *E, f *F, g *G, rel ...RelationIndex) {
1✔
1399
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
1✔
1400
        m.world.newEntitiesWith(count, m.ids, []unsafe.Pointer{
1✔
1401
                unsafe.Pointer(a),
1✔
1402
                unsafe.Pointer(b),
1✔
1403
                unsafe.Pointer(c),
1✔
1404
                unsafe.Pointer(d),
1✔
1405
                unsafe.Pointer(e),
1✔
1406
                unsafe.Pointer(f),
1✔
1407
                unsafe.Pointer(g),
1✔
1408
        }, m.relations)
1✔
1409
}
1✔
1410

1411
// NewBatchFn creates a batch of new entities with the mapped components, running the given initializer function on each.
1412
// The initializer function can be nil.
1413
func (m *Map7[A, B, C, D, E, F, G]) NewBatchFn(count int, fn func(entity Entity, a *A, b *B, c *C, d *D, e *E, f *F, g *G), rel ...RelationIndex) {
1✔
1414
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
1✔
1415
        tableID, start := m.world.newEntities(count, m.ids, m.relations)
1✔
1416
        if fn == nil {
1✔
UNCOV
1417
                return
×
UNCOV
1418
        }
×
1419

1420
        table := &m.world.storage.tables[tableID]
1✔
1421
        columnA := m.storageA.columns[tableID]
1✔
1422
        columnB := m.storageB.columns[tableID]
1✔
1423
        columnC := m.storageC.columns[tableID]
1✔
1424
        columnD := m.storageD.columns[tableID]
1✔
1425
        columnE := m.storageE.columns[tableID]
1✔
1426
        columnF := m.storageF.columns[tableID]
1✔
1427
        columnG := m.storageG.columns[tableID]
1✔
1428

1✔
1429
        lock := m.world.lock()
1✔
1430
        for i := range count {
25✔
1431
                index := uintptr(start + i)
24✔
1432
                fn(
24✔
1433
                        table.GetEntity(index),
24✔
1434
                        (*A)(columnA.Get(index)),
24✔
1435
                        (*B)(columnB.Get(index)),
24✔
1436
                        (*C)(columnC.Get(index)),
24✔
1437
                        (*D)(columnD.Get(index)),
24✔
1438
                        (*E)(columnE.Get(index)),
24✔
1439
                        (*F)(columnF.Get(index)),
24✔
1440
                        (*G)(columnG.Get(index)),
24✔
1441
                )
24✔
1442
        }
24✔
1443
        m.world.unlock(lock)
1✔
1444
}
1445

1446
// Get returns the mapped components for the given entity.
1447
func (m *Map7[A, B, C, D, E, F, G]) Get(entity Entity) (*A, *B, *C, *D, *E, *F, *G) {
25✔
1448
        if !m.world.Alive(entity) {
26✔
1449
                panic("can't get components of a dead entity")
1✔
1450
        }
1451
        return m.GetUnchecked(entity)
24✔
1452
}
1453

1454
// GetUnchecked returns the mapped components for the given entity.
1455
// In contrast to [Map7.Get], it does not check whether the entity is alive.
1456
// Can be used as an optimization when it is certain that the entity is alive.
1457
func (m *Map7[A, B, C, D, E, F, G]) GetUnchecked(entity Entity) (*A, *B, *C, *D, *E, *F, *G) {
24✔
1458
        m.world.storage.checkHasComponent(entity, m.ids[0])
24✔
1459
        m.world.storage.checkHasComponent(entity, m.ids[1])
24✔
1460
        m.world.storage.checkHasComponent(entity, m.ids[2])
24✔
1461
        m.world.storage.checkHasComponent(entity, m.ids[3])
24✔
1462
        m.world.storage.checkHasComponent(entity, m.ids[4])
24✔
1463
        m.world.storage.checkHasComponent(entity, m.ids[5])
24✔
1464
        m.world.storage.checkHasComponent(entity, m.ids[6])
24✔
1465

24✔
1466
        index := m.world.storage.entities[entity.id]
24✔
1467
        row := uintptr(index.row)
24✔
1468

24✔
1469
        return (*A)(m.storageA.columns[index.table].Get(row)),
24✔
1470
                (*B)(m.storageB.columns[index.table].Get(row)),
24✔
1471
                (*C)(m.storageC.columns[index.table].Get(row)),
24✔
1472
                (*D)(m.storageD.columns[index.table].Get(row)),
24✔
1473
                (*E)(m.storageE.columns[index.table].Get(row)),
24✔
1474
                (*F)(m.storageF.columns[index.table].Get(row)),
24✔
1475
                (*G)(m.storageG.columns[index.table].Get(row))
24✔
1476
}
24✔
1477

1478
// HasAll return whether the given entity has all mapped components.
1479
func (m *Map7[A, B, C, D, E, F, G]) HasAll(entity Entity) bool {
54✔
1480
        if !m.world.Alive(entity) {
55✔
1481
                panic("can't check components of a dead entity")
1✔
1482
        }
1483
        index := m.world.storage.entities[entity.id]
53✔
1484
        return m.storageA.columns[index.table] != nil &&
53✔
1485
                m.storageB.columns[index.table] != nil &&
53✔
1486
                m.storageC.columns[index.table] != nil &&
53✔
1487
                m.storageD.columns[index.table] != nil &&
53✔
1488
                m.storageE.columns[index.table] != nil &&
53✔
1489
                m.storageF.columns[index.table] != nil &&
53✔
1490
                m.storageG.columns[index.table] != nil
53✔
1491
}
1492

1493
// Add the mapped components to the given entity.
1494
func (m *Map7[A, B, C, D, E, F, G]) Add(entity Entity, a *A, b *B, c *C, d *D, e *E, f *F, g *G, rel ...RelationIndex) {
13✔
1495
        if !m.world.Alive(entity) {
14✔
1496
                panic("can't add components to a dead entity")
1✔
1497
        }
1498
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
12✔
1499
        m.world.exchange(entity, m.ids, nil, []unsafe.Pointer{
12✔
1500
                unsafe.Pointer(a),
12✔
1501
                unsafe.Pointer(b),
12✔
1502
                unsafe.Pointer(c),
12✔
1503
                unsafe.Pointer(d),
12✔
1504
                unsafe.Pointer(e),
12✔
1505
                unsafe.Pointer(f),
12✔
1506
                unsafe.Pointer(g),
12✔
1507
        }, m.relations)
12✔
1508
}
1509

1510
// AddBatch adds the mapped components to all entities matching the given batch filter.
1511
func (m *Map7[A, B, C, D, E, F, G]) AddBatch(batch *Batch, a *A, b *B, c *C, d *D, e *E, f *F, g *G, rel ...RelationIndex) {
1✔
1512
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
1✔
1513
        m.world.exchangeBatch(batch, m.ids, nil, []unsafe.Pointer{
1✔
1514
                unsafe.Pointer(a),
1✔
1515
                unsafe.Pointer(b),
1✔
1516
                unsafe.Pointer(c),
1✔
1517
                unsafe.Pointer(d),
1✔
1518
                unsafe.Pointer(e),
1✔
1519
                unsafe.Pointer(f),
1✔
1520
                unsafe.Pointer(g),
1✔
1521
        }, m.relations, nil)
1✔
1522
}
1✔
1523

1524
// AddBatchFn adds the mapped components to all entities matching the given batch filter,
1525
// running the given function on each. The function can be nil.
1526
func (m *Map7[A, B, C, D, E, F, G]) AddBatchFn(batch *Batch, fn func(entity Entity, a *A, b *B, c *C, d *D, e *E, f *F, g *G), rel ...RelationIndex) {
1✔
1527
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
1✔
1528

1✔
1529
        var process func(tableID tableID, start, len int)
1✔
1530
        if fn != nil {
2✔
1531
                process = func(tableID tableID, start, len int) {
3✔
1532
                        table := &m.world.storage.tables[tableID]
2✔
1533
                        columnA := m.storageA.columns[tableID]
2✔
1534
                        columnB := m.storageB.columns[tableID]
2✔
1535
                        columnC := m.storageC.columns[tableID]
2✔
1536
                        columnD := m.storageD.columns[tableID]
2✔
1537
                        columnE := m.storageE.columns[tableID]
2✔
1538
                        columnF := m.storageF.columns[tableID]
2✔
1539
                        columnG := m.storageG.columns[tableID]
2✔
1540

2✔
1541
                        lock := m.world.lock()
2✔
1542
                        for i := range len {
26✔
1543
                                index := uintptr(start + i)
24✔
1544
                                fn(
24✔
1545
                                        table.GetEntity(index),
24✔
1546
                                        (*A)(columnA.Get(index)),
24✔
1547
                                        (*B)(columnB.Get(index)),
24✔
1548
                                        (*C)(columnC.Get(index)),
24✔
1549
                                        (*D)(columnD.Get(index)),
24✔
1550
                                        (*E)(columnE.Get(index)),
24✔
1551
                                        (*F)(columnF.Get(index)),
24✔
1552
                                        (*G)(columnG.Get(index)),
24✔
1553
                                )
24✔
1554
                        }
24✔
1555
                        m.world.unlock(lock)
2✔
1556
                }
1557
        }
1558
        m.world.exchangeBatch(batch, m.ids, nil, nil, m.relations, process)
1✔
1559
}
1560

1561
// Remove the mapped components from the given entity.
1562
func (m *Map7[A, B, C, D, E, F, G]) Remove(entity Entity) {
25✔
1563
        if !m.world.Alive(entity) {
26✔
1564
                panic("can't remove components from a dead entity")
1✔
1565
        }
1566
        m.world.exchange(entity, nil, m.ids, nil, nil)
24✔
1567
}
1568

1569
// RemoveBatch removes the mapped components from all entities matching the given batch filter.
1570
func (m *Map7[A, B, C, D, E, F, G]) RemoveBatch(batch *Batch) {
1✔
1571
        m.world.exchangeBatch(batch, nil, m.ids, nil, nil, nil)
1✔
1572
}
1✔
1573

1574
// RemoveBatchFn removes the mapped components from all entities matching the given batch filter,
1575
// running the given function on each. The function can be nil.
1576
func (m *Map7[A, B, C, D, E, F, G]) RemoveBatchFn(batch *Batch, fn func(entity Entity)) {
1✔
1577
        var process func(tableID tableID, start, len int)
1✔
1578
        if fn != nil {
2✔
1579
                process = func(tableID tableID, start, len int) {
3✔
1580
                        table := &m.world.storage.tables[tableID]
2✔
1581

2✔
1582
                        lock := m.world.lock()
2✔
1583
                        for i := range len {
26✔
1584
                                index := uintptr(start + i)
24✔
1585
                                fn(table.GetEntity(index))
24✔
1586
                        }
24✔
1587
                        m.world.unlock(lock)
2✔
1588
                }
1589
        }
1590
        m.world.exchangeBatch(batch, nil, m.ids, nil, nil, process)
1✔
1591
}
1592

1593
// GetRelation returns the relation target of an entity for the component at the given index.
1594
func (m *Map7[A, B, C, D, E, F, G]) GetRelation(entity Entity, index int) Entity {
3✔
1595
        if !m.world.Alive(entity) {
4✔
1596
                panic("can't get entity relation target for a dead entity")
1✔
1597
        }
1598
        return m.GetRelationUnchecked(entity, index)
2✔
1599
}
1600

1601
// GetRelationUnchecked returns the relation target of an entity for the component at the given index.
1602
// In contrast to [Map7.GetRelation], it does not check whether the entity is alive.
1603
// Can be used as an optimization when it is certain that the entity is alive.
1604
func (m *Map7[A, B, C, D, E, F, G]) GetRelationUnchecked(entity Entity, index int) Entity {
3✔
1605
        return m.world.storage.getRelation(entity, m.ids[index])
3✔
1606
}
3✔
1607

1608
// SetRelations sets relation targets for the given entity.
1609
func (m *Map7[A, B, C, D, E, F, G]) SetRelations(entity Entity, rel ...RelationIndex) {
2✔
1610
        if !m.world.Alive(entity) {
3✔
1611
                panic("can't set entity relation targets for a dead entity")
1✔
1612
        }
1613
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
1✔
1614
        m.world.setRelations(entity, m.relations)
1✔
1615
}
1616

1617
// Map8 is a mapper to access 8 components of an entity.
1618
type Map8[A any, B any, C any, D any, E any, F any, G any, H any] struct {
1619
        world     *World
1620
        ids       []ID
1621
        storageA  *componentStorage
1622
        storageB  *componentStorage
1623
        storageC  *componentStorage
1624
        storageD  *componentStorage
1625
        storageE  *componentStorage
1626
        storageF  *componentStorage
1627
        storageG  *componentStorage
1628
        storageH  *componentStorage
1629
        relations []RelationID
1630
}
1631

1632
// NewMap8 creates a new [Map8].
1633
func NewMap8[A any, B any, C any, D any, E any, F any, G any, H any](world *World) Map8[A, B, C, D, E, F, G, H] {
11✔
1634
        ids := []ID{
11✔
1635
                ComponentID[A](world),
11✔
1636
                ComponentID[B](world),
11✔
1637
                ComponentID[C](world),
11✔
1638
                ComponentID[D](world),
11✔
1639
                ComponentID[E](world),
11✔
1640
                ComponentID[F](world),
11✔
1641
                ComponentID[G](world),
11✔
1642
                ComponentID[H](world),
11✔
1643
        }
11✔
1644
        return Map8[A, B, C, D, E, F, G, H]{
11✔
1645
                world:    world,
11✔
1646
                ids:      ids,
11✔
1647
                storageA: &world.storage.components[ids[0].id],
11✔
1648
                storageB: &world.storage.components[ids[1].id],
11✔
1649
                storageC: &world.storage.components[ids[2].id],
11✔
1650
                storageD: &world.storage.components[ids[3].id],
11✔
1651
                storageE: &world.storage.components[ids[4].id],
11✔
1652
                storageF: &world.storage.components[ids[5].id],
11✔
1653
                storageG: &world.storage.components[ids[6].id],
11✔
1654
                storageH: &world.storage.components[ids[7].id],
11✔
1655
        }
11✔
1656
}
11✔
1657

1658
// NewEntity creates a new entity with the mapped components.
1659
func (m *Map8[A, B, C, D, E, F, G, H]) NewEntity(a *A, b *B, c *C, d *D, e *E, f *F, g *G, h *H, rel ...RelationIndex) Entity {
97✔
1660
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
97✔
1661
        return m.world.newEntityWith(m.ids, []unsafe.Pointer{
97✔
1662
                unsafe.Pointer(a),
97✔
1663
                unsafe.Pointer(b),
97✔
1664
                unsafe.Pointer(c),
97✔
1665
                unsafe.Pointer(d),
97✔
1666
                unsafe.Pointer(e),
97✔
1667
                unsafe.Pointer(f),
97✔
1668
                unsafe.Pointer(g),
97✔
1669
                unsafe.Pointer(h),
97✔
1670
        }, m.relations)
97✔
1671
}
97✔
1672

1673
// NewBatch creates a batch of new entities with the mapped components.
1674
func (m *Map8[A, B, C, D, E, F, G, H]) NewBatch(count int, a *A, b *B, c *C, d *D, e *E, f *F, g *G, h *H, rel ...RelationIndex) {
1✔
1675
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
1✔
1676
        m.world.newEntitiesWith(count, m.ids, []unsafe.Pointer{
1✔
1677
                unsafe.Pointer(a),
1✔
1678
                unsafe.Pointer(b),
1✔
1679
                unsafe.Pointer(c),
1✔
1680
                unsafe.Pointer(d),
1✔
1681
                unsafe.Pointer(e),
1✔
1682
                unsafe.Pointer(f),
1✔
1683
                unsafe.Pointer(g),
1✔
1684
                unsafe.Pointer(h),
1✔
1685
        }, m.relations)
1✔
1686
}
1✔
1687

1688
// NewBatchFn creates a batch of new entities with the mapped components, running the given initializer function on each.
1689
// The initializer function can be nil.
1690
func (m *Map8[A, B, C, D, E, F, G, H]) NewBatchFn(count int, fn func(entity Entity, a *A, b *B, c *C, d *D, e *E, f *F, g *G, h *H), rel ...RelationIndex) {
1✔
1691
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
1✔
1692
        tableID, start := m.world.newEntities(count, m.ids, m.relations)
1✔
1693
        if fn == nil {
1✔
UNCOV
1694
                return
×
UNCOV
1695
        }
×
1696

1697
        table := &m.world.storage.tables[tableID]
1✔
1698
        columnA := m.storageA.columns[tableID]
1✔
1699
        columnB := m.storageB.columns[tableID]
1✔
1700
        columnC := m.storageC.columns[tableID]
1✔
1701
        columnD := m.storageD.columns[tableID]
1✔
1702
        columnE := m.storageE.columns[tableID]
1✔
1703
        columnF := m.storageF.columns[tableID]
1✔
1704
        columnG := m.storageG.columns[tableID]
1✔
1705
        columnH := m.storageH.columns[tableID]
1✔
1706

1✔
1707
        lock := m.world.lock()
1✔
1708
        for i := range count {
25✔
1709
                index := uintptr(start + i)
24✔
1710
                fn(
24✔
1711
                        table.GetEntity(index),
24✔
1712
                        (*A)(columnA.Get(index)),
24✔
1713
                        (*B)(columnB.Get(index)),
24✔
1714
                        (*C)(columnC.Get(index)),
24✔
1715
                        (*D)(columnD.Get(index)),
24✔
1716
                        (*E)(columnE.Get(index)),
24✔
1717
                        (*F)(columnF.Get(index)),
24✔
1718
                        (*G)(columnG.Get(index)),
24✔
1719
                        (*H)(columnH.Get(index)),
24✔
1720
                )
24✔
1721
        }
24✔
1722
        m.world.unlock(lock)
1✔
1723
}
1724

1725
// Get returns the mapped components for the given entity.
1726
func (m *Map8[A, B, C, D, E, F, G, H]) Get(entity Entity) (*A, *B, *C, *D, *E, *F, *G, *H) {
25✔
1727
        if !m.world.Alive(entity) {
26✔
1728
                panic("can't get components of a dead entity")
1✔
1729
        }
1730
        return m.GetUnchecked(entity)
24✔
1731
}
1732

1733
// GetUnchecked returns the mapped components for the given entity.
1734
// In contrast to [Map8.Get], it does not check whether the entity is alive.
1735
// Can be used as an optimization when it is certain that the entity is alive.
1736
func (m *Map8[A, B, C, D, E, F, G, H]) GetUnchecked(entity Entity) (*A, *B, *C, *D, *E, *F, *G, *H) {
24✔
1737
        m.world.storage.checkHasComponent(entity, m.ids[0])
24✔
1738
        m.world.storage.checkHasComponent(entity, m.ids[1])
24✔
1739
        m.world.storage.checkHasComponent(entity, m.ids[2])
24✔
1740
        m.world.storage.checkHasComponent(entity, m.ids[3])
24✔
1741
        m.world.storage.checkHasComponent(entity, m.ids[4])
24✔
1742
        m.world.storage.checkHasComponent(entity, m.ids[5])
24✔
1743
        m.world.storage.checkHasComponent(entity, m.ids[6])
24✔
1744
        m.world.storage.checkHasComponent(entity, m.ids[7])
24✔
1745

24✔
1746
        index := m.world.storage.entities[entity.id]
24✔
1747
        row := uintptr(index.row)
24✔
1748

24✔
1749
        return (*A)(m.storageA.columns[index.table].Get(row)),
24✔
1750
                (*B)(m.storageB.columns[index.table].Get(row)),
24✔
1751
                (*C)(m.storageC.columns[index.table].Get(row)),
24✔
1752
                (*D)(m.storageD.columns[index.table].Get(row)),
24✔
1753
                (*E)(m.storageE.columns[index.table].Get(row)),
24✔
1754
                (*F)(m.storageF.columns[index.table].Get(row)),
24✔
1755
                (*G)(m.storageG.columns[index.table].Get(row)),
24✔
1756
                (*H)(m.storageH.columns[index.table].Get(row))
24✔
1757
}
24✔
1758

1759
// HasAll return whether the given entity has all mapped components.
1760
func (m *Map8[A, B, C, D, E, F, G, H]) HasAll(entity Entity) bool {
54✔
1761
        if !m.world.Alive(entity) {
55✔
1762
                panic("can't check components of a dead entity")
1✔
1763
        }
1764
        index := m.world.storage.entities[entity.id]
53✔
1765
        return m.storageA.columns[index.table] != nil &&
53✔
1766
                m.storageB.columns[index.table] != nil &&
53✔
1767
                m.storageC.columns[index.table] != nil &&
53✔
1768
                m.storageD.columns[index.table] != nil &&
53✔
1769
                m.storageE.columns[index.table] != nil &&
53✔
1770
                m.storageF.columns[index.table] != nil &&
53✔
1771
                m.storageG.columns[index.table] != nil &&
53✔
1772
                m.storageH.columns[index.table] != nil
53✔
1773
}
1774

1775
// Add the mapped components to the given entity.
1776
func (m *Map8[A, B, C, D, E, F, G, H]) Add(entity Entity, a *A, b *B, c *C, d *D, e *E, f *F, g *G, h *H, rel ...RelationIndex) {
13✔
1777
        if !m.world.Alive(entity) {
14✔
1778
                panic("can't add components to a dead entity")
1✔
1779
        }
1780
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
12✔
1781
        m.world.exchange(entity, m.ids, nil, []unsafe.Pointer{
12✔
1782
                unsafe.Pointer(a),
12✔
1783
                unsafe.Pointer(b),
12✔
1784
                unsafe.Pointer(c),
12✔
1785
                unsafe.Pointer(d),
12✔
1786
                unsafe.Pointer(e),
12✔
1787
                unsafe.Pointer(f),
12✔
1788
                unsafe.Pointer(g),
12✔
1789
                unsafe.Pointer(h),
12✔
1790
        }, m.relations)
12✔
1791
}
1792

1793
// AddBatch adds the mapped components to all entities matching the given batch filter.
1794
func (m *Map8[A, B, C, D, E, F, G, H]) AddBatch(batch *Batch, a *A, b *B, c *C, d *D, e *E, f *F, g *G, h *H, rel ...RelationIndex) {
1✔
1795
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
1✔
1796
        m.world.exchangeBatch(batch, m.ids, nil, []unsafe.Pointer{
1✔
1797
                unsafe.Pointer(a),
1✔
1798
                unsafe.Pointer(b),
1✔
1799
                unsafe.Pointer(c),
1✔
1800
                unsafe.Pointer(d),
1✔
1801
                unsafe.Pointer(e),
1✔
1802
                unsafe.Pointer(f),
1✔
1803
                unsafe.Pointer(g),
1✔
1804
                unsafe.Pointer(h),
1✔
1805
        }, m.relations, nil)
1✔
1806
}
1✔
1807

1808
// AddBatchFn adds the mapped components to all entities matching the given batch filter,
1809
// running the given function on each. The function can be nil.
1810
func (m *Map8[A, B, C, D, E, F, G, H]) AddBatchFn(batch *Batch, fn func(entity Entity, a *A, b *B, c *C, d *D, e *E, f *F, g *G, h *H), rel ...RelationIndex) {
1✔
1811
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
1✔
1812

1✔
1813
        var process func(tableID tableID, start, len int)
1✔
1814
        if fn != nil {
2✔
1815
                process = func(tableID tableID, start, len int) {
3✔
1816
                        table := &m.world.storage.tables[tableID]
2✔
1817
                        columnA := m.storageA.columns[tableID]
2✔
1818
                        columnB := m.storageB.columns[tableID]
2✔
1819
                        columnC := m.storageC.columns[tableID]
2✔
1820
                        columnD := m.storageD.columns[tableID]
2✔
1821
                        columnE := m.storageE.columns[tableID]
2✔
1822
                        columnF := m.storageF.columns[tableID]
2✔
1823
                        columnG := m.storageG.columns[tableID]
2✔
1824
                        columnH := m.storageH.columns[tableID]
2✔
1825

2✔
1826
                        lock := m.world.lock()
2✔
1827
                        for i := range len {
26✔
1828
                                index := uintptr(start + i)
24✔
1829
                                fn(
24✔
1830
                                        table.GetEntity(index),
24✔
1831
                                        (*A)(columnA.Get(index)),
24✔
1832
                                        (*B)(columnB.Get(index)),
24✔
1833
                                        (*C)(columnC.Get(index)),
24✔
1834
                                        (*D)(columnD.Get(index)),
24✔
1835
                                        (*E)(columnE.Get(index)),
24✔
1836
                                        (*F)(columnF.Get(index)),
24✔
1837
                                        (*G)(columnG.Get(index)),
24✔
1838
                                        (*H)(columnH.Get(index)),
24✔
1839
                                )
24✔
1840
                        }
24✔
1841
                        m.world.unlock(lock)
2✔
1842
                }
1843
        }
1844
        m.world.exchangeBatch(batch, m.ids, nil, nil, m.relations, process)
1✔
1845
}
1846

1847
// Remove the mapped components from the given entity.
1848
func (m *Map8[A, B, C, D, E, F, G, H]) Remove(entity Entity) {
25✔
1849
        if !m.world.Alive(entity) {
26✔
1850
                panic("can't remove components from a dead entity")
1✔
1851
        }
1852
        m.world.exchange(entity, nil, m.ids, nil, nil)
24✔
1853
}
1854

1855
// RemoveBatch removes the mapped components from all entities matching the given batch filter.
1856
func (m *Map8[A, B, C, D, E, F, G, H]) RemoveBatch(batch *Batch) {
1✔
1857
        m.world.exchangeBatch(batch, nil, m.ids, nil, nil, nil)
1✔
1858
}
1✔
1859

1860
// RemoveBatchFn removes the mapped components from all entities matching the given batch filter,
1861
// running the given function on each. The function can be nil.
1862
func (m *Map8[A, B, C, D, E, F, G, H]) RemoveBatchFn(batch *Batch, fn func(entity Entity)) {
1✔
1863
        var process func(tableID tableID, start, len int)
1✔
1864
        if fn != nil {
2✔
1865
                process = func(tableID tableID, start, len int) {
3✔
1866
                        table := &m.world.storage.tables[tableID]
2✔
1867

2✔
1868
                        lock := m.world.lock()
2✔
1869
                        for i := range len {
26✔
1870
                                index := uintptr(start + i)
24✔
1871
                                fn(table.GetEntity(index))
24✔
1872
                        }
24✔
1873
                        m.world.unlock(lock)
2✔
1874
                }
1875
        }
1876
        m.world.exchangeBatch(batch, nil, m.ids, nil, nil, process)
1✔
1877
}
1878

1879
// GetRelation returns the relation target of an entity for the component at the given index.
1880
func (m *Map8[A, B, C, D, E, F, G, H]) GetRelation(entity Entity, index int) Entity {
3✔
1881
        if !m.world.Alive(entity) {
4✔
1882
                panic("can't get entity relation target for a dead entity")
1✔
1883
        }
1884
        return m.GetRelationUnchecked(entity, index)
2✔
1885
}
1886

1887
// GetRelationUnchecked returns the relation target of an entity for the component at the given index.
1888
// In contrast to [Map8.GetRelation], it does not check whether the entity is alive.
1889
// Can be used as an optimization when it is certain that the entity is alive.
1890
func (m *Map8[A, B, C, D, E, F, G, H]) GetRelationUnchecked(entity Entity, index int) Entity {
3✔
1891
        return m.world.storage.getRelation(entity, m.ids[index])
3✔
1892
}
3✔
1893

1894
// SetRelations sets relation targets for the given entity.
1895
func (m *Map8[A, B, C, D, E, F, G, H]) SetRelations(entity Entity, rel ...RelationIndex) {
2✔
1896
        if !m.world.Alive(entity) {
3✔
1897
                panic("can't set entity relation targets for a dead entity")
1✔
1898
        }
1899
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
1✔
1900
        m.world.setRelations(entity, m.relations)
1✔
1901
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc