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

mlange-42 / ark / 13610747635

02 Mar 2025 01:27AM CUT coverage: 97.424%. Remained the same
13610747635

push

github

web-flow
Group and rename pos/vel benchmarks (#99)

3895 of 3998 relevant lines covered (97.42%)

45948.49 hits per line

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

98.06
/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
        filter     Filter
17
        relations  []RelationID
18
        lock       uint8
19
        cursor     cursor
20
        tables     []tableID
21
        table      *table
22
        components []*componentStorage
23
}
24

25
func newQuery0(world *World, filter Filter, relations []RelationID) Query0 {
8✔
26
        components := make([]*componentStorage, 0)
8✔
27

8✔
28
        return Query0{
8✔
29
                world:      world,
8✔
30
                filter:     filter,
8✔
31
                relations:  relations,
8✔
32
                lock:       world.lock(),
8✔
33
                components: components,
8✔
34
                cursor: cursor{
8✔
35
                        archetype: -1,
8✔
36
                        table:     -1,
8✔
37
                        index:     0,
8✔
38
                        maxIndex:  -1,
8✔
39
                },
8✔
40
        }
8✔
41
}
8✔
42

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

53
// Entity returns the current entity.
54
func (q *Query0) Entity() Entity {
185✔
55
        q.world.checkQueryGet(&q.cursor)
185✔
56
        return q.table.GetEntity(q.cursor.index)
185✔
57
}
185✔
58

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

71
func (q *Query0) nextTableOrArchetype() bool {
19✔
72
        if q.cursor.archetype >= 0 && q.nextTable() {
21✔
73
                return true
2✔
74
        }
2✔
75
        return q.nextArchetype()
17✔
76
}
77

78
func (q *Query0) nextArchetype() bool {
17✔
79
        maxArchIndex := len(q.world.storage.archetypes) - 1
17✔
80
        for q.cursor.archetype < maxArchIndex {
34✔
81
                q.cursor.archetype++
17✔
82
                archetype := &q.world.storage.archetypes[q.cursor.archetype]
17✔
83
                if !q.filter.matches(&archetype.mask) {
21✔
84
                        continue
4✔
85
                }
86

87
                if !archetype.HasRelations() {
23✔
88
                        table := &q.world.storage.tables[archetype.tables[0]]
11✔
89
                        if table.Len() > 0 {
18✔
90
                                q.setTable(0, table)
7✔
91
                                return true
7✔
92
                        }
7✔
93
                        continue
4✔
94
                }
95

96
                q.tables = archetype.GetTables(q.relations)
1✔
97
                q.cursor.table = -1
1✔
98
                if q.nextTable() {
2✔
99
                        return true
1✔
100
                }
1✔
101
        }
102
        q.Close()
8✔
103
        return false
8✔
104
}
105

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

123
func (q *Query0) setTable(index int, table *table) {
10✔
124
        q.cursor.table = index
10✔
125
        q.table = table
10✔
126
        q.cursor.index = 0
10✔
127
        q.cursor.maxIndex = int64(q.table.entities.Len() - 1)
10✔
128
}
10✔
129

130
// Query1 is a query for 1 components.
131
// Use a [NewFilter1] to create one.
132
type Query1[A any] struct {
133
        world      *World
134
        filter     Filter
135
        relations  []RelationID
136
        lock       uint8
137
        cursor     cursor
138
        tables     []tableID
139
        table      *table
140
        components []*componentStorage
141
        columnA    *column
142
}
143

144
func newQuery1[A any](world *World, filter Filter, ids []ID, relations []RelationID) Query1[A] {
1,009✔
145
        components := make([]*componentStorage, 1)
1,009✔
146
        for i := range 1 {
2,018✔
147
                components[i] = &world.storage.components[ids[i].id]
1,009✔
148
        }
1,009✔
149

150
        return Query1[A]{
1,009✔
151
                world:      world,
1,009✔
152
                filter:     filter,
1,009✔
153
                relations:  relations,
1,009✔
154
                lock:       world.lock(),
1,009✔
155
                components: components,
1,009✔
156
                cursor: cursor{
1,009✔
157
                        archetype: -1,
1,009✔
158
                        table:     -1,
1,009✔
159
                        index:     0,
1,009✔
160
                        maxIndex:  -1,
1,009✔
161
                },
1,009✔
162
        }
1,009✔
163
}
164

165
// Next advances the query's cursor to the next entity.
166
func (q *Query1[A]) Next() bool {
977,526✔
167
        q.world.checkQueryNext(&q.cursor)
977,526✔
168
        if int64(q.cursor.index) < q.cursor.maxIndex {
1,953,032✔
169
                q.cursor.index++
975,506✔
170
                return true
975,506✔
171
        }
975,506✔
172
        return q.nextTableOrArchetype()
2,020✔
173
}
174

175
// Entity returns the current entity.
176
func (q *Query1[A]) Entity() Entity {
1,952,882✔
177
        q.world.checkQueryGet(&q.cursor)
1,952,882✔
178
        return q.table.GetEntity(q.cursor.index)
1,952,882✔
179
}
1,952,882✔
180

181
// Get returns the queried components of the current entity.
182
func (q *Query1[A]) Get() *A {
976,518✔
183
        q.world.checkQueryGet(&q.cursor)
976,518✔
184
        return (*A)(q.columnA.Get(q.cursor.index))
976,518✔
185
}
976,518✔
186

187
// GetRelation returns the entity relation target of the component at the given index.
188
func (q *Query1[A]) GetRelation(index int) Entity {
10✔
189
        return q.components[index].columns[q.table.id].target
10✔
190
}
10✔
191

192
// Close closes the Query and unlocks the world.
193
//
194
// Automatically called when iteration finishes.
195
// Needs to be called only if breaking out of the query iteration or not iterating at all.
196
func (q *Query1[A]) Close() {
1,009✔
197
        q.cursor.archetype = -2
1,009✔
198
        q.cursor.table = -2
1,009✔
199
        q.tables = nil
1,009✔
200
        q.table = nil
1,009✔
201
        q.columnA = nil
1,009✔
202
        q.world.unlock(q.lock)
1,009✔
203
}
1,009✔
204

205
func (q *Query1[A]) nextTableOrArchetype() bool {
2,020✔
206
        if q.cursor.archetype >= 0 && q.nextTable() {
2,021✔
207
                return true
1✔
208
        }
1✔
209
        return q.nextArchetype()
2,019✔
210
}
211

