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

mlange-42 / ark / 13592982208

28 Feb 2025 05:09PM CUT coverage: 92.671% (-2.1%) from 94.795%
13592982208

Pull #79

github

web-flow
Merge e64da0798 into 10315654e
Pull Request #79: Relation getters for queries and maps

30 of 121 new or added lines in 6 files covered. (24.79%)

44 existing lines in 1 file now uncovered.

3414 of 3684 relevant lines covered (92.67%)

50384.73 hits per line

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

83.93
/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] {
9✔
17
        ids := []ID{
9✔
18
                ComponentID[A](world),
9✔
19
        }
9✔
20
        return Map1[A]{
9✔
21
                world:    world,
9✔
22
                ids:      ids,
9✔
23
                storageA: &world.storage.components[ids[0].id],
9✔
24
        }
9✔
25
}
9✔
26

27
// NewEntity creates a new entity with the mapped components.
28
func (m *Map1[A]) NewEntity(a *A, rel ...RelationIndex) Entity {
96✔
29
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
96✔
30
        return m.world.newEntityWith(m.ids, []unsafe.Pointer{
96✔
31
                unsafe.Pointer(a),
96✔
32
        }, m.relations)
96✔
33
}
96✔
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) {
1✔
46
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
1✔
47
        tableID, start := m.world.newEntities(count, m.ids, m.relations)
1✔
48
        if fn == nil {
1✔
49
                return
×
50
        }
×
51

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

1✔
55
        for i := range count {
25✔
56
                index := uintptr(start + i)
24✔
57
                fn(
24✔
58
                        table.GetEntity(index),
24✔
59
                        (*A)(columnA.Get(index)),
24✔
60
                )
24✔
61
        }
24✔
62
}
63

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

72
// GetUnchecked returns the mapped components for the given entity.
73
// It does not check whether the entity is alive.
74
// Can be used as an optimization when it is certain that the entity is alive.
75
func (m *Map1[A]) GetUnchecked(entity Entity) *A {
24✔
76
        index := m.world.storage.entities[entity.id]
24✔
77
        row := uintptr(index.row)
24✔
78
        checkMapHasComponent(m.storageA, index.table)
24✔
79

24✔
80
        return (*A)(m.storageA.columns[index.table].Get(row))
24✔
81
}
24✔
82

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

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

103
// Remove the mapped components from the given entity.
104
func (m *Map1[A]) Remove(entity Entity) {
24✔
105
        if !m.world.Alive(entity) {
24✔
106
                panic("can't remove components from a dead entity")
×
107
        }
108
        m.world.exchange(entity, nil, m.ids, nil, nil)
24✔
109
}
110

111
// GetRelation returns the relation target of an entity for the component at the given index.
NEW
112
func (m *Map1[A]) GetRelation(entity Entity, index int) Entity {
×
NEW
113
        if !m.world.Alive(entity) {
×
NEW
114
                panic("can't get entity relation target for a dead entity")
×
115
        }
NEW
116
        return m.GetRelationUnchecked(entity, index)
×
117
}
118

119
// GetRelationUnchecked returns the relation target of an entity for the component at the given index.
120
// It does not check whether the entity is alive.
121
// Can be used as an optimization when it is certain that the entity is alive.
NEW
122
func (m *Map1[A]) GetRelationUnchecked(entity Entity, index int) Entity {
×
NEW
123
        return m.world.storage.getRelation(entity, m.ids[index])
×
NEW
124
}
×
125

126
// SetRelations sets relation targets for the given entity.
127
func (m *Map1[A]) SetRelations(entity Entity, rel ...RelationIndex) {
×
128
        if !m.world.Alive(entity) {
×
NEW
129
                panic("can't set entity relation targets for a dead entity")
×
130
        }
131
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
×
132
        m.world.setRelations(entity, m.relations)
×
133
}
134

135
// Map2 is a mapper to access 2 components of an entity.
136
type Map2[A any, B any] struct {
137
        world     *World
138
        ids       []ID
139
        storageA  *componentStorage
140
        storageB  *componentStorage
141
        relations []relationID
142
}
143

144
// NewMap2 creates a new [Map2].
145
func NewMap2[A any, B any](world *World) Map2[A, B] {
35✔
146
        ids := []ID{
35✔
147
                ComponentID[A](world),
35✔
148
                ComponentID[B](world),
35✔
149
        }
35✔
150
        return Map2[A, B]{
35✔
151
                world:    world,
35✔
152
                ids:      ids,
35✔
153
                storageA: &world.storage.components[ids[0].id],
35✔
154
                storageB: &world.storage.components[ids[1].id],
35✔
155
        }
35✔
156
}
35✔
157

158
// NewEntity creates a new entity with the mapped components.
159
func (m *Map2[A, B]) NewEntity(a *A, b *B, rel ...RelationIndex) Entity {
254✔
160
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
254✔
161
        return m.world.newEntityWith(m.ids, []unsafe.Pointer{
254✔
162
                unsafe.Pointer(a),
254✔
163
                unsafe.Pointer(b),
254✔
164
        }, m.relations)
254✔
165
}
254✔
166

167
// NewBatch creates a batch of new entities with the mapped components.
168
func (m *Map2[A, B]) NewBatch(count int, a *A, b *B, rel ...RelationIndex) {
1✔
169
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
1✔
170
        m.world.newEntitiesWith(count, m.ids, []unsafe.Pointer{
1✔
171
                unsafe.Pointer(a),
1✔
172
                unsafe.Pointer(b),
1✔
173
        }, m.relations)
1✔
174
}
1✔
175

176
// NewBatchFn creates a batch of new entities with the mapped components, running the given initializer function on each.
177
// The initializer function can be nil.
178
func (m *Map2[A, B]) NewBatchFn(count int, fn func(entity Entity, a *A, b *B), rel ...RelationIndex) {
1✔
179
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
1✔
180
        tableID, start := m.world.newEntities(count, m.ids, m.relations)
1✔
181
        if fn == nil {
1✔
182
                return
×
183
        }
×
184

185
        table := &m.world.storage.tables[tableID]
1✔
186
        columnA := m.storageA.columns[tableID]
1✔
187
        columnB := m.storageB.columns[tableID]
1✔
188

1✔
189
        for i := range count {
25✔
190
                index := uintptr(start + i)
24✔
191
                fn(
24✔
192
                        table.GetEntity(index),
24✔
193
                        (*A)(columnA.Get(index)),
24✔
194
                        (*B)(columnB.Get(index)),
24✔
195
                )
24✔
196
        }
24✔
197
}
198

199
// Get returns the mapped components for the given entity.
200
func (m *Map2[A, B]) Get(entity Entity) (*A, *B) {
24✔
201
        if !m.world.Alive(entity) {
24✔
202
                panic("can't get components of a dead entity")
×
203
        }
204
        return m.GetUnchecked(entity)
24✔
205
}
206

207
// GetUnchecked returns the mapped components for the given entity.
208
// It does not check whether the entity is alive.
209
// Can be used as an optimization when it is certain that the entity is alive.
210
func (m *Map2[A, B]) GetUnchecked(entity Entity) (*A, *B) {
24✔
211
        index := m.world.storage.entities[entity.id]
24✔
212
        row := uintptr(index.row)
24✔
213
        checkMapHasComponent(m.storageA, index.table)
24✔
214
        checkMapHasComponent(m.storageB, index.table)
24✔
215

24✔
216
        return (*A)(m.storageA.columns[index.table].Get(row)),
24✔
217
                (*B)(m.storageB.columns[index.table].Get(row))
24✔
218
}
24✔
219

