-
-
Notifications
You must be signed in to change notification settings - Fork 4
/
name.go
104 lines (87 loc) · 2.64 KB
/
name.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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
package ecs
import (
"fmt"
"reflect"
"sync"
)
func nameTyped[T any](comp T) CompId {
compId := name(comp)
registerComponentStorage[T](compId)
return compId
}
type storageBuilder interface {
build() storage
}
type storageBuilderImp[T any] struct {
}
func (s storageBuilderImp[T]) build() storage {
return &componentSliceStorage[T]{
slice: make(map[archetypeId]*componentSlice[T], DefaultAllocation),
}
}
var componentStorageLookupMut sync.RWMutex
var componentStorageLookup = make(map[CompId]storageBuilder)
func registerComponentStorage[T any](compId CompId) {
componentStorageLookupMut.Lock()
_, ok := componentStorageLookup[compId]
if !ok {
componentStorageLookup[compId] = storageBuilderImp[T]{}
}
componentStorageLookupMut.Unlock()
}
func newComponentStorage(c CompId) storage {
componentStorageLookupMut.RLock()
s, ok := componentStorageLookup[c]
if !ok {
panic(fmt.Sprintf("tried to build component storage with unregistered componentId: %d", c))
}
componentStorageLookupMut.RUnlock()
return s.build()
}
//--------------------------------------------------------------------------------
var componentIdMutex sync.Mutex
var registeredComponents = make(map[reflect.Type]CompId, maxComponentId)
var invalidComponentId CompId = 0
var componentRegistryCounter CompId = 1
func name(t any) CompId {
// Note: We have to lock here in case there are multiple worlds
// TODO!! - This probably causes some performance penalty
componentIdMutex.Lock()
defer componentIdMutex.Unlock()
typeof := reflect.TypeOf(t)
compId, ok := registeredComponents[typeof]
if !ok {
compId = componentRegistryCounter
registeredComponents[typeof] = compId
componentRegistryCounter++
}
return compId
}
// // Possible solution: Runs faster than reflection (mostly useful for potentially removing/reducing ecs.C(...) overhead
// import (
// "sync"
// "unsafe"
// )
// type emptyInterface struct {
// typ unsafe.Pointer
// ptr unsafe.Pointer
// }
// var componentIdMutex sync.Mutex
// var registeredComponents = make(map[uintptr]componentId, maxComponentId)
// var invalidComponentId componentId = 0
// var componentRegistryCounter componentId = 1
// func name(t any) componentId {
// // Note: We have to lock here in case there are multiple worlds
// // TODO!! - This probably causes some performance penalty
// componentIdMutex.Lock()
// defer componentIdMutex.Unlock()
// iface := (*emptyInterface)(unsafe.Pointer(&t))
// typeptr := uintptr(iface.typ)
// compId, ok := registeredComponents[typeptr]
// if !ok {
// compId = componentRegistryCounter
// registeredComponents[typeptr] = compId
// componentRegistryCounter++
// }
// return compId
// }