212
func (q *Query1[A]) nextArchetype() bool {
2,019✔
213
        maxArchIndex := len(q.world.storage.archetypes) - 1
2,019✔
214
        for q.cursor.archetype < maxArchIndex {
4,042✔
215
                q.cursor.archetype++
2,023✔
216
                archetype := &q.world.storage.archetypes[q.cursor.archetype]
2,023✔
217
                if !q.filter.matches(&archetype.mask) {
3,036✔
218
                        continue
1,013✔
219
                }
220

221
                if !archetype.HasRelations() {
2,016✔
222
                        table := &q.world.storage.tables[archetype.tables[0]]
1,007✔
223
                        if table.Len() > 0 {
2,014✔
224
                                q.setTable(0, table)
1,007✔
225
                                return true
1,007✔
226
                        }
1,007✔
227
                        continue
×
228
                }
229

230
                q.tables = archetype.GetTables(q.relations)
2✔
231
                q.cursor.table = -1
2✔
232
                if q.nextTable() {
4✔
233
                        return true
2✔
234
                }
2✔
235
        }
236
        q.Close()
1,009✔
237
        return false
1,009✔
238
}
239

240
func (q *Query1[A]) nextTable() bool {
1,012✔
241
        maxTableIndex := len(q.tables) - 1
1,012✔
242
        for q.cursor.table < maxTableIndex {
1,016✔
243
                q.cursor.table++
4✔
244
                table := &q.world.storage.tables[q.tables[q.cursor.table]]
4✔
245
                if table.Len() == 0 {
5✔
246
                        continue
1✔
247
                }
248
                if !table.Matches(q.relations) {
3✔
249
                        continue
×
250
                }
251
                q.setTable(q.cursor.table, table)
3✔
252
                return true
3✔
253
        }
254
        return false
1,009✔
255
}
256

257
func (q *Query1[A]) setTable(index int, table *table) {
1,010✔
258
        q.cursor.table = index
1,010✔
259
        q.table = table
1,010✔
260
        q.columnA = q.components[0].columns[q.table.id]
1,010✔
261
        q.cursor.index = 0
1,010✔
262
        q.cursor.maxIndex = int64(q.table.entities.Len() - 1)
1,010✔
263
}
1,010✔
264

265
// Query2 is a query for 2 components.
266
// Use a [NewFilter2] to create one.
267
type Query2[A any, B any] struct {
268
        world      *World
269
        filter     Filter
270
        relations  []RelationID
271
        lock       uint8
272
        cursor     cursor
273
        tables     []tableID
274
        table      *table
275
        components []*componentStorage
276
        columnA    *column
277
        columnB    *column
278
}
279

280
func newQuery2[A any, B any](world *World, filter Filter, ids []ID, relations []RelationID) Query2[A, B] {
10✔
281
        components := make([]*componentStorage, 2)
10✔
282
        for i := range 2 {
30✔
283
                components[i] = &world.storage.components[ids[i].id]
20✔
284
        }
20✔
285

286
        return Query2[A, B]{
10✔
287
                world:      world,
10✔
288
                filter:     filter,
10✔
289
                relations:  relations,
10✔
290
                lock:       world.lock(),
10✔
291
                components: components,
10✔
292
                cursor: cursor{
10✔
293
                        archetype: -1,
10✔
294
                        table:     -1,
10✔
295
                        index:     0,
10✔
296
                        maxIndex:  -1,
10✔
297
                },
10✔
298
        }
10✔
299
}
300

301
// Next advances the query's cursor to the next entity.
302
func (q *Query2[A, B]) Next() bool {
195✔
303
        q.world.checkQueryNext(&q.cursor)
195✔
304
        if int64(q.cursor.index) < q.cursor.maxIndex {
368✔
305
                q.cursor.index++
173✔
306
                return true
173✔
307
        }
173✔
308
        return q.nextTableOrArchetype()
22✔
309
}
310

311
// Entity returns the current entity.
312
func (q *Query2[A, B]) Entity() Entity {
154✔
313
        q.world.checkQueryGet(&q.cursor)
154✔
314
        return q.table.GetEntity(q.cursor.index)
154✔
315
}
154✔
316

317
// Get returns the queried components of the current entity.
318
func (q *Query2[A, B]) Get() (*A, *B) {
186✔
319
        q.world.checkQueryGet(&q.cursor)
186✔
320
        return (*A)(q.columnA.Get(q.cursor.index)),
186✔
321
                (*B)(q.columnB.Get(q.cursor.index))
186✔
322
}
186✔
323

324
// GetRelation returns the entity relation target of the component at the given index.
325
func (q *Query2[A, B]) GetRelation(index int) Entity {
10✔
326
        return q.components[index].columns[q.table.id].target
10✔
327
}
10✔
328

329
// Close closes the Query and unlocks the world.
330
//
331
// Automatically called when iteration finishes.
332
// Needs to be called only if breaking out of the query iteration or not iterating at all.
333
func (q *Query2[A, B]) Close() {
10✔
334
        q.cursor.archetype = -2
10✔
335
        q.cursor.table = -2
10✔
336
        q.tables = nil
10✔
337
        q.table = nil
10✔
338
        q.columnA = nil
10✔
339
        q.columnB = nil
10✔
340
        q.world.unlock(q.lock)
10✔
341
}
10✔
342

343
func (q *Query2[A, B]) nextTableOrArchetype() bool {
22✔
344
        if q.cursor.archetype >= 0 && q.nextTable() {
23✔
345
                return true
1✔
346
        }
1✔
347
        return q.nextArchetype()
21✔
348
}
349

350
func (q *Query2[A, B]) nextArchetype() bool {
21✔
351
        maxArchIndex := len(q.world.storage.archetypes) - 1
21✔
352
        for q.cursor.archetype < maxArchIndex {
50✔
353
                q.cursor.archetype++
29✔
354
                archetype := &q.world.storage.archetypes[q.cursor.archetype]
29✔
355
                if !q.filter.matches(&archetype.mask) {
47✔
356
                        continue
18✔
357
                }
358

359
                if !archetype.HasRelations() {
17✔
360
                        table := &q.world.storage.tables[archetype.tables[0]]
7✔
361
                        if table.Len() > 0 {
14✔
362
                                q.setTable(0, table)
7✔
363
                                return true
7✔
364
                        }
7✔
365
                        continue
×
366
                }
367

368
                q.tables = archetype.GetTables(q.relations)
3✔
369
                q.cursor.table = -1
3✔
370
                if q.nextTable() {
6✔
371
                        return true
3✔
372
                }
3✔
373
        }
374
        q.Close()
10✔
375
        return false
10✔
376
}
377

378
func (q *Query2[A, B]) nextTable() bool {
14✔
379
        maxTableIndex := len(q.tables) - 1
14✔
380
        for q.cursor.table < maxTableIndex {
19✔
381
                q.cursor.table++
5✔
382
                table := &q.world.storage.tables[q.tables[q.cursor.table]]
5✔
383
                if table.Len() == 0 {
6✔
384
                        continue
1✔
385
                }
386
                if !table.Matches(q.relations) {
4✔
387
                        continue
×
388
                }
389
                q.setTable(q.cursor.table, table)
4✔
390
                return true
4✔
391
        }
392
        return false
10✔
393
}
394

