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

mlange-42 / ark / 13618572525

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

Pull #91

github

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

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

14 existing lines in 1 file now uncovered.

4389 of 4528 relevant lines covered (96.93%)

40787.75 hits per line

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

94.83
/ecs/table.go
1
package ecs
2

3
import (
4
        "fmt"
5
        "math"
6
        "unsafe"
7
)
8

9
type tableID uint32
10

11
// maxTableID is used as table ID for unused entities.
12
const maxTableID = math.MaxUint32
13

14
type table struct {
15
        id          tableID
16
        archetype   archetypeID
17
        components  []int16
18
        entities    column
19
        ids         []ID
20
        columns     []column
21
        relationIDs []RelationID
22

23
        zeroValue   []byte
24
        zeroPointer unsafe.Pointer
25
}
26

27
func newTable(id tableID, archetype archetypeID, capacity uint32, reg *componentRegistry,
28
        ids []ID, componentsMap []int16, isRelation []bool, targets []Entity, relationIDs []RelationID) table {
386✔
29

386✔
30
        entities := newColumn(entityType, false, Entity{}, capacity)
386✔
31
        columns := make([]column, len(ids))
386✔
32

386✔
33
        var maxSize uintptr = entitySize
386✔
34
        for i, id := range ids {
1,256✔
35
                columns[i] = newColumn(reg.Types[id.id], isRelation[i], targets[i], capacity)
870✔
36
                if columns[i].itemSize > maxSize {
1,105✔
37
                        maxSize = columns[i].itemSize
235✔
38
                }
235✔
39
        }
40
        var zeroValue []byte
386✔
41
        var zeroPointer unsafe.Pointer
386✔
42
        if maxSize > 0 {
772✔
43
                zeroValue = make([]byte, maxSize)
386✔
44
                zeroPointer = unsafe.Pointer(&zeroValue[0])
386✔
45
        }
386✔
46

47
        return table{
386✔
48
                id:          id,
386✔
49
                archetype:   archetype,
386✔
50
                components:  componentsMap,
386✔
51
                entities:    entities,
386✔
52
                ids:         ids,
386✔
53
                columns:     columns,
386✔
54
                zeroValue:   zeroValue,
386✔
55
                zeroPointer: zeroPointer,
386✔
56
                relationIDs: relationIDs,
386✔
57
        }
386✔
58
}
59

60
func (t *table) recycle(targets []Entity, relationIDs []RelationID) {
1✔
61
        t.relationIDs = relationIDs
1✔
62
        for i := range t.columns {
3✔
63
                t.columns[i].target = targets[i]
2✔
64
        }
2✔
65
}
66

67
func (t *table) Add(entity Entity) uint32 {
493,656✔
68
        _, idx := t.entities.Add(unsafe.Pointer(&entity))
493,656✔
69

493,656✔
70
        for i := range t.columns {
990,936✔
71
                t.columns[i].Alloc(1)
497,280✔
72
        }
497,280✔
73
        return idx
493,656✔
74
}
75

76
func (t *table) Get(component ID, index uintptr) unsafe.Pointer {
895✔
77
        return t.columns[t.components[component.id]].Get(index)
895✔
78
}
895✔
79

80
func (t *table) Has(component ID) bool {
58✔
81
        return t.components[component.id] >= 0
58✔
82
}
58✔
83

84
func (t *table) GetEntity(index uintptr) Entity {
2,490,412✔
85
        return *(*Entity)(t.entities.Get(index))
2,490,412✔
86
}
2,490,412✔
87

88
func (t *table) GetRelation(component ID) Entity {
143✔
89
        return t.columns[t.components[component.id]].target
143✔
90
}
143✔
91

92
func (t *table) GetColumn(component ID) *column {
1,062✔
93
        return &t.columns[t.components[component.id]]
1,062✔
94
}
1,062✔
95

96
func (t *table) GetEntities(component ID) *column {
×
97
        return &t.entities
×
98
}
×
99

100
func (t *table) Set(component ID, index uint32, comp unsafe.Pointer) {
498,777✔
101
        t.columns[t.components[component.id]].Set(index, comp)
498,777✔
102
}
498,777✔
103

104
func (t *table) SetEntity(index uint32, entity Entity) {
768✔
105
        t.entities.Set(index, unsafe.Pointer(&entity))
768✔
106
}
768✔
107

108
// Alloc allocates memory for the given number of entities.
109
func (t *table) Alloc(n uint32) {
48✔
110
        t.entities.Alloc(n)
48✔
111
        for i := range t.columns {
168✔
112
                t.columns[i].Alloc(n)
120✔
113
        }
120✔
114
}
115

116
func (t *table) Remove(index uint32) bool {
492,403✔
117
        swapped := t.entities.Remove(index, nil)
492,403✔
118
        for i := range t.columns {
986,320✔
119
                t.columns[i].Remove(index, t.zeroPointer)
493,917✔
120
        }
493,917✔
121
        return swapped
492,403✔
122
}
123

124
func (t *table) Reset() {
71✔
125
        t.entities.Reset(nil)
71✔
126
        for c := range t.columns {
322✔
127
                t.columns[c].Reset(t.zeroPointer)
251✔
128
        }
251✔
129
}
130

131
func (t *table) AddAll(other *table) {
2✔
132
        t.entities.AddAll(&other.entities)
2✔
133
        for c := range t.columns {
6✔
134
                t.columns[c].AddAll(&other.columns[c])
4✔
135
        }
4✔
136
}
137

138
func (t *table) AddAllEntities(other *table, extendColumns bool) {
64✔
139
        t.entities.AddAll(&other.entities)
64✔
140
        if extendColumns {
128✔
141
                for c := range t.columns {
304✔
142
                        t.columns[c].Alloc(uint32(other.Len()))
240✔
143
                }
240✔
144
        }
145
}
146

147
func (t *table) MatchesExact(relations []RelationID) bool {
390✔
148
        if len(relations) != len(t.relationIDs) {
390✔
149
                panic("relation targets must be fully specified")
×
150
        }
151
        for _, rel := range relations {
838✔
152
                index := t.components[rel.component.id]
448✔
153
                if !t.columns[index].isRelation {
448✔
154
                        panic(fmt.Sprintf("component %d is not a relation component", rel.component.id))
×
155
                }
156
                //if rel.target == wildcard {
157
                //        panic("relation targets must be fully specified, no wildcard allowed")
158
                //}
159
                if rel.target != t.columns[index].target {
469✔
160
                        return false
21✔
161
                }
21✔
162
        }
163
        return true
369✔
164
}
165

166
func (t *table) Matches(relations []RelationID) bool {
43✔
167
        if len(relations) == 0 {
71✔
168
                return true
28✔
169
        }
28✔
170
        for _, rel := range relations {
32✔
171
                if rel.target == wildcard {
17✔
172
                        continue
×
173
                }
174
                if rel.target != t.columns[t.components[rel.component.id]].target {
18✔
175
                        return false
1✔
176
                }
1✔
177
        }
178
        return true
14✔
179
}
180

181
func (t *table) Len() int {
1,737✔
182
        return t.entities.Len()
1,737✔
183
}
1,737✔
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