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

mlange-42 / ark / 13617072942

02 Mar 2025 04:02PM CUT coverage: 97.422% (-0.002%) from 97.424%
13617072942

Pull #100

github

web-flow
Merge d87f29472 into 8f54a3a49
Pull Request #100: Simplify component/resource registration functions

2 of 2 new or added lines in 1 file covered. (100.0%)

3893 of 3996 relevant lines covered (97.42%)

93522.98 hits per line

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

91.24
/ecs/world_internal.go
1
package ecs
2

3
import (
4
        "reflect"
5
        "unsafe"
6
)
7

8
func (w *World) newEntityWith(ids []ID, comps []unsafe.Pointer, relations []RelationID) Entity {
1,004,536✔
9
        w.checkLocked()
1,004,536✔
10

1,004,536✔
11
        mask := NewMask(ids...)
1,004,536✔
12
        newTable := w.storage.findOrCreateTable(&w.storage.tables[0], &mask, relations)
1,004,536✔
13
        entity, idx := w.storage.createEntity(newTable.id)
1,004,536✔
14

1,004,536✔
15
        if comps != nil {
2,008,924✔
16
                if len(ids) != len(comps) {
1,004,388✔
17
                        panic("lengths of IDs and components to add do not match")
×
18
                }
19
                for i, id := range ids {
2,014,684✔
20
                        newTable.Set(id, idx, comps[i])
1,010,296✔
21
                }
1,010,296✔
22
        }
23
        w.storage.registerTargets(relations)
1,004,536✔
24
        return entity
1,004,536✔
25
}
26

27
func (w *World) newEntitiesWith(count int, ids []ID, comps []unsafe.Pointer, relations []RelationID) {
16✔
28
        w.checkLocked()
16✔
29

16✔
30
        mask := NewMask(ids...)
16✔
31
        newTable := w.storage.findOrCreateTable(&w.storage.tables[0], &mask, relations)
16✔
32

16✔
33
        startIdx := newTable.Len()
16✔
34
        w.storage.createEntities(newTable, count)
16✔
35

16✔
36
        if comps != nil {
32✔
37
                if len(ids) != len(comps) {
16✔
38
                        panic("lengths of IDs and components to add do not match")
×
39
                }
40
                for i := range count {
400✔
41
                        for j, id := range ids {
2,112✔
42
                                newTable.Set(id, uint32(startIdx+i), comps[j])
1,728✔
43
                        }
1,728✔
44
                }
45
        }
46
        w.storage.registerTargets(relations)
16✔
47
}
48

49
func (w *World) newEntities(count int, ids []ID, relations []RelationID) (tableID, int) {
16✔
50
        w.checkLocked()
16✔
51

16✔
52
        mask := NewMask(ids...)
16✔
53
        newTable := w.storage.findOrCreateTable(&w.storage.tables[0], &mask, relations)
16✔
54

16✔
55
        startIdx := newTable.Len()
16✔
56
        w.storage.createEntities(newTable, count)
16✔
57
        w.storage.registerTargets(relations)
16✔
58

16✔
59
        return newTable.id, startIdx
16✔
60
}
16✔
61