395
func (q *Query2[A, B]) setTable(index int, table *table) {
11✔
396
        q.cursor.table = index
11✔
397
        q.table = table
11✔
398
        q.columnA = q.components[0].columns[q.table.id]
11✔
399
        q.columnB = q.components[1].columns[q.table.id]
11✔
400
        q.cursor.index = 0
11✔
401
        q.cursor.maxIndex = int64(q.table.entities.Len() - 1)
11✔
402
}
11✔
403

404
// Query3 is a query for 3 components.
405
// Use a [NewFilter3] to create one.
406
type Query3[A any, B any, C any] struct {
407
        world      *World
408
        filter     Filter
409
        relations  []RelationID
410
        lock       uint8
411
        cursor     cursor
412
        tables     []tableID
413
        table      *table
414
        components []*componentStorage
415
        columnA    *column
416
        columnB    *column
417
        columnC    *column
418
}
419

420
func newQuery3[A any, B any, C any](world *World, filter Filter, ids []ID, relations []RelationID) Query3[A, B, C] {
12✔
421
        components := make([]*componentStorage, 3)
12✔
422
        for i := range 3 {
48✔
423
                components[i] = &world.storage.components[ids[i].id]
36✔
424
        }
36✔
425

426
        return Query3[A, B, C]{
12✔
427
                world:      world,
12✔
428
                filter:     filter,
12✔
429
                relations:  relations,
12✔
430
                lock:       world.lock(),
12✔
431
                components: components,
12✔
432
                cursor: cursor{
12✔
433
                        archetype: -1,
12✔
434
                        table:     -1,
12✔
435
                        index:     0,
12✔
436
                        maxIndex:  -1,
12✔
437
                },
12✔
438
        }
12✔
439
}
440

441
// Next advances the query's cursor to the next entity.
442
func (q *Query3[A, B, C]) Next() bool {
235✔
443
        q.world.checkQueryNext(&q.cursor)
235✔
444
        if int64(q.cursor.index) < q.cursor.maxIndex {
440✔
445
                q.cursor.index++
205✔
446
                return true
205✔
447
        }
205✔
448
        return q.nextTableOrArchetype()
30✔
449
}
450

451
// Entity returns the current entity.
452
func (q *Query3[A, B, C]) Entity() Entity {
154✔
453
        q.world.checkQueryGet(&q.cursor)
154✔
454
        return q.table.GetEntity(q.cursor.index)
154✔
455
}
154✔
456

457
// Get returns the queried components of the current entity.
458
func (q *Query3[A, B, C]) Get() (*A, *B, *C) {
154✔
459
        q.world.checkQueryGet(&q.cursor)
154✔
460
        return (*A)(q.columnA.Get(q.cursor.index)),
154✔
461
                (*B)(q.columnB.Get(q.cursor.index)),
154✔
462
                (*C)(q.columnC.Get(q.cursor.index))
154✔
463
}
154✔
464

465
// GetRelation returns the entity relation target of the component at the given index.
466
func (q *Query3[A, B, C]) GetRelation(index int) Entity {
10✔
467
        return q.components[index].columns[q.table.id].target
10✔
468
}
10✔
469

470
// Close closes the Query and unlocks the world.
471
//
472
// Automatically called when iteration finishes.
473
// Needs to be called only if breaking out of the query iteration or not iterating at all.
474
func (q *Query3[A, B, C]) Close() {
12✔
475
        q.cursor.archetype = -2
12✔
476
        q.cursor.table = -2
12✔
477
        q.tables = nil
12✔
478
        q.table = nil
12✔
479
        q.columnA = nil
12✔
480
        q.columnB = nil
12✔
481
        q.columnC = nil
12✔
482
        q.world.unlock(q.lock)
12✔
483
}
12✔
484

485
func (q *Query3[A, B, C]) nextTableOrArchetype() bool {
30✔
486
        if q.cursor.archetype >= 0 && q.nextTable() {
35✔
487
                return true
5✔
488
        }
5✔
489
        return q.nextArchetype()
25✔
490
}
491

492
func (q *Query3[A, B, C]) nextArchetype() bool {
25✔
493
        maxArchIndex := len(q.world.storage.archetypes) - 1
25✔
494
        for q.cursor.archetype < maxArchIndex {
58✔
495
                q.cursor.archetype++
33✔
496
                archetype := &q.world.storage.archetypes[q.cursor.archetype]
33✔
497
                if !q.filter.matches(&archetype.mask) {
53✔
498
                        continue
20✔
499
                }
500

501
                if !archetype.HasRelations() {
19✔
502
                        table := &q.world.storage.tables[archetype.tables[0]]
7✔
503
                        if table.Len() > 0 {
14✔
504
                                q.setTable(0, table)
7✔
505
                                return true
7✔
506
                        }
7✔
507
                        continue
×
508
                }
509

510
                q.tables = archetype.GetTables(q.relations)
5✔
511
                q.cursor.table = -1
5✔
512
                if q.nextTable() {
10✔
513
                        return true
5✔
514
                }
5✔
515
        }
516
        q.Close()
12✔
517
        return false
12✔
518
}
519

520
func (q *Query3[A, B, C]) nextTable() bool {
22✔
521
        maxTableIndex := len(q.tables) - 1
22✔
522
        for q.cursor.table < maxTableIndex {
34✔
523
                q.cursor.table++
12✔
524
                table := &q.world.storage.tables[q.tables[q.cursor.table]]
12✔
525
                if table.Len() == 0 {
13✔
526
                        continue
1✔
527
                }
528
                if !table.Matches(q.relations) {
12✔
529
                        continue
1✔
530
                }
531
                q.setTable(q.cursor.table, table)
10✔
532
                return true
10✔
533
        }
534
        return false
12✔
535
}
536

537
func (q *Query3[A, B, C]) setTable(index int, table *table) {
17✔
538
        q.cursor.table = index
17✔
539
        q.table = table
17✔
540
        q.columnA = q.components[0].columns[q.table.id]
17✔
541
        q.columnB = q.components[1].columns[q.table.id]
17✔
542
        q.columnC = q.components[2].columns[q.table.id]
17✔
543
        q.cursor.index = 0
17✔
544
        q.cursor.maxIndex = int64(q.table.entities.Len() - 1)
17✔
545
}
17✔
546

