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

mlange-42 / ark / 13593560099

28 Feb 2025 05:45PM CUT coverage: 96.274% (+1.5%) from 94.795%
13593560099

Pull #79

github

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

118 of 118 new or added lines in 6 files covered. (100.0%)

22 existing lines in 1 file now uncovered.

3540 of 3677 relevant lines covered (96.27%)

49731.23 hits per line

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

95.68
/ecs/query_gen.go
1
package ecs
2

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

5
type cursor struct {
6
        archetype int
7
        table     int
8
        index     uintptr
9
        maxIndex  int64
10
}
11

12
// Query0 is a query for 0 components.
13
// Use a [NewFilter0] to create one.
14
type Query0 struct {
15
        world      *World
16
        mask       Mask
17
        without    Mask
18
        relations  []relationID
19
        lock       uint8
20
        cursor     cursor
21
        tables     []tableID
22
        table      *table
23
        components []*componentStorage
24
        hasWithout bool
25
}
26

27
func newQuery0(world *World, mask Mask, without Mask, relations []relationID) Query0 {
8✔
28
        components := make([]*componentStorage, 0)
8✔
29

8✔
30
        return Query0{
8✔
31
                world:      world,
8✔
32
                mask:       mask,
8✔
33
                without:    without,
8✔
34
                relations:  relations,
8✔
35
                hasWithout: !without.IsZero(),
8✔
36
                lock:       world.lock(),
8✔
37
                components: components,
8✔
38
                cursor: cursor{
8✔
39
                        archetype: -1,
8✔
40
                        table:     -1,
8✔
41
                        index:     0,
8✔
42
                        maxIndex:  -1,
8✔
43
                },
8✔
44
        }
8✔
45
}
8✔
46

47
// Next advances the query's cursor to the next entity.
48
func (q *Query0) Next() bool {
192✔
49
        checkQueryNext(&q.cursor)
192✔
50
        if int64(q.cursor.index) < q.cursor.maxIndex {
365✔
51
                q.cursor.index++
173✔
52
                return true
173✔
53
        }
173✔
54
        return q.nextTableOrArchetype()
19✔
55
}
56

57
// Entity returns the current entity.
58
func (q *Query0) Entity() Entity {
185✔
59
        checkQueryGet(&q.cursor)
185✔
60
        return q.table.GetEntity(q.cursor.index)
185✔
61
}
185✔
62

63
// Close closes the Query and unlocks the world.
64
//
65
// Automatically called when iteration finishes.
66
// Needs to be called only if breaking out of the query iteration or not iterating at all.
67
func (q *Query0) Close() {
8✔
68
        q.cursor.archetype = -2
8✔
69
        q.cursor.table = -2
8✔
70
        q.tables = nil
8✔
71
        q.table = nil
8✔
72
        q.world.unlock(q.lock)
8✔
73
}
8✔
74

75
func (q *Query0) nextTableOrArchetype() bool {
19✔
76
        if q.cursor.archetype >= 0 && q.nextTable() {
21✔
77
                return true
2✔
78
        }
2✔
79
        return q.nextArchetype()
17✔
80
}
81

82
func (q *Query0) nextArchetype() bool {
17✔
83
        maxArchIndex := len(q.world.storage.archetypes) - 1
17✔
84
        for q.cursor.archetype < maxArchIndex {
34✔
85
                q.cursor.archetype++
17✔
86
                archetype := &q.world.storage.archetypes[q.cursor.archetype]
17✔
87
                if !archetype.mask.Contains(&q.mask) ||
17✔
88
                        archetype.mask.ContainsAny(&q.without) {
21✔
89
                        continue
4✔
90
                }
91

92
                if !archetype.HasRelations() {
23✔
93
                        table := &q.world.storage.tables[archetype.tables[0]]
11✔
94
                        if table.Len() > 0 {
18✔
95
                                q.setTable(0, table)
7✔
96
                                return true
7✔
97
                        }
7✔
98
                        continue
4✔
99
                }
100

101
                q.tables = archetype.GetTables(q.relations)
1✔
102
                q.cursor.table = -1
1✔
103
                if q.nextTable() {
2✔
104
                        return true
1✔
105
                }
1✔
106
        }
107
        q.Close()
8✔
108
        return false
8✔
109
}
110

111
func (q *Query0) nextTable() bool {
11✔
112
        maxTableIndex := len(q.tables) - 1
11✔
113
        for q.cursor.table < maxTableIndex {
14✔
114
                q.cursor.table++
3✔
115
                table := &q.world.storage.tables[q.tables[q.cursor.table]]
3✔
116
                if table.Len() == 0 {
3✔
117
                        continue
×
118
                }
119
                if !table.Matches(q.relations) {
3✔
120
                        continue
×
121
                }
122
                q.setTable(q.cursor.table, table)
3✔
123
                return true
3✔
124
        }
125
        return false
8✔
126
}
127

128
func (q *Query0) setTable(index int, table *table) {
10✔
129
        q.cursor.table = index
10✔
130
        q.table = table
10✔
131
        q.cursor.index = 0
10✔
132
        q.cursor.maxIndex = int64(q.table.entities.Len() - 1)
10✔
133
}
10✔
134

135
// Query1 is a query for 1 components.
136
// Use a [NewFilter1] to create one.
137
type Query1[A any] struct {
138
        world      *World
139
        mask       Mask
140
        without    Mask
141
        relations  []relationID
142
        lock       uint8
143
        cursor     cursor
144
        tables     []tableID
145
        table      *table
146
        components []*componentStorage
147
        columnA    *column
148
        hasWithout bool
149
}
150

151
func newQuery1[A any](world *World, mask Mask, without Mask, ids []ID, relations []relationID) Query1[A] {
1,008✔
152
        components := make([]*componentStorage, 1)
1,008✔
153
        for i := range 1 {
2,016✔
154
                components[i] = &world.storage.components[ids[i].id]
1,008✔
155
        }
1,008✔
156

157
        return Query1[A]{
1,008✔
158
                world:      world,
1,008✔
159
                mask:       mask,
1,008✔
160
                without:    without,
1,008✔
161
                relations:  relations,
1,008✔
162
                hasWithout: !without.IsZero(),
1,008✔
163
                lock:       world.lock(),
1,008✔
164
                components: components,
1,008✔
165
                cursor: cursor{
1,008✔
166
                        archetype: -1,
1,008✔
167
                        table:     -1,
1,008✔
168
                        index:     0,
1,008✔
169
                        maxIndex:  -1,
1,008✔
170
                },
1,008✔
171
        }
1,008✔
172
}
173

174
// Next advances the query's cursor to the next entity.
175
func (q *Query1[A]) Next() bool {
989,925✔
176
        checkQueryNext(&q.cursor)
989,925✔
177
        if int64(q.cursor.index) < q.cursor.maxIndex {
1,977,833✔
178
                q.cursor.index++
987,908✔
179
                return true
987,908✔
180
        }
987,908✔
181
        return q.nextTableOrArchetype()
2,017✔
182
}
183

184
// Entity returns the current entity.
185
func (q *Query1[A]) Entity() Entity {
1,977,702✔
186
        checkQueryGet(&q.cursor)
1,977,702✔
187
        return q.table.GetEntity(q.cursor.index)
1,977,702✔
188
}
1,977,702✔
189

