-
-
Notifications
You must be signed in to change notification settings - Fork 9
Expand file tree
/
Copy pathinject.go
More file actions
127 lines (105 loc) · 2.75 KB
/
inject.go
File metadata and controls
127 lines (105 loc) · 2.75 KB
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
package ecs
import (
"reflect"
"runtime"
"time"
)
func GetInjectable2[T any](world *World, t T) T {
return GetInjectable[T](world)
}
func GetInjectable[T any](world *World) T {
var t T
name := resourceName(t)
// 1. If already created, just use this variable
anyVal, ok := world.resources[name]
if ok {
return anyVal.(T)
}
// 2. If supports initialization, then make a new one and return it
tAny := any(t)
initializer, ok := tAny.(Initializer)
if ok {
anyVal = initializer.Initialize(world)
world.resources[name] = anyVal
return anyVal.(T)
}
// 3. Fallback: Just return the default value for whatever it is
world.resources[name] = t
return t
}
type Initializer interface {
Initialize(*World) any
}
type SystemBuilder interface {
Build(world *World) System
}
type System1[A any] struct {
lambda func(dt time.Duration, a A)
}
func (s System1[A]) Build(world *World) System {
aRes := GetInjectable[A](world)
systemName := runtime.FuncForPC(reflect.ValueOf(any(s.lambda)).Pointer()).Name()
return System{
Name: systemName,
Func: func(dt time.Duration) {
s.lambda(dt, aRes)
},
}
}
func NewSystem1[A any](lambda func(dt time.Duration, a A)) System1[A] {
return System1[A]{
lambda: lambda,
}
}
type System2[A, B any] struct {
lambda func(dt time.Duration, a A, b B)
}
func (s System2[A, B]) Build(world *World) System {
aRes := GetInjectable[A](world)
bRes := GetInjectable[B](world)
systemName := runtime.FuncForPC(reflect.ValueOf(any(s.lambda)).Pointer()).Name()
return System{
Name: systemName,
Func: func(dt time.Duration) {
s.lambda(dt, aRes, bRes)
},
}
}
func NewSystem2[A, B any](lambda func(dt time.Duration, a A, b B)) System2[A, B] {
return System2[A, B]{
lambda: lambda,
}
}
type System3[A, B, C any] struct {
lambda func(dt time.Duration, a A, b B, c C)
}
func (s System3[A, B, C]) Build(world *World) System {
aRes := GetInjectable[A](world)
bRes := GetInjectable[B](world)
cRes := GetInjectable[C](world)
systemName := runtime.FuncForPC(reflect.ValueOf(any(s.lambda)).Pointer()).Name()
return System{
Name: systemName,
Func: func(dt time.Duration) {
s.lambda(dt, aRes, bRes, cRes)
},
}
}
func NewSystem3[A, B, C any](lambda func(dt time.Duration, a A, b B, c C)) System3[A, B, C] {
return System3[A, B, C]{
lambda: lambda,
}
}
// func NewSystem4[A, B, C, D any](world *World, lambda func(dt time.Duration, a A, b B, c C, d D)) System {
// aRes := GetInjectable[A](world)
// bRes := GetInjectable[B](world)
// cRes := GetInjectable[C](world)
// dRes := GetInjectable[D](world)
// systemName := runtime.FuncForPC(reflect.ValueOf(any(lambda)).Pointer()).Name()
// return System{
// Name: systemName,
// Func: func(dt time.Duration) {
// lambda(dt, aRes, bRes, cRes, dRes)
// },
// }
// }