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

mlange-42 / ark / 14191219880

01 Apr 2025 08:44AM CUT coverage: 99.832%. Remained the same
14191219880

push

github

web-flow
Add awesome-go badge (#229)

8298 of 8312 relevant lines covered (99.83%)

20284.26 hits per line

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

99.7
/ecs/query_gen.go
1
package ecs
2

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

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

12
// Query0 is a query for 0 components.
13
// Use a [Filter0] to create one.
14
//
15
// Queries are one-time use iterators and must be re-created each time before iterating.
16
//
17
// See [Query2] for a usage example.
18
type Query0 struct {
19
        world      *World
20
        filter     *filter
21
        table      *table
22
        cache      *cacheEntry
23
        relations  []RelationID
24
        tables     []tableID
25
        components []*componentStorage
26
        cursor     cursor
27
        lock       uint8
28
}
29

30
// Count counts the entities matching this query.
31
//
32
// Has some overhead of iterating through archetypes.
33
// However, this is still much faster than manual counting via iteration.
34
//
35
// Does not iterate or close the query.
36
func (q *Query0) Count() int {
9✔
37
        if q.cache == nil {
16✔
38
                return countQuery(&q.world.storage, q.filter, q.relations)
7✔
39
        }
7✔
40
        return countQueryCache(&q.world.storage, q.cache, q.relations)
2✔
41
}
42

43
// Close closes the Query and unlocks the world.
44
//
45
// Automatically called when iteration completes.
46
// Needs to be called only if breaking out of the query iteration or not iterating at all.
47
func (q *Query0) Close() {
12✔
48
        q.cursor.archetype = -2
12✔
49
        q.cursor.table = -2
12✔
50
        q.tables = nil
12✔
51
        q.table = nil
12✔
52
        q.cache = nil
12✔
53
        q.world.unlock(q.lock)
12✔
54
}
12✔
55

56
func (q *Query0) nextTableOrArchetype() bool {
28✔
57
        if q.cache != nil {
35✔
58
                return q.nextTable(q.cache.tables)
7✔
59
        }
7✔
60
        if q.cursor.archetype >= 0 && q.nextTable(q.tables) {
23✔
61
                return true
2✔
62
        }
2✔
63
        return q.nextArchetype()
19✔
64
}
65

66
func (q *Query0) nextArchetype() bool {
19✔
67
        maxArchIndex := int32(len(q.world.storage.archetypes) - 1)
19✔
68
        for q.cursor.archetype < maxArchIndex {
40✔
69
                q.cursor.archetype++
21✔
70
                archetype := &q.world.storage.archetypes[q.cursor.archetype]
21✔
71
                if !q.filter.matches(archetype.mask) {
25✔
72
                        continue
4✔
73
                }
74

75
                if !archetype.HasRelations() {
31✔
76
                        table := &q.world.storage.tables[archetype.tables[0]]
15✔
77
                        if table.Len() > 0 {
23✔
78
                                q.setTable(0, table)
8✔
79
                                return true
8✔
80
                        }
8✔
81
                        continue
7✔
82
                }
83

84
                q.tables = archetype.GetTables(q.relations)
1✔
85
                q.cursor.table = -1
1✔
86
                if q.nextTable(q.tables) {
2✔
87
                        return true
1✔
88
                }
1✔
89
        }
90
        q.Close()
9✔
91
        return false
9✔
92
}
93

94
func (q *Query0) nextTable(tables []tableID) bool {
19✔
95
        maxTableIndex := int32(len(tables) - 1)
19✔
96
        for q.cursor.table < maxTableIndex {
27✔
97
                q.cursor.table++
8✔
98
                table := &q.world.storage.tables[tables[q.cursor.table]]
8✔
99
                if table.Len() == 0 {
8✔
100
                        continue
×
101
                }
102
                if !table.Matches(q.relations) {
8✔
103
                        continue
×
104
                }
105
                q.setTable(q.cursor.table, table)
8✔
106
                return true
8✔
107
        }
108
        if q.cache != nil {
13✔
109
                q.Close()
2✔
110
        }
2✔
111
        return false
11✔
112
}
113

114
func (q *Query0) setTable(index int32, table *table) {
16✔
115
        q.cursor.table = index
16✔
116
        q.table = table
16✔
117
        q.cursor.index = 0
16✔
118
        q.cursor.maxIndex = int64(q.table.Len() - 1)
16✔
119
}
16✔
120

121
// Query1 is a query for 1 components.
122
// Use a [Filter1] to create one.
123
//
124
// Queries are one-time use iterators and must be re-created each time before iterating.
125
//
126
// See [Query2] for a usage example.
127
type Query1[A any] struct {
128
        world      *World
129
        filter     *filter
130
        table      *table
131
        cache      *cacheEntry
132
        columnA    *column
133
        relations  []RelationID
134
        tables     []tableID
135
        components []*componentStorage
136
        cursor     cursor
137
        lock       uint8
138
}
139

140
// GetRelation returns the entity relation target of the component at the given index.
141
func (q *Query1[A]) GetRelation(index int) Entity {
42✔
142
        return q.components[index].columns[q.table.id].target
42✔
143
}
42✔
144

145
// Count counts the entities matching this query.
146
//
147
// Has some overhead of iterating through archetypes.
148
// However, this is still much faster than manual counting via iteration.
149
//
150
// Does not iterate or close the query.
151
func (q *Query1[A]) Count() int {
11✔
152
        if q.cache == nil {
19✔
153
                return countQuery(&q.world.storage, q.filter, q.relations)
8✔
154
        }
8✔
155
        return countQueryCache(&q.world.storage, q.cache, q.relations)
3✔
156
}
157

158
// Close closes the Query and unlocks the world.
159
//
160
// Automatically called when iteration completes.
161
// Needs to be called only if breaking out of the query iteration or not iterating at all.
162
func (q *Query1[A]) Close() {
1,142✔
163
        q.cursor.archetype = -2
1,142✔
164
        q.cursor.table = -2
1,142✔
165
        q.tables = nil
1,142✔
166
        q.table = nil
1,142✔
167
        q.cache = nil
1,142✔
168
        q.columnA = nil
1,142✔
169
        q.world.unlock(q.lock)
1,142✔
170
}
1,142✔
171

172
func (q *Query1[A]) nextTableOrArchetype() bool {
2,290✔
173
        if q.cache != nil {
2,297✔
174
                return q.nextTable(q.cache.tables)
7✔
175
        }
7✔
176
        if q.cursor.archetype >= 0 && q.nextTable(q.tables) {
2,284✔
177
                return true
1✔
178
        }
1✔
179
        return q.nextArchetype()
2,282✔
180
}
181

182
func (q *Query1[A]) nextArchetype() bool {
2,282✔
183
        maxArchIndex := int32(len(q.world.storage.archetypes) - 1)
2,282✔
184
        for q.cursor.archetype < maxArchIndex {
4,898✔
185
                q.cursor.archetype++
2,616✔
186
                archetype := &q.world.storage.archetypes[q.cursor.archetype]
2,616✔
187
                if !q.filter.matches(archetype.mask) {
3,991✔
188
                        continue
1,375✔
189
                }
190

191
                if !archetype.HasRelations() {
2,450✔
192
                        table := &q.world.storage.tables[archetype.tables[0]]
1,210✔
193
                        if table.Len() > 0 {
2,335✔
194
                                q.setTable(0, table)
1,125✔
195
                                return true
1,125✔
196
                        }
1,125✔
197
                        continue
85✔
198
                }
199

200
                q.tables = archetype.GetTables(q.relations)
30✔
201
                q.cursor.table = -1
30✔
202
                if q.nextTable(q.tables) {
47✔
203
                        return true
17✔
204
                }
17✔
205
        }
206
        q.Close()
1,139✔
207
        return false
1,139✔
208
}
209

210
func (q *Query1[A]) nextTable(tables []tableID) bool {
1,180✔
211
        maxTableIndex := int32(len(tables) - 1)
1,180✔
212
        for q.cursor.table < maxTableIndex {
1,219✔
213
                q.cursor.table++
39✔
214
                table := &q.world.storage.tables[tables[q.cursor.table]]
39✔
215
                if table.Len() == 0 {
55✔
216
                        continue
16✔
217
                }
218
                if !table.Matches(q.relations) {
24✔
219
                        continue
1✔
220
                }
221
                q.setTable(q.cursor.table, table)
22✔
222
                return true
22✔
223
        }
224
        if q.cache != nil {
1,161✔
225
                q.Close()
3✔
226
        }
3✔
227
        return false
1,158✔
228
}
229

230
func (q *Query1[A]) setTable(index int32, table *table) {
1,147✔
231
        q.cursor.table = index
1,147✔
232
        q.table = table
1,147✔
233
        q.columnA = q.components[0].columns[q.table.id]
1,147✔
234
        q.cursor.index = 0
1,147✔
235
        q.cursor.maxIndex = int64(q.table.Len() - 1)
1,147✔
236
}
1,147✔
237

238
// Query2 is a query for 2 components.
239
// Use a [Filter2] to create one.
240
//
241
// Queries are one-time use iterators and must be re-created each time before iterating.
242
type Query2[A any, B any] struct {
243
        world      *World
244
        filter     *filter
245
        table      *table
246
        cache      *cacheEntry
247
        columnA    *column
248
        columnB    *column
249
        relations  []RelationID
250
        tables     []tableID
251
        components []*componentStorage
252
        cursor     cursor
253
        lock       uint8
254
}
255

256
// GetRelation returns the entity relation target of the component at the given index.
257
func (q *Query2[A, B]) GetRelation(index int) Entity {
40✔
258
        return q.components[index].columns[q.table.id].target
40✔
259
}
40✔
260

261
// Count counts the entities matching this query.
262
//
263
// Has some overhead of iterating through archetypes.
264
// However, this is still much faster than manual counting via iteration.
265
//
266
// Does not iterate or close the query.
267
func (q *Query2[A, B]) Count() int {
11✔
268
        if q.cache == nil {
19✔
269
                return countQuery(&q.world.storage, q.filter, q.relations)
8✔
270
        }
8✔
271
        return countQueryCache(&q.world.storage, q.cache, q.relations)
3✔
272
}
273

274
// Close closes the Query and unlocks the world.
275
//
276
// Automatically called when iteration completes.
277
// Needs to be called only if breaking out of the query iteration or not iterating at all.
278
func (q *Query2[A, B]) Close() {
16✔
279
        q.cursor.archetype = -2
16✔
280
        q.cursor.table = -2
16✔
281
        q.tables = nil
16✔
282
        q.table = nil
16✔
283
        q.cache = nil
16✔
284
        q.columnA = nil
16✔
285
        q.columnB = nil
16✔
286
        q.world.unlock(q.lock)
16✔
287
}
16✔
288

289
func (q *Query2[A, B]) nextTableOrArchetype() bool {
33✔
290
        if q.cache != nil {
40✔
291
                return q.nextTable(q.cache.tables)
7✔
292
        }
7✔
293
        if q.cursor.archetype >= 0 && q.nextTable(q.tables) {
27✔
294
                return true
1✔
295
        }
1✔
296
        return q.nextArchetype()
25✔
297
}
298

299
func (q *Query2[A, B]) nextArchetype() bool {
25✔
300
        maxArchIndex := int32(len(q.world.storage.archetypes) - 1)
25✔
301
        for q.cursor.archetype < maxArchIndex {
63✔
302
                q.cursor.archetype++
38✔
303
                archetype := &q.world.storage.archetypes[q.cursor.archetype]
38✔
304
                if !q.filter.matches(archetype.mask) {
63✔
305
                        continue
25✔
306
                }
307

308
                if !archetype.HasRelations() {
20✔
309
                        table := &q.world.storage.tables[archetype.tables[0]]
8✔
310
                        if table.Len() > 0 {
15✔
311
                                q.setTable(0, table)
7✔
312
                                return true
7✔
313
                        }
7✔
314
                        continue
1✔
315
                }
316

317
                q.tables = archetype.GetTables(q.relations)
4✔
318
                q.cursor.table = -1
4✔
319
                if q.nextTable(q.tables) {
8✔
320
                        return true
4✔
321
                }
4✔
322
        }
323
        q.Close()
13✔
324
        return false
13✔
325
}
326

327
func (q *Query2[A, B]) nextTable(tables []tableID) bool {
23✔
328
        maxTableIndex := int32(len(tables) - 1)
23✔
329
        for q.cursor.table < maxTableIndex {
36✔
330
                q.cursor.table++
13✔
331
                table := &q.world.storage.tables[tables[q.cursor.table]]
13✔
332
                if table.Len() == 0 {
16✔
333
                        continue
3✔
334
                }
335
                if !table.Matches(q.relations) {
11✔
336
                        continue
1✔
337
                }
338
                q.setTable(q.cursor.table, table)
9✔
339
                return true
9✔
340
        }
341
        if q.cache != nil {
17✔
342
                q.Close()
3✔
343
        }
3✔
344
        return false
14✔
345
}
346

347
func (q *Query2[A, B]) setTable(index int32, table *table) {
16✔
348
        q.cursor.table = index
16✔
349
        q.table = table
16✔
350
        q.columnA = q.components[0].columns[q.table.id]
16✔
351
        q.columnB = q.components[1].columns[q.table.id]
16✔
352
        q.cursor.index = 0
16✔
353
        q.cursor.maxIndex = int64(q.table.Len() - 1)
16✔
354
}
16✔
355

356
// Query3 is a query for 3 components.
357
// Use a [Filter3] to create one.
358
//
359
// Queries are one-time use iterators and must be re-created each time before iterating.
360
//
361
// See [Query2] for a usage example.
362
type Query3[A any, B any, C any] struct {
363
        world      *World
364
        filter     *filter
365
        table      *table
366
        cache      *cacheEntry
367
        columnA    *column
368
        columnB    *column
369
        columnC    *column
370
        relations  []RelationID
371
        tables     []tableID
372
        components []*componentStorage
373
        cursor     cursor
374
        lock       uint8
375
}
376

377
// GetRelation returns the entity relation target of the component at the given index.
378
func (q *Query3[A, B, C]) GetRelation(index int) Entity {
40✔
379
        return q.components[index].columns[q.table.id].target
40✔
380
}
40✔
381

382
// Count counts the entities matching this query.
383
//
384
// Has some overhead of iterating through archetypes.
385
// However, this is still much faster than manual counting via iteration.
386
//
387
// Does not iterate or close the query.
388
func (q *Query3[A, B, C]) Count() int {
14✔
389
        if q.cache == nil {
25✔
390
                return countQuery(&q.world.storage, q.filter, q.relations)
11✔
391
        }
11✔
392
        return countQueryCache(&q.world.storage, q.cache, q.relations)
3✔
393
}
394

395
// Close closes the Query and unlocks the world.
396
//
397
// Automatically called when iteration completes.
398
// Needs to be called only if breaking out of the query iteration or not iterating at all.
399
func (q *Query3[A, B, C]) Close() {
16✔
400
        q.cursor.archetype = -2
16✔
401
        q.cursor.table = -2
16✔
402
        q.tables = nil
16✔
403
        q.table = nil
16✔
404
        q.cache = nil
16✔
405
        q.columnA = nil
16✔
406
        q.columnB = nil
16✔
407
        q.columnC = nil
16✔
408
        q.world.unlock(q.lock)
16✔
409
}
16✔
410

411
func (q *Query3[A, B, C]) nextTableOrArchetype() bool {
41✔
412
        if q.cache != nil {
48✔
413
                return q.nextTable(q.cache.tables)
7✔
414
        }
7✔
415
        if q.cursor.archetype >= 0 && q.nextTable(q.tables) {
41✔
416
                return true
7✔
417
        }
7✔
418
        return q.nextArchetype()
27✔
419
}
420

421
func (q *Query3[A, B, C]) nextArchetype() bool {
27✔
422
        maxArchIndex := int32(len(q.world.storage.archetypes) - 1)
27✔
423
        for q.cursor.archetype < maxArchIndex {
67✔
424
                q.cursor.archetype++
40✔
425
                archetype := &q.world.storage.archetypes[q.cursor.archetype]
40✔
426
                if !q.filter.matches(archetype.mask) {
65✔
427
                        continue
25✔
428
                }
429

430
                if !archetype.HasRelations() {
22✔
431
                        table := &q.world.storage.tables[archetype.tables[0]]
8✔
432
                        if table.Len() > 0 {
15✔
433
                                q.setTable(0, table)
7✔
434
                                return true
7✔
435
                        }
7✔
436
                        continue
1✔
437
                }
438

439
                q.tables = archetype.GetTables(q.relations)
6✔
440
                q.cursor.table = -1
6✔
441
                if q.nextTable(q.tables) {
12✔
442
                        return true
6✔
443
                }
6✔
444
        }
445
        q.Close()
13✔
446
        return false
13✔
447
}
448

449
func (q *Query3[A, B, C]) nextTable(tables []tableID) bool {
33✔
450
        maxTableIndex := int32(len(tables) - 1)
33✔
451
        for q.cursor.table < maxTableIndex {
56✔
452
                q.cursor.table++
23✔
453
                table := &q.world.storage.tables[tables[q.cursor.table]]
23✔
454
                if table.Len() == 0 {
26✔
455
                        continue
3✔
456
                }
457
                if !table.Matches(q.relations) {
23✔
458
                        continue
3✔
459
                }
460
                q.setTable(q.cursor.table, table)
17✔
461
                return true
17✔
462
        }
463
        if q.cache != nil {
19✔
464
                q.Close()
3✔
465
        }
3✔
466
        return false
16✔
467
}
468

469
func (q *Query3[A, B, C]) setTable(index int32, table *table) {
24✔
470
        q.cursor.table = index
24✔
471
        q.table = table
24✔
472
        q.columnA = q.components[0].columns[q.table.id]
24✔
473
        q.columnB = q.components[1].columns[q.table.id]
24✔
474
        q.columnC = q.components[2].columns[q.table.id]
24✔
475
        q.cursor.index = 0
24✔
476
        q.cursor.maxIndex = int64(q.table.Len() - 1)
24✔
477
}
24✔
478

479
// Query4 is a query for 4 components.
480
// Use a [Filter4] to create one.
481
//
482
// Queries are one-time use iterators and must be re-created each time before iterating.
483
//
484
// See [Query2] for a usage example.
485
type Query4[A any, B any, C any, D any] struct {
486
        world      *World
487
        filter     *filter
488
        table      *table
489
        cache      *cacheEntry
490
        columnA    *column
491
        columnB    *column
492
        columnC    *column
493
        columnD    *column
494
        relations  []RelationID
495
        tables     []tableID
496
        components []*componentStorage
497
        cursor     cursor
498
        lock       uint8
499
}
500

501
// GetRelation returns the entity relation target of the component at the given index.
502
func (q *Query4[A, B, C, D]) GetRelation(index int) Entity {
40✔
503
        return q.components[index].columns[q.table.id].target
40✔
504
}
40✔
505

506
// Count counts the entities matching this query.
507
//
508
// Has some overhead of iterating through archetypes.
509
// However, this is still much faster than manual counting via iteration.
510
//
511
// Does not iterate or close the query.
512
func (q *Query4[A, B, C, D]) Count() int {
11✔
513
        if q.cache == nil {
19✔
514
                return countQuery(&q.world.storage, q.filter, q.relations)
8✔
515
        }
8✔
516
        return countQueryCache(&q.world.storage, q.cache, q.relations)
3✔
517
}
518

519
// Close closes the Query and unlocks the world.
520
//
521
// Automatically called when iteration completes.
522
// Needs to be called only if breaking out of the query iteration or not iterating at all.
523
func (q *Query4[A, B, C, D]) Close() {
13✔
524
        q.cursor.archetype = -2
13✔
525
        q.cursor.table = -2
13✔
526
        q.tables = nil
13✔
527
        q.table = nil
13✔
528
        q.cache = nil
13✔
529
        q.columnA = nil
13✔
530
        q.columnB = nil
13✔
531
        q.columnC = nil
13✔
532
        q.columnD = nil
13✔
533
        q.world.unlock(q.lock)
13✔
534
}
13✔
535

536
func (q *Query4[A, B, C, D]) nextTableOrArchetype() bool {
29✔
537
        if q.cache != nil {
36✔
538
                return q.nextTable(q.cache.tables)
7✔
539
        }
7✔
540
        if q.cursor.archetype >= 0 && q.nextTable(q.tables) {
23✔
541
                return true
1✔
542
        }
1✔
543
        return q.nextArchetype()
21✔
544
}
545

546
func (q *Query4[A, B, C, D]) nextArchetype() bool {
21✔
547
        maxArchIndex := int32(len(q.world.storage.archetypes) - 1)
21✔
548
        for q.cursor.archetype < maxArchIndex {
55✔
549
                q.cursor.archetype++
34✔
550
                archetype := &q.world.storage.archetypes[q.cursor.archetype]
34✔
551
                if !q.filter.matches(archetype.mask) {
56✔
552
                        continue
22✔
553
                }
554

555
                if !archetype.HasRelations() {
19✔
556
                        table := &q.world.storage.tables[archetype.tables[0]]
8✔
557
                        if table.Len() > 0 {
15✔
558
                                q.setTable(0, table)
7✔
559
                                return true
7✔
560
                        }
7✔
561
                        continue
1✔
562
                }
563

564
                q.tables = archetype.GetTables(q.relations)
3✔
565
                q.cursor.table = -1
3✔
566
                if q.nextTable(q.tables) {
6✔
567
                        return true
3✔
568
                }
3✔
569
        }
570
        q.Close()
10✔
571
        return false
10✔
572
}
573

574
func (q *Query4[A, B, C, D]) nextTable(tables []tableID) bool {
21✔
575
        maxTableIndex := int32(len(tables) - 1)
21✔
576
        for q.cursor.table < maxTableIndex {
33✔
577
                q.cursor.table++
12✔
578
                table := &q.world.storage.tables[tables[q.cursor.table]]
12✔
579
                if table.Len() == 0 {
15✔
580
                        continue
3✔
581
                }
582
                if !table.Matches(q.relations) {
10✔
583
                        continue
1✔
584
                }
585
                q.setTable(q.cursor.table, table)
8✔
586
                return true
8✔
587
        }
588
        if q.cache != nil {
16✔
589
                q.Close()
3✔
590
        }
3✔
591
        return false
13✔
592
}
593

594
func (q *Query4[A, B, C, D]) setTable(index int32, table *table) {
15✔
595
        q.cursor.table = index
15✔
596
        q.table = table
15✔
597
        q.columnA = q.components[0].columns[q.table.id]
15✔
598
        q.columnB = q.components[1].columns[q.table.id]
15✔
599
        q.columnC = q.components[2].columns[q.table.id]
15✔
600
        q.columnD = q.components[3].columns[q.table.id]
15✔
601
        q.cursor.index = 0
15✔
602
        q.cursor.maxIndex = int64(q.table.Len() - 1)
15✔
603
}
15✔
604

605
// Query5 is a query for 5 components.
606
// Use a [Filter5] to create one.
607
//
608
// Queries are one-time use iterators and must be re-created each time before iterating.
609
//
610
// See [Query2] for a usage example.
611
type Query5[A any, B any, C any, D any, E any] struct {
612
        world      *World
613
        filter     *filter
614
        table      *table
615
        cache      *cacheEntry
616
        columnA    *column
617
        columnB    *column
618
        columnC    *column
619
        columnD    *column
620
        columnE    *column
621
        relations  []RelationID
622
        tables     []tableID
623
        components []*componentStorage
624
        cursor     cursor
625
        lock       uint8
626
}
627

628
// GetRelation returns the entity relation target of the component at the given index.
629
func (q *Query5[A, B, C, D, E]) GetRelation(index int) Entity {
40✔
630
        return q.components[index].columns[q.table.id].target
40✔
631
}
40✔
632

633
// Count counts the entities matching this query.
634
//
635
// Has some overhead of iterating through archetypes.
636
// However, this is still much faster than manual counting via iteration.
637
//
638
// Does not iterate or close the query.
639
func (q *Query5[A, B, C, D, E]) Count() int {
11✔
640
        if q.cache == nil {
19✔
641
                return countQuery(&q.world.storage, q.filter, q.relations)
8✔
642
        }
8✔
643
        return countQueryCache(&q.world.storage, q.cache, q.relations)
3✔
644
}
645

646
// Close closes the Query and unlocks the world.
647
//
648
// Automatically called when iteration completes.
649
// Needs to be called only if breaking out of the query iteration or not iterating at all.
650
func (q *Query5[A, B, C, D, E]) Close() {
13✔
651
        q.cursor.archetype = -2
13✔
652
        q.cursor.table = -2
13✔
653
        q.tables = nil
13✔
654
        q.table = nil
13✔
655
        q.cache = nil
13✔
656
        q.columnA = nil
13✔
657
        q.columnB = nil
13✔
658
        q.columnC = nil
13✔
659
        q.columnD = nil
13✔
660
        q.columnE = nil
13✔
661
        q.world.unlock(q.lock)
13✔
662
}
13✔
663

664
func (q *Query5[A, B, C, D, E]) nextTableOrArchetype() bool {
29✔
665
        if q.cache != nil {
36✔
666
                return q.nextTable(q.cache.tables)
7✔
667
        }
7✔
668
        if q.cursor.archetype >= 0 && q.nextTable(q.tables) {
23✔
669
                return true
1✔
670
        }
1✔
671
        return q.nextArchetype()
21✔
672
}
673

674
func (q *Query5[A, B, C, D, E]) nextArchetype() bool {
21✔
675
        maxArchIndex := int32(len(q.world.storage.archetypes) - 1)
21✔
676
        for q.cursor.archetype < maxArchIndex {
55✔
677
                q.cursor.archetype++
34✔
678
                archetype := &q.world.storage.archetypes[q.cursor.archetype]
34✔
679
                if !q.filter.matches(archetype.mask) {
56✔
680
                        continue
22✔
681
                }
682

683
                if !archetype.HasRelations() {
19✔
684
                        table := &q.world.storage.tables[archetype.tables[0]]
8✔
685
                        if table.Len() > 0 {
15✔
686
                                q.setTable(0, table)
7✔
687
                                return true
7✔
688
                        }
7✔
689
                        continue
1✔
690
                }
691

692
                q.tables = archetype.GetTables(q.relations)
3✔
693
                q.cursor.table = -1
3✔
694
                if q.nextTable(q.tables) {
6✔
695
                        return true
3✔
696
                }
3✔
697
        }
698
        q.Close()
10✔
699
        return false
10✔
700
}
701

702
func (q *Query5[A, B, C, D, E]) nextTable(tables []tableID) bool {
21✔
703
        maxTableIndex := int32(len(tables) - 1)
21✔
704
        for q.cursor.table < maxTableIndex {
33✔
705
                q.cursor.table++
12✔
706
                table := &q.world.storage.tables[tables[q.cursor.table]]
12✔
707
                if table.Len() == 0 {
15✔
708
                        continue
3✔
709
                }
710
                if !table.Matches(q.relations) {
10✔
711
                        continue
1✔
712
                }
713
                q.setTable(q.cursor.table, table)
8✔
714
                return true
8✔
715
        }
716
        if q.cache != nil {
16✔
717
                q.Close()
3✔
718
        }
3✔
719
        return false
13✔
720
}
721

722
func (q *Query5[A, B, C, D, E]) setTable(index int32, table *table) {
15✔
723
        q.cursor.table = index
15✔
724
        q.table = table
15✔
725
        q.columnA = q.components[0].columns[q.table.id]
15✔
726
        q.columnB = q.components[1].columns[q.table.id]
15✔
727
        q.columnC = q.components[2].columns[q.table.id]
15✔
728
        q.columnD = q.components[3].columns[q.table.id]
15✔
729
        q.columnE = q.components[4].columns[q.table.id]
15✔
730
        q.cursor.index = 0
15✔
731
        q.cursor.maxIndex = int64(q.table.Len() - 1)
15✔
732
}
15✔
733

734
// Query6 is a query for 6 components.
735
// Use a [Filter6] to create one.
736
//
737
// Queries are one-time use iterators and must be re-created each time before iterating.
738
//
739
// See [Query2] for a usage example.
740
type Query6[A any, B any, C any, D any, E any, F any] struct {
741
        world      *World
742
        filter     *filter
743
        table      *table
744
        cache      *cacheEntry
745
        columnA    *column
746
        columnB    *column
747
        columnC    *column
748
        columnD    *column
749
        columnE    *column
750
        columnF    *column
751
        relations  []RelationID
752
        tables     []tableID
753
        components []*componentStorage
754
        cursor     cursor
755
        lock       uint8
756
}
757

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

763
// Count counts the entities matching this query.
764
//
765
// Has some overhead of iterating through archetypes.
766
// However, this is still much faster than manual counting via iteration.
767
//
768
// Does not iterate or close the query.
769
func (q *Query6[A, B, C, D, E, F]) Count() int {
11✔
770
        if q.cache == nil {
19✔
771
                return countQuery(&q.world.storage, q.filter, q.relations)
8✔
772
        }
8✔
773
        return countQueryCache(&q.world.storage, q.cache, q.relations)
3✔
774
}
775

776
// Close closes the Query and unlocks the world.
777
//
778
// Automatically called when iteration completes.
779
// Needs to be called only if breaking out of the query iteration or not iterating at all.
780
func (q *Query6[A, B, C, D, E, F]) Close() {
13✔
781
        q.cursor.archetype = -2
13✔
782
        q.cursor.table = -2
13✔
783
        q.tables = nil
13✔
784
        q.table = nil
13✔
785
        q.cache = nil
13✔
786
        q.columnA = nil
13✔
787
        q.columnB = nil
13✔
788
        q.columnC = nil
13✔
789
        q.columnD = nil
13✔
790
        q.columnE = nil
13✔
791
        q.columnF = nil
13✔
792
        q.world.unlock(q.lock)
13✔
793
}
13✔
794

795
func (q *Query6[A, B, C, D, E, F]) nextTableOrArchetype() bool {
29✔
796
        if q.cache != nil {
36✔
797
                return q.nextTable(q.cache.tables)
7✔
798
        }
7✔
799
        if q.cursor.archetype >= 0 && q.nextTable(q.tables) {
23✔
800
                return true
1✔
801
        }
1✔
802
        return q.nextArchetype()
21✔
803
}
804

805
func (q *Query6[A, B, C, D, E, F]) nextArchetype() bool {
21✔
806
        maxArchIndex := int32(len(q.world.storage.archetypes) - 1)
21✔
807
        for q.cursor.archetype < maxArchIndex {
55✔
808
                q.cursor.archetype++
34✔
809
                archetype := &q.world.storage.archetypes[q.cursor.archetype]
34✔
810
                if !q.filter.matches(archetype.mask) {
56✔
811
                        continue
22✔
812
                }
813

814
                if !archetype.HasRelations() {
19✔
815
                        table := &q.world.storage.tables[archetype.tables[0]]
8✔
816
                        if table.Len() > 0 {
15✔
817
                                q.setTable(0, table)
7✔
818
                                return true
7✔
819
                        }
7✔
820
                        continue
1✔
821
                }
822

823
                q.tables = archetype.GetTables(q.relations)
3✔
824
                q.cursor.table = -1
3✔
825
                if q.nextTable(q.tables) {
6✔
826
                        return true
3✔
827
                }
3✔
828
        }
829
        q.Close()
10✔
830
        return false
10✔
831
}
832

833
func (q *Query6[A, B, C, D, E, F]) nextTable(tables []tableID) bool {
21✔
834
        maxTableIndex := int32(len(tables) - 1)
21✔
835
        for q.cursor.table < maxTableIndex {
33✔
836
                q.cursor.table++
12✔
837
                table := &q.world.storage.tables[tables[q.cursor.table]]
12✔
838
                if table.Len() == 0 {
15✔
839
                        continue
3✔
840
                }
841
                if !table.Matches(q.relations) {
10✔
842
                        continue
1✔
843
                }
844
                q.setTable(q.cursor.table, table)
8✔
845
                return true
8✔
846
        }
847
        if q.cache != nil {
16✔
848
                q.Close()
3✔
849
        }
3✔
850
        return false
13✔
851
}
852

853
func (q *Query6[A, B, C, D, E, F]) setTable(index int32, table *table) {
15✔
854
        q.cursor.table = index
15✔
855
        q.table = table
15✔
856
        q.columnA = q.components[0].columns[q.table.id]
15✔
857
        q.columnB = q.components[1].columns[q.table.id]
15✔
858
        q.columnC = q.components[2].columns[q.table.id]
15✔
859
        q.columnD = q.components[3].columns[q.table.id]
15✔
860
        q.columnE = q.components[4].columns[q.table.id]
15✔
861
        q.columnF = q.components[5].columns[q.table.id]
15✔
862
        q.cursor.index = 0
15✔
863
        q.cursor.maxIndex = int64(q.table.Len() - 1)
15✔
864
}
15✔
865

866
// Query7 is a query for 7 components.
867
// Use a [Filter7] to create one.
868
//
869
// Queries are one-time use iterators and must be re-created each time before iterating.
870
//
871
// See [Query2] for a usage example.
872
type Query7[A any, B any, C any, D any, E any, F any, G any] struct {
873
        world      *World
874
        filter     *filter
875
        table      *table
876
        cache      *cacheEntry
877
        columnA    *column
878
        columnB    *column
879
        columnC    *column
880
        columnD    *column
881
        columnE    *column
882
        columnF    *column
883
        columnG    *column
884
        relations  []RelationID
885
        tables     []tableID
886
        components []*componentStorage
887
        cursor     cursor
888
        lock       uint8
889
}
890

891
// GetRelation returns the entity relation target of the component at the given index.
892
func (q *Query7[A, B, C, D, E, F, G]) GetRelation(index int) Entity {
40✔
893
        return q.components[index].columns[q.table.id].target
40✔
894
}
40✔
895

896
// Count counts the entities matching this query.
897
//
898
// Has some overhead of iterating through archetypes.
899
// However, this is still much faster than manual counting via iteration.
900
//
901
// Does not iterate or close the query.
902
func (q *Query7[A, B, C, D, E, F, G]) Count() int {
11✔
903
        if q.cache == nil {
19✔
904
                return countQuery(&q.world.storage, q.filter, q.relations)
8✔
905
        }
8✔
906
        return countQueryCache(&q.world.storage, q.cache, q.relations)
3✔
907
}
908

909
// Close closes the Query and unlocks the world.
910
//
911
// Automatically called when iteration completes.
912
// Needs to be called only if breaking out of the query iteration or not iterating at all.
913
func (q *Query7[A, B, C, D, E, F, G]) Close() {
13✔
914
        q.cursor.archetype = -2
13✔
915
        q.cursor.table = -2
13✔
916
        q.tables = nil
13✔
917
        q.table = nil
13✔
918
        q.cache = nil
13✔
919
        q.columnA = nil
13✔
920
        q.columnB = nil
13✔
921
        q.columnC = nil
13✔
922
        q.columnD = nil
13✔
923
        q.columnE = nil
13✔
924
        q.columnF = nil
13✔
925
        q.columnG = nil
13✔
926
        q.world.unlock(q.lock)
13✔
927
}
13✔
928

929
func (q *Query7[A, B, C, D, E, F, G]) nextTableOrArchetype() bool {
29✔
930
        if q.cache != nil {
36✔
931
                return q.nextTable(q.cache.tables)
7✔
932
        }
7✔
933
        if q.cursor.archetype >= 0 && q.nextTable(q.tables) {
23✔
934
                return true
1✔
935
        }
1✔
936
        return q.nextArchetype()
21✔
937
}
938

939
func (q *Query7[A, B, C, D, E, F, G]) nextArchetype() bool {
21✔
940
        maxArchIndex := int32(len(q.world.storage.archetypes) - 1)
21✔
941
        for q.cursor.archetype < maxArchIndex {
55✔
942
                q.cursor.archetype++
34✔
943
                archetype := &q.world.storage.archetypes[q.cursor.archetype]
34✔
944
                if !q.filter.matches(archetype.mask) {
56✔
945
                        continue
22✔
946
                }
947

948
                if !archetype.HasRelations() {
19✔
949
                        table := &q.world.storage.tables[archetype.tables[0]]
8✔
950
                        if table.Len() > 0 {
15✔
951
                                q.setTable(0, table)
7✔
952
                                return true
7✔
953
                        }
7✔
954
                        continue
1✔
955
                }
956

957
                q.tables = archetype.GetTables(q.relations)
3✔
958
                q.cursor.table = -1
3✔
959
                if q.nextTable(q.tables) {
6✔
960
                        return true
3✔
961
                }
3✔
962
        }
963
        q.Close()
10✔
964
        return false
10✔
965
}
966

967
func (q *Query7[A, B, C, D, E, F, G]) nextTable(tables []tableID) bool {
21✔
968
        maxTableIndex := int32(len(tables) - 1)
21✔
969
        for q.cursor.table < maxTableIndex {
33✔
970
                q.cursor.table++
12✔
971
                table := &q.world.storage.tables[tables[q.cursor.table]]
12✔
972
                if table.Len() == 0 {
15✔
973
                        continue
3✔
974
                }
975
                if !table.Matches(q.relations) {
10✔
976
                        continue
1✔
977
                }
978
                q.setTable(q.cursor.table, table)
8✔
979
                return true
8✔
980
        }
981
        if q.cache != nil {
16✔
982
                q.Close()
3✔
983
        }
3✔
984
        return false
13✔
985
}
986

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

1001
// Query8 is a query for 8 components.
1002
// Use a [Filter8] to create one.
1003
//
1004
// Queries are one-time use iterators and must be re-created each time before iterating.
1005
//
1006
// See [Query2] for a usage example.
1007
type Query8[A any, B any, C any, D any, E any, F any, G any, H any] struct {
1008
        world      *World
1009
        filter     *filter
1010
        table      *table
1011
        cache      *cacheEntry
1012
        columnA    *column
1013
        columnB    *column
1014
        columnC    *column
1015
        columnD    *column
1016
        columnE    *column
1017
        columnF    *column
1018
        columnG    *column
1019
        columnH    *column
1020
        relations  []RelationID
1021
        tables     []tableID
1022
        components []*componentStorage
1023
        cursor     cursor
1024
        lock       uint8
1025
}
1026

1027
// GetRelation returns the entity relation target of the component at the given index.
1028
func (q *Query8[A, B, C, D, E, F, G, H]) GetRelation(index int) Entity {
40✔
1029
        return q.components[index].columns[q.table.id].target
40✔
1030
}
40✔
1031

1032
// Count counts the entities matching this query.
1033
//
1034
// Has some overhead of iterating through archetypes.
1035
// However, this is still much faster than manual counting via iteration.
1036
//
1037
// Does not iterate or close the query.
1038
func (q *Query8[A, B, C, D, E, F, G, H]) Count() int {
11✔
1039
        if q.cache == nil {
19✔
1040
                return countQuery(&q.world.storage, q.filter, q.relations)
8✔
1041
        }
8✔
1042
        return countQueryCache(&q.world.storage, q.cache, q.relations)
3✔
1043
}
1044

1045
// Close closes the Query and unlocks the world.
1046
//
1047
// Automatically called when iteration completes.
1048
// Needs to be called only if breaking out of the query iteration or not iterating at all.
1049
func (q *Query8[A, B, C, D, E, F, G, H]) Close() {
21✔
1050
        q.cursor.archetype = -2
21✔
1051
        q.cursor.table = -2
21✔
1052
        q.tables = nil
21✔
1053
        q.table = nil
21✔
1054
        q.cache = nil
21✔
1055
        q.columnA = nil
21✔
1056
        q.columnB = nil
21✔
1057
        q.columnC = nil
21✔
1058
        q.columnD = nil
21✔
1059
        q.columnE = nil
21✔
1060
        q.columnF = nil
21✔
1061
        q.columnG = nil
21✔
1062
        q.columnH = nil
21✔
1063
        q.world.unlock(q.lock)
21✔
1064
}
21✔
1065

1066
func (q *Query8[A, B, C, D, E, F, G, H]) nextTableOrArchetype() bool {
45✔
1067
        if q.cache != nil {
52✔
1068
                return q.nextTable(q.cache.tables)
7✔
1069
        }
7✔
1070
        if q.cursor.archetype >= 0 && q.nextTable(q.tables) {
39✔
1071
                return true
1✔
1072
        }
1✔
1073
        return q.nextArchetype()
37✔
1074
}
1075

1076
func (q *Query8[A, B, C, D, E, F, G, H]) nextArchetype() bool {
37✔
1077
        maxArchIndex := int32(len(q.world.storage.archetypes) - 1)
37✔
1078
        for q.cursor.archetype < maxArchIndex {
87✔
1079
                q.cursor.archetype++
50✔
1080
                archetype := &q.world.storage.archetypes[q.cursor.archetype]
50✔
1081
                if !q.filter.matches(archetype.mask) {
80✔
1082
                        continue
30✔
1083
                }
1084

1085
                if !archetype.HasRelations() {
35✔
1086
                        table := &q.world.storage.tables[archetype.tables[0]]
16✔
1087
                        if table.Len() > 0 {
31✔
1088
                                q.setTable(0, table)
15✔
1089
                                return true
15✔
1090
                        }
15✔
1091
                        continue
1✔
1092
                }
1093

1094
                q.tables = archetype.GetTables(q.relations)
3✔
1095
                q.cursor.table = -1
3✔
1096
                if q.nextTable(q.tables) {
6✔
1097
                        return true
3✔
1098
                }
3✔
1099
        }
1100
        q.Close()
18✔
1101
        return false
18✔
1102
}
1103

1104
func (q *Query8[A, B, C, D, E, F, G, H]) nextTable(tables []tableID) bool {
29✔
1105
        maxTableIndex := int32(len(tables) - 1)
29✔
1106
        for q.cursor.table < maxTableIndex {
41✔
1107
                q.cursor.table++
12✔
1108
                table := &q.world.storage.tables[tables[q.cursor.table]]
12✔
1109
                if table.Len() == 0 {
15✔
1110
                        continue
3✔
1111
                }
1112
                if !table.Matches(q.relations) {
10✔
1113
                        continue
1✔
1114
                }
1115
                q.setTable(q.cursor.table, table)
8✔
1116
                return true
8✔
1117
        }
1118
        if q.cache != nil {
24✔
1119
                q.Close()
3✔
1120
        }
3✔
1121
        return false
21✔
1122
}
1123

1124
func (q *Query8[A, B, C, D, E, F, G, H]) setTable(index int32, table *table) {
23✔
1125
        q.cursor.table = index
23✔
1126
        q.table = table
23✔
1127
        q.columnA = q.components[0].columns[q.table.id]
23✔
1128
        q.columnB = q.components[1].columns[q.table.id]
23✔
1129
        q.columnC = q.components[2].columns[q.table.id]
23✔
1130
        q.columnD = q.components[3].columns[q.table.id]
23✔
1131
        q.columnE = q.components[4].columns[q.table.id]
23✔
1132
        q.columnF = q.components[5].columns[q.table.id]
23✔
1133
        q.columnG = q.components[6].columns[q.table.id]
23✔
1134
        q.columnH = q.components[7].columns[q.table.id]
23✔
1135
        q.cursor.index = 0
23✔
1136
        q.cursor.maxIndex = int64(q.table.Len() - 1)
23✔
1137
}
23✔
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