190
// Get returns the queried components of the current entity.
191
func (q *Query1[A]) Get() *A {
988,908✔
192
        checkQueryGet(&q.cursor)
988,908✔
193
        return (*A)(q.columnA.Get(q.cursor.index))
988,908✔
194
}
988,908✔
195

196
// GetRelation returns the entity relation target of the component at the given index.
197
func (q *Query1[A]) GetRelation(index int) Entity {
10✔
198
        return q.components[index].columns[q.table.id].target
10✔
199
}
10✔
200

201
// Close closes the Query and unlocks the world.
202
//
203
// Automatically called when iteration finishes.
204
// Needs to be called only if breaking out of the query iteration or not iterating at all.
205
func (q *Query1[A]) Close() {
1,008✔
206
        q.cursor.archetype = -2
1,008✔
207
        q.cursor.table = -2
1,008✔
208
        q.tables = nil
1,008✔
209
        q.table = nil
1,008✔
210
        q.columnA = nil
1,008✔
211
        q.world.unlock(q.lock)
1,008✔
212
}
1,008✔
213

214
func (q *Query1[A]) nextTableOrArchetype() bool {
2,017✔
215
        if q.cursor.archetype >= 0 && q.nextTable() {
2,017✔
UNCOV
216
                return true
×
UNCOV
217
        }
×
218
        return q.nextArchetype()
2,017✔
219
}
220

221
func (q *Query1[A]) nextArchetype() bool {
2,017✔
222
        maxArchIndex := len(q.world.storage.archetypes) - 1
2,017✔
223
        for q.cursor.archetype < maxArchIndex {
4,038✔
224
                q.cursor.archetype++
2,021✔
225
                archetype := &q.world.storage.archetypes[q.cursor.archetype]
2,021✔
226
                if !archetype.mask.Contains(&q.mask) ||
2,021✔
227
                        archetype.mask.ContainsAny(&q.without) {
3,033✔
228
                        continue
1,012✔
229
                }
230

231
                if !archetype.HasRelations() {
2,015✔
232
                        table := &q.world.storage.tables[archetype.tables[0]]
1,007✔
233
                        if table.Len() > 0 {
2,014✔
234
                                q.setTable(0, table)
1,007✔
235
                                return true
1,007✔
236
                        }
1,007✔
UNCOV
237
                        continue
×
238
                }
239

240
                q.tables = archetype.GetTables(q.relations)
1✔
241
                q.cursor.table = -1
1✔
242
                if q.nextTable() {
2✔
243
                        return true
1✔
244
                }
1✔
245
        }
246
        q.Close()
1,008✔
247
        return false
1,008✔
248
}
249

250
func (q *Query1[A]) nextTable() bool {
1,009✔
251
        maxTableIndex := len(q.tables) - 1
1,009✔
252
        for q.cursor.table < maxTableIndex {
1,010✔
253
                q.cursor.table++
1✔
254
                table := &q.world.storage.tables[q.tables[q.cursor.table]]
1✔
255
                if table.Len() == 0 {
1✔
256
                        continue
×
257
                }
258
                if !table.Matches(q.relations) {
1✔
259
                        continue
×
260
                }
261
                q.setTable(q.cursor.table, table)
1✔
262
                return true
1✔
263
        }
264
        return false
1,008✔
265
}
266

267
func (q *Query1[A]) setTable(index int, table *table) {
1,008✔
268
        q.cursor.table = index
1,008✔
269
        q.table = table
1,008✔
270
        q.columnA = q.components[0].columns[q.table.id]
1,008✔
271
        q.cursor.index = 0
1,008✔
272
        q.cursor.maxIndex = int64(q.table.entities.Len() - 1)
1,008✔
273
}
1,008✔
274

275
// Query2 is a query for 2 components.
276
// Use a [NewFilter2] to create one.
277
type Query2[A any, B any] struct {
278
        world      *World
279
        mask       Mask
280
        without    Mask
281
        relations  []relationID
282
        lock       uint8
283
        cursor     cursor
284
        tables     []tableID
285
        table      *table
286
        components []*componentStorage
287
        columnA    *column
288
        columnB    *column
289
        hasWithout bool
290
}
291

292
func newQuery2[A any, B any](world *World, mask Mask, without Mask, ids []ID, relations []relationID) Query2[A, B] {
9✔
293
        components := make([]*componentStorage, 2)
9✔
294
        for i := range 2 {
27✔
295
                components[i] = &world.storage.components[ids[i].id]
18✔
296
        }
18✔
297

298
        return Query2[A, B]{
9✔
299
                world:      world,
9✔
300
                mask:       mask,
9✔
301
                without:    without,
9✔
302
                relations:  relations,
9✔
303
                hasWithout: !without.IsZero(),
9✔
304
                lock:       world.lock(),
9✔
305
                components: components,
9✔
306
                cursor: cursor{
9✔
307
                        archetype: -1,
9✔
308
                        table:     -1,
9✔
309
                        index:     0,
9✔
310
                        maxIndex:  -1,
9✔
311
                },
9✔
312
        }
9✔
313
}
314

315
// Next advances the query's cursor to the next entity.
316
func (q *Query2[A, B]) Next() bool {
174✔
317
        checkQueryNext(&q.cursor)
174✔
318
        if int64(q.cursor.index) < q.cursor.maxIndex {
329✔
319
                q.cursor.index++
155✔
320
                return true
155✔
321
        }
155✔
322
        return q.nextTableOrArchetype()
19✔
323
}
324

325
// Entity returns the current entity.
326
func (q *Query2[A, B]) Entity() Entity {
134✔
327
        checkQueryGet(&q.cursor)
134✔
328
        return q.table.GetEntity(q.cursor.index)
134✔
329
}
134✔
330

331
// Get returns the queried components of the current entity.
332
func (q *Query2[A, B]) Get() (*A, *B) {
156✔
333
        checkQueryGet(&q.cursor)
156✔
334
        return (*A)(q.columnA.Get(q.cursor.index)),
156✔
335
                (*B)(q.columnB.Get(q.cursor.index))
156✔
336
}
156✔
337

338
// GetRelation returns the entity relation target of the component at the given index.
339
func (q *Query2[A, B]) GetRelation(index int) Entity {
10✔
340
        return q.components[index].columns[q.table.id].target
10✔
341
}
10✔
342

343
// Close closes the Query and unlocks the world.
344
//
345
// Automatically called when iteration finishes.
346
// Needs to be called only if breaking out of the query iteration or not iterating at all.
347
func (q *Query2[A, B]) Close() {
9✔
348
        q.cursor.archetype = -2
9✔
349
        q.cursor.table = -2
9✔
350
        q.tables = nil
9✔
351
        q.table = nil
9✔
352
        q.columnA = nil
9✔
353
        q.columnB = nil
9✔
354
        q.world.unlock(q.lock)
9✔
355
}
9✔
356

357
func (q *Query2[A, B]) nextTableOrArchetype() bool {
19✔
358
        if q.cursor.archetype >= 0 && q.nextTable() {
19✔
UNCOV
359
                return true
×
UNCOV
360
        }
×
361
        return q.nextArchetype()
19✔
362
}
363