220
// HasAll return whether the given entity has all mapped components.
221
func (m *Map2[A, B]) HasAll(entity Entity) bool {
53✔
222
        if !m.world.Alive(entity) {
53✔
223
                panic("can't check components of a dead entity")
×
224
        }
225
        index := m.world.storage.entities[entity.id]
53✔
226
        return m.storageA.columns[index.table] != nil &&
53✔
227
                m.storageB.columns[index.table] != nil
53✔
228
}
229

230
// Add the mapped components to the given entity.
231
func (m *Map2[A, B]) Add(entity Entity, a *A, b *B, rel ...RelationIndex) {
12✔
232
        if !m.world.Alive(entity) {
12✔
233
                panic("can't add components to a dead entity")
×
234
        }
235
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
12✔
236
        m.world.exchange(entity, m.ids, nil, []unsafe.Pointer{
12✔
237
                unsafe.Pointer(a),
12✔
238
                unsafe.Pointer(b),
12✔
239
        }, m.relations)
12✔
240
}
241

242
// Remove the mapped components from the given entity.
243
func (m *Map2[A, B]) Remove(entity Entity) {
24✔
244
        if !m.world.Alive(entity) {
24✔
245
                panic("can't remove components from a dead entity")
×
246
        }
247
        m.world.exchange(entity, nil, m.ids, nil, nil)
24✔
248
}
249

250
// GetRelation returns the relation target of an entity for the component at the given index.
NEW
251
func (m *Map2[A, B]) GetRelation(entity Entity, index int) Entity {
×
NEW
252
        if !m.world.Alive(entity) {
×
NEW
253
                panic("can't get entity relation target for a dead entity")
×
254
        }
NEW
255
        return m.GetRelationUnchecked(entity, index)
×
256
}
257

258
// GetRelationUnchecked returns the relation target of an entity for the component at the given index.
259
// It does not check whether the entity is alive.
260
// Can be used as an optimization when it is certain that the entity is alive.
NEW
261
func (m *Map2[A, B]) GetRelationUnchecked(entity Entity, index int) Entity {
×
NEW
262
        return m.world.storage.getRelation(entity, m.ids[index])
×
NEW
263
}
×
264

265
// SetRelations sets relation targets for the given entity.
266
func (m *Map2[A, B]) SetRelations(entity Entity, rel ...RelationIndex) {
×
267
        if !m.world.Alive(entity) {
×
NEW
268
                panic("can't set entity relation targets for a dead entity")
×
269
        }
270
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
×
271
        m.world.setRelations(entity, m.relations)
×
272
}
273

274
// Map3 is a mapper to access 3 components of an entity.
275
type Map3[A any, B any, C any] struct {
276
        world     *World
277
        ids       []ID
278
        storageA  *componentStorage
279
        storageB  *componentStorage
280
        storageC  *componentStorage
281
        relations []relationID
282
}
283

284
// NewMap3 creates a new [Map3].
285
func NewMap3[A any, B any, C any](world *World) Map3[A, B, C] {
9✔
286
        ids := []ID{
9✔
287
                ComponentID[A](world),
9✔
288
                ComponentID[B](world),
9✔
289
                ComponentID[C](world),
9✔
290
        }
9✔
291
        return Map3[A, B, C]{
9✔
292
                world:    world,
9✔
293
                ids:      ids,
9✔
294
                storageA: &world.storage.components[ids[0].id],
9✔
295
                storageB: &world.storage.components[ids[1].id],
9✔
296
                storageC: &world.storage.components[ids[2].id],
9✔
297
        }
9✔
298
}
9✔
299

300
// NewEntity creates a new entity with the mapped components.
301
func (m *Map3[A, B, C]) NewEntity(a *A, b *B, c *C, rel ...RelationIndex) Entity {
136✔
302
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
136✔
303
        return m.world.newEntityWith(m.ids, []unsafe.Pointer{
136✔
304
                unsafe.Pointer(a),
136✔
305
                unsafe.Pointer(b),
136✔
306
                unsafe.Pointer(c),
136✔
307
        }, m.relations)
136✔
308
}
136✔
309

310
// NewBatch creates a batch of new entities with the mapped components.
311
func (m *Map3[A, B, C]) NewBatch(count int, a *A, b *B, c *C, rel ...RelationIndex) {
1✔
312
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
1✔
313
        m.world.newEntitiesWith(count, m.ids, []unsafe.Pointer{
1✔
314
                unsafe.Pointer(a),
1✔
315
                unsafe.Pointer(b),
1✔
316
                unsafe.Pointer(c),
1✔
317
        }, m.relations)
1✔
318
}
1✔
319

320
// NewBatchFn creates a batch of new entities with the mapped components, running the given initializer function on each.
321
// The initializer function can be nil.
322
func (m *Map3[A, B, C]) NewBatchFn(count int, fn func(entity Entity, a *A, b *B, c *C), rel ...RelationIndex) {
1✔
323
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
1✔
324
        tableID, start := m.world.newEntities(count, m.ids, m.relations)
1✔
325
        if fn == nil {
1✔
326
                return
×
327
        }
×
328

329
        table := &m.world.storage.tables[tableID]
1✔
330
        columnA := m.storageA.columns[tableID]
1✔
331
        columnB := m.storageB.columns[tableID]
1✔
332
        columnC := m.storageC.columns[tableID]
1✔
333

1✔
334
        for i := range count {
25✔
335
                index := uintptr(start + i)
24✔
336
                fn(
24✔
337
                        table.GetEntity(index),
24✔
338
                        (*A)(columnA.Get(index)),
24✔
339
                        (*B)(columnB.Get(index)),
24✔
340
                        (*C)(columnC.Get(index)),
24✔
341
                )
24✔
342
        }
24✔
343
}
344

345
// Get returns the mapped components for the given entity.
346
func (m *Map3[A, B, C]) Get(entity Entity) (*A, *B, *C) {
24✔
347
        if !m.world.Alive(entity) {
24✔
348
                panic("can't get components of a dead entity")
×
349
        }
350
        return m.GetUnchecked(entity)
24✔
351
}
352

353
// GetUnchecked returns the mapped components for the given entity.
354
// It does not check whether the entity is alive.
355
// Can be used as an optimization when it is certain that the entity is alive.
356
func (m *Map3[A, B, C]) GetUnchecked(entity Entity) (*A, *B, *C) {
24✔
357
        index := m.world.storage.entities[entity.id]
24✔
358
        row := uintptr(index.row)
24✔
359
        checkMapHasComponent(m.storageA, index.table)
24✔
360
        checkMapHasComponent(m.storageB, index.table)
24✔
361
        checkMapHasComponent(m.storageC, index.table)
24✔
362

24✔
363
        return (*A)(m.storageA.columns[index.table].Get(row)),
24✔
364
                (*B)(m.storageB.columns[index.table].Get(row)),
24✔
365
                (*C)(m.storageC.columns[index.table].Get(row))
24✔
366
}
24✔
367

368
// HasAll return whether the given entity has all mapped components.
369
func (m *Map3[A, B, C]) HasAll(entity Entity) bool {
29✔
370
        if !m.world.Alive(entity) {
29✔
371
                panic("can't check components of a dead entity")
×
372
        }
373
        index := m.world.storage.entities[entity.id]
29✔
374
        return m.storageA.columns[index.table] != nil &&
29✔
375
                m.storageB.columns[index.table] != nil &&
29✔
376
                m.storageC.columns[index.table] != nil
29✔
377
}
378

379
// Add the mapped components to the given entity.
380
func (m *Map3[A, B, C]) Add(entity Entity, a *A, b *B, c *C, rel ...RelationIndex) {
12✔
381
        if !m.world.Alive(entity) {
12✔
382
                panic("can't add components to a dead entity")
×
383
        }
384
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
12✔
385
        m.world.exchange(entity, m.ids, nil, []unsafe.Pointer{
12✔
386
                unsafe.Pointer(a),
12✔
387
                unsafe.Pointer(b),
12✔
388
                unsafe.Pointer(c),
12✔
389
        }, m.relations)
12✔
390
}
391

