-
Notifications
You must be signed in to change notification settings - Fork 1
/
entitycreator.go
175 lines (153 loc) · 4.49 KB
/
entitycreator.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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
package framework
import (
"fmt"
"git.golaxy.org/core"
"git.golaxy.org/core/ec"
"git.golaxy.org/core/pt"
"git.golaxy.org/core/runtime"
"git.golaxy.org/core/service"
"git.golaxy.org/core/utils/async"
"git.golaxy.org/core/utils/iface"
"git.golaxy.org/core/utils/meta"
"git.golaxy.org/core/utils/option"
"git.golaxy.org/core/utils/uid"
)
// CreateConcurrentEntity 创建实体
func CreateConcurrentEntity(ctx service.Context, prototype string) ConcurrentEntityCreator {
if ctx == nil {
panic(fmt.Errorf("%w: ctx is nil", core.ErrArgs))
}
return ConcurrentEntityCreator{
ctx: ctx,
prototype: prototype,
}
}
// ConcurrentEntityCreator 实体构建器
type ConcurrentEntityCreator struct {
ctx service.Context
prototype string
rt IRuntimeInstance
rtCreator RuntimeCreator
parentId uid.Id
settings []option.Setting[ec.EntityOptions]
}
// Runtime 设置运行时(优先使用)
func (c ConcurrentEntityCreator) Runtime(rt IRuntimeInstance) ConcurrentEntityCreator {
c.rt = rt
return c
}
// RuntimeCreator 设置运行时构建器
func (c ConcurrentEntityCreator) RuntimeCreator(rtCreator RuntimeCreator) ConcurrentEntityCreator {
c.rtCreator = rtCreator
return c
}
// CompositeFace 设置扩展者,在扩展实体自身能力时使用
func (c ConcurrentEntityCreator) CompositeFace(face iface.Face[ec.Entity]) ConcurrentEntityCreator {
c.settings = append(c.settings, ec.With.CompositeFace(face))
return c
}
// Composite 设置扩展者,在扩展实体自身能力时使用
func (c ConcurrentEntityCreator) Composite(composite ec.Entity) ConcurrentEntityCreator {
c.settings = append(c.settings, ec.With.CompositeFace(iface.MakeFaceT(composite)))
return c
}
// Scope 设置实体的可访问作用域
func (c ConcurrentEntityCreator) Scope(scope ec.Scope) ConcurrentEntityCreator {
c.settings = append(c.settings, ec.With.Scope(scope))
return c
}
// PersistId 设置实体持久化Id
func (c ConcurrentEntityCreator) PersistId(id uid.Id) ConcurrentEntityCreator {
c.settings = append(c.settings, ec.With.PersistId(id))
return c
}
// AwakeOnFirstAccess 设置开启组件被首次访问时,检测并调用Awake()
func (c ConcurrentEntityCreator) AwakeOnFirstAccess(b bool) ConcurrentEntityCreator {
c.settings = append(c.settings, ec.With.AwakeOnFirstAccess(b))
return c
}
// Meta 设置Meta信息
func (c ConcurrentEntityCreator) Meta(m meta.Meta) ConcurrentEntityCreator {
c.settings = append(c.settings, ec.With.Meta(m))
return c
}
// ParentId 设置父实体Id
func (c ConcurrentEntityCreator) ParentId(id uid.Id) ConcurrentEntityCreator {
c.parentId = id
return c
}
// Spawn 创建实体
func (c ConcurrentEntityCreator) Spawn() (ec.ConcurrentEntity, error) {
if c.ctx == nil {
panic(" setting ctx is nil")
}
entity := pt.For(c.ctx, c.prototype).Construct(c.settings...)
rt := c.rt
if rt == nil {
if c.rtCreator.servCtx != nil {
rt = c.rtCreator.Spawn()
} else {
rt = CreateRuntime(c.ctx).PersistId(entity.GetId()).Spawn()
}
}
err := core.Async(rt, func(ctx runtime.Context, _ ...any) async.Ret {
if c.parentId.IsNil() {
if err := ctx.GetEntityMgr().AddEntity(entity); err != nil {
return async.MakeRet(nil, err)
}
} else {
if err := ctx.GetEntityTree().AddNode(entity, c.parentId); err != nil {
return async.MakeRet(nil, err)
}
}
return async.VoidRet
}).Wait(c.ctx).Error
if err != nil {
if c.rt == nil {
rt.Terminate()
}
return nil, err
}
return entity, nil
}
// SpawnAsync 创建实体
func (c ConcurrentEntityCreator) SpawnAsync() async.AsyncRetT[ec.ConcurrentEntity] {
if c.ctx == nil {
panic(" setting ctx is nil")
}
entity := pt.For(c.ctx, c.prototype).Construct(c.settings...)
rt := c.rt
if rt == nil {
if c.rtCreator.servCtx != nil {
rt = c.rtCreator.Spawn()
} else {
rt = CreateRuntime(c.ctx).PersistId(entity.GetId()).Spawn()
}
}
asyncRet := core.Async(rt, func(ctx runtime.Context, _ ...any) async.Ret {
if c.parentId.IsNil() {
if err := ctx.GetEntityMgr().AddEntity(entity); err != nil {
return async.MakeRet(nil, err)
}
} else {
if err := ctx.GetEntityTree().AddNode(entity, c.parentId); err != nil {
return async.MakeRet(nil, err)
}
}
return async.VoidRet
})
ch := async.MakeAsyncRetT[ec.ConcurrentEntity]()
go func() {
ret := asyncRet.Wait(c.ctx)
if ret.OK() {
ch <- async.MakeRetT[ec.ConcurrentEntity](entity, nil)
} else {
if c.rt == nil {
rt.Terminate()
}
ch <- async.MakeRetT[ec.ConcurrentEntity](nil, ret.Error)
}
close(ch)
}()
return ch
}