547
// Query4 is a query for 4 components.
548
// Use a [NewFilter4] to create one.
549
type Query4[A any, B any, C any, D any] struct {
550
        world      *World
551
        filter     Filter
552
        relations  []RelationID
553
        lock       uint8
554
        cursor     cursor
555
        tables     []tableID
556
        table      *table
557
        components []*componentStorage
558
        columnA    *column
559
        columnB    *column
560
        columnC    *column
561
        columnD    *column
562
}
563

564
func newQuery4[A any, B any, C any, D any](world *World, filter Filter, ids []ID, relations []RelationID) Query4[A, B, C, D] {
9✔
565
        components := make([]*componentStorage, 4)
9✔
566
        for i := range 4 {
45✔
567
                components[i] = &world.storage.components[ids[i].id]
36✔
568
        }
36✔
569

570
        return Query4[A, B, C, D]{
9✔
571
                world:      world,
9✔
572
                filter:     filter,
9✔
573
                relations:  relations,
9✔
574
                lock:       world.lock(),
9✔
575
                components: components,
9✔
576
                cursor: cursor{
9✔
577
                        archetype: -1,
9✔
578
                        table:     -1,
9✔
579
                        index:     0,
9✔
580
                        maxIndex:  -1,
9✔
581
                },
9✔
582
        }
9✔
583
}
584

585
// Next advances the query's cursor to the next entity.
586
func (q *Query4[A, B, C, D]) Next() bool {
162✔
587
        q.world.checkQueryNext(&q.cursor)
162✔
588
        if int64(q.cursor.index) < q.cursor.maxIndex {
304✔
589
                q.cursor.index++
142✔
590
                return true
142✔
591
        }
142✔
592
        return q.nextTableOrArchetype()
20✔
593
}
594

595
// Entity returns the current entity.
596
func (q *Query4[A, B, C, D]) Entity() Entity {
154✔
597
        q.world.checkQueryGet(&q.cursor)
154✔
598
        return q.table.GetEntity(q.cursor.index)
154✔
599
}
154✔
600

601
// Get returns the queried components of the current entity.
602
func (q *Query4[A, B, C, D]) Get() (*A, *B, *C, *D) {
154✔
603
        q.world.checkQueryGet(&q.cursor)
154✔
604
        return (*A)(q.columnA.Get(q.cursor.index)),
154✔
605
                (*B)(q.columnB.Get(q.cursor.index)),
154✔
606
                (*C)(q.columnC.Get(q.cursor.index)),
154✔
607
                (*D)(q.columnD.Get(q.cursor.index))
154✔
608
}
154✔
609

610
// GetRelation returns the entity relation target of the component at the given index.
611
func (q *Query4[A, B, C, D]) GetRelation(index int) Entity {
10✔
612
        return q.components[index].columns[q.table.id].target
10✔
613
}
10✔
614

615
// Close closes the Query and unlocks the world.
616
//
617
// Automatically called when iteration finishes.
618
// Needs to be called only if breaking out of the query iteration or not iterating at all.
619
func (q *Query4[A, B, C, D]) Close() {
9✔
620
        q.cursor.archetype = -2
9✔
621
        q.cursor.table = -2
9✔
622
        q.tables = nil
9✔
623
        q.table = nil
9✔
624
        q.columnA = nil
9✔
625
        q.columnB = nil
9✔
626
        q.columnC = nil
9✔
627
        q.columnD = nil
9✔
628
        q.world.unlock(q.lock)
9✔
629
}
9✔
630

631
func (q *Query4[A, B, C, D]) nextTableOrArchetype() bool {
20✔
632
        if q.cursor.archetype >= 0 && q.nextTable() {
21✔
633
                return true
1✔
634
        }
1✔
635
        return q.nextArchetype()
19✔
636
}
637

638
func (q *Query4[A, B, C, D]) nextArchetype() bool {
19✔
639
        maxArchIndex := len(q.world.storage.archetypes) - 1
19✔
640
        for q.cursor.archetype < maxArchIndex {
46✔
641
                q.cursor.archetype++
27✔
642
                archetype := &q.world.storage.archetypes[q.cursor.archetype]
27✔
643
                if !q.filter.matches(&archetype.mask) {
44✔
644
                        continue
17✔
645
                }
646

647
                if !archetype.HasRelations() {
16✔
648
                        table := &q.world.storage.tables[archetype.tables[0]]
7✔
649
                        if table.Len() > 0 {
14✔
650
                                q.setTable(0, table)
7✔
651
                                return true
7✔
652
                        }
7✔
653
                        continue
×
654
                }
655

656
                q.tables = archetype.GetTables(q.relations)
2✔
657
                q.cursor.table = -1
2✔
658
                if q.nextTable() {
4✔
659
                        return true
2✔
660
                }
2✔
661
        }
662
        q.Close()
9✔
663
        return false
9✔
664
}
665

666
func (q *Query4[A, B, C, D]) nextTable() bool {
12✔
667
        maxTableIndex := len(q.tables) - 1
12✔
668
        for q.cursor.table < maxTableIndex {
16✔
669
                q.cursor.table++
4✔
670
                table := &q.world.storage.tables[q.tables[q.cursor.table]]
4✔
671
                if table.Len() == 0 {
5✔
672
                        continue
1✔
673
                }
674
                if !table.Matches(q.relations) {
3✔
675
                        continue
×
676
                }
677
                q.setTable(q.cursor.table, table)
3✔
678
                return true
3✔
679
        }
680
        return false
9✔
681
}
682

683
func (q *Query4[A, B, C, D]) setTable(index int, table *table) {
10✔
684
        q.cursor.table = index
10✔
685
        q.table = table
10✔
686
        q.columnA = q.components[0].columns[q.table.id]
10✔
687
        q.columnB = q.components[1].columns[q.table.id]
10✔
688
        q.columnC = q.components[2].columns[q.table.id]
10✔
689
        q.columnD = q.components[3].columns[q.table.id]
10✔
690
        q.cursor.index = 0
10✔
691
        q.cursor.maxIndex = int64(q.table.entities.Len() - 1)
10✔
692
}
10✔
693

694
// Query5 is a query for 5 components.
695
// Use a [NewFilter5] to create one.
696
type Query5[A any, B any, C any, D any, E any] struct {
697
        world      *World
698
        filter     Filter
699
        relations  []RelationID
700
        lock       uint8
701
        cursor     cursor
702
        tables     []tableID
703
        table      *table
704
        components []*componentStorage
705
        columnA    *column
706
        columnB    *column
707
        columnC    *column
708
        columnD    *column
709
        columnE    *column
710
}
711