364
func (q *Query2[A, B]) nextArchetype() bool {
19✔
365
        maxArchIndex := len(q.world.storage.archetypes) - 1
19✔
366
        for q.cursor.archetype < maxArchIndex {
46✔
367
                q.cursor.archetype++
27✔
368
                archetype := &q.world.storage.archetypes[q.cursor.archetype]
27✔
369
                if !archetype.mask.Contains(&q.mask) ||
27✔
370
                        archetype.mask.ContainsAny(&q.without) {
44✔
371
                        continue
17✔
372
                }
373

374
                if !archetype.HasRelations() {
16✔
375
                        table := &q.world.storage.tables[archetype.tables[0]]
7✔
376
                        if table.Len() > 0 {
14✔
377
                                q.setTable(0, table)
7✔
378
                                return true
7✔
379
                        }
7✔
UNCOV
380
                        continue
×
381
                }
382

383
                q.tables = archetype.GetTables(q.relations)
2✔
384
                q.cursor.table = -1
2✔
385
                if q.nextTable() {
4✔
386
                        return true
2✔
387
                }
2✔
388
        }
389
        q.Close()
9✔
390
        return false
9✔
391
}
392

393
func (q *Query2[A, B]) nextTable() bool {
11✔
394
        maxTableIndex := len(q.tables) - 1
11✔
395
        for q.cursor.table < maxTableIndex {
13✔
396
                q.cursor.table++
2✔
397
                table := &q.world.storage.tables[q.tables[q.cursor.table]]
2✔
398
                if table.Len() == 0 {
2✔
399
                        continue
×
400
                }
401
                if !table.Matches(q.relations) {
2✔
402
                        continue
×
403
                }
404
                q.setTable(q.cursor.table, table)
2✔
405
                return true
2✔
406
        }
407
        return false
9✔
408
}
409

410
func (q *Query2[A, B]) setTable(index int, table *table) {
9✔
411
        q.cursor.table = index
9✔
412
        q.table = table
9✔
413
        q.columnA = q.components[0].columns[q.table.id]
9✔
414
        q.columnB = q.components[1].columns[q.table.id]
9✔
415
        q.cursor.index = 0
9✔
416
        q.cursor.maxIndex = int64(q.table.entities.Len() - 1)
9✔
417
}
9✔
418

419
// Query3 is a query for 3 components.
420
// Use a [NewFilter3] to create one.
421
type Query3[A any, B any, C any] struct {
422
        world      *World
423
        mask       Mask
424
        without    Mask
425
        relations  []relationID
426
        lock       uint8
427
        cursor     cursor
428
        tables     []tableID
429
        table      *table
430
        components []*componentStorage
431
        columnA    *column
432
        columnB    *column
433
        columnC    *column
434
        hasWithout bool
435
}
436

437
func newQuery3[A any, B any, C any](world *World, mask Mask, without Mask, ids []ID, relations []relationID) Query3[A, B, C] {
11✔
438
        components := make([]*componentStorage, 3)
11✔
439
        for i := range 3 {
44✔
440
                components[i] = &world.storage.components[ids[i].id]
33✔
441
        }
33✔
442

443
        return Query3[A, B, C]{
11✔
444
                world:      world,
11✔
445
                mask:       mask,
11✔
446
                without:    without,
11✔
447
                relations:  relations,
11✔
448
                hasWithout: !without.IsZero(),
11✔
449
                lock:       world.lock(),
11✔
450
                components: components,
11✔
451
                cursor: cursor{
11✔
452
                        archetype: -1,
11✔
453
                        table:     -1,
11✔
454
                        index:     0,
11✔
455
                        maxIndex:  -1,
11✔
456
                },
11✔
457
        }
11✔
458
}
459

460
// Next advances the query's cursor to the next entity.
461
func (q *Query3[A, B, C]) Next() bool {
214✔
462
        checkQueryNext(&q.cursor)
214✔
463
        if int64(q.cursor.index) < q.cursor.maxIndex {
401✔
464
                q.cursor.index++
187✔
465
                return true
187✔
466
        }
187✔
467
        return q.nextTableOrArchetype()
27✔
468
}
469

470
// Entity returns the current entity.
471
func (q *Query3[A, B, C]) Entity() Entity {
134✔
472
        checkQueryGet(&q.cursor)
134✔
473
        return q.table.GetEntity(q.cursor.index)
134✔
474
}
134✔
475

476
// Get returns the queried components of the current entity.
477
func (q *Query3[A, B, C]) Get() (*A, *B, *C) {
124✔
478
        checkQueryGet(&q.cursor)
124✔
479
        return (*A)(q.columnA.Get(q.cursor.index)),
124✔
480
                (*B)(q.columnB.Get(q.cursor.index)),
124✔
481
                (*C)(q.columnC.Get(q.cursor.index))
124✔
482
}
124✔
483

484
// GetRelation returns the entity relation target of the component at the given index.
485
func (q *Query3[A, B, C]) GetRelation(index int) Entity {
10✔
486
        return q.components[index].columns[q.table.id].target
10✔
487
}
10✔
488

489
// Close closes the Query and unlocks the world.
490
//
491
// Automatically called when iteration finishes.
492
// Needs to be called only if breaking out of the query iteration or not iterating at all.
493
func (q *Query3[A, B, C]) Close() {
11✔
494
        q.cursor.archetype = -2
11✔
495
        q.cursor.table = -2
11✔
496
        q.tables = nil
11✔
497
        q.table = nil
11✔
498
        q.columnA = nil
11✔
499
        q.columnB = nil
11✔
500
        q.columnC = nil
11✔
501
        q.world.unlock(q.lock)
11✔
502
}
11✔
503

504
func (q *Query3[A, B, C]) nextTableOrArchetype() bool {
27✔
505
        if q.cursor.archetype >= 0 && q.nextTable() {
31✔
506
                return true
4✔
507
        }
4✔
508
        return q.nextArchetype()
23✔
509
}
510

511
func (q *Query3[A, B, C]) nextArchetype() bool {
23✔
512
        maxArchIndex := len(q.world.storage.archetypes) - 1
23✔
513
        for q.cursor.archetype < maxArchIndex {
54✔
514
                q.cursor.archetype++
31✔
515
                archetype := &q.world.storage.archetypes[q.cursor.archetype]
31✔
516
                if !archetype.mask.Contains(&q.mask) ||
31✔
517
                        archetype.mask.ContainsAny(&q.without) {
50✔
518
                        continue
19✔
519
                }
520

521
                if !archetype.HasRelations() {
18✔
522
                        table := &q.world.storage.tables[archetype.tables[0]]
7✔
523
                        if table.Len() > 0 {
14✔
524
                                q.setTable(0, table)
7✔
525
                                return true
7✔
526
                        }
7✔
UNCOV
527
                        continue
×
528
                }
529

530
                q.tables = archetype.GetTables(q.relations)
4✔
531
                q.cursor.table = -1
4✔
532
                if q.nextTable() {
8✔
533
                        return true
4✔
534
                }
4✔
535
        }
536
        q.Close()
11✔
537
        return false
11✔
538
}
539