392
// Remove the mapped components from the given entity.
393
func (m *Map3[A, B, C]) Remove(entity Entity) {
24✔
394
        if !m.world.Alive(entity) {
24✔
395
                panic("can't remove components from a dead entity")
×
396
        }
397
        m.world.exchange(entity, nil, m.ids, nil, nil)
24✔
398
}
399

400
// GetRelation returns the relation target of an entity for the component at the given index.
NEW
401
func (m *Map3[A, B, C]) GetRelation(entity Entity, index int) Entity {
×
NEW
402
        if !m.world.Alive(entity) {
×
NEW
403
                panic("can't get entity relation target for a dead entity")
×
404
        }
NEW
405
        return m.GetRelationUnchecked(entity, index)
×
406
}
407

408
// GetRelationUnchecked returns the relation target of an entity for the component at the given index.
409
// It does not check whether the entity is alive.
410
// Can be used as an optimization when it is certain that the entity is alive.
NEW
411
func (m *Map3[A, B, C]) GetRelationUnchecked(entity Entity, index int) Entity {
×
NEW
412
        return m.world.storage.getRelation(entity, m.ids[index])
×
NEW
413
}
×
414

415
// SetRelations sets relation targets for the given entity.
416
func (m *Map3[A, B, C]) SetRelations(entity Entity, rel ...RelationIndex) {
×
417
        if !m.world.Alive(entity) {
×
NEW
418
                panic("can't set entity relation targets for a dead entity")
×
419
        }
420
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
×
421
        m.world.setRelations(entity, m.relations)
×
422
}
423

424
// Map4 is a mapper to access 4 components of an entity.
425
type Map4[A any, B any, C any, D any] struct {
426
        world     *World
427
        ids       []ID
428
        storageA  *componentStorage
429
        storageB  *componentStorage
430
        storageC  *componentStorage
431
        storageD  *componentStorage
432
        relations []relationID
433
}
434

435
// NewMap4 creates a new [Map4].
436
func NewMap4[A any, B any, C any, D any](world *World) Map4[A, B, C, D] {
8✔
437
        ids := []ID{
8✔
438
                ComponentID[A](world),
8✔
439
                ComponentID[B](world),
8✔
440
                ComponentID[C](world),
8✔
441
                ComponentID[D](world),
8✔
442
        }
8✔
443
        return Map4[A, B, C, D]{
8✔
444
                world:    world,
8✔
445
                ids:      ids,
8✔
446
                storageA: &world.storage.components[ids[0].id],
8✔
447
                storageB: &world.storage.components[ids[1].id],
8✔
448
                storageC: &world.storage.components[ids[2].id],
8✔
449
                storageD: &world.storage.components[ids[3].id],
8✔
450
        }
8✔
451
}
8✔
452

453
// NewEntity creates a new entity with the mapped components.
454
func (m *Map4[A, B, C, D]) NewEntity(a *A, b *B, c *C, d *D, rel ...RelationIndex) Entity {
96✔
455
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
96✔
456
        return m.world.newEntityWith(m.ids, []unsafe.Pointer{
96✔
457
                unsafe.Pointer(a),
96✔
458
                unsafe.Pointer(b),
96✔
459
                unsafe.Pointer(c),
96✔
460
                unsafe.Pointer(d),
96✔
461
        }, m.relations)
96✔
462
}
96✔
463

464
// NewBatch creates a batch of new entities with the mapped components.
465
func (m *Map4[A, B, C, D]) NewBatch(count int, a *A, b *B, c *C, d *D, rel ...RelationIndex) {
1✔
466
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
1✔
467
        m.world.newEntitiesWith(count, m.ids, []unsafe.Pointer{
1✔
468
                unsafe.Pointer(a),
1✔
469
                unsafe.Pointer(b),
1✔
470
                unsafe.Pointer(c),
1✔
471
                unsafe.Pointer(d),
1✔
472
        }, m.relations)
1✔
473
}
1✔
474

475
// NewBatchFn creates a batch of new entities with the mapped components, running the given initializer function on each.
476
// The initializer function can be nil.
477
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✔
478
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
1✔
479
        tableID, start := m.world.newEntities(count, m.ids, m.relations)
1✔
480
        if fn == nil {
1✔
481
                return
×
482
        }
×
483

484
        table := &m.world.storage.tables[tableID]
1✔
485
        columnA := m.storageA.columns[tableID]
1✔
486
        columnB := m.storageB.columns[tableID]
1✔
487
        columnC := m.storageC.columns[tableID]
1✔
488
        columnD := m.storageD.columns[tableID]
1✔
489

1✔
490
        for i := range count {
25✔
491
                index := uintptr(start + i)
24✔
492
                fn(
24✔
493
                        table.GetEntity(index),
24✔
494
                        (*A)(columnA.Get(index)),
24✔
495
                        (*B)(columnB.Get(index)),
24✔
496
                        (*C)(columnC.Get(index)),
24✔
497
                        (*D)(columnD.Get(index)),
24✔
498
                )
24✔
499
        }
24✔
500
}
501

502
// Get returns the mapped components for the given entity.
503
func (m *Map4[A, B, C, D]) Get(entity Entity) (*A, *B, *C, *D) {
24✔
504
        if !m.world.Alive(entity) {
24✔
505
                panic("can't get components of a dead entity")
×
506
        }
507
        return m.GetUnchecked(entity)
24✔
508
}
509

510
// GetUnchecked returns the mapped components for the given entity.
511
// It does not check whether the entity is alive.
512
// Can be used as an optimization when it is certain that the entity is alive.
513
func (m *Map4[A, B, C, D]) GetUnchecked(entity Entity) (*A, *B, *C, *D) {
24✔
514
        index := m.world.storage.entities[entity.id]
24✔
515
        row := uintptr(index.row)
24✔
516
        checkMapHasComponent(m.storageA, index.table)
24✔
517
        checkMapHasComponent(m.storageB, index.table)
24✔
518
        checkMapHasComponent(m.storageC, index.table)
24✔
519
        checkMapHasComponent(m.storageD, index.table)
24✔
520

24✔
521
        return (*A)(m.storageA.columns[index.table].Get(row)),
24✔
522
                (*B)(m.storageB.columns[index.table].Get(row)),
24✔
523
                (*C)(m.storageC.columns[index.table].Get(row)),
24✔
524
                (*D)(m.storageD.columns[index.table].Get(row))
24✔
525
}
24✔
526

527
// HasAll return whether the given entity has all mapped components.
528
func (m *Map4[A, B, C, D]) HasAll(entity Entity) bool {
29✔
529
        if !m.world.Alive(entity) {
29✔
530
                panic("can't check components of a dead entity")
×
531
        }
532
        index := m.world.storage.entities[entity.id]
29✔
533
        return m.storageA.columns[index.table] != nil &&
29✔
534
                m.storageB.columns[index.table] != nil &&
29✔
535
                m.storageC.columns[index.table] != nil &&
29✔
536
                m.storageD.columns[index.table] != nil
29✔
537
}
538

539
// Add the mapped components to the given entity.
540
func (m *Map4[A, B, C, D]) Add(entity Entity, a *A, b *B, c *C, d *D, rel ...RelationIndex) {
12✔
541
        if !m.world.Alive(entity) {
12✔
542
                panic("can't add components to a dead entity")
×
543
        }
544
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
12✔
545
        m.world.exchange(entity, m.ids, nil, []unsafe.Pointer{
12✔
546
                unsafe.Pointer(a),
12✔
547
                unsafe.Pointer(b),
12✔
548
                unsafe.Pointer(c),
12✔
549
                unsafe.Pointer(d),
12✔
550
        }, m.relations)
12✔
551
}
552

