-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathdirect_api.go
89 lines (79 loc) · 1.99 KB
/
direct_api.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 ecs
import (
"reflect"
"unsafe"
)
func RegisterSystem[T SystemObject, TP SystemPointer[T]](world IWorld, order ...Order) {
sys := TP(new(T))
if len(order) > 0 {
sys.setOrder(order[0])
}
world.registerSystem(sys)
}
func AddFreeComponent[T FreeComponentObject, TP FreeComponentPointer[T]](world IWorld, component *T) {
world.addFreeComponent(TP(component))
}
func GetComponent[T ComponentObject](sys ISystem, entity Entity) *T {
return GetRelated[T](sys, entity)
}
func GetComponentAll[T ComponentObject](sys ISystem) Iterator[T] {
if sys.getState() == SystemStateInvalid {
return EmptyIter[T]()
}
if !sys.isExecuting() {
return EmptyIter[T]()
}
typ := GetType[T]()
r, ok := sys.GetRequirements()[typ]
if !ok {
return EmptyIter[T]()
}
c := sys.World().getComponentSet(typ)
if c == nil {
return EmptyIter[T]()
}
return NewComponentSetIterator[T](c.(*ComponentSet[T]), r.getPermission() == ComponentReadOnly)
}
func GetRelated[T ComponentObject](sys ISystem, entity Entity) *T {
typ := TypeOf[T]()
isRequire := sys.isRequire(typ)
if !isRequire {
return nil
}
var cache *ComponentGetter[T]
cacheMap := sys.getGetterCache()
c := cacheMap.Get(typ)
if c != nil {
cache = (*ComponentGetter[T])(c)
} else {
cache = NewComponentGetter[T](sys)
cacheMap.Add(typ, unsafe.Pointer(cache))
}
return cache.Get(entity)
}
func BindUtility[T UtilityObject, TP UtilityPointer[T]](si SystemInitConstraint) {
if si.isValid() {
panic("out of initialization stage")
}
utility := TP(new(T))
sys := si.getSystem()
utility.setSystem(sys)
utility.setWorld(sys.World())
sys.setUtility(utility)
sys.World().base().utilities[utility.Type()] = utility
}
func GetUtility[T UtilityObject, TP UtilityPointer[T]](getter IUtilityGetter) (*T, bool) {
w := getter.getWorld()
if w == nil {
return nil, false
}
u, ok := w.getUtilityForT(TypeOf[T]())
if !ok {
return nil, false
}
return (*T)(u), true
}
func TypeOf[T any]() reflect.Type {
ins := (*T)(nil)
return reflect.TypeOf(ins).Elem()
}