712
func newQuery5[A any, B any, C any, D any, E any](world *World, filter Filter, ids []ID, relations []RelationID) Query5[A, B, C, D, E] {
9✔
713
        components := make([]*componentStorage, 5)
9✔
714
        for i := range 5 {
54✔
715
                components[i] = &world.storage.components[ids[i].id]
45✔
716
        }
45✔
717

718
        return Query5[A, B, C, D, E]{
9✔
719
                world:      world,
9✔
720
                filter:     filter,
9✔
721
                relations:  relations,
9✔
722
                lock:       world.lock(),
9✔
723
                components: components,
9✔
724
                cursor: cursor{
9✔
725
                        archetype: -1,
9✔
726
                        table:     -1,
9✔
727
                        index:     0,
9✔
728
                        maxIndex:  -1,
9✔
729
                },
9✔
730
        }
9✔
731
}
732

733
// Next advances the query's cursor to the next entity.
734
func (q *Query5[A, B, C, D, E]) Next() bool {
162✔
735
        q.world.checkQueryNext(&q.cursor)
162✔
736
        if int64(q.cursor.index) < q.cursor.maxIndex {
304✔
737
                q.cursor.index++
142✔
738
                return true
142✔
739
        }
142✔
740
        return q.nextTableOrArchetype()
20✔
741
}
742

743
// Entity returns the current entity.
744
func (q *Query5[A, B, C, D, E]) Entity() Entity {
154✔
745
        q.world.checkQueryGet(&q.cursor)
154✔
746
        return q.table.GetEntity(q.cursor.index)
154✔
747
}
154✔
748

749
// Get returns the queried components of the current entity.
750
func (q *Query5[A, B, C, D, E]) Get() (*A, *B, *C, *D, *E) {
154✔
751
        q.world.checkQueryGet(&q.cursor)
154✔
752
        return (*A)(q.columnA.Get(q.cursor.index)),
154✔
753
                (*B)(q.columnB.Get(q.cursor.index)),
154✔
754
                (*C)(q.columnC.Get(q.cursor.index)),
154✔
755
                (*D)(q.columnD.Get(q.cursor.index)),
154✔
756
                (*E)(q.columnE.Get(q.cursor.index))
154✔
757
}
154✔
758

759
// GetRelation returns the entity relation target of the component at the given index.
760
func (q *Query5[A, B, C, D, E]) GetRelation(index int) Entity {
10✔
761
        return q.components[index].columns[q.table.id].target
10✔
762
}
10✔
763

764
// Close closes the Query and unlocks the world.
765
//
766
// Automatically called when iteration finishes.
767
// Needs to be called only if breaking out of the query iteration or not iterating at all.
768
func (q *Query5[A, B, C, D, E]) Close() {
9✔
769
        q.cursor.archetype = -2
9✔
770
        q.cursor.table = -2
9✔
771
        q.tables = nil
9✔
772
        q.table = nil
9✔
773
        q.columnA = nil
9✔
774
        q.columnB = nil
9✔
775
        q.columnC = nil
9✔
776
        q.columnD = nil
9✔
777
        q.columnE = nil
9✔
778
        q.world.unlock(q.lock)
9✔
779
}
9✔
780

781
func (q *Query5[A, B, C, D, E]) nextTableOrArchetype() bool {
20✔
782
        if q.cursor.archetype >= 0 && q.nextTable() {
21✔
783
                return true
1✔
784
        }
1✔
785
        return q.nextArchetype()
19✔
786
}
787

788
func (q *Query5[A, B, C, D, E]) nextArchetype() bool {
19✔
789
        maxArchIndex := len(q.world.storage.archetypes) - 1
19✔
790
        for q.cursor.archetype < maxArchIndex {
46✔
791
                q.cursor.archetype++
27✔
792
                archetype := &q.world.storage.archetypes[q.cursor.archetype]
27✔
793
                if !q.filter.matches(&archetype.mask) {
44✔
794
                        continue
17✔
795
                }
796

797
                if !archetype.HasRelations() {
16✔
798
                        table := &q.world.storage.tables[archetype.tables[0]]
7✔
799
                        if table.Len() > 0 {
14✔
800
                                q.setTable(0, table)
7✔
801
                                return true
7✔
802
                        }
7✔
803
                        continue
×
804
                }
805

806
                q.tables = archetype.GetTables(q.relations)
2✔
807
                q.cursor.table = -1
2✔
808
                if q.nextTable() {
4✔
809
                        return true
2✔
810
                }
2✔
811
        }
812
        q.Close()
9✔
813
        return false
9✔
814
}
815

816
func (q *Query5[A, B, C, D, E]) nextTable() bool {
12✔
817
        maxTableIndex := len(q.tables) - 1
12✔
818
        for q.cursor.table < maxTableIndex {
16✔
819
                q.cursor.table++
4✔
820
                table := &q.world.storage.tables[q.tables[q.cursor.table]]
4✔
821
                if table.Len() == 0 {
5✔
822
                        continue
1✔
823
                }
824
                if !table.Matches(q.relations) {
3✔
825
                        continue
×
826
                }
827
                q.setTable(q.cursor.table, table)
3✔
828
                return true
3✔
829
        }
830
        return false
9✔
831
}
832

833
func (q *Query5[A, B, C, D, E]) setTable(index int, table *table) {
10✔
834
        q.cursor.table = index
10✔
835
        q.table = table
10✔
836
        q.columnA = q.components[0].columns[q.table.id]
10✔
837
        q.columnB = q.components[1].columns[q.table.id]
10✔
838
        q.columnC = q.components[2].columns[q.table.id]
10✔
839
        q.columnD = q.components[3].columns[q.table.id]
10✔
840
        q.columnE = q.components[4].columns[q.table.id]
10✔
841
        q.cursor.index = 0
10✔
842
        q.cursor.maxIndex = int64(q.table.entities.Len() - 1)
10✔
843
}
10✔
844

845
// Query6 is a query for 6 components.
846
// Use a [NewFilter6] to create one.
847
type Query6[A any, B any, C any, D any, E any, F any] struct {
848
        world      *World
849
        filter     Filter
850
        relations  []RelationID
851
        lock       uint8
852
        cursor     cursor
853
        tables     []tableID
854
        table      *table
855
        components []*componentStorage
856
        columnA    *column
857
        columnB    *column
858
        columnC    *column
859
        columnD    *column
860
        columnE    *column
861
        columnF    *column
862
}
863

864
func newQuery6[A any, B any, C any, D any, E any, F any](world *World, filter Filter, ids []ID, relations []RelationID) Query6[A, B, C, D, E, F] {
9✔
865
        components := make([]*componentStorage, 6)
9✔
866
        for i := range 6 {
63✔
867
                components[i] = &world.storage.components[ids[i].id]
54✔
868
        }
54✔
869

870
        return Query6[A, B, C, D, E, F]{
9✔
871
                world:      world,
9✔
872
                filter:     filter,
9✔
873
                relations:  relations,
9✔
874
                lock:       world.lock(),
9✔
875
                components: components,
9✔
876
                cursor: cursor{
9✔
877
                        archetype: -1,
9✔
878
                        table:     -1,
9✔
879
                        index:     0,
9✔
880
                        maxIndex:  -1,
9✔
881
                },
9✔
882
        }
9✔
883
}
884