553
// Remove the mapped components from the given entity.
554
func (m *Map4[A, B, C, D]) Remove(entity Entity) {
24✔
555
        if !m.world.Alive(entity) {
24✔
556
                panic("can't remove components from a dead entity")
×
557
        }
558
        m.world.exchange(entity, nil, m.ids, nil, nil)
24✔
559
}
560

561
// GetRelation returns the relation target of an entity for the component at the given index.
NEW
562
func (m *Map4[A, B, C, D]) GetRelation(entity Entity, index int) Entity {
×
NEW
563
        if !m.world.Alive(entity) {
×
NEW
564
                panic("can't get entity relation target for a dead entity")
×
565
        }
NEW
566
        return m.GetRelationUnchecked(entity, index)
×
567
}
568

569
// GetRelationUnchecked returns the relation target of an entity for the component at the given index.
570
// It does not check whether the entity is alive.
571
// Can be used as an optimization when it is certain that the entity is alive.
NEW
572
func (m *Map4[A, B, C, D]) GetRelationUnchecked(entity Entity, index int) Entity {
×
NEW
573
        return m.world.storage.getRelation(entity, m.ids[index])
×
NEW
574
}
×
575

576
// SetRelations sets relation targets for the given entity.
577
func (m *Map4[A, B, C, D]) SetRelations(entity Entity, rel ...RelationIndex) {
×
578
        if !m.world.Alive(entity) {
×
NEW
579
                panic("can't set entity relation targets for a dead entity")
×
580
        }
581
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
×
582
        m.world.setRelations(entity, m.relations)
×
583
}
584

585
// Map5 is a mapper to access 5 components of an entity.
586
type Map5[A any, B any, C any, D any, E any] struct {
587
        world     *World
588
        ids       []ID
589
        storageA  *componentStorage
590
        storageB  *componentStorage
591
        storageC  *componentStorage
592
        storageD  *componentStorage
593
        storageE  *componentStorage
594
        relations []relationID
595
}
596

597
// NewMap5 creates a new [Map5].
598
func NewMap5[A any, B any, C any, D any, E any](world *World) Map5[A, B, C, D, E] {
8✔
599
        ids := []ID{
8✔
600
                ComponentID[A](world),
8✔
601
                ComponentID[B](world),
8✔
602
                ComponentID[C](world),
8✔
603
                ComponentID[D](world),
8✔
604
                ComponentID[E](world),
8✔
605
        }
8✔
606
        return Map5[A, B, C, D, E]{
8✔
607
                world:    world,
8✔
608
                ids:      ids,
8✔
609
                storageA: &world.storage.components[ids[0].id],
8✔
610
                storageB: &world.storage.components[ids[1].id],
8✔
611
                storageC: &world.storage.components[ids[2].id],
8✔
612
                storageD: &world.storage.components[ids[3].id],
8✔
613
                storageE: &world.storage.components[ids[4].id],
8✔
614
        }
8✔
615
}
8✔
616

617
// NewEntity creates a new entity with the mapped components.
618
func (m *Map5[A, B, C, D, E]) NewEntity(a *A, b *B, c *C, d *D, e *E, rel ...RelationIndex) Entity {
96✔
619
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
96✔
620
        return m.world.newEntityWith(m.ids, []unsafe.Pointer{
96✔
621
                unsafe.Pointer(a),
96✔
622
                unsafe.Pointer(b),
96✔
623
                unsafe.Pointer(c),
96✔
624
                unsafe.Pointer(d),
96✔
625
                unsafe.Pointer(e),
96✔
626
        }, m.relations)
96✔
627
}
96✔
628

629
// NewBatch creates a batch of new entities with the mapped components.
630
func (m *Map5[A, B, C, D, E]) NewBatch(count int, a *A, b *B, c *C, d *D, e *E, rel ...RelationIndex) {
1✔
631
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
1✔
632
        m.world.newEntitiesWith(count, m.ids, []unsafe.Pointer{
1✔
633
                unsafe.Pointer(a),
1✔
634
                unsafe.Pointer(b),
1✔
635
                unsafe.Pointer(c),
1✔
636
                unsafe.Pointer(d),
1✔
637
                unsafe.Pointer(e),
1✔
638
        }, m.relations)
1✔
639
}
1✔
640

641
// NewBatchFn creates a batch of new entities with the mapped components, running the given initializer function on each.
642
// The initializer function can be nil.
643
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✔
644
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
1✔
645
        tableID, start := m.world.newEntities(count, m.ids, m.relations)
1✔
646
        if fn == nil {
1✔
647
                return
×
648
        }
×
649

650
        table := &m.world.storage.tables[tableID]
1✔
651
        columnA := m.storageA.columns[tableID]
1✔
652
        columnB := m.storageB.columns[tableID]
1✔
653
        columnC := m.storageC.columns[tableID]
1✔
654
        columnD := m.storageD.columns[tableID]
1✔
655
        columnE := m.storageE.columns[tableID]
1✔
656

1✔
657
        for i := range count {
25✔
658
                index := uintptr(start + i)
24✔
659
                fn(
24✔
660
                        table.GetEntity(index),
24✔
661
                        (*A)(columnA.Get(index)),
24✔
662
                        (*B)(columnB.Get(index)),
24✔
663
                        (*C)(columnC.Get(index)),
24✔
664
                        (*D)(columnD.Get(index)),
24✔
665
                        (*E)(columnE.Get(index)),
24✔
666
                )
24✔
667
        }
24✔
668
}
669

670
// Get returns the mapped components for the given entity.
671
func (m *Map5[A, B, C, D, E]) Get(entity Entity) (*A, *B, *C, *D, *E) {
24✔
672
        if !m.world.Alive(entity) {
24✔
673
                panic("can't get components of a dead entity")
×
674
        }
675
        return m.GetUnchecked(entity)
24✔
676
}
677

678
// GetUnchecked returns the mapped components for the given entity.
679
// It does not check whether the entity is alive.
680
// Can be used as an optimization when it is certain that the entity is alive.
681
func (m *Map5[A, B, C, D, E]) GetUnchecked(entity Entity) (*A, *B, *C, *D, *E) {
24✔
682
        index := m.world.storage.entities[entity.id]
24✔
683
        row := uintptr(index.row)
24✔
684
        checkMapHasComponent(m.storageA, index.table)
24✔
685
        checkMapHasComponent(m.storageB, index.table)
24✔
686
        checkMapHasComponent(m.storageC, index.table)
24✔
687
        checkMapHasComponent(m.storageD, index.table)
24✔
688
        checkMapHasComponent(m.storageE, index.table)
24✔
689

24✔
690
        return (*A)(m.storageA.columns[index.table].Get(row)),
24✔
691
                (*B)(m.storageB.columns[index.table].Get(row)),
24✔
692
                (*C)(m.storageC.columns[index.table].Get(row)),
24✔
693
                (*D)(m.storageD.columns[index.table].Get(row)),
24✔
694
                (*E)(m.storageE.columns[index.table].Get(row))
24✔
695
}
24✔
696

697
// HasAll return whether the given entity has all mapped components.
698
func (m *Map5[A, B, C, D, E]) HasAll(entity Entity) bool {
29✔
699
        if !m.world.Alive(entity) {
29✔
700
                panic("can't check components of a dead entity")
×
701
        }
702
        index := m.world.storage.entities[entity.id]
29✔
703
        return m.storageA.columns[index.table] != nil &&
29✔
704
                m.storageB.columns[index.table] != nil &&
29✔
705
                m.storageC.columns[index.table] != nil &&
29✔
706
                m.storageD.columns[index.table] != nil &&
29✔
707
                m.storageE.columns[index.table] != nil
29✔
708
}
709