540
func (q *Query3[A, B, C]) nextTable() bool {
19✔
541
        maxTableIndex := len(q.tables) - 1
19✔
542
        for q.cursor.table < maxTableIndex {
28✔
543
                q.cursor.table++
9✔
544
                table := &q.world.storage.tables[q.tables[q.cursor.table]]
9✔
545
                if table.Len() == 0 {
9✔
546
                        continue
×
547
                }
548
                if !table.Matches(q.relations) {
10✔
549
                        continue
1✔
550
                }
551
                q.setTable(q.cursor.table, table)
8✔
552
                return true
8✔
553
        }
554
        return false
11✔
555
}
556

557
func (q *Query3[A, B, C]) setTable(index int, table *table) {
15✔
558
        q.cursor.table = index
15✔
559
        q.table = table
15✔
560
        q.columnA = q.components[0].columns[q.table.id]
15✔
561
        q.columnB = q.components[1].columns[q.table.id]
15✔
562
        q.columnC = q.components[2].columns[q.table.id]
15✔
563
        q.cursor.index = 0
15✔
564
        q.cursor.maxIndex = int64(q.table.entities.Len() - 1)
15✔
565
}
15✔
566

567
// Query4 is a query for 4 components.
568
// Use a [NewFilter4] to create one.
569
type Query4[A any, B any, C any, D any] struct {
570
        world      *World
571
        mask       Mask
572
        without    Mask
573
        relations  []relationID
574
        lock       uint8
575
        cursor     cursor
576
        tables     []tableID
577
        table      *table
578
        components []*componentStorage
579
        columnA    *column
580
        columnB    *column
581
        columnC    *column
582
        columnD    *column
583
        hasWithout bool
584
}
585

586
func newQuery4[A any, B any, C any, D any](world *World, mask Mask, without Mask, ids []ID, relations []relationID) Query4[A, B, C, D] {
8✔
587
        components := make([]*componentStorage, 4)
8✔
588
        for i := range 4 {
40✔
589
                components[i] = &world.storage.components[ids[i].id]
32✔
590
        }
32✔
591

592
        return Query4[A, B, C, D]{
8✔
593
                world:      world,
8✔
594
                mask:       mask,
8✔
595
                without:    without,
8✔
596
                relations:  relations,
8✔
597
                hasWithout: !without.IsZero(),
8✔
598
                lock:       world.lock(),
8✔
599
                components: components,
8✔
600
                cursor: cursor{
8✔
601
                        archetype: -1,
8✔
602
                        table:     -1,
8✔
603
                        index:     0,
8✔
604
                        maxIndex:  -1,
8✔
605
                },
8✔
606
        }
8✔
607
}
608

609
// Next advances the query's cursor to the next entity.
610
func (q *Query4[A, B, C, D]) Next() bool {
141✔
611
        checkQueryNext(&q.cursor)
141✔
612
        if int64(q.cursor.index) < q.cursor.maxIndex {
265✔
613
                q.cursor.index++
124✔
614
                return true
124✔
615
        }
124✔
616
        return q.nextTableOrArchetype()
17✔
617
}
618

619
// Entity returns the current entity.
620
func (q *Query4[A, B, C, D]) Entity() Entity {
134✔
621
        checkQueryGet(&q.cursor)
134✔
622
        return q.table.GetEntity(q.cursor.index)
134✔
623
}
134✔
624

625
// Get returns the queried components of the current entity.
626
func (q *Query4[A, B, C, D]) Get() (*A, *B, *C, *D) {
124✔
627
        checkQueryGet(&q.cursor)
124✔
628
        return (*A)(q.columnA.Get(q.cursor.index)),
124✔
629
                (*B)(q.columnB.Get(q.cursor.index)),
124✔
630
                (*C)(q.columnC.Get(q.cursor.index)),
124✔
631
                (*D)(q.columnD.Get(q.cursor.index))
124✔
632
}
124✔
633

634
// GetRelation returns the entity relation target of the component at the given index.
635
func (q *Query4[A, B, C, D]) GetRelation(index int) Entity {
10✔
636
        return q.components[index].columns[q.table.id].target
10✔
637
}
10✔
638

639
// Close closes the Query and unlocks the world.
640
//
641
// Automatically called when iteration finishes.
642
// Needs to be called only if breaking out of the query iteration or not iterating at all.
643
func (q *Query4[A, B, C, D]) Close() {
8✔
644
        q.cursor.archetype = -2
8✔
645
        q.cursor.table = -2
8✔
646
        q.tables = nil
8✔
647
        q.table = nil
8✔
648
        q.columnA = nil
8✔
649
        q.columnB = nil
8✔
650
        q.columnC = nil
8✔
651
        q.columnD = nil
8✔
652
        q.world.unlock(q.lock)
8✔
653
}
8✔
654

655
func (q *Query4[A, B, C, D]) nextTableOrArchetype() bool {
17✔
656
        if q.cursor.archetype >= 0 && q.nextTable() {
17✔
UNCOV
657
                return true
×
UNCOV
658
        }
×
659
        return q.nextArchetype()
17✔
660
}
661

662
func (q *Query4[A, B, C, D]) nextArchetype() bool {
17✔
663
        maxArchIndex := len(q.world.storage.archetypes) - 1
17✔
664
        for q.cursor.archetype < maxArchIndex {
42✔
665
                q.cursor.archetype++
25✔
666
                archetype := &q.world.storage.archetypes[q.cursor.archetype]
25✔
667
                if !archetype.mask.Contains(&q.mask) ||
25✔
668
                        archetype.mask.ContainsAny(&q.without) {
41✔
669
                        continue
16✔
670
                }
671

672
                if !archetype.HasRelations() {
15✔
673
                        table := &q.world.storage.tables[archetype.tables[0]]
7✔
674
                        if table.Len() > 0 {
14✔
675
                                q.setTable(0, table)
7✔
676
                                return true
7✔
677
                        }
7✔
UNCOV
678
                        continue
×
679
                }
680

681
                q.tables = archetype.GetTables(q.relations)
1✔
682
                q.cursor.table = -1
1✔
683
                if q.nextTable() {
2✔
684
                        return true
1✔
685
                }
1✔
686
        }
687
        q.Close()
8✔
688
        return false
8✔
689
}
690

691
func (q *Query4[A, B, C, D]) nextTable() bool {
9✔
692
        maxTableIndex := len(q.tables) - 1
9✔
693
        for q.cursor.table < maxTableIndex {
10✔
694
                q.cursor.table++
1✔
695
                table := &q.world.storage.tables[q.tables[q.cursor.table]]
1✔
696
                if table.Len() == 0 {
1✔
697
                        continue
×
698
                }
699
                if !table.Matches(q.relations) {
1✔
700
                        continue
×
701
                }
702
                q.setTable(q.cursor.table, table)
1✔
703
                return true
1✔
704
        }
705
        return false
8✔
706
}
707

708
func (q *Query4[A, B, C, D]) setTable(index int, table *table) {
8✔
709
        q.cursor.table = index
8✔
710
        q.table = table
8✔
711
        q.columnA = q.components[0].columns[q.table.id]
8✔
712
        q.columnB = q.components[1].columns[q.table.id]
8✔
713
        q.columnC = q.components[2].columns[q.table.id]
8✔
714
        q.columnD = q.components[3].columns[q.table.id]
8✔
715
        q.cursor.index = 0
8✔
716
        q.cursor.maxIndex = int64(q.table.entities.Len() - 1)
8✔
717
}
8✔
718

