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

mlange-42 / ark / 13617144606

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

push

github

web-flow
Simplify component/resource registration functions (#100)

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

3893 of 3996 relevant lines covered (97.42%)

46242.85 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 {
246✔
18
        return registry{
246✔
19
                Components: map[reflect.Type]uint8{},
246✔
20
                Types:      make([]reflect.Type, MaskTotalBits),
246✔
21
                Used:       Mask{},
246✔
22
                IDs:        []uint8{},
246✔
23
        }
246✔
24
}
246✔
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) {
13✔
29
        if id, ok := r.Components[tp]; ok {
14✔
30
                return id, false
1✔
31
        }
1✔
32
        return r.registerComponent(tp, MaskTotalBits), true
12✔
33
}
34

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

40
// Count returns the total number of reserved IDs. It is the maximum ID plus 1.
41
func (r *registry) Count() int {
148✔
42
        return len(r.Components)
148✔
43
}
148✔
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 {
503✔
59
        val := len(r.Components)
503✔
60
        if val >= totalBits {
504✔
61
                panic(fmt.Sprintf("exceeded the maximum of %d component types or resource types", totalBits))
1✔
62
        }
63
        newID := uint8(val)
502✔
64
        id := id(val)
502✔
65
        r.Components[tp], r.Types[newID] = newID, tp
502✔
66
        r.Used.Set(id, true)
502✔
67
        r.IDs = append(r.IDs, newID)
502✔
68
        return newID
502✔
69
}
70

71
func (r *registry) unregisterLastComponent() {
1✔
72
        newID := uint8(len(r.Components) - 1)
1✔
73
        id := id8(newID)
1✔
74
        tp, _ := r.ComponentType(newID)
1✔
75
        delete(r.Components, tp)
1✔
76
        r.Types[newID] = nil
1✔
77
        r.Used.Set(id, false)
1✔
78
        r.IDs = r.IDs[:len(r.IDs)-1]
1✔
79
}
1✔
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 {
123✔
91
        return componentRegistry{
123✔
92
                registry:   newRegistry(),
123✔
93
                IsRelation: make([]bool, MaskTotalBits),
123✔
94
        }
123✔
95
}
123✔
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) {
1,973✔
100
        if id, ok := r.Components[tp]; ok {
3,459✔
101
                return id, false
1,486✔
102
        }
1,486✔
103
        return r.registerComponent(tp, MaskTotalBits), true
487✔
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 {
491✔
114
        newID := r.registry.registerComponent(tp, totalBits)
491✔
115
        if r.isRelation(tp) {
520✔
116
                r.IsRelation[newID] = true
29✔
117
        }
29✔
118
        return newID
490✔
119
}
120

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

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