• 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

83.54
/ecs/registry.go
1
package ecs
2

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

8
// componentRegistry keeps track of type IDs.
9
type registry struct {
10
        Components map[reflect.Type]uint8 // Mapping from types to IDs.
11
        Types      []reflect.Type         // Mapping from IDs to types.
12
        IDs        []uint8                // List of IDs.
13
        Used       Mask                   // Mapping from IDs tu used status.
14
}
15

16
// newComponentRegistry creates a new ComponentRegistry.
17
func newRegistry() registry {
492✔
18
        return registry{
492✔
19
                Components: map[reflect.Type]uint8{},
492✔
20
                Types:      make([]reflect.Type, MaskTotalBits),
492✔
21
                Used:       Mask{},
492✔
22
                IDs:        []uint8{},
492✔
23
        }
492✔
24
}
492✔
25

26
// ComponentID returns the ID for a component type, and registers it if not already registered.
27
// The second return value indicates if it is a newly created ID.
28
func (r *registry) ComponentID(tp reflect.Type) (uint8, bool) {
26✔
29
        if id, ok := r.Components[tp]; ok {
28✔
30
                return id, false
2✔
31
        }
2✔
32
        return r.registerComponent(tp, MaskTotalBits), true
24✔
33
}
34

35
// ComponentType returns the type of a component by ID.
36
func (r *registry) ComponentType(id uint8) (reflect.Type, bool) {
14✔
37
        return r.Types[id], r.Used.Get(ID{id: id})
14✔
38
}
14✔
39

40
// Count returns the total number of reserved IDs. It is the maximum ID plus 1.
41
func (r *registry) Count() int {
296✔
42
        return len(r.Components)
296✔
43
}
296✔
44

45
// Reset clears the registry.
46
func (r *registry) Reset() {
×
47
        for t := range r.Components {
×
48
                delete(r.Components, t)
×
49
        }
×
50
        for i := range r.Types {
×
51
                r.Types[i] = nil
×
52
        }
×
53
        r.Used.Reset()
×
54
        r.IDs = r.IDs[:0]
×
55
}
56

57
// registerComponent registers a components and assigns an ID for it.
58
func (r *registry) registerComponent(tp reflect.Type, totalBits int) uint8 {
1,006✔
59
        val := len(r.Components)
1,006✔
60
        if val >= totalBits {
1,008✔
61
                panic(fmt.Sprintf("exceeded the maximum of %d component types or resource types", totalBits))
2✔
62
        }
63
        newID := uint8(val)
1,004✔
64
        id := id(val)
1,004✔
65
        r.Components[tp], r.Types[newID] = newID, tp
1,004✔
66
        r.Used.Set(id, true)
1,004✔
67
        r.IDs = append(r.IDs, newID)
1,004✔
68
        return newID
1,004✔
69
}
70

71
func (r *registry) unregisterLastComponent() {
2✔
72
        newID := uint8(len(r.Components) - 1)
2✔
73
        id := id8(newID)
2✔
74
        tp, _ := r.ComponentType(newID)
2✔
75
        delete(r.Components, tp)
2✔
76
        r.Types[newID] = nil
2✔
77
        r.Used.Set(id, false)
2✔
78
        r.IDs = r.IDs[:len(r.IDs)-1]
2✔
79
}
2✔
80

81
// componentRegistry keeps track of component IDs.
82
// In addition to [registry], it determines whether types
83
// are relation components and/or contain (or are) pointers.
84
type componentRegistry struct {
85
        registry
86
        IsRelation []bool
87
}
88

89
// newComponentRegistry creates a new ComponentRegistry.
90
func newComponentRegistry() componentRegistry {
246✔
91
        return componentRegistry{
246✔
92
                registry:   newRegistry(),
246✔
93
                IsRelation: make([]bool, MaskTotalBits),
246✔
94
        }
246✔
95
}
246✔
96

97
// ComponentID returns the ID for a component type, and registers it if not already registered.
98
// The second return value indicates if it is a newly created ID.
99
func (r *componentRegistry) ComponentID(tp reflect.Type) (uint8, bool) {
3,946✔
100
        if id, ok := r.Components[tp]; ok {
6,918✔
101
                return id, false
2,972✔
102
        }
2,972✔
103
        return r.registerComponent(tp, MaskTotalBits), true
974✔
104
}
105

106
// Reset clears the registry.
107
func (r *componentRegistry) Reset() {
×
108
        r.registry.Reset()
×
109
        r.IsRelation = make([]bool, MaskTotalBits)
×
110
}
×
111

112
// registerComponent registers a components and assigns an ID for it.
113
func (r *componentRegistry) registerComponent(tp reflect.Type, totalBits int) uint8 {
982✔
114
        newID := r.registry.registerComponent(tp, totalBits)
982✔
115
        if r.isRelation(tp) {
1,040✔
116
                r.IsRelation[newID] = true
58✔
117
        }
58✔
118
        return newID
980✔
119
}
120

121
func (r *componentRegistry) unregisterLastComponent() {
2✔
122
        newID := uint8(len(r.Components) - 1)
2✔
123
        r.registry.unregisterLastComponent()
2✔
124
        r.IsRelation[newID] = false
2✔
125
}
2✔
126

127
// isRelation determines whether a type is a relation component.
128
func (r *componentRegistry) isRelation(tp reflect.Type) bool {
980✔
129
        if tp.Kind() != reflect.Struct || tp.NumField() == 0 {
982✔
130
                return false
2✔
131
        }
2✔
132
        field := tp.Field(0)
978✔
133
        return field.Type == relationType && field.Name == relationType.Name()
978✔
134
}
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