885
// Next advances the query's cursor to the next entity.
886
func (q *Query6[A, B, C, D, E, F]) Next() bool {
162✔
887
        q.world.checkQueryNext(&q.cursor)
162✔
888
        if int64(q.cursor.index) < q.cursor.maxIndex {
304✔
889
                q.cursor.index++
142✔
890
                return true
142✔
891
        }
142✔
892
        return q.nextTableOrArchetype()
20✔
893
}
894

895
// Entity returns the current entity.
896
func (q *Query6[A, B, C, D, E, F]) Entity() Entity {
154✔
897
        q.world.checkQueryGet(&q.cursor)
154✔
898
        return q.table.GetEntity(q.cursor.index)
154✔
899
}
154✔
900

901
// Get returns the queried components of the current entity.
902
func (q *Query6[A, B, C, D, E, F]) Get() (*A, *B, *C, *D, *E, *F) {
154✔
903
        q.world.checkQueryGet(&q.cursor)
154✔
904
        return (*A)(q.columnA.Get(q.cursor.index)),
154✔
905
                (*B)(q.columnB.Get(q.cursor.index)),
154✔
906
                (*C)(q.columnC.Get(q.cursor.index)),
154✔
907
                (*D)(q.columnD.Get(q.cursor.index)),
154✔
908
                (*E)(q.columnE.Get(q.cursor.index)),
154✔
909
                (*F)(q.columnF.Get(q.cursor.index))
154✔
910
}
154✔
911

912
// GetRelation returns the entity relation target of the component at the given index.
913
func (q *Query6[A, B, C, D, E, F]) GetRelation(index int) Entity {
10✔
914
        return q.components[index].columns[q.table.id].target
10✔
915
}
10✔
916

917
// Close closes the Query and unlocks the world.
918
//
919
// Automatically called when iteration finishes.
920
// Needs to be called only if breaking out of the query iteration or not iterating at all.
921
func (q *Query6[A, B, C, D, E, F]) Close() {
9✔
922
        q.cursor.archetype = -2
9✔
923
        q.cursor.table = -2
9✔
924
        q.tables = nil
9✔
925
        q.table = nil
9✔
926
        q.columnA = nil
9✔
927
        q.columnB = nil
9✔
928
        q.columnC = nil
9✔
929
        q.columnD = nil
9✔
930
        q.columnE = nil
9✔
931
        q.columnF = nil
9✔
932
        q.world.unlock(q.lock)
9✔
933
}
9✔
934

935
func (q *Query6[A, B, C, D, E, F]) nextTableOrArchetype() bool {
20✔
936
        if q.cursor.archetype >= 0 && q.nextTable() {
21✔
937
                return true
1✔
938
        }
1✔
939
        return q.nextArchetype()
19✔
940
}
941

942
func (q *Query6[A, B, C, D, E, F]) nextArchetype() bool {
19✔
943
        maxArchIndex := len(q.world.storage.archetypes) - 1
19✔
944
        for q.cursor.archetype < maxArchIndex {
46✔
945
                q.cursor.archetype++
27✔
946
                archetype := &q.world.storage.archetypes[q.cursor.archetype]
27✔
947
                if !q.filter.matches(&archetype.mask) {
44✔
948
                        continue
17✔
949
                }
950

951
                if !archetype.HasRelations() {
16✔
952
                        table := &q.world.storage.tables[archetype.tables[0]]
7✔
953
                        if table.Len() > 0 {
14✔
954
                                q.setTable(0, table)
7✔
955
                                return true
7✔
956
                        }
7✔
957
                        continue
×
958
                }
959

960
                q.tables = archetype.GetTables(q.relations)
2✔
961
                q.cursor.table = -1
2✔
962
                if q.nextTable() {
4✔
963
                        return true
2✔
964
                }
2✔
965
        }
966
        q.Close()
9✔
967
        return false
9✔
968
}
969

970
func (q *Query6[A, B, C, D, E, F]) nextTable() bool {
12✔
971
        maxTableIndex := len(q.tables) - 1
12✔
972
        for q.cursor.table < maxTableIndex {
16✔
973
                q.cursor.table++
4✔
974
                table := &q.world.storage.tables[q.tables[q.cursor.table]]
4✔
975
                if table.Len() == 0 {
5✔
976
                        continue
1✔
977
                }
978
                if !table.Matches(q.relations) {
3✔
979
                        continue
×
980
                }
981
                q.setTable(q.cursor.table, table)
3✔
982
                return true
3✔
983
        }
984
        return false
9✔
985
}
986

987
func (q *Query6[A, B, C, D, E, F]) setTable(index int, table *table) {
10✔
988
        q.cursor.table = index
10✔
989
        q.table = table
10✔
990
        q.columnA = q.components[0].columns[q.table.id]
10✔
991
        q.columnB = q.components[1].columns[q.table.id]
10✔
992
        q.columnC = q.components[2].columns[q.table.id]
10✔
993
        q.columnD = q.components[3].columns[q.table.id]
10✔
994
        q.columnE = q.components[4].columns[q.table.id]
10✔
995
        q.columnF = q.components[5].columns[q.table.id]
10✔
996
        q.cursor.index = 0
10✔
997
        q.cursor.maxIndex = int64(q.table.entities.Len() - 1)
10✔
998
}
10✔
999

1000
// Query7 is a query for 7 components.
1001
// Use a [NewFilter7] to create one.
1002
type Query7[A any, B any, C any, D any, E any, F any, G any] struct {
1003
        world      *World
1004
        filter     Filter
1005
        relations  []RelationID
1006
        lock       uint8
1007
        cursor     cursor
1008
        tables     []tableID
1009
        table      *table
1010
        components []*componentStorage
1011
        columnA    *column
1012
        columnB    *column
1013
        columnC    *column
1014
        columnD    *column
1015
        columnE    *column
1016
        columnF    *column
1017
        columnG    *column
1018
}
1019

1020
func newQuery7[A any, B any, C any, D any, E any, F any, G any](world *World, filter Filter, ids []ID, relations []RelationID) Query7[A, B, C, D, E, F, G] {
9✔
1021
        components := make([]*componentStorage, 7)
9✔
1022
        for i := range 7 {
72✔
1023
                components[i] = &world.storage.components[ids[i].id]
63✔
1024
        }
63✔
1025

1026
        return Query7[A, B, C, D, E, F, G]{
9✔
1027
                world:      world,
9✔
1028
                filter:     filter,
9✔
1029
                relations:  relations,
9✔
1030
                lock:       world.lock(),
9✔
1031
                components: components,
9✔
1032
                cursor: cursor{
9✔
1033
                        archetype: -1,
9✔
1034
                        table:     -1,
9✔
1035
                        index:     0,
9✔
1036
                        maxIndex:  -1,
9✔
1037
                },
9✔
1038
        }
9✔
1039
}
1040