710
// Add the mapped components to the given entity.
711
func (m *Map5[A, B, C, D, E]) Add(entity Entity, a *A, b *B, c *C, d *D, e *E, rel ...RelationIndex) {
12✔
712
        if !m.world.Alive(entity) {
12✔
713
                panic("can't add components to a dead entity")
×
714
        }
715
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
12✔
716
        m.world.exchange(entity, m.ids, nil, []unsafe.Pointer{
12✔
717
                unsafe.Pointer(a),
12✔
718
                unsafe.Pointer(b),
12✔
719
                unsafe.Pointer(c),
12✔
720
                unsafe.Pointer(d),
12✔
721
                unsafe.Pointer(e),
12✔
722
        }, m.relations)
12✔
723
}
724

725
// Remove the mapped components from the given entity.
726
func (m *Map5[A, B, C, D, E]) Remove(entity Entity) {
24✔
727
        if !m.world.Alive(entity) {
24✔
728
                panic("can't remove components from a dead entity")
×
729
        }
730
        m.world.exchange(entity, nil, m.ids, nil, nil)
24✔
731
}
732

733
// GetRelation returns the relation target of an entity for the component at the given index.
NEW
734
func (m *Map5[A, B, C, D, E]) GetRelation(entity Entity, index int) Entity {
×
NEW
735
        if !m.world.Alive(entity) {
×
NEW
736
                panic("can't get entity relation target for a dead entity")
×
737
        }
NEW
738
        return m.GetRelationUnchecked(entity, index)
×
739
}
740

741
// GetRelationUnchecked returns the relation target of an entity for the component at the given index.
742
// It does not check whether the entity is alive.
743
// Can be used as an optimization when it is certain that the entity is alive.
NEW
744
func (m *Map5[A, B, C, D, E]) GetRelationUnchecked(entity Entity, index int) Entity {
×
NEW
745
        return m.world.storage.getRelation(entity, m.ids[index])
×
NEW
746
}
×
747

748
// SetRelations sets relation targets for the given entity.
749
func (m *Map5[A, B, C, D, E]) SetRelations(entity Entity, rel ...RelationIndex) {
×
750
        if !m.world.Alive(entity) {
×
NEW
751
                panic("can't set entity relation targets for a dead entity")
×
752
        }
753
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
×
754
        m.world.setRelations(entity, m.relations)
×
755
}
756

757
// Map6 is a mapper to access 6 components of an entity.
758
type Map6[A any, B any, C any, D any, E any, F any] struct {
759
        world     *World
760
        ids       []ID
761
        storageA  *componentStorage
762
        storageB  *componentStorage
763
        storageC  *componentStorage
764
        storageD  *componentStorage
765
        storageE  *componentStorage
766
        storageF  *componentStorage
767
        relations []relationID
768
}
769

770
// NewMap6 creates a new [Map6].
771
func NewMap6[A any, B any, C any, D any, E any, F any](world *World) Map6[A, B, C, D, E, F] {
8✔
772
        ids := []ID{
8✔
773
                ComponentID[A](world),
8✔
774
                ComponentID[B](world),
8✔
775
                ComponentID[C](world),
8✔
776
                ComponentID[D](world),
8✔
777
                ComponentID[E](world),
8✔
778
                ComponentID[F](world),
8✔
779
        }
8✔
780
        return Map6[A, B, C, D, E, F]{
8✔
781
                world:    world,
8✔
782
                ids:      ids,
8✔
783
                storageA: &world.storage.components[ids[0].id],
8✔
784
                storageB: &world.storage.components[ids[1].id],
8✔
785
                storageC: &world.storage.components[ids[2].id],
8✔
786
                storageD: &world.storage.components[ids[3].id],
8✔
787
                storageE: &world.storage.components[ids[4].id],
8✔
788
                storageF: &world.storage.components[ids[5].id],
8✔
789
        }
8✔
790
}
8✔
791

792
// NewEntity creates a new entity with the mapped components.
793
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 {
96✔
794
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
96✔
795
        return m.world.newEntityWith(m.ids, []unsafe.Pointer{
96✔
796
                unsafe.Pointer(a),
96✔
797
                unsafe.Pointer(b),
96✔
798
                unsafe.Pointer(c),
96✔
799
                unsafe.Pointer(d),
96✔
800
                unsafe.Pointer(e),
96✔
801
                unsafe.Pointer(f),
96✔
802
        }, m.relations)
96✔
803
}
96✔
804

805
// NewBatch creates a batch of new entities with the mapped components.
806
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✔
807
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
1✔
808
        m.world.newEntitiesWith(count, m.ids, []unsafe.Pointer{
1✔
809
                unsafe.Pointer(a),
1✔
810
                unsafe.Pointer(b),
1✔
811
                unsafe.Pointer(c),
1✔
812
                unsafe.Pointer(d),
1✔
813
                unsafe.Pointer(e),
1✔
814
                unsafe.Pointer(f),
1✔
815
        }, m.relations)
1✔
816
}
1✔
817

818
// NewBatchFn creates a batch of new entities with the mapped components, running the given initializer function on each.
819
// The initializer function can be nil.
820
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✔
821
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
1✔
822
        tableID, start := m.world.newEntities(count, m.ids, m.relations)
1✔
823
        if fn == nil {
1✔
824
                return
×
825
        }
×
826

827
        table := &m.world.storage.tables[tableID]
1✔
828
        columnA := m.storageA.columns[tableID]
1✔
829
        columnB := m.storageB.columns[tableID]
1✔
830
        columnC := m.storageC.columns[tableID]
1✔
831
        columnD := m.storageD.columns[tableID]
1✔
832
        columnE := m.storageE.columns[tableID]
1✔
833
        columnF := m.storageF.columns[tableID]
1✔
834

1✔
835
        for i := range count {
25✔
836
                index := uintptr(start + i)
24✔
837
                fn(
24✔
838
                        table.GetEntity(index),
24✔
839
                        (*A)(columnA.Get(index)),
24✔
840
                        (*B)(columnB.Get(index)),
24✔
841
                        (*C)(columnC.Get(index)),
24✔
842
                        (*D)(columnD.Get(index)),
24✔
843
                        (*E)(columnE.Get(index)),
24✔
844
                        (*F)(columnF.Get(index)),
24✔
845
                )
24✔
846
        }
24✔
847
}
848

849
// Get returns the mapped components for the given entity.
850
func (m *Map6[A, B, C, D, E, F]) Get(entity Entity) (*A, *B, *C, *D, *E, *F) {
24✔
851
        if !m.world.Alive(entity) {
24✔
852
                panic("can't get components of a dead entity")
×
853
        }
854
        return m.GetUnchecked(entity)
24✔
855
}
856

857
// GetUnchecked returns the mapped components for the given entity.
858
// It does not check whether the entity is alive.
859
// Can be used as an optimization when it is certain that the entity is alive.
860
func (m *Map6[A, B, C, D, E, F]) GetUnchecked(entity Entity) (*A, *B, *C, *D, *E, *F) {
24✔
861
        index := m.world.storage.entities[entity.id]
24✔
862
        row := uintptr(index.row)
24✔
863
        checkMapHasComponent(m.storageA, index.table)
24✔
864
        checkMapHasComponent(m.storageB, index.table)
24✔
865
        checkMapHasComponent(m.storageC, index.table)
24✔
866
        checkMapHasComponent(m.storageD, index.table)
24✔
867
        checkMapHasComponent(m.storageE, index.table)
24✔
868
        checkMapHasComponent(m.storageF, index.table)
24✔
869

24✔
870
        return (*A)(m.storageA.columns[index.table].Get(row)),
24✔
871
                (*B)(m.storageB.columns[index.table].Get(row)),
24✔
872
                (*C)(m.storageC.columns[index.table].Get(row)),
24✔
873
                (*D)(m.storageD.columns[index.table].Get(row)),
24✔
874
                (*E)(m.storageE.columns[index.table].Get(row)),
24✔
875
                (*F)(m.storageF.columns[index.table].Get(row))
24✔
876
}
24✔
877

