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

mlange-42 / ark / 13617072942

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

Pull #100

github

web-flow
Merge d87f29472 into 8f54a3a49
Pull Request #100: Simplify component/resource registration functions

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

3893 of 3996 relevant lines covered (97.42%)

93522.98 hits per line

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

98.06
/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
        isRelation bool
13
        target     Entity
14
        itemSize   uintptr
15
        len        uint32
16
}
17

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

1,878✔
24
        return column{
1,878✔
25
                data:       data,
1,878✔
26
                pointer:    pointer,
1,878✔
27
                itemSize:   sizeOf(tp),
1,878✔
28
                isRelation: isRelation,
1,878✔
29
                target:     target,
1,878✔
30
                len:        0,
1,878✔
31
        }
1,878✔
32
}
1,878✔
33

34
// Len returns the number of components in the column.
35
func (c *column) Len() int {
2,025,236✔
36
        return int(c.len)
2,025,236✔
37
}
2,025,236✔
38

39
// Cap returns the current capacity of the column.
40
func (c *column) Cap() int {
2,020,660✔
41
        return c.data.Cap()
2,020,660✔
42
}
2,020,660✔
43

44
// Get returns a pointer to the component at the given index.
45
func (c *column) Get(index uintptr) unsafe.Pointer {
9,980,700✔
46
        return unsafe.Add(c.pointer, index*c.itemSize)
9,980,700✔
47
}
9,980,700✔
48

49
// Add adds a component to the column.
50
func (c *column) Add(comp unsafe.Pointer) (unsafe.Pointer, uint32) {
1,006,628✔
51
        c.Extend(1)
1,006,628✔
52
        c.len++
1,006,628✔
53
        return c.Set(c.len-1, comp), c.len - 1
1,006,628✔
54
}
1,006,628✔
55

56
// Alloc allocates memory for the given number of components.
57
func (c *column) Alloc(n uint32) {
1,014,020✔
58
        c.Extend(n)
1,014,020✔
59
        c.len += n
1,014,020✔
60
}
1,014,020✔
61

62
func (c *column) AddAll(other *column) {
12✔
63
        oldLen := c.len
12✔
64
        c.Alloc(other.len)
12✔
65
        src := other.Get(0)
12✔
66
        dst := c.Get(uintptr(oldLen))
12✔
67
        copyPtr(src, dst, c.itemSize*uintptr(other.len))
12✔
68
}
12✔
69

70
// Set overwrites the component at the given index.
71
func (c *column) Set(index uint32, comp unsafe.Pointer) unsafe.Pointer {
2,022,498✔
72
        dst := c.Get(uintptr(index))
2,022,498✔
73
        if c.itemSize == 0 {
2,023,408✔
74
                return dst
910✔
75
        }
910✔
76

77
        copyPtr(comp, dst, uintptr(c.itemSize))
2,021,588✔
78
        return dst
2,021,588✔
79
}
80

81
// Remove swap-removes the component at the given index.
82
// Returns whether a swap was necessary.
83
func (c *column) Remove(index uint32, zero unsafe.Pointer) bool {
2,007,758✔
84
        lastIndex := uintptr(c.len - 1)
2,007,758✔
85
        swapped := index != uint32(lastIndex)
2,007,758✔
86

2,007,758✔
87
        if swapped && c.itemSize != 0 {
4,006,218✔
88
                src := unsafe.Add(c.pointer, lastIndex*c.itemSize)
1,998,460✔
89
                dst := unsafe.Add(c.pointer, uintptr(index)*c.itemSize)
1,998,460✔
90
                copyPtr(src, dst, uintptr(c.itemSize))
1,998,460✔
91
        }
1,998,460✔
92
        c.len--
2,007,758✔
93
        if zero != nil {
3,013,151✔
94
                c.Zero(lastIndex, zero)
1,005,393✔
95
        }
1,005,393✔
96
        return swapped
2,007,758✔
97
}
98

99
// Extend the column to be able to store the given number of additional components.
100
// Has no effect of the column's capacity is already sufficient.
101
// If the capacity needs to be increased, it will be doubled until it is sufficient.
102
func (c *column) Extend(by uint32) {
2,020,648✔
103
        required := c.Len() + int(by)
2,020,648✔
104
        cap := c.Cap()
2,020,648✔
105
        if cap >= required {
4,039,504✔
106
                return
2,018,856✔
107
        }
2,018,856✔
108
        for cap < required {
3,760✔
109
                cap *= 2
1,968✔
110
        }
1,968✔
111
        old := c.data
1,792✔
112
        c.data = reflect.New(reflect.ArrayOf(cap, old.Type().Elem())).Elem()
1,792✔
113
        c.pointer = c.data.Addr().UnsafePointer()
1,792✔
114
        reflect.Copy(c.data, old)
1,792✔
115
}
116

117
// Zero resets the memory at the given index.
118
func (c *column) Zero(index uintptr, zero unsafe.Pointer) {
1,005,393✔
119
        if c.itemSize == 0 {
1,005,669✔
120
                return
276✔
121
        }
276✔
122
        dst := unsafe.Add(c.pointer, index*c.itemSize)
1,005,117✔
123
        copyPtr(zero, dst, uintptr(c.itemSize))
1,005,117✔
124
}
125

126
// Zero resets a block of storage in one buffer.
127
func (c *column) ZeroRange(start, len uint32, zero unsafe.Pointer) {
14✔
128
        size := uint32(c.itemSize)
14✔
129
        if size == 0 {
18✔
130
                return
4✔
131
        }
4✔
132
        var i uint32
10✔
133
        for i = 0; i < len; i++ {
86✔
134
                dst := unsafe.Add(c.pointer, (i+start)*size)
76✔
135
                copyPtr(zero, dst, c.itemSize)
76✔
136
        }
76✔
137
}
138

139
func (c *column) Reset(zero unsafe.Pointer) {
36✔
140
        len := c.len
36✔
141
        if c.len == 0 {
48✔
142
                return
12✔
143
        }
12✔
144
        c.len = 0
24✔
145
        if zero == nil {
34✔
146
                return
10✔
147
        }
10✔
148
        if len <= 64 { // A coarse estimate where manually zeroing is faster
28✔
149
                c.ZeroRange(0, len, zero)
14✔
150
        } else {
14✔
151
                c.data.SetZero()
×
152
        }
×
153
}
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