62
func (w *World) exchange(entity Entity, add []ID, rem []ID, addComps []unsafe.Pointer, relations []RelationID) {
1,292✔
63
        w.checkLocked()
1,292✔
64

1,292✔
65
        if !w.Alive(entity) {
1,292✔
66
                panic("can't exchange components on a dead entity")
×
67
        }
68
        if len(add) == 0 && len(rem) == 0 {
1,292✔
69
                return
×
70
        }
×
71

72
        index := &w.storage.entities[entity.id]
1,292✔
73
        oldTable := &w.storage.tables[index.table]
1,292✔
74
        oldArchetype := &w.storage.archetypes[oldTable.archetype]
1,292✔
75

1,292✔
76
        mask := oldArchetype.mask
1,292✔
77
        w.storage.getExchangeMask(&mask, add, rem)
1,292✔
78

1,292✔
79
        oldIDs := oldArchetype.components
1,292✔
80

1,292✔
81
        newTable := w.storage.findOrCreateTable(oldTable, &mask, relations)
1,292✔
82
        newIndex := newTable.Add(entity)
1,292✔
83

1,292✔
84
        for _, id := range oldIDs {
4,696✔
85
                if mask.Get(id) {
4,828✔
86
                        comp := oldTable.Get(id, uintptr(index.row))
1,424✔
87
                        newTable.Set(id, newIndex, comp)
1,424✔
88
                }
1,424✔
89
        }
90
        if addComps != nil {
1,946✔
91
                if len(add) != len(addComps) {
654✔
92
                        panic("lengths of IDs and components to add do not match")
×
93
                }
94
                for i, id := range add {
2,092✔
95
                        newTable.Set(id, newIndex, addComps[i])
1,438✔
96
                }
1,438✔
97
        }
98

99
        swapped := oldTable.Remove(index.row)
1,292✔
100

1,292✔
101
        if swapped {
1,488✔
102
                swapEntity := oldTable.GetEntity(uintptr(index.row))
196✔
103
                w.storage.entities[swapEntity.id].row = index.row
196✔
104
        }
196✔
105
        w.storage.entities[entity.id] = entityIndex{table: newTable.id, row: newIndex}
1,292✔
106

1,292✔
107
        w.storage.registerTargets(relations)
1,292✔
108
}
109

110
// setRelations sets the target entities for an entity relations.
111
func (w *World) setRelations(entity Entity, relations []RelationID) {
86✔
112
        w.checkLocked()
86✔
113

86✔
114
        if !w.storage.entityPool.Alive(entity) {
86✔
115
                panic("can't set relation for a dead entity")
×
116
        }
117

118
        index := &w.storage.entities[entity.id]
86✔
119
        oldTable := &w.storage.tables[index.table]
86✔
120

86✔
121
        newRelations, changed := w.storage.getExchangeTargets(oldTable, relations)
86✔
122
        if !changed {
86✔
123
                return
×
124
        }
×
125

126
        oldArch := &w.storage.archetypes[oldTable.archetype]
86✔
127
        newTable, ok := oldArch.GetTable(&w.storage, newRelations)
86✔
128
        if !ok {
110✔
129
                newTable = w.storage.createTable(oldArch, newRelations)
24✔
130
        }
24✔
131
        newIndex := newTable.Add(entity)
86✔
132

86✔
133
        for _, id := range oldArch.components {
298✔
134
                comp := oldTable.Get(id, uintptr(index.row))
212✔
135
                newTable.Set(id, newIndex, comp)
212✔
136
        }
212✔
137

138
        swapped := oldTable.Remove(index.row)
86✔
139

86✔
140
        if swapped {
118✔
141
                swapEntity := oldTable.GetEntity(uintptr(index.row))
32✔
142
                w.storage.entities[swapEntity.id].row = index.row
32✔
143
        }
32✔
144
        w.storage.entities[entity.id] = entityIndex{table: newTable.id, row: newIndex}
86✔
145

86✔
146
        w.storage.registerTargets(relations)
86✔
147
}
148

149
func (w *World) componentID(tp reflect.Type) ID {
3,942✔
150
        id, newID := w.storage.registry.ComponentID(tp)
3,942✔
151
        if newID {
4,914✔
152
                if w.IsLocked() {
972✔
153
                        w.storage.registry.unregisterLastComponent()
×
154
                        panic("attempt to register a new component in a locked world")
×
155
                }
156
                w.storage.AddComponent(id)
972✔
157
        }
158
        return ID{id: id}
3,942✔
159
}
160

161
func (w *World) resourceID(tp reflect.Type) ResID {
18✔
162
        id, _ := w.resources.registry.ComponentID(tp)
18✔
163
        return ResID{id: id}
18✔
164
}
18✔
165

166
// lock the world and get the lock bit for later unlocking.
167
func (w *World) lock() uint8 {
2,210✔
168
        return w.locks.Lock()
2,210✔
169
}
2,210✔
170

171
// unlock unlocks the given lock bit.
172
func (w *World) unlock(l uint8) {
2,210✔
173
        w.locks.Unlock(l)
2,210✔
174
}
2,210✔
175

176
// checkLocked checks if the world is locked, and panics if so.
177
func (w *World) checkLocked() {
2,007,601✔
178
        if w.IsLocked() {
2,007,601✔
179
                panic("attempt to modify a locked world")
×
180
        }
181
}
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