1041
// Next advances the query's cursor to the next entity.
1042
func (q *Query7[A, B, C, D, E, F, G]) Next() bool {
162✔
1043
        q.world.checkQueryNext(&q.cursor)
162✔
1044
        if int64(q.cursor.index) < q.cursor.maxIndex {
304✔
1045
                q.cursor.index++
142✔
1046
                return true
142✔
1047
        }
142✔
1048
        return q.nextTableOrArchetype()
20✔
1049
}
1050

1051
// Entity returns the current entity.
1052
func (q *Query7[A, B, C, D, E, F, G]) Entity() Entity {
154✔
1053
        q.world.checkQueryGet(&q.cursor)
154✔
1054
        return q.table.GetEntity(q.cursor.index)
154✔
1055
}
154✔
1056

1057
// Get returns the queried components of the current entity.
1058
func (q *Query7[A, B, C, D, E, F, G]) Get() (*A, *B, *C, *D, *E, *F, *G) {
154✔
1059
        q.world.checkQueryGet(&q.cursor)
154✔
1060
        return (*A)(q.columnA.Get(q.cursor.index)),
154✔
1061
                (*B)(q.columnB.Get(q.cursor.index)),
154✔
1062
                (*C)(q.columnC.Get(q.cursor.index)),
154✔
1063
                (*D)(q.columnD.Get(q.cursor.index)),
154✔
1064
                (*E)(q.columnE.Get(q.cursor.index)),
154✔
1065
                (*F)(q.columnF.Get(q.cursor.index)),
154✔
1066
                (*G)(q.columnG.Get(q.cursor.index))
154✔
1067
}
154✔
1068

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

1074
// Close closes the Query and unlocks the world.
1075
//
1076
// Automatically called when iteration finishes.
1077
// Needs to be called only if breaking out of the query iteration or not iterating at all.
1078
func (q *Query7[A, B, C, D, E, F, G]) Close() {
9✔
1079
        q.cursor.archetype = -2
9✔
1080
        q.cursor.table = -2
9✔
1081
        q.tables = nil
9✔
1082
        q.table = nil
9✔
1083
        q.columnA = nil
9✔
1084
        q.columnB = nil
9✔
1085
        q.columnC = nil
9✔
1086
        q.columnD = nil
9✔
1087
        q.columnE = nil
9✔
1088
        q.columnF = nil
9✔
1089
        q.columnG = nil
9✔
1090
        q.world.unlock(q.lock)
9✔
1091
}
9✔
1092

1093
func (q *Query7[A, B, C, D, E, F, G]) nextTableOrArchetype() bool {
20✔
1094
        if q.cursor.archetype >= 0 && q.nextTable() {
21✔
1095
                return true
1✔
1096
        }
1✔
1097
        return q.nextArchetype()
19✔
1098
}
1099

1100
func (q *Query7[A, B, C, D, E, F, G]) nextArchetype() bool {
19✔
1101
        maxArchIndex := len(q.world.storage.archetypes) - 1
19✔
1102
        for q.cursor.archetype < maxArchIndex {
46✔
1103
                q.cursor.archetype++
27✔
1104
                archetype := &q.world.storage.archetypes[q.cursor.archetype]
27✔
1105
                if !q.filter.matches(&archetype.mask) {
44✔
1106
                        continue
17✔
1107
                }
1108

1109
                if !archetype.HasRelations() {
16✔
1110
                        table := &q.world.storage.tables[archetype.tables[0]]
7✔
1111
                        if table.Len() > 0 {
14✔
1112
                                q.setTable(0, table)
7✔
1113
                                return true
7✔
1114
                        }
7✔
1115
                        continue
×
1116
                }
1117

1118
                q.tables = archetype.GetTables(q.relations)
2✔
1119
                q.cursor.table = -1
2✔
1120
                if q.nextTable() {
4✔
1121
                        return true
2✔
1122
                }
2✔
1123
        }
1124
        q.Close()
9✔
1125
        return false
9✔
1126
}
1127

1128
func (q *Query7[A, B, C, D, E, F, G]) nextTable() bool {
12✔
1129
        maxTableIndex := len(q.tables) - 1
12✔
1130
        for q.cursor.table < maxTableIndex {
16✔
1131
                q.cursor.table++
4✔
1132
                table := &q.world.storage.tables[q.tables[q.cursor.table]]
4✔
1133
                if table.Len() == 0 {
5✔
1134
                        continue
1✔
1135
                }
1136
                if !table.Matches(q.relations) {
3✔
1137
                        continue
×
1138
                }
1139
                q.setTable(q.cursor.table, table)
3✔
1140
                return true
3✔
1141
        }
1142
        return false
9✔
1143
}
1144

1145
func (q *Query7[A, B, C, D, E, F, G]) setTable(index int, table *table) {
10✔
1146
        q.cursor.table = index
10✔
1147
        q.table = table
10✔
1148
        q.columnA = q.components[0].columns[q.table.id]
10✔
1149
        q.columnB = q.components[1].columns[q.table.id]
10✔
1150
        q.columnC = q.components[2].columns[q.table.id]
10✔
1151
        q.columnD = q.components[3].columns[q.table.id]
10✔
1152
        q.columnE = q.components[4].columns[q.table.id]
10✔
1153
        q.columnF = q.components[5].columns[q.table.id]
10✔
1154
        q.columnG = q.components[6].columns[q.table.id]
10✔
1155
        q.cursor.index = 0
10✔
1156
        q.cursor.maxIndex = int64(q.table.entities.Len() - 1)
10✔
1157
}
10✔
1158

1159
// Query8 is a query for 8 components.
1160
// Use a [NewFilter8] to create one.
1161
type Query8[A any, B any, C any, D any, E any, F any, G any, H any] struct {
1162
        world      *World
1163
        filter     Filter
1164
        relations  []RelationID
1165
        lock       uint8
1166
        cursor     cursor
1167
        tables     []tableID
1168
        table      *table
1169
        components []*componentStorage
1170
        columnA    *column
1171
        columnB    *column
1172
        columnC    *column
1173
        columnD    *column
1174
        columnE    *column
1175
        columnF    *column
1176
        columnG    *column
1177
        columnH    *column
1178
}
1179