878
// HasAll return whether the given entity has all mapped components.
879
func (m *Map6[A, B, C, D, E, F]) HasAll(entity Entity) bool {
29✔
880
        if !m.world.Alive(entity) {
29✔
881
                panic("can't check components of a dead entity")
×
882
        }
883
        index := m.world.storage.entities[entity.id]
29✔
884
        return m.storageA.columns[index.table] != nil &&
29✔
885
                m.storageB.columns[index.table] != nil &&
29✔
886
                m.storageC.columns[index.table] != nil &&
29✔
887
                m.storageD.columns[index.table] != nil &&
29✔
888
                m.storageE.columns[index.table] != nil &&
29✔
889
                m.storageF.columns[index.table] != nil
29✔
890
}
891

892
// Add the mapped components to the given entity.
893
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) {
12✔
894
        if !m.world.Alive(entity) {
12✔
895
                panic("can't add components to a dead entity")
×
896
        }
897
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
12✔
898
        m.world.exchange(entity, m.ids, nil, []unsafe.Pointer{
12✔
899
                unsafe.Pointer(a),
12✔
900
                unsafe.Pointer(b),
12✔
901
                unsafe.Pointer(c),
12✔
902
                unsafe.Pointer(d),
12✔
903
                unsafe.Pointer(e),
12✔
904
                unsafe.Pointer(f),
12✔
905
        }, m.relations)
12✔
906
}
907

908
// Remove the mapped components from the given entity.
909
func (m *Map6[A, B, C, D, E, F]) Remove(entity Entity) {
24✔
910
        if !m.world.Alive(entity) {
24✔
911
                panic("can't remove components from a dead entity")
×
912
        }
913
        m.world.exchange(entity, nil, m.ids, nil, nil)
24✔
914
}
915

916
// GetRelation returns the relation target of an entity for the component at the given index.
NEW
917
func (m *Map6[A, B, C, D, E, F]) GetRelation(entity Entity, index int) Entity {
×
NEW
918
        if !m.world.Alive(entity) {
×
NEW
919
                panic("can't get entity relation target for a dead entity")
×
920
        }
NEW
921
        return m.GetRelationUnchecked(entity, index)
×
922
}
923

924
// GetRelationUnchecked returns the relation target of an entity for the component at the given index.
925
// It does not check whether the entity is alive.
926
// Can be used as an optimization when it is certain that the entity is alive.
NEW
927
func (m *Map6[A, B, C, D, E, F]) GetRelationUnchecked(entity Entity, index int) Entity {
×
NEW
928
        return m.world.storage.getRelation(entity, m.ids[index])
×
NEW
929
}
×
930

931
// SetRelations sets relation targets for the given entity.
932
func (m *Map6[A, B, C, D, E, F]) SetRelations(entity Entity, rel ...RelationIndex) {
×
933
        if !m.world.Alive(entity) {
×
NEW
934
                panic("can't set entity relation targets for a dead entity")
×
935
        }
936
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
×
937
        m.world.setRelations(entity, m.relations)
×
938
}
939

940
// Map7 is a mapper to access 7 components of an entity.
941
type Map7[A any, B any, C any, D any, E any, F any, G any] struct {
942
        world     *World
943
        ids       []ID
944
        storageA  *componentStorage
945
        storageB  *componentStorage
946
        storageC  *componentStorage
947
        storageD  *componentStorage
948
        storageE  *componentStorage
949
        storageF  *componentStorage
950
        storageG  *componentStorage
951
        relations []relationID
952
}
953

954
// NewMap7 creates a new [Map7].
955
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] {
8✔
956
        ids := []ID{
8✔
957
                ComponentID[A](world),
8✔
958
                ComponentID[B](world),
8✔
959
                ComponentID[C](world),
8✔
960
                ComponentID[D](world),
8✔
961
                ComponentID[E](world),
8✔
962
                ComponentID[F](world),
8✔
963
                ComponentID[G](world),
8✔
964
        }
8✔
965
        return Map7[A, B, C, D, E, F, G]{
8✔
966
                world:    world,
8✔
967
                ids:      ids,
8✔
968
                storageA: &world.storage.components[ids[0].id],
8✔
969
                storageB: &world.storage.components[ids[1].id],
8✔
970
                storageC: &world.storage.components[ids[2].id],
8✔
971
                storageD: &world.storage.components[ids[3].id],
8✔
972
                storageE: &world.storage.components[ids[4].id],
8✔
973
                storageF: &world.storage.components[ids[5].id],
8✔
974
                storageG: &world.storage.components[ids[6].id],
8✔
975
        }
8✔
976
}
8✔
977

978
// NewEntity creates a new entity with the mapped components.
979
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 {
96✔
980
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
96✔
981
        return m.world.newEntityWith(m.ids, []unsafe.Pointer{
96✔
982
                unsafe.Pointer(a),
96✔
983
                unsafe.Pointer(b),
96✔
984
                unsafe.Pointer(c),
96✔
985
                unsafe.Pointer(d),
96✔
986
                unsafe.Pointer(e),
96✔
987
                unsafe.Pointer(f),
96✔
988
                unsafe.Pointer(g),
96✔
989
        }, m.relations)
96✔
990
}
96✔
991

992
// NewBatch creates a batch of new entities with the mapped components.
993
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✔
994
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
1✔
995
        m.world.newEntitiesWith(count, m.ids, []unsafe.Pointer{
1✔
996
                unsafe.Pointer(a),
1✔
997
                unsafe.Pointer(b),
1✔
998
                unsafe.Pointer(c),
1✔
999
                unsafe.Pointer(d),
1✔
1000
                unsafe.Pointer(e),
1✔
1001
                unsafe.Pointer(f),
1✔
1002
                unsafe.Pointer(g),
1✔
1003
        }, m.relations)
1✔
1004
}
1✔
1005

1006
// NewBatchFn creates a batch of new entities with the mapped components, running the given initializer function on each.
1007
// The initializer function can be nil.
1008
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✔
1009
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
1✔
1010
        tableID, start := m.world.newEntities(count, m.ids, m.relations)
1✔
1011
        if fn == nil {
1✔
1012
                return
×
1013
        }
×
1014

1015
        table := &m.world.storage.tables[tableID]
1✔
1016
        columnA := m.storageA.columns[tableID]
1✔
1017
        columnB := m.storageB.columns[tableID]
1✔
1018
        columnC := m.storageC.columns[tableID]
1✔
1019
        columnD := m.storageD.columns[tableID]
1✔
1020
        columnE := m.storageE.columns[tableID]
1✔
1021
        columnF := m.storageF.columns[tableID]
1✔
1022
        columnG := m.storageG.columns[tableID]
1✔
1023

1✔
1024
        for i := range count {
25✔
1025
                index := uintptr(start + i)
24✔
1026
                fn(
24✔
1027
                        table.GetEntity(index),
24✔
1028
                        (*A)(columnA.Get(index)),
24✔
1029
                        (*B)(columnB.Get(index)),
24✔
1030
                        (*C)(columnC.Get(index)),
24✔
1031
                        (*D)(columnD.Get(index)),
24✔
1032
                        (*E)(columnE.Get(index)),
24✔
1033
                        (*F)(columnF.Get(index)),
24✔
1034
                        (*G)(columnG.Get(index)),
24✔
1035
                )
24✔
1036
        }
24✔
1037
}
1038

1039
// Get returns the mapped components for the given entity.
1040
func (m *Map7[A, B, C, D, E, F, G]) Get(entity Entity) (*A, *B, *C, *D, *E, *F, *G) {
24✔
1041
        if !m.world.Alive(entity) {
24✔
1042
                panic("can't get components of a dead entity")
×
1043
        }
1044
        return m.GetUnchecked(entity)
24✔
1045
}
1046