719
// Query5 is a query for 5 components.
720
// Use a [NewFilter5] to create one.
721
type Query5[A any, B any, C any, D any, E any] struct {
722
        world      *World
723
        mask       Mask
724
        without    Mask
725
        relations  []relationID
726
        lock       uint8
727
        cursor     cursor
728
        tables     []tableID
729
        table      *table
730
        components []*componentStorage
731
        columnA    *column
732
        columnB    *column
733
        columnC    *column
734
        columnD    *column
735
        columnE    *column
736
        hasWithout bool
737
}
738

739
func newQuery5[A any, B any, C any, D any, E any](world *World, mask Mask, without Mask, ids []ID, relations []relationID) Query5[A, B, C, D, E] {
8✔
740
        components := make([]*componentStorage, 5)
8✔
741
        for i := range 5 {
48✔
742
                components[i] = &world.storage.components[ids[i].id]
40✔
743
        }
40✔
744

745
        return Query5[A, B, C, D, E]{
8✔
746
                world:      world,
8✔
747
                mask:       mask,
8✔
748
                without:    without,
8✔
749
                relations:  relations,
8✔
750
                hasWithout: !without.IsZero(),
8✔
751
                lock:       world.lock(),
8✔
752
                components: components,
8✔
753
                cursor: cursor{
8✔
754
                        archetype: -1,
8✔
755
                        table:     -1,
8✔
756
                        index:     0,
8✔
757
                        maxIndex:  -1,
8✔
758
                },
8✔
759
        }
8✔
760
}
761

762
// Next advances the query's cursor to the next entity.
763
func (q *Query5[A, B, C, D, E]) Next() bool {
141✔
764
        checkQueryNext(&q.cursor)
141✔
765
        if int64(q.cursor.index) < q.cursor.maxIndex {
265✔
766
                q.cursor.index++
124✔
767
                return true
124✔
768
        }
124✔
769
        return q.nextTableOrArchetype()
17✔
770
}
771

772
// Entity returns the current entity.
773
func (q *Query5[A, B, C, D, E]) Entity() Entity {
134✔
774
        checkQueryGet(&q.cursor)
134✔
775
        return q.table.GetEntity(q.cursor.index)
134✔
776
}
134✔
777

778
// Get returns the queried components of the current entity.
779
func (q *Query5[A, B, C, D, E]) Get() (*A, *B, *C, *D, *E) {
124✔
780
        checkQueryGet(&q.cursor)
124✔
781
        return (*A)(q.columnA.Get(q.cursor.index)),
124✔
782
                (*B)(q.columnB.Get(q.cursor.index)),
124✔
783
                (*C)(q.columnC.Get(q.cursor.index)),
124✔
784
                (*D)(q.columnD.Get(q.cursor.index)),
124✔
785
                (*E)(q.columnE.Get(q.cursor.index))
124✔
786
}
124✔
787

788
// GetRelation returns the entity relation target of the component at the given index.
789
func (q *Query5[A, B, C, D, E]) GetRelation(index int) Entity {
10✔
790
        return q.components[index].columns[q.table.id].target
10✔
791
}
10✔
792

793
// Close closes the Query and unlocks the world.
794
//
795
// Automatically called when iteration finishes.
796
// Needs to be called only if breaking out of the query iteration or not iterating at all.
797
func (q *Query5[A, B, C, D, E]) Close() {
8✔
798
        q.cursor.archetype = -2
8✔
799
        q.cursor.table = -2
8✔
800
        q.tables = nil
8✔
801
        q.table = nil
8✔
802
        q.columnA = nil
8✔
803
        q.columnB = nil
8✔
804
        q.columnC = nil
8✔
805
        q.columnD = nil
8✔
806
        q.columnE = nil
8✔
807
        q.world.unlock(q.lock)
8✔
808
}
8✔
809

810
func (q *Query5[A, B, C, D, E]) nextTableOrArchetype() bool {
17✔
811
        if q.cursor.archetype >= 0 && q.nextTable() {
17✔
UNCOV
812
                return true
×
UNCOV
813
        }
×
814
        return q.nextArchetype()
17✔
815
}
816

817
func (q *Query5[A, B, C, D, E]) nextArchetype() bool {
17✔
818
        maxArchIndex := len(q.world.storage.archetypes) - 1
17✔
819
        for q.cursor.archetype < maxArchIndex {
42✔
820
                q.cursor.archetype++
25✔
821
                archetype := &q.world.storage.archetypes[q.cursor.archetype]
25✔
822
                if !archetype.mask.Contains(&q.mask) ||
25✔
823
                        archetype.mask.ContainsAny(&q.without) {
41✔
824
                        continue
16✔
825
                }
826

827
                if !archetype.HasRelations() {
15✔
828
                        table := &q.world.storage.tables[archetype.tables[0]]
7✔
829
                        if table.Len() > 0 {
14✔
830
                                q.setTable(0, table)
7✔
831
                                return true
7✔
832
                        }
7✔
UNCOV
833
                        continue
×
834
                }
835

836
                q.tables = archetype.GetTables(q.relations)
1✔
837
                q.cursor.table = -1
1✔
838
                if q.nextTable() {
2✔
839
                        return true
1✔
840
                }
1✔
841
        }
842
        q.Close()
8✔
843
        return false
8✔
844
}
845

846
func (q *Query5[A, B, C, D, E]) nextTable() bool {
9✔
847
        maxTableIndex := len(q.tables) - 1
9✔
848
        for q.cursor.table < maxTableIndex {
10✔
849
                q.cursor.table++
1✔
850
                table := &q.world.storage.tables[q.tables[q.cursor.table]]
1✔
851
                if table.Len() == 0 {
1✔
852
                        continue
×
853
                }
854
                if !table.Matches(q.relations) {
1✔
855
                        continue
×
856
                }
857
                q.setTable(q.cursor.table, table)
1✔
858
                return true
1✔
859
        }
860
        return false
8✔
861
}
862

863
func (q *Query5[A, B, C, D, E]) setTable(index int, table *table) {
8✔
864
        q.cursor.table = index
8✔
865
        q.table = table
8✔
866
        q.columnA = q.components[0].columns[q.table.id]
8✔
867
        q.columnB = q.components[1].columns[q.table.id]
8✔
868
        q.columnC = q.components[2].columns[q.table.id]
8✔
869
        q.columnD = q.components[3].columns[q.table.id]
8✔
870
        q.columnE = q.components[4].columns[q.table.id]
8✔
871
        q.cursor.index = 0
8✔
872
        q.cursor.maxIndex = int64(q.table.entities.Len() - 1)
8✔
873
}
8✔
874

875
// Query6 is a query for 6 components.
876
// Use a [NewFilter6] to create one.
877
type Query6[A any, B any, C any, D any, E any, F any] struct {
878
        world      *World
879
        mask       Mask
880
        without    Mask
881
        relations  []relationID
882
        lock       uint8
883
        cursor     cursor
884
        tables     []tableID
885
        table      *table
886
        components []*componentStorage
887
        columnA    *column
888
        columnB    *column
889
        columnC    *column
890
        columnD    *column
891
        columnE    *column
892
        columnF    *column
893
        hasWithout bool
894
}
895

