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

mlange-42 / ark / 13526736655

25 Feb 2025 05:02PM CUT coverage: 94.787%. Remained the same
13526736655

push

github

web-flow
Add an example to the README (#74)

3400 of 3587 relevant lines covered (94.79%)

51722.1 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 {
1,004,836✔
32
        return int(c.len)
1,004,836✔
33
}
1,004,836✔
34

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

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

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

52
// Alloc allocates memory for the given number of components.
53
func (c *column) Alloc(n uint32) {
503,590✔
54
        c.Extend(n)
503,590✔
55
        c.len += n
503,590✔
56
}
503,590✔
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 {
1,003,737✔
68
        dst := c.Get(uintptr(index))
1,003,737✔
69
        if c.itemSize == 0 {
1,004,172✔
70
                return dst
435✔
71
        }
435✔
72

73
        copyPtr(comp, dst, uintptr(c.itemSize))
1,003,302✔
74
        return dst
1,003,302✔
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 {
996,936✔
80
        lastIndex := uintptr(c.len - 1)
996,936✔
81
        swapped := index != uint32(lastIndex)
996,936✔
82

996,936✔
83
        if swapped && c.itemSize != 0 {
1,988,596✔
84
                src := unsafe.Add(c.pointer, lastIndex*c.itemSize)
991,660✔
85
                dst := unsafe.Add(c.pointer, uintptr(index)*c.itemSize)
991,660✔
86
                copyPtr(src, dst, uintptr(c.itemSize))
991,660✔
87
        }
991,660✔
88
        c.len--
996,936✔
89
        if zero != nil {
1,496,404✔
90
                c.Zero(lastIndex, zero)
499,468✔
91
        }
499,468✔
92
        return swapped
996,936✔
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) {
1,002,583✔
99
        required := c.Len() + int(by)
1,002,583✔
100
        cap := c.Cap()
1,002,583✔
101
        if cap >= required {
2,004,178✔
102
                return
1,001,595✔
103
        }
1,001,595✔
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) {
499,468✔
115
        if c.itemSize == 0 {
499,504✔
116
                return
36✔
117
        }
36✔
118
        dst := unsafe.Add(c.pointer, index*c.itemSize)
499,432✔
119
        copyPtr(zero, dst, uintptr(c.itemSize))
499,432✔
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