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

mlange-42 / ark / 13620061485

02 Mar 2025 10:46PM CUT coverage: 97.683% (-0.04%) from 97.72%
13620061485

Pull #104

github

web-flow
Merge bef2b62aa into a70f75dd5
Pull Request #104: Implement archetype graph

85 of 89 new or added lines in 2 files covered. (95.51%)

37 existing lines in 3 files now uncovered.

5186 of 5309 relevant lines covered (97.68%)

35910.42 hits per line

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

97.44
/ecs/archetype.go
1
package ecs
2

3
import (
4
        "math"
5
        "slices"
6
)
7

8
type archetypeID uint32
9

10
// maxTArchetypeID is used as unassigned archetype ID.
11
const maxTArchetypeID = math.MaxUint32
12

13
type archetype struct {
14
        id             archetypeID
15
        mask           Mask
16
        components     []ID
17
        componentsMap  []int16
18
        isRelation     []bool
19
        tables         []tableID
20
        freeTables     []tableID
21
        numRelations   uint8
22
        relationTables []map[entityID]*tableIDs
23
}
24

25
type tableIDs struct {
26
        tables []tableID
27
}
28

29
func newArchetype(id archetypeID, mask *Mask, components []ID, tables []tableID, reg *componentRegistry) archetype {
557✔
30
        componentsMap := make([]int16, MaskTotalBits)
557✔
31
        for i := range MaskTotalBits {
143,149✔
32
                componentsMap[i] = -1
142,592✔
33
        }
142,592✔
34
        for i, id := range components {
1,931✔
35
                componentsMap[id.id] = int16(i)
1,374✔
36
        }
1,374✔
37

38
        numRelations := uint8(0)
557✔
39
        isRelation := make([]bool, len(components))
557✔
40
        relationTables := make([]map[entityID]*tableIDs, len(components))
557✔
41
        for i, id := range components {
1,931✔
42
                if reg.IsRelation[id.id] {
1,414✔
43
                        isRelation[i] = true
40✔
44
                        relationTables[i] = map[entityID]*tableIDs{}
40✔
45
                        numRelations++
40✔
46
                }
40✔
47
        }
48
        return archetype{
557✔
49
                id:             id,
557✔
50
                mask:           *mask,
557✔
51
                components:     components,
557✔
52
                componentsMap:  componentsMap,
557✔
53
                isRelation:     isRelation,
557✔
54
                tables:         tables,
557✔
55
                numRelations:   numRelations,
557✔
56
                relationTables: relationTables,
557✔
57
        }
557✔
58
}
59

60
func (a *archetype) HasRelations() bool {
512,707✔
61
        return a.numRelations > 0
512,707✔
62
}
512,707✔
63

64
func (a *archetype) GetTable(storage *storage, relations []RelationID) (*table, bool) {
510,746✔
65
        if len(a.tables) == 0 {
511,124✔
66
                return nil, false
378✔
67
        }
378✔
68
        if !a.HasRelations() {
1,020,310✔
69
                return &storage.tables[a.tables[0]], true
509,942✔
70
        }
509,942✔
71

72
        index := a.componentsMap[relations[0].component.id]
426✔
73
        tables, ok := a.relationTables[index][relations[0].target.id]
426✔
74
        if !ok {
481✔
75
                return nil, false
55✔
76
        }
55✔
77
        for _, t := range tables.tables {
761✔
78
                table := &storage.tables[t]
390✔
79
                if table.MatchesExact(relations) {
759✔
80
                        return table, true
369✔
81
                }
369✔
82
        }
83
        return nil, false
2✔
84
}
85

86
func (a *archetype) GetTables(relations []RelationID) []tableID {
54✔
87
        if !a.HasRelations() {
54✔
UNCOV
88
                return a.tables
×
UNCOV
89
        }
×
90
        if len(relations) == 0 {
68✔
91
                return a.tables
14✔
92
        }
14✔
93
        index := a.componentsMap[relations[0].component.id]
40✔
94
        if tables, ok := a.relationTables[index][relations[0].target.id]; ok {
80✔
95
                return tables.tables
40✔
96
        }
40✔
UNCOV
97
        return nil
×
98
}
99

100
func (a *archetype) GetFreeTable() (tableID, bool) {
435✔
101
        if len(a.freeTables) == 0 {
869✔
102
                return 0, false
434✔
103
        }
434✔
104
        last := len(a.freeTables) - 1
1✔
105
        table := a.freeTables[last]
1✔
106

1✔
107
        a.freeTables = a.freeTables[:last]
1✔
108

1✔
109
        return table, true
1✔
110
}
111

112
func (a *archetype) FreeTable(table tableID) {
4✔
113
        index := slices.Index(a.tables, table)
4✔
114
        last := len(a.tables) - 1
4✔
115

4✔
116
        a.tables[index], a.tables[last] = a.tables[last], a.tables[index]
4✔
117
        a.tables = a.tables[:last]
4✔
118

4✔
119
        a.freeTables = append(a.freeTables, table)
4✔
120
}
4✔
121

122
func (a *archetype) AddTable(table *table) {
435✔
123
        a.tables = append(a.tables, table.id)
435✔
124
        if !a.HasRelations() {
776✔
125
                return
341✔
126
        }
341✔
127

128
        for i := range table.ids {
447✔
129
                column := &table.columns[i]
353✔
130
                if !column.isRelation {
604✔
131
                        continue
251✔
132
                }
133
                target := column.target
102✔
134
                relations := a.relationTables[i]
102✔
135

102✔
136
                if tables, ok := relations[target.id]; ok {
107✔
137
                        tables.tables = append(tables.tables, table.id)
5✔
138
                } else {
102✔
139
                        relations[target.id] = &tableIDs{tables: []tableID{table.id}}
97✔
140
                }
97✔
141
        }
142
}
143

144
func (a *archetype) RemoveTarget(entity Entity) {
2✔
145
        for i := range a.relationTables {
6✔
146
                if !a.isRelation[i] {
6✔
147
                        continue
2✔
148
                }
149
                delete(a.relationTables[i], entity.id)
2✔
150
        }
151
}
152

153
func (a *archetype) Reset(storage *storage) {
4✔
154
        if !a.HasRelations() {
7✔
155
                storage.tables[a.tables[0]].Reset()
3✔
156
                return
3✔
157
        }
3✔
158

159
        for _, tab := range a.tables {
3✔
160
                table := &storage.tables[tab]
2✔
161
                table.Reset()
2✔
162
        }
2✔
163

164
        for i := len(a.tables) - 1; i >= 0; i-- {
3✔
165
                a.FreeTable(a.tables[i])
2✔
166
        }
2✔
167

168
        for _, m := range a.relationTables {
3✔
169
                for key := range m {
4✔
170
                        delete(m, key)
2✔
171
                }
2✔
172
        }
173
}
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