@vyr/engine 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +19 -0
- package/src/ArrayUtils.ts +65 -0
- package/src/AsyncTask.ts +72 -0
- package/src/Category.ts +119 -0
- package/src/Color.ts +111 -0
- package/src/Engine.ts +101 -0
- package/src/Generate.ts +40 -0
- package/src/InputSystem.ts +108 -0
- package/src/Listener.ts +59 -0
- package/src/ObjectPool.ts +84 -0
- package/src/ObjectUtils.ts +49 -0
- package/src/Scriptable.ts +27 -0
- package/src/Serialization.ts +49 -0
- package/src/Traverser.ts +39 -0
- package/src/actor/Actor.ts +28 -0
- package/src/actor/AnimationUnitActor.ts +289 -0
- package/src/actor/DivActor.ts +70 -0
- package/src/actor/FragmentActor.ts +56 -0
- package/src/actor/HTMActor.ts +166 -0
- package/src/actor/HTMServiceActor.ts +57 -0
- package/src/actor/HTMTransformControllerActor.ts +404 -0
- package/src/actor/StyleActor.ts +96 -0
- package/src/actor/index.ts +8 -0
- package/src/asset/Asset.ts +271 -0
- package/src/asset/AssetGraph.ts +246 -0
- package/src/asset/index.ts +2 -0
- package/src/descriptor/AnimationUnitDescriptor.ts +65 -0
- package/src/descriptor/CameraDescriptor.ts +12 -0
- package/src/descriptor/ControllerDescriptor.ts +16 -0
- package/src/descriptor/DatasetDescriptor.ts +92 -0
- package/src/descriptor/Descriptor.ts +415 -0
- package/src/descriptor/DivDescriptor.ts +18 -0
- package/src/descriptor/DynamicDescriptor.ts +27 -0
- package/src/descriptor/HTMLDescriptor.ts +87 -0
- package/src/descriptor/HTMLServiceDescriptor.ts +19 -0
- package/src/descriptor/HTMLTransformControllerDescriptor.ts +34 -0
- package/src/descriptor/NodeDescriptor.ts +32 -0
- package/src/descriptor/PrefabDescriptor.ts +53 -0
- package/src/descriptor/PrefabInstanceDescriptor.ts +32 -0
- package/src/descriptor/RoutineDescriptor.ts +54 -0
- package/src/descriptor/ServiceDescriptor.ts +32 -0
- package/src/descriptor/ServiceSchedulerDescriptor.ts +32 -0
- package/src/descriptor/StyleDescriptor.ts +213 -0
- package/src/descriptor/index.ts +17 -0
- package/src/graphics/Collection.ts +25 -0
- package/src/graphics/Compilation.ts +82 -0
- package/src/graphics/Graphics.ts +475 -0
- package/src/graphics/Observer.ts +36 -0
- package/src/graphics/Unit.ts +83 -0
- package/src/graphics/VariableProxy.ts +92 -0
- package/src/graphics/index.ts +5 -0
- package/src/index.ts +26 -0
- package/src/interpreter/AnimationUnitInterpreter.ts +53 -0
- package/src/interpreter/DatasetInterpreter.ts +11 -0
- package/src/interpreter/DivInterpreter.ts +44 -0
- package/src/interpreter/DynamicInterpreter.ts +207 -0
- package/src/interpreter/FragmentInterpreter.ts +34 -0
- package/src/interpreter/HTMLServiceInterpreter.ts +47 -0
- package/src/interpreter/HTMLTransformControllerInterpreter.ts +40 -0
- package/src/interpreter/Interpreter.ts +69 -0
- package/src/interpreter/PrefaInterpreter.ts +11 -0
- package/src/interpreter/PrefabInstanceInterpreter.ts +12 -0
- package/src/interpreter/RoutineInterpreter.ts +88 -0
- package/src/interpreter/ServiceInterpreter.ts +24 -0
- package/src/interpreter/ServiceSchedulerInterpreter.ts +42 -0
- package/src/interpreter/StyleInterpreter.ts +66 -0
- package/src/interpreter/index.ts +14 -0
- package/src/locale/Language.ts +10 -0
- package/src/locale/LanguageProvider.ts +48 -0
- package/src/locale/index.ts +2 -0
- package/src/math/Euler.ts +303 -0
- package/src/math/Matrix4.ts +1123 -0
- package/src/math/Quaternion.ts +737 -0
- package/src/math/Vector2.ts +680 -0
- package/src/math/Vector3.ts +1062 -0
- package/src/math/index.ts +5 -0
- package/src/math/utils.ts +17 -0
- package/src/preset/execute/dataset/index.ts +1 -0
- package/src/preset/execute/dataset/update.ts +52 -0
- package/src/preset/execute/graphics/index.ts +1 -0
- package/src/preset/execute/graphics/invoke.ts +49 -0
- package/src/preset/execute/index.ts +4 -0
- package/src/preset/execute/net/index.ts +1 -0
- package/src/preset/execute/net/request.ts +103 -0
- package/src/preset/execute/scheduler/index.ts +1 -0
- package/src/preset/execute/scheduler/switch.ts +46 -0
- package/src/preset/index.ts +7 -0
- package/src/preset/routine/graphics/index.ts +1 -0
- package/src/preset/routine/graphics/invoke.ts +27 -0
- package/src/preset/routine/index.ts +2 -0
- package/src/preset/routine/scheduler/index.ts +1 -0
- package/src/preset/routine/scheduler/switch.ts +27 -0
- package/src/setup/index.ts +17 -0
- package/src/utils/AssetProvider.ts +72 -0
- package/src/utils/index.ts +1 -0
|
@@ -0,0 +1,475 @@
|
|
|
1
|
+
import { language } from '../locale'
|
|
2
|
+
import { ArrayUtils } from "../ArrayUtils";
|
|
3
|
+
import { Asset, Dependencide } from "../asset";
|
|
4
|
+
import { Descriptor, HTMLDescriptor, HTMLServiceDescriptor, RoutineDescriptor, ServiceDescriptor, ServiceSchedulerDescriptor, UpdateArgs } from "../descriptor";
|
|
5
|
+
import { privateState } from "../interpreter/Interpreter";
|
|
6
|
+
import { Interpreter, RoutineInterpreter, ServiceInterpreter, ServiceSchedulerInterpreter } from "../interpreter";
|
|
7
|
+
import { observer, UpdateDepsWatcherArgs, UpdateWatcherArgs, WatcherArgs } from "./Observer";
|
|
8
|
+
import { Operation, Queue, Unit } from "./Unit";
|
|
9
|
+
import { Actor } from '../actor/Actor';
|
|
10
|
+
import { UnitCollection } from "./Collection";
|
|
11
|
+
import { VariableProxy } from "./VariableProxy";
|
|
12
|
+
import { Engine } from '../Engine';
|
|
13
|
+
|
|
14
|
+
interface PickupObject {
|
|
15
|
+
[k: string]: any
|
|
16
|
+
uuid: string
|
|
17
|
+
generatedBy: string
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
type OverrideUpdate = (descriptor: Descriptor, interpreter: Interpreter, args: UpdateArgs) => void
|
|
21
|
+
|
|
22
|
+
class Graphics {
|
|
23
|
+
static createInterpreter<T extends Interpreter = Interpreter>(descriptor: Descriptor, graphics: Graphics) {
|
|
24
|
+
const Class = Interpreter.getClass(descriptor.type)
|
|
25
|
+
if (Class === null) throw language.get('graphics.interpreter.notRegister', { type: descriptor.type })
|
|
26
|
+
privateState.factory = true
|
|
27
|
+
let unit = graphics.unitCollection.get(descriptor.uuid) as Unit
|
|
28
|
+
if (unit === undefined) unit = graphics._freeCollection.get(descriptor.uuid) as Unit
|
|
29
|
+
const interpreter = new Class(unit, graphics) as T
|
|
30
|
+
privateState.factory = false
|
|
31
|
+
return interpreter
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
__VYR_REMOTE_WRAPPER?: boolean
|
|
35
|
+
private readonly _overwriteUpdate = new Map<string, OverrideUpdate>()
|
|
36
|
+
private readonly _interpreterCollection = new Map<string, Interpreter>()
|
|
37
|
+
private readonly _staticAssetQueue: Unit[] = []
|
|
38
|
+
private readonly _assetCollection = new Map<string, Unit>()
|
|
39
|
+
private readonly _freeCollection = new Map<string, Unit>()
|
|
40
|
+
private readonly _dependencide = new Dependencide()
|
|
41
|
+
private readonly _services: ServiceDescriptor[] = []
|
|
42
|
+
private readonly _freeQueue: Unit[] = []
|
|
43
|
+
private _currentCamera = ''
|
|
44
|
+
readonly unitCollection = new UnitCollection()
|
|
45
|
+
readonly variableProxy = new VariableProxy()
|
|
46
|
+
readonly scheduler: ServiceSchedulerDescriptor
|
|
47
|
+
readonly engine: Engine
|
|
48
|
+
readonly url: string
|
|
49
|
+
|
|
50
|
+
constructor(url: string, scheduler: ServiceSchedulerDescriptor, engine: Engine) {
|
|
51
|
+
this.scheduler = scheduler
|
|
52
|
+
this.engine = engine
|
|
53
|
+
this.url = url
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
listen(args: UpdateArgs) {
|
|
57
|
+
observer.listen('add', this.addWatcher)
|
|
58
|
+
observer.listen('remove', this.removeWatcher)
|
|
59
|
+
observer.listen('update', this.updateWatcher)
|
|
60
|
+
observer.listen('updateDeps', this.updateDepsWatcher)
|
|
61
|
+
observer.listen('free', this.freeWatcher)
|
|
62
|
+
|
|
63
|
+
const root = Asset.get<Descriptor>(this.url)
|
|
64
|
+
if (root instanceof Descriptor) this.addRoot(this.url, root)
|
|
65
|
+
|
|
66
|
+
Asset.graph.getDependencide(this.url, this._dependencide)
|
|
67
|
+
this._dependencide.foreach(asset => {
|
|
68
|
+
const root = Asset.get<Descriptor>(asset)
|
|
69
|
+
if (root instanceof Descriptor) {
|
|
70
|
+
this._assetCollection.set(asset, this.addRoot(asset, root))
|
|
71
|
+
}
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
const descriptor = this.variableProxy.get<ServiceSchedulerDescriptor>(this.scheduler.uuid, this, args)
|
|
75
|
+
const interpreter = this.getInterpreter<ServiceSchedulerInterpreter>(descriptor)
|
|
76
|
+
interpreter.install(descriptor, args)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
unlisten(args: UpdateArgs) {
|
|
80
|
+
const descriptor = this.variableProxy.get<ServiceSchedulerDescriptor>(this.scheduler.uuid, this, args)
|
|
81
|
+
const interpreter = this.getInterpreter<ServiceSchedulerInterpreter>(descriptor)
|
|
82
|
+
interpreter.uninstall(descriptor, args)
|
|
83
|
+
|
|
84
|
+
const master = this.unitCollection.get(this.scheduler.uuid) as Unit
|
|
85
|
+
const assets = [...this._assetCollection.values(), master]
|
|
86
|
+
|
|
87
|
+
for (const asset of assets) {
|
|
88
|
+
const unit = this.removeRoot(asset.queue.url)
|
|
89
|
+
if (unit === null) continue
|
|
90
|
+
unit.queue.iterator(operation => this.do(operation, args))
|
|
91
|
+
this._assetCollection.delete(asset.queue.url)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const _freeQueue = this._freeCollection.values()
|
|
95
|
+
for (const unit of _freeQueue) this.doFree(unit, args)
|
|
96
|
+
|
|
97
|
+
observer.unlisten('add', this.addWatcher)
|
|
98
|
+
observer.unlisten('remove', this.removeWatcher)
|
|
99
|
+
observer.unlisten('update', this.updateWatcher)
|
|
100
|
+
observer.unlisten('updateDeps', this.updateDepsWatcher)
|
|
101
|
+
observer.unlisten('free', this.freeWatcher)
|
|
102
|
+
|
|
103
|
+
this._dependencide.clear()
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
process(args: UpdateArgs) {
|
|
107
|
+
for (const unit of this._freeQueue) this.doFree(unit, args)
|
|
108
|
+
this._freeQueue.length = 0
|
|
109
|
+
|
|
110
|
+
this.updateStaticAsset(args)
|
|
111
|
+
|
|
112
|
+
this._dependencide.clear()
|
|
113
|
+
Asset.graph.getDependencide(this.url, this._dependencide)
|
|
114
|
+
Asset.activate(...this._dependencide.all, this.url)
|
|
115
|
+
const patch = this.diffAsset()
|
|
116
|
+
|
|
117
|
+
for (const removeAsset of patch.removeQueue) {
|
|
118
|
+
const unit = this.removeRoot(removeAsset)
|
|
119
|
+
if (unit !== null) unit.queue.iterator(operation => this.do(operation, args))
|
|
120
|
+
this._assetCollection.delete(removeAsset)
|
|
121
|
+
}
|
|
122
|
+
for (const addAsset of patch.addQueue) {
|
|
123
|
+
const root = Asset.get<Descriptor>(addAsset)
|
|
124
|
+
if (root instanceof Descriptor) {
|
|
125
|
+
this._assetCollection.set(addAsset, this.addRoot(addAsset, root))
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
const assets: Unit[] = []
|
|
130
|
+
this._dependencide.foreach(asset => {
|
|
131
|
+
const descriptor = Asset.get<Descriptor>(asset)
|
|
132
|
+
const unit = this.unitCollection.get(descriptor.uuid)
|
|
133
|
+
if (unit === undefined) return console.warn(asset, descriptor)
|
|
134
|
+
assets.push(unit)
|
|
135
|
+
})
|
|
136
|
+
assets.push(...this._staticAssetQueue)
|
|
137
|
+
|
|
138
|
+
for (const asset of assets) {
|
|
139
|
+
asset.queue.iterator(operation => this.do(operation, args))
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const master = this.unitCollection.get(this.scheduler.uuid) as Unit
|
|
143
|
+
|
|
144
|
+
master.queue.iterator(operation => this.do(operation, args))
|
|
145
|
+
|
|
146
|
+
for (const asset of assets) {
|
|
147
|
+
asset.queue.iterator(unit => this.doUpdate(unit, args), Queue.Update)
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
const invokeQueue = master.queue.iterator(unit => this.doUpdate(unit, args), Queue.Update)
|
|
151
|
+
for (const unit of invokeQueue) {
|
|
152
|
+
const descriptor = Descriptor.get<Descriptor>(unit.uuid)
|
|
153
|
+
this.invoke('mount', descriptor)
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
this._freeQueue.push(...this._freeCollection.values())
|
|
157
|
+
this._freeCollection.clear()
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
clear(args: UpdateArgs) {
|
|
161
|
+
for (const service of this._services) {
|
|
162
|
+
const descriptor = this.variableProxy.get<ServiceDescriptor>(service.uuid, this, args)
|
|
163
|
+
const interpreter = this.getInterpreter<ServiceInterpreter>(descriptor)
|
|
164
|
+
interpreter.clear(descriptor, args)
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
beforeRender(args: UpdateArgs) {
|
|
169
|
+
for (const service of this._services) {
|
|
170
|
+
const descriptor = this.variableProxy.get<ServiceDescriptor>(service.uuid, this, args)
|
|
171
|
+
const interpreter = this.getInterpreter<ServiceInterpreter>(descriptor)
|
|
172
|
+
interpreter.beforeRender(descriptor, args)
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
render(args: UpdateArgs) {
|
|
177
|
+
for (const service of this._services) {
|
|
178
|
+
const descriptor = this.variableProxy.get<ServiceDescriptor>(service.uuid, this, args)
|
|
179
|
+
const interpreter = this.getInterpreter<ServiceInterpreter>(descriptor)
|
|
180
|
+
interpreter.render(descriptor, args)
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
afterRender(args: UpdateArgs) {
|
|
185
|
+
for (const service of this._services) {
|
|
186
|
+
const descriptor = this.variableProxy.get<ServiceDescriptor>(service.uuid, this, args)
|
|
187
|
+
const interpreter = this.getInterpreter<ServiceInterpreter>(descriptor)
|
|
188
|
+
interpreter.afterRender(descriptor, args)
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
addRoot(asset: string, root: Descriptor) {
|
|
193
|
+
const unit = new Unit(root.uuid, '', new Queue(asset))
|
|
194
|
+
this.unitCollection.set(unit)
|
|
195
|
+
this._freeCollection.delete(unit.uuid)
|
|
196
|
+
|
|
197
|
+
unit.trigger(Queue.Update)
|
|
198
|
+
for (const sub of root.children) {
|
|
199
|
+
observer.trigger('add', { self: sub.uuid, puid: root.uuid })
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
return unit
|
|
203
|
+
}
|
|
204
|
+
removeRoot(asset: string) {
|
|
205
|
+
const root = Asset.get<Descriptor>(asset)
|
|
206
|
+
const unit = this.unitCollection.get(root.uuid)
|
|
207
|
+
if (unit === undefined) return null
|
|
208
|
+
this.unitCollection.delete(unit.uuid)
|
|
209
|
+
unit.queue.clear()
|
|
210
|
+
|
|
211
|
+
this._freeCollection.set(unit.uuid, unit)
|
|
212
|
+
for (const sub of root.children) {
|
|
213
|
+
observer.trigger('remove', { self: sub.uuid, puid: root.uuid })
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
return unit
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
private addWatcher = (args: WatcherArgs) => {
|
|
220
|
+
const pUnit = this.unitCollection.get(args.puid)
|
|
221
|
+
if (pUnit === undefined) return
|
|
222
|
+
this.addCallback(args, pUnit)
|
|
223
|
+
const descriptor = Descriptor.get<Descriptor>(args.self)
|
|
224
|
+
descriptor.traverse(sub => observer.trigger('update', { self: sub.uuid }))
|
|
225
|
+
}
|
|
226
|
+
private removeWatcher = (args: WatcherArgs) => {
|
|
227
|
+
const unit = this.unitCollection.get(args.self)
|
|
228
|
+
if (unit === undefined) return
|
|
229
|
+
this.removeCallback(args)
|
|
230
|
+
}
|
|
231
|
+
private updateWatcher = (args: UpdateWatcherArgs) => {
|
|
232
|
+
const unit = this.unitCollection.get(args.self)
|
|
233
|
+
if (unit === undefined) return
|
|
234
|
+
const descriptor = Descriptor.get<Descriptor>(args.self)
|
|
235
|
+
this.variableProxy.update(descriptor)
|
|
236
|
+
unit.trigger(Queue.Update)
|
|
237
|
+
}
|
|
238
|
+
private updateDepsWatcher = (args: UpdateDepsWatcherArgs) => {
|
|
239
|
+
const unit = this.unitCollection.get(args.self)
|
|
240
|
+
if (unit === undefined) return
|
|
241
|
+
|
|
242
|
+
const deps = Asset.graph.getDependents(unit.queue.url)
|
|
243
|
+
for (const dep of deps) {
|
|
244
|
+
for (const port of dep.ports) {
|
|
245
|
+
if (Asset.graph.hasAssetReference(port, unit.queue.url)) {
|
|
246
|
+
observer.trigger('update', { self: port.descriptor })
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
private freeWatcher = (args: UpdateWatcherArgs) => {
|
|
252
|
+
let unit = this.unitCollection.get(args.self)
|
|
253
|
+
|
|
254
|
+
if (unit === undefined) {
|
|
255
|
+
unit = this._freeCollection.get(args.self)
|
|
256
|
+
if (unit === undefined) return
|
|
257
|
+
this._freeCollection.delete(args.self)
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
this._freeQueue.push(unit)
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
private addCallback(args: WatcherArgs, pUnit: Unit) {
|
|
264
|
+
const parentDescriptor = Descriptor.get<Descriptor>(pUnit.uuid)
|
|
265
|
+
const descriptor = Descriptor.get<Descriptor>(args.self)
|
|
266
|
+
descriptor.traverse((sub, parent) => {
|
|
267
|
+
const unit = new Unit(sub.uuid, parent.uuid, pUnit.queue)
|
|
268
|
+
this.unitCollection.set(unit)
|
|
269
|
+
unit.trigger(Queue.Add)
|
|
270
|
+
this._freeCollection.delete(unit.uuid)
|
|
271
|
+
}, false, parentDescriptor)
|
|
272
|
+
}
|
|
273
|
+
private removeCallback(args: WatcherArgs) {
|
|
274
|
+
const descriptor = Descriptor.get<Descriptor>(args.self)
|
|
275
|
+
descriptor.traverse((sub) => {
|
|
276
|
+
const unit = this.unitCollection.get(sub.uuid)
|
|
277
|
+
if (unit === undefined) return
|
|
278
|
+
this.unitCollection.delete(sub.uuid)
|
|
279
|
+
unit.trigger(Queue.Remove)
|
|
280
|
+
this._freeCollection.set(unit.uuid, unit)
|
|
281
|
+
})
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
private updateStaticAsset(args: UpdateArgs) {
|
|
285
|
+
if (this.scheduler.camera !== this._currentCamera) {
|
|
286
|
+
const descriptor = Descriptor.get<Descriptor>(this.scheduler.camera)
|
|
287
|
+
if (descriptor === null) return
|
|
288
|
+
const oldNode = this.unitCollection.get(this._currentCamera)
|
|
289
|
+
if (oldNode) {
|
|
290
|
+
this.unitCollection.delete(this._currentCamera)
|
|
291
|
+
this._freeCollection.set(oldNode.uuid, oldNode)
|
|
292
|
+
ArrayUtils.remove(this._staticAssetQueue, oldNode)
|
|
293
|
+
}
|
|
294
|
+
const newNode = new Unit(descriptor.uuid, '', new Queue(Asset.createVirtualUrl('graphics/camera.ts')))
|
|
295
|
+
this.unitCollection.set(newNode)
|
|
296
|
+
ArrayUtils.insert(this._staticAssetQueue, newNode)
|
|
297
|
+
this._currentCamera = this.scheduler.camera
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
private diffAsset() {
|
|
302
|
+
const temp = new Map(this._assetCollection)
|
|
303
|
+
const addQueue: string[] = [], removeQueue: string[] = []
|
|
304
|
+
|
|
305
|
+
this._dependencide.foreach(asset => {
|
|
306
|
+
temp.has(asset) ? temp.delete(asset) : addQueue.push(asset)
|
|
307
|
+
})
|
|
308
|
+
removeQueue.push(...temp.keys())
|
|
309
|
+
|
|
310
|
+
return { addQueue, removeQueue }
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
private onMount(unit: Unit, args: UpdateArgs) {
|
|
314
|
+
const parentDescriptor = this.variableProxy.get<Descriptor>(unit.parent, this, args)
|
|
315
|
+
const parentInterpreter = this.getInterpreter(parentDescriptor)
|
|
316
|
+
|
|
317
|
+
const descriptor = this.variableProxy.get<Descriptor>(unit.uuid, this, args)
|
|
318
|
+
const interpreter = this.getInterpreter(descriptor)
|
|
319
|
+
|
|
320
|
+
if (descriptor instanceof ServiceDescriptor) ArrayUtils.insert(this._services, descriptor)
|
|
321
|
+
|
|
322
|
+
interpreter.mount(descriptor, args, parentInterpreter, parentDescriptor)
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
private onUnmount(unit: Unit, args: UpdateArgs) {
|
|
326
|
+
const parentDescriptor = this.variableProxy.get<Descriptor>(unit.parent, this, args)
|
|
327
|
+
const parentInterpreter = this.getInterpreter(parentDescriptor)
|
|
328
|
+
|
|
329
|
+
const descriptor = this.variableProxy.get<Descriptor>(unit.uuid, this, args)
|
|
330
|
+
const interpreter = this.getInterpreter(descriptor)
|
|
331
|
+
|
|
332
|
+
if (descriptor instanceof ServiceDescriptor) ArrayUtils.remove(this._services, descriptor)
|
|
333
|
+
|
|
334
|
+
interpreter.unmount(descriptor, args, parentInterpreter, parentDescriptor)
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
getUnit<T extends Unit | null = Unit>(uuid: string) {
|
|
338
|
+
return (this.unitCollection.get(uuid) ?? null) as T
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
do(operation: Operation, args: UpdateArgs) {
|
|
342
|
+
switch (operation.type) {
|
|
343
|
+
case Queue.Add:
|
|
344
|
+
this.onMount(operation.unit, args)
|
|
345
|
+
break;
|
|
346
|
+
case Queue.Remove:
|
|
347
|
+
this.onUnmount(operation.unit, args)
|
|
348
|
+
break;
|
|
349
|
+
default:
|
|
350
|
+
console.log('do', operation.type)
|
|
351
|
+
break;
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
doUpdate(unit: Unit, args: UpdateArgs) {
|
|
356
|
+
const descriptor = this.variableProxy.get<Descriptor>(unit.uuid, this, args)
|
|
357
|
+
const interpreter = this.getInterpreter(descriptor)
|
|
358
|
+
const override = this._overwriteUpdate.get(descriptor.uuid)
|
|
359
|
+
override === undefined ? interpreter.update(descriptor, args) : override(descriptor, interpreter, args)
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
doFree(unit: Unit, args: UpdateArgs) {
|
|
363
|
+
const interpreter = this._interpreterCollection.get(unit.uuid)
|
|
364
|
+
if (interpreter === undefined) return
|
|
365
|
+
const descriptor = this.variableProxy.get<Descriptor>(unit.uuid, this, args)
|
|
366
|
+
interpreter.free(descriptor, args)
|
|
367
|
+
this._interpreterCollection.delete(unit.uuid)
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
getInterpreter<T extends Interpreter = Interpreter>(descriptor: Descriptor) {
|
|
371
|
+
let interpreter = this._interpreterCollection.get(descriptor.uuid) as T
|
|
372
|
+
if (interpreter === undefined) {
|
|
373
|
+
interpreter = Graphics.createInterpreter(descriptor, this)
|
|
374
|
+
this._interpreterCollection.set(descriptor.uuid, interpreter)
|
|
375
|
+
}
|
|
376
|
+
return interpreter
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
getParent<T extends Descriptor = Descriptor>(uuid: string) {
|
|
380
|
+
const unit = this.unitCollection.get(uuid)
|
|
381
|
+
if (unit === undefined) return null
|
|
382
|
+
return Descriptor.get<T>(unit.parent)
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
getActor<T extends Actor = Actor>(descriptor: Descriptor, args: UpdateArgs) {
|
|
386
|
+
const interpreter = this.getInterpreter(descriptor)
|
|
387
|
+
return interpreter.getActor<T>(descriptor, args)
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
private _pickupItem(target: Descriptor, args: UpdateArgs, result: PickupObject[]) {
|
|
391
|
+
if (target.selectable === false) return
|
|
392
|
+
const interpreter = this._interpreterCollection.get(target.uuid)
|
|
393
|
+
if (interpreter === undefined) return
|
|
394
|
+
interpreter.pickup(target, args, result)
|
|
395
|
+
}
|
|
396
|
+
private _pickupScene(args: UpdateArgs, result: PickupObject[]) {
|
|
397
|
+
const master = this.unitCollection.get(this.scheduler.uuid)
|
|
398
|
+
if (master === undefined) return result
|
|
399
|
+
|
|
400
|
+
const units = this.unitCollection.values()
|
|
401
|
+
for (const unit of units) {
|
|
402
|
+
const descriptor = Descriptor.get<Descriptor>(unit.uuid)
|
|
403
|
+
if (descriptor instanceof HTMLDescriptor) continue
|
|
404
|
+
this._pickupItem(descriptor, args, result)
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
getMouseAndRect(event: MouseEvent) {
|
|
409
|
+
//@ts-ignore
|
|
410
|
+
const rect = event.target.getBoundingClientRect()
|
|
411
|
+
const mouse = { x: event.clientX - rect.left, y: event.clientY - rect.top }
|
|
412
|
+
return { mouse, rect }
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
traceService(target: Descriptor): ServiceDescriptor | null {
|
|
416
|
+
if (target instanceof ServiceDescriptor) return target
|
|
417
|
+
|
|
418
|
+
const parent = this.getParent(target.uuid)
|
|
419
|
+
if (parent === null) return null
|
|
420
|
+
|
|
421
|
+
return this.traceService(parent)
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
pickup(event: MouseEvent) {
|
|
425
|
+
const result: PickupObject[] = []
|
|
426
|
+
|
|
427
|
+
const isElement = event.target instanceof Element
|
|
428
|
+
if (isElement === false) return result
|
|
429
|
+
const uuid = event.target.getAttribute('data-vyr-uuid')
|
|
430
|
+
if (uuid === null) return result
|
|
431
|
+
|
|
432
|
+
const { mouse, rect } = this.getMouseAndRect(event)
|
|
433
|
+
const target = Descriptor.get<Descriptor>(uuid)
|
|
434
|
+
const args = { delta: 0 }
|
|
435
|
+
if (target instanceof ServiceDescriptor) {
|
|
436
|
+
if (target instanceof HTMLServiceDescriptor) {
|
|
437
|
+
this._pickupItem(target, args, result)
|
|
438
|
+
} else {
|
|
439
|
+
const interpreter = this.getInterpreter<ServiceInterpreter>(target)
|
|
440
|
+
interpreter.beforePickup(mouse, rect, args)
|
|
441
|
+
this._pickupScene(args, result)
|
|
442
|
+
interpreter.orderBy(result)
|
|
443
|
+
}
|
|
444
|
+
} else {
|
|
445
|
+
this._pickupItem(target, args, result)
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
return result
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
invoke(interaction: string, descriptor: Descriptor) {
|
|
452
|
+
if (descriptor.interactions.length === 0) return
|
|
453
|
+
const eventArgs = { delta: 0, trigger: descriptor }
|
|
454
|
+
for (const inter of descriptor.interactions) {
|
|
455
|
+
if (inter.type === interaction) {
|
|
456
|
+
const routine = Asset.get<RoutineDescriptor>(inter.url)
|
|
457
|
+
const interpreter = this.getInterpreter<RoutineInterpreter>(routine)
|
|
458
|
+
interpreter.do(inter.inputs, routine, eventArgs)
|
|
459
|
+
break
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
setOverrideByUpdate(uuid: string, override: OverrideUpdate) {
|
|
465
|
+
this._overwriteUpdate.set(uuid, override)
|
|
466
|
+
}
|
|
467
|
+
deleteOverrideByUpdate(uuid: string) {
|
|
468
|
+
this._overwriteUpdate.delete(uuid)
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
export {
|
|
473
|
+
PickupObject,
|
|
474
|
+
Graphics,
|
|
475
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { Listener } from "../Listener"
|
|
2
|
+
|
|
3
|
+
interface WatcherArgs {
|
|
4
|
+
self: string
|
|
5
|
+
puid: string
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
interface UpdateWatcherArgs {
|
|
9
|
+
self: string
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
interface UpdateDepsWatcherArgs {
|
|
13
|
+
self: string
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
interface FreeWatcherArgs {
|
|
17
|
+
self: string
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
interface Observer {
|
|
21
|
+
add(args: WatcherArgs): void
|
|
22
|
+
remove(args: WatcherArgs): void
|
|
23
|
+
update(args: UpdateWatcherArgs): void
|
|
24
|
+
updateDeps(args: UpdateDepsWatcherArgs): void
|
|
25
|
+
free(args: FreeWatcherArgs): void
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const observer = new Listener<Observer>()
|
|
29
|
+
|
|
30
|
+
export {
|
|
31
|
+
WatcherArgs,
|
|
32
|
+
UpdateWatcherArgs,
|
|
33
|
+
UpdateDepsWatcherArgs,
|
|
34
|
+
FreeWatcherArgs,
|
|
35
|
+
observer,
|
|
36
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { ArrayUtils } from "../ArrayUtils"
|
|
2
|
+
|
|
3
|
+
interface Operation {
|
|
4
|
+
type: number
|
|
5
|
+
unit: Unit
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
class Queue {
|
|
9
|
+
static readonly Add = 1
|
|
10
|
+
static readonly Remove = 2
|
|
11
|
+
static readonly Update = 3
|
|
12
|
+
readonly url: string
|
|
13
|
+
readonly operationCollection: Operation[] = []
|
|
14
|
+
readonly updateCollection: Unit[] = []
|
|
15
|
+
|
|
16
|
+
constructor(url: string) {
|
|
17
|
+
this.url = url
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
iterator<T extends Operation>(cb: (unit: T) => void): T[]
|
|
21
|
+
iterator<T extends Unit>(cb: (unit: T) => void, type: number): T[]
|
|
22
|
+
iterator<T extends Operation | Unit>(cb: (unit: T) => void, type?: number) {
|
|
23
|
+
let queue
|
|
24
|
+
switch (type) {
|
|
25
|
+
case Queue.Update:
|
|
26
|
+
queue = [...this.updateCollection]
|
|
27
|
+
this.updateCollection.length = 0
|
|
28
|
+
break
|
|
29
|
+
default:
|
|
30
|
+
queue = [...this.operationCollection]
|
|
31
|
+
this.operationCollection.length = 0
|
|
32
|
+
break
|
|
33
|
+
}
|
|
34
|
+
for (const unit of queue) cb(unit as any)
|
|
35
|
+
|
|
36
|
+
return queue as T[]
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
clear(type?: number) {
|
|
40
|
+
let queue
|
|
41
|
+
switch (type) {
|
|
42
|
+
case Queue.Update:
|
|
43
|
+
queue = this.updateCollection
|
|
44
|
+
break
|
|
45
|
+
default:
|
|
46
|
+
queue = this.operationCollection
|
|
47
|
+
break
|
|
48
|
+
}
|
|
49
|
+
queue.length = 0
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
class Unit {
|
|
54
|
+
uuid: string
|
|
55
|
+
parent: string
|
|
56
|
+
queue: Queue
|
|
57
|
+
|
|
58
|
+
constructor(uuid: string, parent: string, queue: Queue) {
|
|
59
|
+
this.uuid = uuid
|
|
60
|
+
this.parent = parent
|
|
61
|
+
this.queue = queue
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
trigger(type: number) {
|
|
65
|
+
switch (type) {
|
|
66
|
+
case Queue.Add:
|
|
67
|
+
this.queue.operationCollection.push({ type, unit: this })
|
|
68
|
+
break
|
|
69
|
+
case Queue.Remove:
|
|
70
|
+
this.queue.operationCollection.push({ type, unit: this })
|
|
71
|
+
break
|
|
72
|
+
case Queue.Update:
|
|
73
|
+
ArrayUtils.insert(this.queue.updateCollection, this)
|
|
74
|
+
break
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export {
|
|
80
|
+
Operation,
|
|
81
|
+
Queue,
|
|
82
|
+
Unit,
|
|
83
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { ObjectUtils } from "../ObjectUtils";
|
|
2
|
+
import { Asset } from "../asset";
|
|
3
|
+
import { Scriptable } from "../Scriptable";
|
|
4
|
+
import { Data, DatasetDescriptor, Descriptor, UpdateArgs, VariabConfig } from "../descriptor";
|
|
5
|
+
import { Graphics } from "./Graphics";
|
|
6
|
+
|
|
7
|
+
interface ActorCollection { [k: string]: any }
|
|
8
|
+
|
|
9
|
+
interface Variables { [k: string]: any }
|
|
10
|
+
|
|
11
|
+
class VariableProxy {
|
|
12
|
+
private readonly proxyCollection = new Map<Descriptor, any>()
|
|
13
|
+
private readonly variablesCollection = new Map<Descriptor, Variables>()
|
|
14
|
+
|
|
15
|
+
private createNestedProxy = (current: ActorCollection, root: Descriptor, currentPath = '') => {
|
|
16
|
+
return new Proxy(current, {
|
|
17
|
+
get: (target, prop: string) => {
|
|
18
|
+
if (typeof prop === 'symbol') return Reflect.get(target, prop)
|
|
19
|
+
|
|
20
|
+
const fullPath = currentPath ? `${currentPath}.${prop}` : prop
|
|
21
|
+
const variables = this.variablesCollection.get(root) as Variables
|
|
22
|
+
|
|
23
|
+
if (variables[fullPath] !== undefined) {
|
|
24
|
+
return variables[fullPath]
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const value = Reflect.get(target, prop)
|
|
28
|
+
|
|
29
|
+
if (value !== null && typeof value === 'object' && !Array.isArray(value)) {
|
|
30
|
+
return this.createNestedProxy(value, root, fullPath)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return value
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
private getVariableValue = (descriptor: Descriptor, data: Data, key: string, config: VariabConfig, graphics: Graphics, args: UpdateArgs) => {
|
|
38
|
+
if (config.type === 'key') {
|
|
39
|
+
return ObjectUtils.getValueByKey(data, config.value)
|
|
40
|
+
} else if (config.type === 'custom') {
|
|
41
|
+
const scriptable = Asset.get<Scriptable>(config.value)
|
|
42
|
+
if (scriptable === null) return
|
|
43
|
+
const currentArgs = { ...args, key, config, data }
|
|
44
|
+
return scriptable.execute(descriptor, graphics, currentArgs)
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
get<T extends Descriptor | null = Descriptor | null>(uuid: string, graphics: Graphics, args: UpdateArgs) {
|
|
49
|
+
const descriptor = Descriptor.get<Descriptor>(uuid)
|
|
50
|
+
if (descriptor === null) return null as unknown as T
|
|
51
|
+
|
|
52
|
+
let proxy = this.proxyCollection.get(descriptor)
|
|
53
|
+
let variables = this.variablesCollection.get(descriptor)
|
|
54
|
+
|
|
55
|
+
if (variables === undefined || variables.version > 0) {
|
|
56
|
+
variables = Object.create(null) as Variables
|
|
57
|
+
variables.version = 0
|
|
58
|
+
|
|
59
|
+
const data = DatasetDescriptor.getData(descriptor.dataset)
|
|
60
|
+
|
|
61
|
+
if (data !== null) {
|
|
62
|
+
const keys = Object.keys(descriptor.variables)
|
|
63
|
+
for (const key of keys) {
|
|
64
|
+
const variable = descriptor.variables[key]
|
|
65
|
+
if (variable.enabled === false) continue
|
|
66
|
+
const value = this.getVariableValue(descriptor, data, key, variable, graphics, args)
|
|
67
|
+
if (value === undefined) continue
|
|
68
|
+
variables[key] = value
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
this.variablesCollection.set(descriptor, variables)
|
|
73
|
+
proxy = this.createNestedProxy(descriptor, descriptor)
|
|
74
|
+
this.proxyCollection.set(descriptor, proxy)
|
|
75
|
+
} else if (proxy === undefined) {
|
|
76
|
+
proxy = this.createNestedProxy(descriptor, descriptor)
|
|
77
|
+
this.proxyCollection.set(descriptor, proxy)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return proxy as T
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
update(descriptor: Descriptor) {
|
|
84
|
+
const variables = this.variablesCollection.get(descriptor)
|
|
85
|
+
if (variables !== undefined) variables.version++
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export {
|
|
90
|
+
Variables,
|
|
91
|
+
VariableProxy
|
|
92
|
+
}
|