Skip to content

Commit ce9e765

Browse files
committed
fix interface, implement appender, add benchmarks
1 parent e3ff491 commit ce9e765

File tree

2 files changed

+105
-17
lines changed

2 files changed

+105
-17
lines changed

ecs/entity.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,11 +85,19 @@ func (e *Entity) UnmarshalJSON(data []byte) error {
8585
}
8686

8787
// MarshalBinary returns a binary representation of the entity, for serialization and networking purposes.
88-
func (e *Entity) MarshalBinary() []byte {
88+
func (e *Entity) MarshalBinary() (data []byte, err error) {
8989
buf := make([]byte, 8)
9090
binary.BigEndian.PutUint32(buf[0:4], uint32(e.id))
9191
binary.BigEndian.PutUint32(buf[4:8], e.gen)
92-
return buf
92+
return buf, nil
93+
}
94+
95+
// AppendBinary appends the binary representation of the entity to the given slice,
96+
// for serialization and networking purposes.
97+
func (e *Entity) AppendBinary(buf []byte) ([]byte, error) {
98+
buf = binary.BigEndian.AppendUint32(buf, uint32(e.id))
99+
buf = binary.BigEndian.AppendUint32(buf, e.gen)
100+
return buf, nil
93101
}
94102

95103
// UnmarshalBinary into an entity.

ecs/entity_test.go

Lines changed: 95 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package ecs
22

33
import (
4+
"encoding"
45
"encoding/json"
6+
"runtime"
57
"testing"
68
)
79

@@ -34,16 +36,15 @@ func TestReservedEntities(t *testing.T) {
3436
func TestEntityMarshal(t *testing.T) {
3537
e := Entity{2, 3}
3638

39+
var _ json.Marshaler = &e
40+
var _ json.Unmarshaler = &e
41+
3742
jsonData, err := json.Marshal(&e)
38-
if err != nil {
39-
t.Fatal(err)
40-
}
43+
expectNil(t, err)
4144

4245
e2 := Entity{}
4346
err = json.Unmarshal(jsonData, &e2)
44-
if err != nil {
45-
t.Fatal(err)
46-
}
47+
expectNil(t, err)
4748

4849
expectEqual(t, e2, e)
4950

@@ -54,19 +55,98 @@ func TestEntityMarshal(t *testing.T) {
5455
func TestEntityMarshalBinary(t *testing.T) {
5556
e := Entity{2, 3}
5657

57-
binData, err := json.Marshal(&e)
58-
if err != nil {
59-
t.Fatal(err)
60-
}
58+
var _ encoding.BinaryMarshaler = &e
59+
var _ encoding.BinaryUnmarshaler = &e
60+
var _ encoding.BinaryAppender = &e
61+
62+
binData, err := e.MarshalBinary()
63+
expectNil(t, err)
6164

6265
e2 := Entity{}
63-
err = json.Unmarshal(binData, &e2)
64-
if err != nil {
65-
t.Fatal(err)
66-
}
66+
err = e2.UnmarshalBinary(binData)
67+
expectNil(t, err)
68+
expectEqual(t, 8, len(binData))
6769

6870
expectEqual(t, e2, e)
6971

70-
err = e2.UnmarshalJSON(make([]byte, 9))
72+
err = e2.UnmarshalBinary(make([]byte, 9))
7173
expectNotNil(t, err)
74+
75+
e = Entity{4, 5}
76+
binData, err = e.AppendBinary(binData)
77+
expectNil(t, err)
78+
expectEqual(t, 16, len(binData))
79+
80+
err = e2.UnmarshalBinary(binData[8:])
81+
expectNil(t, err)
82+
expectEqual(t, e2, e)
83+
84+
err = e2.UnmarshalBinary(binData[:8])
85+
expectNil(t, err)
86+
expectEqual(t, e2, Entity{2, 3})
87+
}
88+
89+
func BenchmarkEntityMarshalBinary_1000(b *testing.B) {
90+
w := NewWorld()
91+
92+
entities := make([]Entity, 0, 1000)
93+
w.NewEntities(1000, func(e Entity) {
94+
entities = append(entities, e)
95+
})
96+
97+
var binData []byte
98+
loop := func() {
99+
for _, e := range entities {
100+
binData, _ = e.MarshalBinary()
101+
}
102+
}
103+
for b.Loop() {
104+
loop()
105+
}
106+
107+
runtime.KeepAlive(binData)
108+
}
109+
110+
func BenchmarkEntityAppendBinary_1000(b *testing.B) {
111+
w := NewWorld()
112+
113+
entities := make([]Entity, 0, 1000)
114+
w.NewEntities(1000, func(e Entity) {
115+
entities = append(entities, e)
116+
})
117+
118+
binData := make([]byte, 0, 8000)
119+
loop := func() {
120+
binData = binData[:0]
121+
for _, e := range entities {
122+
binData, _ = e.AppendBinary(binData)
123+
}
124+
}
125+
for b.Loop() {
126+
loop()
127+
}
128+
129+
runtime.KeepAlive(binData)
130+
}
131+
132+
func BenchmarkEntityUnmarshalBinary_1000(b *testing.B) {
133+
w := NewWorld()
134+
135+
entities := make([][]byte, 0, 1000)
136+
w.NewEntities(1000, func(e Entity) {
137+
binData, _ := e.MarshalBinary()
138+
entities = append(entities, binData)
139+
})
140+
141+
var entity Entity
142+
loop := func() {
143+
for _, e := range entities {
144+
_ = entity.UnmarshalBinary(e)
145+
}
146+
}
147+
for b.Loop() {
148+
loop()
149+
}
150+
151+
runtime.KeepAlive(entity)
72152
}

0 commit comments

Comments
 (0)