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

mlange-42 / arche / 7577914431

19 Jan 2024 12:52AM CUT coverage: 100.0%. Remained the same
7577914431

push

github

web-flow
Make the Arche logo a link to the GitHub repository (#343)

6036 of 6036 relevant lines covered (100.0%)

53013.84 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
//
11
// It is the maximum number of component types that may exist in any [World].
12
//
13
// Use build tag `tiny` to reduce all masks to 64 bits.
14
const MaskTotalBits = 256
15

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

27
// Get reports whether the bit at the given index [ID] is set.
28
//
29
// Returns false for bit >= [MaskTotalBits].
30
func (b *Mask) Get(bit ID) bool {
254,364✔
31
        idx := bit.id / 64
254,364✔
32
        offset := bit.id - (64 * idx)
254,364✔
33
        mask := uint64(1 << offset)
254,364✔
34
        return b.bits[idx]&mask == mask
254,364✔
35
}
254,364✔
36

37
// Set sets the state of the bit at the given index.
38
//
39
// Has no effect for bit >= [MaskTotalBits].
40
func (b *Mask) Set(bit ID, value bool) {
162,361✔
41
        idx := bit.id / 64
162,361✔
42
        offset := bit.id - (64 * idx)
162,361✔
43
        if value {
298,546✔
44
                b.bits[idx] |= (1 << offset)
136,185✔
45
        } else {
162,361✔
46
                b.bits[idx] &= ^(1 << offset)
26,176✔
47
        }
26,176✔
48
}
49

50
// Not returns the inversion of this mask.
51
func (b *Mask) Not() Mask {
6✔
52
        return Mask{
6✔
53
                bits: [4]uint64{^b.bits[0], ^b.bits[1], ^b.bits[2], ^b.bits[3]},
6✔
54
        }
6✔
55
}
6✔
56

57
// IsZero returns whether no bits are set in the mask.
58
func (b *Mask) IsZero() bool {
164,758✔
59
        return b.bits[0] == 0 && b.bits[1] == 0 && b.bits[2] == 0 && b.bits[3] == 0
164,758✔
60
}
164,758✔
61

62
// Reset the mask setting all bits to false.
63
func (b *Mask) Reset() {
1✔
64
        b.bits = [4]uint64{0, 0, 0, 0}
1✔
65
}
1✔
66

67
// Contains reports if the other mask is a subset of this mask.
68
func (b *Mask) Contains(other *Mask) bool {
77,151✔
69
        return b.bits[0]&other.bits[0] == other.bits[0] &&
77,151✔
70
                b.bits[1]&other.bits[1] == other.bits[1] &&
77,151✔
71
                b.bits[2]&other.bits[2] == other.bits[2] &&
77,151✔
72
                b.bits[3]&other.bits[3] == other.bits[3]
77,151✔
73
}
77,151✔
74

75
// ContainsAny reports if any bit of the other mask is in this mask.
76
func (b *Mask) ContainsAny(other *Mask) bool {
447✔
77
        return b.bits[0]&other.bits[0] != 0 ||
447✔
78
                b.bits[1]&other.bits[1] != 0 ||
447✔
79
                b.bits[2]&other.bits[2] != 0 ||
447✔
80
                b.bits[3]&other.bits[3] != 0
447✔
81
}
447✔
82

83
// And returns the bitwise AND of two masks.
84
func (b *Mask) And(other *Mask) Mask {
1,251✔
85
        return Mask{
1,251✔
86
                bits: [4]uint64{
1,251✔
87
                        b.bits[0] & other.bits[0],
1,251✔
88
                        b.bits[1] & other.bits[1],
1,251✔
89
                        b.bits[2] & other.bits[2],
1,251✔
90
                        b.bits[3] & other.bits[3],
1,251✔
91
                },
1,251✔
92
        }
1,251✔
93
}
1,251✔
94

95
// Or returns the bitwise OR of two masks.
96
func (b *Mask) Or(other *Mask) Mask {
1✔
97
        return Mask{
1✔
98
                bits: [4]uint64{
1✔
99
                        b.bits[0] | other.bits[0],
1✔
100
                        b.bits[1] | other.bits[1],
1✔
101
                        b.bits[2] | other.bits[2],
1✔
102
                        b.bits[3] | other.bits[3],
1✔
103
                },
1✔
104
        }
1✔
105
}
1✔
106

107
// Xor returns the bitwise XOR of two masks.
108
func (b *Mask) Xor(other *Mask) Mask {
626✔
109
        return Mask{
626✔
110
                bits: [4]uint64{
626✔
111
                        b.bits[0] ^ other.bits[0],
626✔
112
                        b.bits[1] ^ other.bits[1],
626✔
113
                        b.bits[2] ^ other.bits[2],
626✔
114
                        b.bits[3] ^ other.bits[3],
626✔
115
                },
626✔
116
        }
626✔
117
}
626✔
118

119
// TotalBitsSet returns how many bits are set in this mask.
120
func (b *Mask) TotalBitsSet() int {
1,865✔
121
        return bits.OnesCount64(b.bits[0]) + bits.OnesCount64(b.bits[1]) + bits.OnesCount64(b.bits[2]) + bits.OnesCount64(b.bits[3])
1,865✔
122
}
1,865✔
123

124
func (b *Mask) toTypes(reg *componentRegistry) []componentType {
1,350✔
125
        count := int(b.TotalBitsSet())
1,350✔
126
        types := make([]componentType, count)
1,350✔
127

1,350✔
128
        idx := 0
1,350✔
129
        for i := range b.bits {
6,750✔
130
                if b.bits[i] == 0 {
9,577✔
131
                        continue
4,177✔
132
                }
133
                for j := 0; j < wordSize; j++ {
79,495✔
134
                        id := ID{id: uint8(i*wordSize + j)}
78,272✔
135
                        if b.Get(id) {
83,684✔
136
                                types[idx] = componentType{ID: id, Type: reg.Types[id.id]}
5,412✔
137
                                idx++
5,412✔
138
                        }
5,412✔
139
                }
140
        }
141
        return types
1,350✔
142
}
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