1047
// GetUnchecked returns the mapped components for the given entity.
1048
// It does not check whether the entity is alive.
1049
// Can be used as an optimization when it is certain that the entity is alive.
1050
func (m *Map7[A, B, C, D, E, F, G]) GetUnchecked(entity Entity) (*A, *B, *C, *D, *E, *F, *G) {
24✔
1051
        index := m.world.storage.entities[entity.id]
24✔
1052
        row := uintptr(index.row)
24✔
1053
        checkMapHasComponent(m.storageA, index.table)
24✔
1054
        checkMapHasComponent(m.storageB, index.table)
24✔
1055
        checkMapHasComponent(m.storageC, index.table)
24✔
1056
        checkMapHasComponent(m.storageD, index.table)
24✔
1057
        checkMapHasComponent(m.storageE, index.table)
24✔
1058
        checkMapHasComponent(m.storageF, index.table)
24✔
1059
        checkMapHasComponent(m.storageG, index.table)
24✔
1060

24✔
1061
        return (*A)(m.storageA.columns[index.table].Get(row)),
24✔
1062
                (*B)(m.storageB.columns[index.table].Get(row)),
24✔
1063
                (*C)(m.storageC.columns[index.table].Get(row)),
24✔
1064
                (*D)(m.storageD.columns[index.table].Get(row)),
24✔
1065
                (*E)(m.storageE.columns[index.table].Get(row)),
24✔
1066
                (*F)(m.storageF.columns[index.table].Get(row)),
24✔
1067
                (*G)(m.storageG.columns[index.table].Get(row))
24✔
1068
}
24✔
1069

1070
// HasAll return whether the given entity has all mapped components.
1071
func (m *Map7[A, B, C, D, E, F, G]) HasAll(entity Entity) bool {
29✔
1072
        if !m.world.Alive(entity) {
29✔
1073
                panic("can't check components of a dead entity")
×
1074
        }
1075
        index := m.world.storage.entities[entity.id]
29✔
1076
        return m.storageA.columns[index.table] != nil &&
29✔
1077
                m.storageB.columns[index.table] != nil &&
29✔
1078
                m.storageC.columns[index.table] != nil &&
29✔
1079
                m.storageD.columns[index.table] != nil &&
29✔
1080
                m.storageE.columns[index.table] != nil &&
29✔
1081
                m.storageF.columns[index.table] != nil &&
29✔
1082
                m.storageG.columns[index.table] != nil
29✔
1083
}
1084

1085
// Add the mapped components to the given entity.
1086
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) {
12✔
1087
        if !m.world.Alive(entity) {
12✔
1088
                panic("can't add components to a dead entity")
×
1089
        }
1090
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
12✔
1091
        m.world.exchange(entity, m.ids, nil, []unsafe.Pointer{
12✔
1092
                unsafe.Pointer(a),
12✔
1093
                unsafe.Pointer(b),
12✔
1094
                unsafe.Pointer(c),
12✔
1095
                unsafe.Pointer(d),
12✔
1096
                unsafe.Pointer(e),
12✔
1097
                unsafe.Pointer(f),
12✔
1098
                unsafe.Pointer(g),
12✔
1099
        }, m.relations)
12✔
1100
}
1101

1102
// Remove the mapped components from the given entity.
1103
func (m *Map7[A, B, C, D, E, F, G]) Remove(entity Entity) {
24✔
1104
        if !m.world.Alive(entity) {
24✔
1105
                panic("can't remove components from a dead entity")
×
1106
        }
1107
        m.world.exchange(entity, nil, m.ids, nil, nil)
24✔
1108
}
1109

1110
// GetRelation returns the relation target of an entity for the component at the given index.
NEW
1111
func (m *Map7[A, B, C, D, E, F, G]) GetRelation(entity Entity, index int) Entity {
×
NEW
1112
        if !m.world.Alive(entity) {
×
NEW
1113
                panic("can't get entity relation target for a dead entity")
×
1114
        }
NEW
1115
        return m.GetRelationUnchecked(entity, index)
×
1116
}
1117

1118
// GetRelationUnchecked returns the relation target of an entity for the component at the given index.
1119
// It does not check whether the entity is alive.
1120
// Can be used as an optimization when it is certain that the entity is alive.
NEW
1121
func (m *Map7[A, B, C, D, E, F, G]) GetRelationUnchecked(entity Entity, index int) Entity {
×
NEW
1122
        return m.world.storage.getRelation(entity, m.ids[index])
×
NEW
1123
}
×
1124

1125
// SetRelations sets relation targets for the given entity.
1126
func (m *Map7[A, B, C, D, E, F, G]) SetRelations(entity Entity, rel ...RelationIndex) {
×
1127
        if !m.world.Alive(entity) {
×
NEW
1128
                panic("can't set entity relation targets for a dead entity")
×
1129
        }
1130
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
×
1131
        m.world.setRelations(entity, m.relations)
×
1132
}
1133

1134
// Map8 is a mapper to access 8 components of an entity.
1135
type Map8[A any, B any, C any, D any, E any, F any, G any, H any] struct {
1136
        world     *World
1137
        ids       []ID
1138
        storageA  *componentStorage
1139
        storageB  *componentStorage
1140
        storageC  *componentStorage
1141
        storageD  *componentStorage
1142
        storageE  *componentStorage
1143
        storageF  *componentStorage
1144
        storageG  *componentStorage
1145
        storageH  *componentStorage
1146
        relations []relationID
1147
}
1148

1149
// NewMap8 creates a new [Map8].
1150
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] {
8✔
1151
        ids := []ID{
8✔
1152
                ComponentID[A](world),
8✔
1153
                ComponentID[B](world),
8✔
1154
                ComponentID[C](world),
8✔
1155
                ComponentID[D](world),
8✔
1156
                ComponentID[E](world),
8✔
1157
                ComponentID[F](world),
8✔
1158
                ComponentID[G](world),
8✔
1159
                ComponentID[H](world),
8✔
1160
        }
8✔
1161
        return Map8[A, B, C, D, E, F, G, H]{
8✔
1162
                world:    world,
8✔
1163
                ids:      ids,
8✔
1164
                storageA: &world.storage.components[ids[0].id],
8✔
1165
                storageB: &world.storage.components[ids[1].id],
8✔
1166
                storageC: &world.storage.components[ids[2].id],
8✔
1167
                storageD: &world.storage.components[ids[3].id],
8✔
1168
                storageE: &world.storage.components[ids[4].id],
8✔
1169
                storageF: &world.storage.components[ids[5].id],
8✔
1170
                storageG: &world.storage.components[ids[6].id],
8✔
1171
                storageH: &world.storage.components[ids[7].id],
8✔
1172
        }
8✔
1173
}
8✔
1174

1175
// NewEntity creates a new entity with the mapped components.
1176
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 {
96✔
1177
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
96✔
1178
        return m.world.newEntityWith(m.ids, []unsafe.Pointer{
96✔
1179
                unsafe.Pointer(a),
96✔
1180
                unsafe.Pointer(b),
96✔
1181
                unsafe.Pointer(c),
96✔
1182
                unsafe.Pointer(d),
96✔
1183
                unsafe.Pointer(e),
96✔
1184
                unsafe.Pointer(f),
96✔
1185
                unsafe.Pointer(g),
96✔
1186
                unsafe.Pointer(h),
96✔
1187
        }, m.relations)
96✔
1188
}
96✔
1189