1180
func newQuery8[A any, B any, C any, D any, E any, F any, G any, H any](world *World, filter Filter, ids []ID, relations []RelationID) Query8[A, B, C, D, E, F, G, H] {
9✔
1181
        components := make([]*componentStorage, 8)
9✔
1182
        for i := range 8 {
81✔
1183
                components[i] = &world.storage.components[ids[i].id]
72✔
1184
        }
72✔
1185

1186
        return Query8[A, B, C, D, E, F, G, H]{
9✔
1187
                world:      world,
9✔
1188
                filter:     filter,
9✔
1189
                relations:  relations,
9✔
1190
                lock:       world.lock(),
9✔
1191
                components: components,
9✔
1192
                cursor: cursor{
9✔
1193
                        archetype: -1,
9✔
1194
                        table:     -1,
9✔
1195
                        index:     0,
9✔
1196
                        maxIndex:  -1,
9✔
1197
                },
9✔
1198
        }
9✔
1199
}
1200

1201
// Next advances the query's cursor to the next entity.
1202
func (q *Query8[A, B, C, D, E, F, G, H]) Next() bool {
162✔
1203
        q.world.checkQueryNext(&q.cursor)
162✔
1204
        if int64(q.cursor.index) < q.cursor.maxIndex {
304✔
1205
                q.cursor.index++
142✔
1206
                return true
142✔
1207
        }
142✔
1208
        return q.nextTableOrArchetype()
20✔
1209
}
1210

1211
// Entity returns the current entity.
1212
func (q *Query8[A, B, C, D, E, F, G, H]) Entity() Entity {
154✔
1213
        q.world.checkQueryGet(&q.cursor)
154✔
1214
        return q.table.GetEntity(q.cursor.index)
154✔
1215
}
154✔
1216

1217
// Get returns the queried components of the current entity.
1218
func (q *Query8[A, B, C, D, E, F, G, H]) Get() (*A, *B, *C, *D, *E, *F, *G, *H) {
154✔
1219
        q.world.checkQueryGet(&q.cursor)
154✔
1220
        return (*A)(q.columnA.Get(q.cursor.index)),
154✔
1221
                (*B)(q.columnB.Get(q.cursor.index)),
154✔
1222
                (*C)(q.columnC.Get(q.cursor.index)),
154✔
1223
                (*D)(q.columnD.Get(q.cursor.index)),
154✔
1224
                (*E)(q.columnE.Get(q.cursor.index)),
154✔
1225
                (*F)(q.columnF.Get(q.cursor.index)),
154✔
1226
                (*G)(q.columnG.Get(q.cursor.index)),
154✔
1227
                (*H)(q.columnH.Get(q.cursor.index))
154✔
1228
}
154✔
1229

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

1235
// Close closes the Query and unlocks the world.
1236
//
1237
// Automatically called when iteration finishes.
1238
// Needs to be called only if breaking out of the query iteration or not iterating at all.
1239
func (q *Query8[A, B, C, D, E, F, G, H]) Close() {
9✔
1240
        q.cursor.archetype = -2
9✔
1241
        q.cursor.table = -2
9✔
1242
        q.tables = nil
9✔
1243
        q.table = nil
9✔
1244
        q.columnA = nil
9✔
1245
        q.columnB = nil
9✔
1246
        q.columnC = nil
9✔
1247
        q.columnD = nil
9✔
1248
        q.columnE = nil
9✔
1249
        q.columnF = nil
9✔
1250
        q.columnG = nil
9✔
1251
        q.columnH = nil
9✔
1252
        q.world.unlock(q.lock)
9✔
1253
}
9✔
1254

1255
func (q *Query8[A, B, C, D, E, F, G, H]) nextTableOrArchetype() bool {
20✔
1256
        if q.cursor.archetype >= 0 && q.nextTable() {
21✔
1257
                return true
1✔
1258
        }
1✔
1259
        return q.nextArchetype()
19✔
1260
}
1261

1262
func (q *Query8[A, B, C, D, E, F, G, H]) nextArchetype() bool {
19✔
1263
        maxArchIndex := len(q.world.storage.archetypes) - 1
19✔
1264
        for q.cursor.archetype < maxArchIndex {
46✔
1265
                q.cursor.archetype++
27✔
1266
                archetype := &q.world.storage.archetypes[q.cursor.archetype]
27✔
1267
                if !q.filter.matches(&archetype.mask) {
44✔
1268
                        continue
17✔
1269
                }
1270

1271
                if !archetype.HasRelations() {
16✔
1272
                        table := &q.world.storage.tables[archetype.tables[0]]
7✔
1273
                        if table.Len() > 0 {
14✔
1274
                                q.setTable(0, table)
7✔
1275
                                return true
7✔
1276
                        }
7✔
1277
                        continue
×
1278
                }
1279

1280
                q.tables = archetype.GetTables(q.relations)
2✔
1281
                q.cursor.table = -1
2✔
1282
                if q.nextTable() {
4✔
1283
                        return true
2✔
1284
                }
2✔
1285
        }
1286
        q.Close()
9✔
1287
        return false
9✔
1288
}
1289

1290
func (q *Query8[A, B, C, D, E, F, G, H]) nextTable() bool {
12✔
1291
        maxTableIndex := len(q.tables) - 1
12✔
1292
        for q.cursor.table < maxTableIndex {
16✔
1293
                q.cursor.table++
4✔
1294
                table := &q.world.storage.tables[q.tables[q.cursor.table]]
4✔
1295
                if table.Len() == 0 {
5✔
1296
                        continue
1✔
1297
                }
1298
                if !table.Matches(q.relations) {
3✔
1299
                        continue
×
1300
                }
1301
                q.setTable(q.cursor.table, table)
3✔
1302
                return true
3✔
1303
        }
1304
        return false
9✔
1305
}
1306

1307
func (q *Query8[A, B, C, D, E, F, G, H]) setTable(index int, table *table) {
10✔
1308
        q.cursor.table = index
10✔
1309
        q.table = table
10✔
1310
        q.columnA = q.components[0].columns[q.table.id]
10✔
1311
        q.columnB = q.components[1].columns[q.table.id]
10✔
1312
        q.columnC = q.components[2].columns[q.table.id]
10✔
1313
        q.columnD = q.components[3].columns[q.table.id]
10✔
1314
        q.columnE = q.components[4].columns[q.table.id]
10✔
1315
        q.columnF = q.components[5].columns[q.table.id]
10✔
1316
        q.columnG = q.components[6].columns[q.table.id]
10✔
1317
        q.columnH = q.components[7].columns[q.table.id]
10✔
1318
        q.cursor.index = 0
10✔
1319
        q.cursor.maxIndex = int64(q.table.entities.Len() - 1)
10✔
1320
}
10✔
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