896
func newQuery6[A any, B any, C any, D any, E any, F any](world *World, mask Mask, without Mask, ids []ID, relations []relationID) Query6[A, B, C, D, E, F] {
8✔
897
        components := make([]*componentStorage, 6)
8✔
898
        for i := range 6 {
56✔
899
                components[i] = &world.storage.components[ids[i].id]
48✔
900
        }
48✔
901

902
        return Query6[A, B, C, D, E, F]{
8✔
903
                world:      world,
8✔
904
                mask:       mask,
8✔
905
                without:    without,
8✔
906
                relations:  relations,
8✔
907
                hasWithout: !without.IsZero(),
8✔
908
                lock:       world.lock(),
8✔
909
                components: components,
8✔
910
                cursor: cursor{
8✔
911
                        archetype: -1,
8✔
912
                        table:     -1,
8✔
913
                        index:     0,
8✔
914
                        maxIndex:  -1,
8✔
915
                },
8✔
916
        }
8✔
917
}
918

919
// Next advances the query's cursor to the next entity.
920
func (q *Query6[A, B, C, D, E, F]) Next() bool {
141✔
921
        checkQueryNext(&q.cursor)
141✔
922
        if int64(q.cursor.index) < q.cursor.maxIndex {
265✔
923
                q.cursor.index++
124✔
924
                return true
124✔
925
        }
124✔
926
        return q.nextTableOrArchetype()
17✔
927
}
928

929
// Entity returns the current entity.
930
func (q *Query6[A, B, C, D, E, F]) Entity() Entity {
134✔
931
        checkQueryGet(&q.cursor)
134✔
932
        return q.table.GetEntity(q.cursor.index)
134✔
933
}
134✔
934

935
// Get returns the queried components of the current entity.
936
func (q *Query6[A, B, C, D, E, F]) Get() (*A, *B, *C, *D, *E, *F) {
124✔
937
        checkQueryGet(&q.cursor)
124✔
938
        return (*A)(q.columnA.Get(q.cursor.index)),
124✔
939
                (*B)(q.columnB.Get(q.cursor.index)),
124✔
940
                (*C)(q.columnC.Get(q.cursor.index)),
124✔
941
                (*D)(q.columnD.Get(q.cursor.index)),
124✔
942
                (*E)(q.columnE.Get(q.cursor.index)),
124✔
943
                (*F)(q.columnF.Get(q.cursor.index))
124✔
944
}
124✔
945

946
// GetRelation returns the entity relation target of the component at the given index.
947
func (q *Query6[A, B, C, D, E, F]) GetRelation(index int) Entity {
10✔
948
        return q.components[index].columns[q.table.id].target
10✔
949
}
10✔
950

951
// Close closes the Query and unlocks the world.
952
//
953
// Automatically called when iteration finishes.
954
// Needs to be called only if breaking out of the query iteration or not iterating at all.
955
func (q *Query6[A, B, C, D, E, F]) Close() {
8✔
956
        q.cursor.archetype = -2
8✔
957
        q.cursor.table = -2
8✔
958
        q.tables = nil
8✔
959
        q.table = nil
8✔
960
        q.columnA = nil
8✔
961
        q.columnB = nil
8✔
962
        q.columnC = nil
8✔
963
        q.columnD = nil
8✔
964
        q.columnE = nil
8✔
965
        q.columnF = nil
8✔
966
        q.world.unlock(q.lock)
8✔
967
}
8✔
968

969
func (q *Query6[A, B, C, D, E, F]) nextTableOrArchetype() bool {
17✔
970
        if q.cursor.archetype >= 0 && q.nextTable() {
17✔
UNCOV
971
                return true
×
UNCOV
972
        }
×
973
        return q.nextArchetype()
17✔
974
}
975

976
func (q *Query6[A, B, C, D, E, F]) nextArchetype() bool {
17✔
977
        maxArchIndex := len(q.world.storage.archetypes) - 1
17✔
978
        for q.cursor.archetype < maxArchIndex {
42✔
979
                q.cursor.archetype++
25✔
980
                archetype := &q.world.storage.archetypes[q.cursor.archetype]
25✔
981
                if !archetype.mask.Contains(&q.mask) ||
25✔
982
                        archetype.mask.ContainsAny(&q.without) {
41✔
983
                        continue
16✔
984
                }
985

986
                if !archetype.HasRelations() {
15✔
987
                        table := &q.world.storage.tables[archetype.tables[0]]
7✔
988
                        if table.Len() > 0 {
14✔
989
                                q.setTable(0, table)
7✔
990
                                return true
7✔
991
                        }
7✔
UNCOV
992
                        continue
×
993
                }
994

995
                q.tables = archetype.GetTables(q.relations)
1✔
996
                q.cursor.table = -1
1✔
997
                if q.nextTable() {
2✔
998
                        return true
1✔
999
                }
1✔
1000
        }
1001
        q.Close()
8✔
1002
        return false
8✔
1003
}
1004

1005
func (q *Query6[A, B, C, D, E, F]) nextTable() bool {
9✔
1006
        maxTableIndex := len(q.tables) - 1
9✔
1007
        for q.cursor.table < maxTableIndex {
10✔
1008
                q.cursor.table++
1✔
1009
                table := &q.world.storage.tables[q.tables[q.cursor.table]]
1✔
1010
                if table.Len() == 0 {
1✔
1011
                        continue
×
1012
                }
1013
                if !table.Matches(q.relations) {
1✔
1014
                        continue
×
1015
                }
1016
                q.setTable(q.cursor.table, table)
1✔
1017
                return true
1✔
1018
        }
1019
        return false
8✔
1020
}
1021

1022
func (q *Query6[A, B, C, D, E, F]) setTable(index int, table *table) {
8✔
1023
        q.cursor.table = index
8✔
1024
        q.table = table
8✔
1025
        q.columnA = q.components[0].columns[q.table.id]
8✔
1026
        q.columnB = q.components[1].columns[q.table.id]
8✔
1027
        q.columnC = q.components[2].columns[q.table.id]
8✔
1028
        q.columnD = q.components[3].columns[q.table.id]
8✔
1029
        q.columnE = q.components[4].columns[q.table.id]
8✔
1030
        q.columnF = q.components[5].columns[q.table.id]
8✔
1031
        q.cursor.index = 0
8✔
1032
        q.cursor.maxIndex = int64(q.table.entities.Len() - 1)
8✔
1033
}
8✔
1034

1035
// Query7 is a query for 7 components.
1036
// Use a [NewFilter7] to create one.
1037
type Query7[A any, B any, C any, D any, E any, F any, G any] struct {
1038
        world      *World
1039
        mask       Mask
1040
        without    Mask
1041
        relations  []relationID
1042
        lock       uint8
1043
        cursor     cursor
1044
        tables     []tableID
1045
        table      *table
1046
        components []*componentStorage
1047
        columnA    *column
1048
        columnB    *column
1049
        columnC    *column
1050
        columnD    *column
1051
        columnE    *column
1052
        columnF    *column
1053
        columnG    *column
1054
        hasWithout bool
1055
}
1056