1190
// NewBatch creates a batch of new entities with the mapped components.
1191
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✔
1192
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
1✔
1193
        m.world.newEntitiesWith(count, m.ids, []unsafe.Pointer{
1✔
1194
                unsafe.Pointer(a),
1✔
1195
                unsafe.Pointer(b),
1✔
1196
                unsafe.Pointer(c),
1✔
1197
                unsafe.Pointer(d),
1✔
1198
                unsafe.Pointer(e),
1✔
1199
                unsafe.Pointer(f),
1✔
1200
                unsafe.Pointer(g),
1✔
1201
                unsafe.Pointer(h),
1✔
1202
        }, m.relations)
1✔
1203
}
1✔
1204

1205
// NewBatchFn creates a batch of new entities with the mapped components, running the given initializer function on each.
1206
// The initializer function can be nil.
1207
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✔
1208
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
1✔
1209
        tableID, start := m.world.newEntities(count, m.ids, m.relations)
1✔
1210
        if fn == nil {
1✔
1211
                return
×
1212
        }
×
1213

1214
        table := &m.world.storage.tables[tableID]
1✔
1215
        columnA := m.storageA.columns[tableID]
1✔
1216
        columnB := m.storageB.columns[tableID]
1✔
1217
        columnC := m.storageC.columns[tableID]
1✔
1218
        columnD := m.storageD.columns[tableID]
1✔
1219
        columnE := m.storageE.columns[tableID]
1✔
1220
        columnF := m.storageF.columns[tableID]
1✔
1221
        columnG := m.storageG.columns[tableID]
1✔
1222
        columnH := m.storageH.columns[tableID]
1✔
1223

1✔
1224
        for i := range count {
25✔
1225
                index := uintptr(start + i)
24✔
1226
                fn(
24✔
1227
                        table.GetEntity(index),
24✔
1228
                        (*A)(columnA.Get(index)),
24✔
1229
                        (*B)(columnB.Get(index)),
24✔
1230
                        (*C)(columnC.Get(index)),
24✔
1231
                        (*D)(columnD.Get(index)),
24✔
1232
                        (*E)(columnE.Get(index)),
24✔
1233
                        (*F)(columnF.Get(index)),
24✔
1234
                        (*G)(columnG.Get(index)),
24✔
1235
                        (*H)(columnH.Get(index)),
24✔
1236
                )
24✔
1237
        }
24✔
1238
}
1239

1240
// Get returns the mapped components for the given entity.
1241
func (m *Map8[A, B, C, D, E, F, G, H]) Get(entity Entity) (*A, *B, *C, *D, *E, *F, *G, *H) {
24✔
1242
        if !m.world.Alive(entity) {
24✔
1243
                panic("can't get components of a dead entity")
×
1244
        }
1245
        return m.GetUnchecked(entity)
24✔
1246
}
1247

1248
// GetUnchecked returns the mapped components for the given entity.
1249
// It does not check whether the entity is alive.
1250
// Can be used as an optimization when it is certain that the entity is alive.
1251
func (m *Map8[A, B, C, D, E, F, G, H]) GetUnchecked(entity Entity) (*A, *B, *C, *D, *E, *F, *G, *H) {
24✔
1252
        index := m.world.storage.entities[entity.id]
24✔
1253
        row := uintptr(index.row)
24✔
1254
        checkMapHasComponent(m.storageA, index.table)
24✔
1255
        checkMapHasComponent(m.storageB, index.table)
24✔
1256
        checkMapHasComponent(m.storageC, index.table)
24✔
1257
        checkMapHasComponent(m.storageD, index.table)
24✔
1258
        checkMapHasComponent(m.storageE, index.table)
24✔
1259
        checkMapHasComponent(m.storageF, index.table)
24✔
1260
        checkMapHasComponent(m.storageG, index.table)
24✔
1261
        checkMapHasComponent(m.storageH, index.table)
24✔
1262

24✔
1263
        return (*A)(m.storageA.columns[index.table].Get(row)),
24✔
1264
                (*B)(m.storageB.columns[index.table].Get(row)),
24✔
1265
                (*C)(m.storageC.columns[index.table].Get(row)),
24✔
1266
                (*D)(m.storageD.columns[index.table].Get(row)),
24✔
1267
                (*E)(m.storageE.columns[index.table].Get(row)),
24✔
1268
                (*F)(m.storageF.columns[index.table].Get(row)),
24✔
1269
                (*G)(m.storageG.columns[index.table].Get(row)),
24✔
1270
                (*H)(m.storageH.columns[index.table].Get(row))
24✔
1271
}
24✔
1272

1273
// HasAll return whether the given entity has all mapped components.
1274
func (m *Map8[A, B, C, D, E, F, G, H]) HasAll(entity Entity) bool {
29✔
1275
        if !m.world.Alive(entity) {
29✔
1276
                panic("can't check components of a dead entity")
×
1277
        }
1278
        index := m.world.storage.entities[entity.id]
29✔
1279
        return m.storageA.columns[index.table] != nil &&
29✔
1280
                m.storageB.columns[index.table] != nil &&
29✔
1281
                m.storageC.columns[index.table] != nil &&
29✔
1282
                m.storageD.columns[index.table] != nil &&
29✔
1283
                m.storageE.columns[index.table] != nil &&
29✔
1284
                m.storageF.columns[index.table] != nil &&
29✔
1285
                m.storageG.columns[index.table] != nil &&
29✔
1286
                m.storageH.columns[index.table] != nil
29✔
1287
}
1288

1289
// Add the mapped components to the given entity.
1290
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) {
12✔
1291
        if !m.world.Alive(entity) {
12✔
1292
                panic("can't add components to a dead entity")
×
1293
        }
1294
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
12✔
1295
        m.world.exchange(entity, m.ids, nil, []unsafe.Pointer{
12✔
1296
                unsafe.Pointer(a),
12✔
1297
                unsafe.Pointer(b),
12✔
1298
                unsafe.Pointer(c),
12✔
1299
                unsafe.Pointer(d),
12✔
1300
                unsafe.Pointer(e),
12✔
1301
                unsafe.Pointer(f),
12✔
1302
                unsafe.Pointer(g),
12✔
1303
                unsafe.Pointer(h),
12✔
1304
        }, m.relations)
12✔
1305
}
1306

1307
// Remove the mapped components from the given entity.
1308
func (m *Map8[A, B, C, D, E, F, G, H]) Remove(entity Entity) {
24✔
1309
        if !m.world.Alive(entity) {
24✔
1310
                panic("can't remove components from a dead entity")
×
1311
        }
1312
        m.world.exchange(entity, nil, m.ids, nil, nil)
24✔
1313
}
1314

1315
// GetRelation returns the relation target of an entity for the component at the given index.
NEW
1316
func (m *Map8[A, B, C, D, E, F, G, H]) GetRelation(entity Entity, index int) Entity {
×
NEW
1317
        if !m.world.Alive(entity) {
×
NEW
1318
                panic("can't get entity relation target for a dead entity")
×
1319
        }
NEW
1320
        return m.GetRelationUnchecked(entity, index)
×
1321
}
1322

1323
// GetRelationUnchecked returns the relation target of an entity for the component at the given index.
1324
// It does not check whether the entity is alive.
1325
// Can be used as an optimization when it is certain that the entity is alive.
NEW
1326
func (m *Map8[A, B, C, D, E, F, G, H]) GetRelationUnchecked(entity Entity, index int) Entity {
×
NEW
1327
        return m.world.storage.getRelation(entity, m.ids[index])
×
NEW
1328
}
×
1329

1330
// SetRelations sets relation targets for the given entity.
1331
func (m *Map8[A, B, C, D, E, F, G, H]) SetRelations(entity Entity, rel ...RelationIndex) {
×
1332
        if !m.world.Alive(entity) {
×
NEW
1333
                panic("can't set entity relation targets for a dead entity")
×
1334
        }
1335
        m.relations = relations(rel).toRelations(&m.world.storage.registry, m.ids, m.relations)
×
1336
        m.world.setRelations(entity, m.relations)
×
1337
}
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