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

mlange-42 / arche / 7547290353

16 Jan 2024 08:41PM CUT coverage: 100.0%. Remained the same
7547290353

push

github

web-flow
Listener component subscriptions (#335)

* Events are filtered by component IDs in addition to event types
* `Mask` has new methods `And`, `Or` and `Xor`

# Commits

* filter events by component IDs in addition to event types
* rename listener Dispatched to Dispatch
* tweak docstrings and examples, update changelog and readme
* add the world as argument to listener function, tweak docs and examples

5181 of 5181 relevant lines covered (100.0%)

61723.0 hits per line

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

100.0
/ecs/bitmask.go
1
package ecs
2

3
import (
4
        "math/bits"
5
)
6

7
// MaskTotalBits is the size of Mask in bits.
8
//
9
// It is the maximum number of component types that may exist in any [World].
10
const MaskTotalBits = 256
11
const wordSize = 64
12

13
// Mask is a 256 bit bitmask.
14
// It is also a [Filter] for including certain components.
15
//
16
// Use [All] to create a mask for a list of component IDs.
17
// A mask can be further specified using [Mask.Without] or [Mask.Exclusive].
18
type Mask struct {
19
        bits [4]uint64 // 4x 64 bits of the mask
20
}
21

22
// All creates a new Mask from a list of IDs.
23
// Matches all entities that have the respective components, and potentially further components.
24
//
25
// See also [Mask.Without] and [Mask.Exclusive]
26
//
27
// If any [ID] is greater than or equal to [MaskTotalBits], it will not be added to the mask.
28
func All(ids ...ID) Mask {
25,769✔
29
        var mask Mask
25,769✔
30
        for _, id := range ids {
51,934✔
31
                mask.Set(id, true)
26,165✔
32
        }
26,165✔
33
        return mask
25,769✔
34
}
35

36
// Matches the mask as filter against another mask.
37
func (b Mask) Matches(bits *Mask) bool {
77,064✔
38
        return bits.Contains(&b)
77,064✔
39
}
77,064✔
40

41
// Without creates a [MaskFilter] which filters for including the mask's components,
42
// and excludes the components given as arguments.
43
func (b Mask) Without(comps ...ID) MaskFilter {
7✔
44
        return MaskFilter{
7✔
45
                Include: b,
7✔
46
                Exclude: All(comps...),
7✔
47
        }
7✔
48
}
7✔
49

50
// Exclusive creates a [MaskFilter] which filters for exactly the mask's components.
51
// Matches only entities that have exactly the given components, and no other.
52
func (b Mask) Exclusive() MaskFilter {
6✔
53
        return MaskFilter{
6✔
54
                Include: b,
6✔
55
                Exclude: b.Not(),
6✔
56
        }
6✔
57
}
6✔
58

59
// Get reports whether the bit at the given index [ID] is set.
60
//
61
// Returns false for bit >= [MaskTotalBits].
62
func (b *Mask) Get(bit ID) bool {
252,248✔
63
        idx := bit.id / 64
252,248✔
64
        offset := bit.id - (64 * idx)
252,248✔
65
        mask := uint64(1 << offset)
252,248✔
66
        return b.bits[idx]&mask == mask
252,248✔
67
}
252,248✔
68

69
// Set sets the state of the bit at the given index.
70
//
71
// Has no effect for bit >= [MaskTotalBits].
72
func (b *Mask) Set(bit ID, value bool) {
157,110✔
73
        idx := bit.id / 64
157,110✔
74
        offset := bit.id - (64 * idx)
157,110✔
75
        if value {
288,062✔
76
                b.bits[idx] |= (1 << offset)
130,952✔
77
        } else {
157,110✔
78
                b.bits[idx] &= ^(1 << offset)
26,158✔
79
        }
26,158✔
80
}
81

82
// Not returns the inversion of this mask.
83
func (b *Mask) Not() Mask {
6✔
84
        return Mask{
6✔
85
                bits: [4]uint64{^b.bits[0], ^b.bits[1], ^b.bits[2], ^b.bits[3]},
6✔
86
        }
6✔
87
}
6✔
88

89
// IsZero returns whether no bits are set in the mask.
90
func (b *Mask) IsZero() bool {
164,734✔
91
        return b.bits[0] == 0 && b.bits[1] == 0 && b.bits[2] == 0 && b.bits[3] == 0
164,734✔
92
}
164,734✔
93

94
// Reset the mask setting all bits to false.
95
func (b *Mask) Reset() {
1✔
96
        b.bits = [4]uint64{0, 0, 0, 0}
1✔
97
}
1✔
98

99
// Contains reports if the other mask is a subset of this mask.
100
func (b *Mask) Contains(other *Mask) bool {
77,111✔
101
        return b.bits[0]&other.bits[0] == other.bits[0] &&
77,111✔
102
                b.bits[1]&other.bits[1] == other.bits[1] &&
77,111✔
103
                b.bits[2]&other.bits[2] == other.bits[2] &&
77,111✔
104
                b.bits[3]&other.bits[3] == other.bits[3]
77,111✔
105
}
77,111✔
106

107
// ContainsAny reports if any bit of the other mask is in this mask.
108
func (b *Mask) ContainsAny(other *Mask) bool {
29✔
109
        return b.bits[0]&other.bits[0] != 0 ||
29✔
110
                b.bits[1]&other.bits[1] != 0 ||
29✔
111
                b.bits[2]&other.bits[2] != 0 ||
29✔
112
                b.bits[3]&other.bits[3] != 0
29✔
113
}
29✔
114

115
// And returns the bitwise AND of two masks.
116
func (b *Mask) And(other *Mask) Mask {
1✔
117
        return Mask{
1✔
118
                bits: [4]uint64{
1✔
119
                        b.bits[0] & other.bits[0],
1✔
120
                        b.bits[1] & other.bits[1],
1✔
121
                        b.bits[2] & other.bits[2],
1✔
122
                        b.bits[3] & other.bits[3],
1✔
123
                },
1✔
124
        }
1✔
125
}
1✔
126

127
// Or returns the bitwise OR of two masks.
128
func (b *Mask) Or(other *Mask) Mask {
1✔
129
        return Mask{
1✔
130
                bits: [4]uint64{
1✔
131
                        b.bits[0] | other.bits[0],
1✔
132
                        b.bits[1] | other.bits[1],
1✔
133
                        b.bits[2] | other.bits[2],
1✔
134
                        b.bits[3] | other.bits[3],
1✔
135
                },
1✔
136
        }
1✔
137
}
1✔
138

139
// Xor returns the bitwise XOR of two masks.
140
func (b *Mask) Xor(other *Mask) Mask {
620✔
141
        return Mask{
620✔
142
                bits: [4]uint64{
620✔
143
                        b.bits[0] ^ other.bits[0],
620✔
144
                        b.bits[1] ^ other.bits[1],
620✔
145
                        b.bits[2] ^ other.bits[2],
620✔
146
                        b.bits[3] ^ other.bits[3],
620✔
147
                },
620✔
148
        }
620✔
149
}
620✔
150

151
// TotalBitsSet returns how many bits are set in this mask.
152
func (b *Mask) TotalBitsSet() int {
1,855✔
153
        return bits.OnesCount64(b.bits[0]) + bits.OnesCount64(b.bits[1]) + bits.OnesCount64(b.bits[2]) + bits.OnesCount64(b.bits[3])
1,855✔
154
}
1,855✔
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