1057
func newQuery7[A any, B any, C any, D any, E any, F any, G any](world *World, mask Mask, without Mask, ids []ID, relations []relationID) Query7[A, B, C, D, E, F, G] {
8✔
1058
        components := make([]*componentStorage, 7)
8✔
1059
        for i := range 7 {
64✔
1060
                components[i] = &world.storage.components[ids[i].id]
56✔
1061
        }
56✔
1062

1063
        return Query7[A, B, C, D, E, F, G]{
8✔
1064
                world:      world,
8✔
1065
                mask:       mask,
8✔
1066
                without:    without,
8✔
1067
                relations:  relations,
8✔
1068
                hasWithout: !without.IsZero(),
8✔
1069
                lock:       world.lock(),
8✔
1070
                components: components,
8✔
1071
                cursor: cursor{
8✔
1072
                        archetype: -1,
8✔
1073
                        table:     -1,
8✔
1074
                        index:     0,
8✔
1075
                        maxIndex:  -1,
8✔
1076
                },
8✔
1077
        }
8✔
1078
}
1079

1080
// Next advances the query's cursor to the next entity.
1081
func (q *Query7[A, B, C, D, E, F, G]) Next() bool {
141✔
1082
        checkQueryNext(&q.cursor)
141✔
1083
        if int64(q.cursor.index) < q.cursor.maxIndex {
265✔
1084
                q.cursor.index++
124✔
1085
                return true
124✔
1086
        }
124✔
1087
        return q.nextTableOrArchetype()
17✔
1088
}
1089

1090
// Entity returns the current entity.
1091
func (q *Query7[A, B, C, D, E, F, G]) Entity() Entity {
134✔
1092
        checkQueryGet(&q.cursor)
134✔
1093
        return q.table.GetEntity(q.cursor.index)
134✔
1094
}
134✔
1095

1096
// Get returns the queried components of the current entity.
1097
func (q *Query7[A, B, C, D, E, F, G]) Get() (*A, *B, *C, *D, *E, *F, *G) {
124✔
1098
        checkQueryGet(&q.cursor)
124✔
1099
        return (*A)(q.columnA.Get(q.cursor.index)),
124✔
1100
                (*B)(q.columnB.Get(q.cursor.index)),
124✔
1101
                (*C)(q.columnC.Get(q.cursor.index)),
124✔
1102
                (*D)(q.columnD.Get(q.cursor.index)),
124✔
1103
                (*E)(q.columnE.Get(q.cursor.index)),
124✔
1104
                (*F)(q.columnF.Get(q.cursor.index)),
124✔
1105
                (*G)(q.columnG.Get(q.cursor.index))
124✔
1106
}
124✔
1107

1108
// GetRelation returns the entity relation target of the component at the given index.
1109
func (q *Query7[A, B, C, D, E, F, G]) GetRelation(index int) Entity {
10✔
1110
        return q.components[index].columns[q.table.id].target
10✔
1111
}
10✔
1112

1113
// Close closes the Query and unlocks the world.
1114
//
1115
// Automatically called when iteration finishes.
1116
// Needs to be called only if breaking out of the query iteration or not iterating at all.
1117
func (q *Query7[A, B, C, D, E, F, G]) Close() {
8✔
1118
        q.cursor.archetype = -2
8✔
1119
        q.cursor.table = -2
8✔
1120
        q.tables = nil
8✔
1121
        q.table = nil
8✔
1122
        q.columnA = nil
8✔
1123
        q.columnB = nil
8✔
1124
        q.columnC = nil
8✔
1125
        q.columnD = nil
8✔
1126
        q.columnE = nil
8✔
1127
        q.columnF = nil
8✔
1128
        q.columnG = nil
8✔
1129
        q.world.unlock(q.lock)
8✔
1130
}
8✔
1131

1132
func (q *Query7[A, B, C, D, E, F, G]) nextTableOrArchetype() bool {
17✔
1133
        if q.cursor.archetype >= 0 && q.nextTable() {
17✔
UNCOV
1134
                return true
×
UNCOV
1135
        }
×
1136
        return q.nextArchetype()
17✔
1137
}
1138

1139
func (q *Query7[A, B, C, D, E, F, G]) nextArchetype() bool {
17✔
1140
        maxArchIndex := len(q.world.storage.archetypes) - 1
17✔
1141
        for q.cursor.archetype < maxArchIndex {
42✔
1142
                q.cursor.archetype++
25✔
1143
                archetype := &q.world.storage.archetypes[q.cursor.archetype]
25✔
1144
                if !archetype.mask.Contains(&q.mask) ||
25✔
1145
                        archetype.mask.ContainsAny(&q.without) {
41✔
1146
                        continue
16✔
1147
                }
1148

1149
                if !archetype.HasRelations() {
15✔
1150
                        table := &q.world.storage.tables[archetype.tables[0]]
7✔
1151
                        if table.Len() > 0 {
14✔
1152
                                q.setTable(0, table)
7✔
1153
                                return true
7✔
1154
                        }
7✔
UNCOV
1155
                        continue
×
1156
                }
1157

1158
                q.tables = archetype.GetTables(q.relations)
1✔
1159
                q.cursor.table = -1
1✔
1160
                if q.nextTable() {
2✔
1161
                        return true
1✔
1162
                }
1✔
1163
        }
1164
        q.Close()
8✔
1165
        return false
8✔
1166
}
1167

1168
func (q *Query7[A, B, C, D, E, F, G]) nextTable() bool {
9✔
1169
        maxTableIndex := len(q.tables) - 1
9✔
1170
        for q.cursor.table < maxTableIndex {
10✔
1171
                q.cursor.table++
1✔
1172
                table := &q.world.storage.tables[q.tables[q.cursor.table]]
1✔
1173
                if table.Len() == 0 {
1✔
1174
                        continue
×
1175
                }
1176
                if !table.Matches(q.relations) {
1✔
1177
                        continue
×
1178
                }
1179
                q.setTable(q.cursor.table, table)
1✔
1180
                return true
1✔
1181
        }
1182
        return false
8✔
1183
}
1184

1185
func (q *Query7[A, B, C, D, E, F, G]) setTable(index int, table *table) {
8✔
1186
        q.cursor.table = index
8✔
1187
        q.table = table
8✔
1188
        q.columnA = q.components[0].columns[q.table.id]
8✔
1189
        q.columnB = q.components[1].columns[q.table.id]
8✔
1190
        q.columnC = q.components[2].columns[q.table.id]
8✔
1191
        q.columnD = q.components[3].columns[q.table.id]
8✔
1192
        q.columnE = q.components[4].columns[q.table.id]
8✔
1193
        q.columnF = q.components[5].columns[q.table.id]
8✔
1194
        q.columnG = q.components[6].columns[q.table.id]
8✔
1195
        q.cursor.index = 0
8✔
1196
        q.cursor.maxIndex = int64(q.table.entities.Len() - 1)
8✔
1197
}
8✔
1198

1199
// Query8 is a query for 8 components.
1200
// Use a [NewFilter8] to create one.
1201
type Query8[A any, B any, C any, D any, E any, F any, G any, H any] struct {
1202
        world      *World
1203
        mask       Mask
1204
        without    Mask
1205
        relations  []relationID
1206
        lock       uint8
1207
        cursor     cursor
1208
        tables     []tableID
1209
        table      *table
1210
        components []*componentStorage
1211
        columnA    *column
1212
        columnB    *column
1213
        columnC    *column
1214
        columnD    *column
1215
        columnE    *column
1216
        columnF    *column
1217
        columnG    *column
1218
        columnH    *column
1219
        hasWithout bool
1220
}
1221

