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

mlange-42 / arche / 12455637666

22 Dec 2024 03:48PM CUT coverage: 100.0%. Remained the same
12455637666

Pull #442

github

web-flow
Merge dcf4cea1c into 30c1f4bc4
Pull Request #442: Update CHANGELOG for release v0.14.0

6411 of 6411 relevant lines covered (100.0%)

114030.79 hits per line

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

100.0
/ecs/bitmask.go
1
//go:build !tiny
2

3
package ecs
4

5
import (
6
        "math/bits"
7
)
8

9
// MaskTotalBits is the size of a [Mask] in bits.
10
// It is the maximum number of component types that may exist in any [World].
11
//
12
// Use build tag `tiny` to reduce all masks to 64 bits.
13
const MaskTotalBits = 256
14

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

26
// All creates a new Mask from a list of IDs.
27
// Matches all entities that have the respective components, and potentially further components.
28
//
29
// See also [Mask.Without] and [Mask.Exclusive]
30
func All(ids ...ID) Mask {
27,804✔
31
        var mask Mask
27,804✔
32
        for _, id := range ids {
54,019✔
33
                mask.Set(id, true)
26,215✔
34
        }
26,215✔
35
        return mask
27,804✔
36
}
37

38
// Get reports whether the bit at the given index [ID] is set.
39
func (b *Mask) Get(bit ID) bool {
4,771,757✔
40
        idx := bit.id / 64
4,771,757✔
41
        offset := bit.id - (64 * idx)
4,771,757✔
42
        mask := uint64(1 << offset)
4,771,757✔
43
        return b.bits[idx]&mask == mask
4,771,757✔
44
}
4,771,757✔
45

46
// Set sets the state of the bit at the given index.
47
func (b *Mask) Set(bit ID, value bool) {
1,629,334✔
48
        idx := bit.id / 64
1,629,334✔
49
        offset := bit.id - (64 * idx)
1,629,334✔
50
        if value {
3,230,474✔
51
                b.bits[idx] |= (1 << offset)
1,601,140✔
52
        } else {
1,629,334✔
53
                b.bits[idx] &= ^(1 << offset)
28,194✔
54
        }
28,194✔
55
}
56

57
// Not returns the inversion of this mask.
58
func (b *Mask) Not() Mask {
8✔
59
        return Mask{
8✔
60
                bits: [4]uint64{^b.bits[0], ^b.bits[1], ^b.bits[2], ^b.bits[3]},
8✔
61
        }
8✔
62
}
8✔
63

64
// IsZero returns whether no bits are set in the mask.
65
func (b *Mask) IsZero() bool {
2,601,603✔
66
        return b.bits[0] == 0 && b.bits[1] == 0 && b.bits[2] == 0 && b.bits[3] == 0
2,601,603✔
67
}
2,601,603✔
68

69
// Reset the mask setting all bits to false.
70
func (b *Mask) Reset() {
1✔
71
        b.bits = [4]uint64{0, 0, 0, 0}
1✔
72
}
1✔
73

74
// Contains reports if the other mask is a subset of this mask.
75
func (b *Mask) Contains(other *Mask) bool {
81,607✔
76
        return b.bits[0]&other.bits[0] == other.bits[0] &&
81,607✔
77
                b.bits[1]&other.bits[1] == other.bits[1] &&
81,607✔
78
                b.bits[2]&other.bits[2] == other.bits[2] &&
81,607✔
79
                b.bits[3]&other.bits[3] == other.bits[3]
81,607✔
80
}
81,607✔
81

82
// ContainsAny reports if any bit of the other mask is in this mask.
83
func (b *Mask) ContainsAny(other *Mask) bool {
452✔
84
        return b.bits[0]&other.bits[0] != 0 ||
452✔
85
                b.bits[1]&other.bits[1] != 0 ||
452✔
86
                b.bits[2]&other.bits[2] != 0 ||
452✔
87
                b.bits[3]&other.bits[3] != 0
452✔
88
}
452✔
89

90
// And returns the bitwise AND of two masks.
91
func (b *Mask) And(other *Mask) Mask {
1,253✔
92
        return Mask{
1,253✔
93
                bits: [4]uint64{
1,253✔
94
                        b.bits[0] & other.bits[0],
1,253✔
95
                        b.bits[1] & other.bits[1],
1,253✔
96
                        b.bits[2] & other.bits[2],
1,253✔
97
                        b.bits[3] & other.bits[3],
1,253✔
98
                },
1,253✔
99
        }
1,253✔
100
}
1,253✔
101

102
// Or returns the bitwise OR of two masks.
103
func (b *Mask) Or(other *Mask) Mask {
1✔
104
        return Mask{
1✔
105
                bits: [4]uint64{
1✔
106
                        b.bits[0] | other.bits[0],
1✔
107
                        b.bits[1] | other.bits[1],
1✔
108
                        b.bits[2] | other.bits[2],
1✔
109
                        b.bits[3] | other.bits[3],
1✔
110
                },
1✔
111
        }
1✔
112
}
1✔
113

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

126
// TotalBitsSet returns how many bits are set in this mask.
127
func (b *Mask) TotalBitsSet() int {
1,898✔
128
        return bits.OnesCount64(b.bits[0]) + bits.OnesCount64(b.bits[1]) + bits.OnesCount64(b.bits[2]) + bits.OnesCount64(b.bits[3])
1,898✔
129
}
1,898✔
130

131
func (b *Mask) toTypes(reg *componentRegistry) []componentType {
1,383✔
132
        count := int(b.TotalBitsSet())
1,383✔
133
        types := make([]componentType, count)
1,383✔
134

1,383✔
135
        idx := 0
1,383✔
136
        for i := range b.bits {
6,915✔
137
                if b.bits[i] == 0 {
9,818✔
138
                        continue
4,286✔
139
                }
140
                for j := 0; j < wordSize; j++ {
80,990✔
141
                        id := ID{id: uint8(i*wordSize + j)}
79,744✔
142
                        if b.Get(id) {
85,196✔
143
                                types[idx] = componentType{ID: id, Type: reg.Types[id.id]}
5,452✔
144
                                idx++
5,452✔
145
                        }
5,452✔
146
                }
147
        }
148
        return types
1,383✔
149
}
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