-
Notifications
You must be signed in to change notification settings - Fork 0
/
esync_shared.go
89 lines (71 loc) · 2.08 KB
/
esync_shared.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
package esync
import (
"github.com/leap-fish/necs/typemapper"
"github.com/yohamta/donburi"
"github.com/yohamta/donburi/filter"
"reflect"
"unsafe"
)
type ComponentId uint
type NetworkId uint
type EntityState map[ComponentId][]byte
type SerializedEntity struct {
Id NetworkId
State EntityState
}
type WorldSnapshot []SerializedEntity
var NetworkEntityQuery = donburi.NewQuery(filter.Contains(NetworkIdComponent))
var registered = map[reflect.Type]donburi.IComponentType{}
var (
Mapper = typemapper.NewMapper(map[uint]any{})
NetworkIdComponent = donburi.NewComponentType[NetworkId]()
)
func Registered(componentType reflect.Type) (donburi.IComponentType, bool) {
ctype, ok := registered[componentType]
return ctype, ok
}
// RegisterComponent registers a component for use with esync. Make sure the client and server have the same definition of components.
// Note that ID 1 is reserved for the NetworkId component used by esync.
func RegisterComponent(id uint, component any, ctype donburi.IComponentType) error {
typ := reflect.TypeOf(component)
err := Mapper.RegisterType(id, typ)
if err != nil {
return err
}
registered[typ] = ctype
return nil
}
// FindByNetworkId performs an "Each" query over network entities to find one with a matching ID.
func FindByNetworkId(world donburi.World, networkId NetworkId) donburi.Entity {
var found donburi.Entity
NetworkEntityQuery.Each(world, func(entry *donburi.Entry) {
id := GetNetworkId(entry)
if id == nil || *id != networkId {
return
}
found = entry.Entity()
})
return found
}
func GetNetworkId(entry *donburi.Entry) *NetworkId {
if entry == nil {
return nil
}
if !entry.Valid() {
return nil
}
if !entry.HasComponent(NetworkIdComponent) {
return nil
}
nid := NetworkIdComponent.Get(entry)
return nid
}
func ComponentFromVal(ctype donburi.IComponentType, value interface{}) unsafe.Pointer {
if reflect.TypeOf(value) != ctype.Typ() {
panic("Type assertion failed")
}
newVal := reflect.New(ctype.Typ()).Elem()
newVal.Set(reflect.ValueOf(value))
ptr := unsafe.Pointer(newVal.UnsafeAddr())
return ptr
}