1222
func newQuery8[A any, B any, C any, D any, E any, F any, G any, H any](world *World, mask Mask, without Mask, ids []ID, relations []relationID) Query8[A, B, C, D, E, F, G, H] {
8✔
1223
        components := make([]*componentStorage, 8)
8✔
1224
        for i := range 8 {
72✔
1225
                components[i] = &world.storage.components[ids[i].id]
64✔
1226
        }
64✔
1227

1228
        return Query8[A, B, C, D, E, F, G, H]{
8✔
1229
                world:      world,
8✔
1230
                mask:       mask,
8✔
1231
                without:    without,
8✔
1232
                relations:  relations,
8✔
1233
                hasWithout: !without.IsZero(),
8✔
1234
                lock:       world.lock(),
8✔
1235
                components: components,
8✔
1236
                cursor: cursor{
8✔
1237
                        archetype: -1,
8✔
1238
                        table:     -1,
8✔
1239
                        index:     0,
8✔
1240
                        maxIndex:  -1,
8✔
1241
                },
8✔
1242
        }
8✔
1243
}
1244

1245
// Next advances the query's cursor to the next entity.
1246
func (q *Query8[A, B, C, D, E, F, G, H]) Next() bool {
141✔
1247
        checkQueryNext(&q.cursor)
141✔
1248
        if int64(q.cursor.index) < q.cursor.maxIndex {
265✔
1249
                q.cursor.index++
124✔
1250
                return true
124✔
1251
        }
124✔
1252
        return q.nextTableOrArchetype()
17✔
1253
}
1254

1255
// Entity returns the current entity.
1256
func (q *Query8[A, B, C, D, E, F, G, H]) Entity() Entity {
134✔
1257
        checkQueryGet(&q.cursor)
134✔
1258
        return q.table.GetEntity(q.cursor.index)
134✔
1259
}
134✔
1260

1261
// Get returns the queried components of the current entity.
1262
func (q *Query8[A, B, C, D, E, F, G, H]) Get() (*A, *B, *C, *D, *E, *F, *G, *H) {
124✔
1263
        checkQueryGet(&q.cursor)
124✔
1264
        return (*A)(q.columnA.Get(q.cursor.index)),
124✔
1265
                (*B)(q.columnB.Get(q.cursor.index)),
124✔
1266
                (*C)(q.columnC.Get(q.cursor.index)),
124✔
1267
                (*D)(q.columnD.Get(q.cursor.index)),
124✔
1268
                (*E)(q.columnE.Get(q.cursor.index)),
124✔
1269
                (*F)(q.columnF.Get(q.cursor.index)),
124✔
1270
                (*G)(q.columnG.Get(q.cursor.index)),
124✔
1271
                (*H)(q.columnH.Get(q.cursor.index))
124✔
1272
}
124✔
1273

1274
// GetRelation returns the entity relation target of the component at the given index.
1275
func (q *Query8[A, B, C, D, E, F, G, H]) GetRelation(index int) Entity {
10✔
1276
        return q.components[index].columns[q.table.id].target
10✔
1277
}
10✔
1278

1279
// Close closes the Query and unlocks the world.
1280
//
1281
// Automatically called when iteration finishes.
1282
// Needs to be called only if breaking out of the query iteration or not iterating at all.
1283
func (q *Query8[A, B, C, D, E, F, G, H]) Close() {
8✔
1284
        q.cursor.archetype = -2
8✔
1285
        q.cursor.table = -2
8✔
1286
        q.tables = nil
8✔
1287
        q.table = nil
8✔
1288
        q.columnA = nil
8✔
1289
        q.columnB = nil
8✔
1290
        q.columnC = nil
8✔
1291
        q.columnD = nil
8✔
1292
        q.columnE = nil
8✔
1293
        q.columnF = nil
8✔
1294
        q.columnG = nil
8✔
1295
        q.columnH = nil
8✔
1296
        q.world.unlock(q.lock)
8✔
1297
}
8✔
1298

1299
func (q *Query8[A, B, C, D, E, F, G, H]) nextTableOrArchetype() bool {
17✔
1300
        if q.cursor.archetype >= 0 && q.nextTable() {
17✔
UNCOV
1301
                return true
×
UNCOV
1302
        }
×
1303
        return q.nextArchetype()
17✔
1304
}
1305

1306
func (q *Query8[A, B, C, D, E, F, G, H]) nextArchetype() bool {
17✔
1307
        maxArchIndex := len(q.world.storage.archetypes) - 1
17✔
1308
        for q.cursor.archetype < maxArchIndex {
42✔
1309
                q.cursor.archetype++
25✔
1310
                archetype := &q.world.storage.archetypes[q.cursor.archetype]
25✔
1311
                if !archetype.mask.Contains(&q.mask) ||
25✔
1312
                        archetype.mask.ContainsAny(&q.without) {
41✔
1313
                        continue
16✔
1314
                }
1315

1316
                if !archetype.HasRelations() {
15✔
1317
                        table := &q.world.storage.tables[archetype.tables[0]]
7✔
1318
                        if table.Len() > 0 {
14✔
1319
                                q.setTable(0, table)
7✔
1320
                                return true
7✔
1321
                        }
7✔
UNCOV
1322
                        continue
×
1323
                }
1324

1325
                q.tables = archetype.GetTables(q.relations)
1✔
1326
                q.cursor.table = -1
1✔
1327
                if q.nextTable() {
2✔
1328
                        return true
1✔
1329
                }
1✔
1330
        }
1331
        q.Close()
8✔
1332
        return false
8✔
1333
}
1334

1335
func (q *Query8[A, B, C, D, E, F, G, H]) nextTable() bool {
9✔
1336
        maxTableIndex := len(q.tables) - 1
9✔
1337
        for q.cursor.table < maxTableIndex {
10✔
1338
                q.cursor.table++
1✔
1339
                table := &q.world.storage.tables[q.tables[q.cursor.table]]
1✔
1340
                if table.Len() == 0 {
1✔
1341
                        continue
×
1342
                }
1343
                if !table.Matches(q.relations) {
1✔
1344
                        continue
×
1345
                }
1346
                q.setTable(q.cursor.table, table)
1✔
1347
                return true
1✔
1348
        }
1349
        return false
8✔
1350
}
1351

1352
func (q *Query8[A, B, C, D, E, F, G, H]) setTable(index int, table *table) {
8✔
1353
        q.cursor.table = index
8✔
1354
        q.table = table
8✔
1355
        q.columnA = q.components[0].columns[q.table.id]
8✔
1356
        q.columnB = q.components[1].columns[q.table.id]
8✔
1357
        q.columnC = q.components[2].columns[q.table.id]
8✔
1358
        q.columnD = q.components[3].columns[q.table.id]
8✔
1359
        q.columnE = q.components[4].columns[q.table.id]
8✔
1360
        q.columnF = q.components[5].columns[q.table.id]
8✔
1361
        q.columnG = q.components[6].columns[q.table.id]
8✔
1362
        q.columnH = q.components[7].columns[q.table.id]
8✔
1363
        q.cursor.index = 0
8✔
1364
        q.cursor.maxIndex = int64(q.table.entities.Len() - 1)
8✔
1365
}
8✔
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