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

mlange-42 / ark / 13524488713

25 Feb 2025 03:11PM CUT coverage: 94.787% (+3.8%) from 90.995%
13524488713

Pull #71

github

web-flow
Merge bd465a302 into bf2c655d7
Pull Request #71: Tests filters and registry

3400 of 3587 relevant lines covered (94.79%)

51035.73 hits per line

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

96.04
/ecs/column.go
1
package ecs
2

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

8
// column storage for components in an archetype.
9
type column struct {
10
        data     reflect.Value
11
        pointer  unsafe.Pointer
12
        itemSize uintptr
13
        len      uint32
14
}
15

16
// newColumn creates a new column for a given type and capacity.
17
func newColumn(tp reflect.Type, capacity uint32) column {
822✔
18
        // TODO: should be use a slice instead of an array here?
822✔
19
        data := reflect.New(reflect.ArrayOf(int(capacity), tp)).Elem()
822✔
20
        pointer := data.Addr().UnsafePointer()
822✔
21

822✔
22
        return column{
822✔
23
                data:     data,
822✔
24
                pointer:  pointer,
822✔
25
                itemSize: sizeOf(tp),
822✔
26
                len:      0,
822✔
27
        }
822✔
28
}
822✔
29

30
// Len returns the number of components in the column.
31
func (c *column) Len() int {
992,078✔
32
        return int(c.len)
992,078✔
33
}
992,078✔
34

35
// Cap returns the current capacity of the column.
36
func (c *column) Cap() int {
989,831✔
37
        return c.data.Cap()
989,831✔
38
}
989,831✔
39

40
// Get returns a pointer to the component at the given index.
41
func (c *column) Get(index uintptr) unsafe.Pointer {
4,906,627✔
42
        return unsafe.Add(c.pointer, index*c.itemSize)
4,906,627✔
43
}
4,906,627✔
44

45
// Add adds a component to the column.
46
func (c *column) Add(comp unsafe.Pointer) (unsafe.Pointer, uint32) {
492,614✔
47
        c.Extend(1)
492,614✔
48
        c.len++
492,614✔
49
        return c.Set(c.len-1, comp), c.len - 1
492,614✔
50
}
492,614✔
51

52
// Alloc allocates memory for the given number of components.
53
func (c *column) Alloc(n uint32) {
497,211✔
54
        c.Extend(n)
497,211✔
55
        c.len += n
497,211✔
56
}
497,211✔
57

58
func (c *column) AddAll(other *column) {
3✔
59
        oldLen := c.len
3✔
60
        c.Alloc(other.len)
3✔
61
        src := other.Get(0)
3✔
62
        dst := c.Get(uintptr(oldLen))
3✔
63
        copyPtr(src, dst, c.itemSize*uintptr(other.len))
3✔
64
}
3✔
65

66
// Set overwrites the component at the given index.
67
func (c *column) Set(index uint32, comp unsafe.Pointer) unsafe.Pointer {
990,979✔
68
        dst := c.Get(uintptr(index))
990,979✔
69
        if c.itemSize == 0 {
991,414✔
70
                return dst
435✔
71
        }
435✔
72

73
        copyPtr(comp, dst, uintptr(c.itemSize))
990,544✔
74
        return dst
990,544✔
75
}
76

77
// Remove swap-removes the component at the given index.
78
// Returns whether a swap was necessary.
79
func (c *column) Remove(index uint32, zero unsafe.Pointer) bool {
983,102✔
80
        lastIndex := uintptr(c.len - 1)
983,102✔
81
        swapped := index != uint32(lastIndex)
983,102✔
82

983,102✔
83
        if swapped && c.itemSize != 0 {
1,960,930✔
84
                src := unsafe.Add(c.pointer, lastIndex*c.itemSize)
977,828✔
85
                dst := unsafe.Add(c.pointer, uintptr(index)*c.itemSize)
977,828✔
86
                copyPtr(src, dst, uintptr(c.itemSize))
977,828✔
87
        }
977,828✔
88
        c.len--
983,102✔
89
        if zero != nil {
1,475,653✔
90
                c.Zero(lastIndex, zero)
492,551✔
91
        }
492,551✔
92
        return swapped
983,102✔
93
}
94

95
// Extend the column to be able to store the given number of additional components.
96
// Has no effect of the column's capacity is already sufficient.
97
// If the capacity needs to be increased, it will be doubled until it is sufficient.
98
func (c *column) Extend(by uint32) {
989,825✔
99
        required := c.Len() + int(by)
989,825✔
100
        cap := c.Cap()
989,825✔
101
        if cap >= required {
1,978,662✔
102
                return
988,837✔
103
        }
988,837✔
104
        for cap < required {
2,064✔
105
                cap *= 2
1,076✔
106
        }
1,076✔
107
        old := c.data
988✔
108
        c.data = reflect.New(reflect.ArrayOf(cap, old.Type().Elem())).Elem()
988✔
109
        c.pointer = c.data.Addr().UnsafePointer()
988✔
110
        reflect.Copy(c.data, old)
988✔
111
}
112

113
// Zero resets the memory at the given index.
114
func (c *column) Zero(index uintptr, zero unsafe.Pointer) {
492,551✔
115
        if c.itemSize == 0 {
492,587✔
116
                return
36✔
117
        }
36✔
118
        dst := unsafe.Add(c.pointer, index*c.itemSize)
492,515✔
119
        copyPtr(zero, dst, uintptr(c.itemSize))
492,515✔
120
}
121

122
// Zero resets a block of storage in one buffer.
123
func (c *column) ZeroRange(start, len uint32, zero unsafe.Pointer) {
2✔
124
        size := uint32(c.itemSize)
2✔
125
        if size == 0 {
3✔
126
                return
1✔
127
        }
1✔
128
        var i uint32
1✔
129
        for i = 0; i < len; i++ {
33✔
130
                dst := unsafe.Add(c.pointer, (i+start)*size)
32✔
131
                copyPtr(zero, dst, c.itemSize)
32✔
132
        }
32✔
133
}
134

135
func (c *column) Reset(zero unsafe.Pointer) {
3✔
136
        len := c.len
3✔
137
        if c.len == 0 {
3✔
138
                return
×
139
        }
×
140
        c.len = 0
3✔
141
        if zero == nil {
4✔
142
                return
1✔
143
        }
1✔
144
        if len <= 64 { // A coarse estimate where manually zeroing is faster
4✔
145
                c.ZeroRange(0, len, zero)
2✔
146
        } else {
2✔
147
                c.data.SetZero()
×
148
        }
×
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