@vyr/engine 0.0.2 → 0.0.4
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 +1 -1
- package/src/Engine.ts +17 -3
- package/src/asset/Asset.ts +18 -3
- package/src/graphics/Compilation.ts +20 -17
- package/src/graphics/Graphics.ts +4 -5
- package/src/locale/LanguageProvider.ts +2 -0
- package/src/preset/execute/dataset/compile.ts +60 -4
- package/src/preset/execute/net/http.ts +2 -1
- package/src/preset/execute/scheduler/switch.ts +1 -0
- package/src/preset/interaction/dataset/compile.ts +27 -0
- package/src/preset/interaction/dataset/index.ts +1 -0
- package/src/preset/interaction/graphics/invoke.ts +1 -1
- package/src/preset/interaction/index.ts +1 -0
- package/src/preset/interaction/scheduler/switch.ts +1 -1
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"@vyr/engine","version":"0.0.
|
|
1
|
+
{"name":"@vyr/engine","version":"0.0.4","description":"","main":"./src/index.ts","author":"","license":"MIT","dependencies":{"@vyr/locale":"0.0.4","tinycolor2":"1.6.0"},"devDependencies":{"@types/tinycolor2":"1.4.6"},"files":["package.json","src/"]}
|
package/src/Engine.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { language } from './locale'
|
|
2
|
+
import { Asset } from './asset'
|
|
2
3
|
import { ServiceSchedulerDescriptor, StyleDescriptor } from './descriptor'
|
|
3
4
|
import { Generate } from './Generate'
|
|
4
5
|
import { InputSystem } from './InputSystem'
|
|
@@ -15,6 +16,7 @@ interface EngineListener {
|
|
|
15
16
|
|
|
16
17
|
class Engine extends Listener<EngineListener> {
|
|
17
18
|
private compilation = new Compilation()
|
|
19
|
+
private active = ''
|
|
18
20
|
private prevTimestamp = 0
|
|
19
21
|
private frame = 0
|
|
20
22
|
|
|
@@ -76,9 +78,17 @@ class Engine extends Listener<EngineListener> {
|
|
|
76
78
|
}
|
|
77
79
|
|
|
78
80
|
switch(scheduler: ServiceSchedulerDescriptor) {
|
|
79
|
-
|
|
81
|
+
const url = Asset.getUrlByUuid(scheduler.uuid)
|
|
80
82
|
|
|
81
|
-
|
|
83
|
+
if (!url) throw language.get('engine.switch.url.notFound')
|
|
84
|
+
|
|
85
|
+
const current = Asset.get<ServiceSchedulerDescriptor>(this.active)
|
|
86
|
+
if (current) this.compilation.unlisten(current)
|
|
87
|
+
|
|
88
|
+
const graphics = this.compilation.ensureExists(url, scheduler, this)
|
|
89
|
+
|
|
90
|
+
this.compilation.listen(graphics)
|
|
91
|
+
this.active = url
|
|
82
92
|
|
|
83
93
|
window.dispatchEvent(new Event('resize'))
|
|
84
94
|
|
|
@@ -90,12 +100,16 @@ class Engine extends Listener<EngineListener> {
|
|
|
90
100
|
}
|
|
91
101
|
|
|
92
102
|
clear() {
|
|
93
|
-
this.compilation.clear(
|
|
103
|
+
this.compilation.clear()
|
|
94
104
|
}
|
|
95
105
|
|
|
96
106
|
getGraphics(scheduler: ServiceSchedulerDescriptor) {
|
|
97
107
|
return this.compilation.get(scheduler)
|
|
98
108
|
}
|
|
109
|
+
|
|
110
|
+
ensureGraphicsExists(url: string, scheduler: ServiceSchedulerDescriptor) {
|
|
111
|
+
return this.compilation.ensureExists(url, scheduler, this)
|
|
112
|
+
}
|
|
99
113
|
}
|
|
100
114
|
|
|
101
115
|
export { Engine }
|
package/src/asset/Asset.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { language } from "../locale"
|
|
2
2
|
import { Category } from "../Category"
|
|
3
3
|
import { AsyncTask } from "../AsyncTask"
|
|
4
|
-
import { DatasetDescriptor, Descriptor } from "../descriptor"
|
|
4
|
+
import { DatasetDescriptor, Descriptor, ServiceSchedulerDescriptor } from "../descriptor"
|
|
5
5
|
import { InteractionDescriptor, Scriptable, ScriptableArgs } from "../interaction"
|
|
6
6
|
import { AssetGraph } from "./AssetGraph"
|
|
7
|
+
import { Engine } from "../Engine"
|
|
7
8
|
|
|
8
9
|
type JsonAsset = { [k: string]: any }
|
|
9
10
|
type RawAsset = HTMLImageElement | ImageBitmap | HTMLAudioElement | AudioBuffer | HTMLVideoElement | string | JsonAsset
|
|
@@ -31,7 +32,7 @@ const privateState = {
|
|
|
31
32
|
}
|
|
32
33
|
|
|
33
34
|
class Asset {
|
|
34
|
-
static baseUrl =
|
|
35
|
+
static baseUrl = location.origin
|
|
35
36
|
static graph = new AssetGraph()
|
|
36
37
|
|
|
37
38
|
static fetch(url: string, params?: any) {
|
|
@@ -169,6 +170,20 @@ class Asset {
|
|
|
169
170
|
privateState.activeAssets.length = 0
|
|
170
171
|
}
|
|
171
172
|
|
|
173
|
+
static async compileDataset(url: string, engine: Engine) {
|
|
174
|
+
const descriptor = this.get<ServiceSchedulerDescriptor>(url)
|
|
175
|
+
const graphics = engine.ensureGraphicsExists(url, descriptor)
|
|
176
|
+
const dependencide = Asset.graph.getDependencide(url)
|
|
177
|
+
|
|
178
|
+
const queue: Promise<void>[] = []
|
|
179
|
+
for (const dataset of dependencide.dataset) {
|
|
180
|
+
const trigger = Asset.get<Descriptor>(dataset)
|
|
181
|
+
queue.push(graphics.invoke('compile', trigger))
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
await Promise.all(queue)
|
|
185
|
+
}
|
|
186
|
+
|
|
172
187
|
static async loadAll(url: string, forced = false, record: string[] = []) {
|
|
173
188
|
await Asset.load(url, forced)
|
|
174
189
|
Asset.graph.create(url)
|
|
@@ -214,7 +229,7 @@ Asset.register(Category.scene, factoryDescriptor)
|
|
|
214
229
|
const factoryDataset = async (url: string) => {
|
|
215
230
|
const asset = await factoryDescriptor(url) as DatasetDescriptor
|
|
216
231
|
// if (asset.auto) await asset.fetch()
|
|
217
|
-
|
|
232
|
+
|
|
218
233
|
return asset
|
|
219
234
|
}
|
|
220
235
|
Asset.register(Category.dataset, factoryDataset)
|
|
@@ -10,27 +10,30 @@ class Compilation {
|
|
|
10
10
|
return (this.collection.get(scheduler.uuid) ?? null) as Graphics
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
const url = Asset.getUrlByUuid(scheduler.uuid)
|
|
15
|
-
if (url) {
|
|
16
|
-
let graphics = this.collection.get(scheduler.uuid)
|
|
17
|
-
if (graphics === undefined) {
|
|
18
|
-
graphics = new Graphics(url, scheduler, engine)
|
|
19
|
-
this.collection.set(scheduler.uuid, graphics)
|
|
20
|
-
}
|
|
21
|
-
graphics.listen()
|
|
22
|
-
|
|
23
|
-
return graphics
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
unlisten(scheduler: ServiceSchedulerDescriptor, engine: Engine) {
|
|
13
|
+
delete(scheduler: ServiceSchedulerDescriptor) {
|
|
28
14
|
const graphics = this.collection.get(scheduler.uuid)
|
|
29
15
|
if (graphics === undefined) return
|
|
30
16
|
graphics.unlisten()
|
|
31
17
|
this.collection.delete(scheduler.uuid)
|
|
32
18
|
}
|
|
33
19
|
|
|
20
|
+
ensureExists(url: string, scheduler: ServiceSchedulerDescriptor, engine: Engine) {
|
|
21
|
+
let graphics = this.collection.get(scheduler.uuid)
|
|
22
|
+
if (graphics === undefined) {
|
|
23
|
+
graphics = new Graphics(url, scheduler, engine)
|
|
24
|
+
this.collection.set(scheduler.uuid, graphics)
|
|
25
|
+
}
|
|
26
|
+
return graphics
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
listen(graphics: Graphics) {
|
|
30
|
+
graphics.listen()
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
unlisten(scheduler: ServiceSchedulerDescriptor) {
|
|
34
|
+
this.delete(scheduler)
|
|
35
|
+
}
|
|
36
|
+
|
|
34
37
|
foreach(executor: (graphics: Graphics) => void) {
|
|
35
38
|
const collection = this.collection.values()
|
|
36
39
|
|
|
@@ -58,10 +61,10 @@ class Compilation {
|
|
|
58
61
|
engine.trigger('afterRender', args)
|
|
59
62
|
}
|
|
60
63
|
|
|
61
|
-
clear(
|
|
64
|
+
clear() {
|
|
62
65
|
const collection = this.collection.values()
|
|
63
66
|
for (const graphics of collection) {
|
|
64
|
-
this.unlisten(graphics.scheduler
|
|
67
|
+
this.unlisten(graphics.scheduler)
|
|
65
68
|
}
|
|
66
69
|
}
|
|
67
70
|
}
|
package/src/graphics/Graphics.ts
CHANGED
|
@@ -151,7 +151,8 @@ class Graphics {
|
|
|
151
151
|
asset.queue.iterator(operation => this.do(operation))
|
|
152
152
|
}
|
|
153
153
|
|
|
154
|
-
const master = this.unitCollection.get(this.scheduler.uuid)
|
|
154
|
+
const master = this.unitCollection.get(this.scheduler.uuid)
|
|
155
|
+
if (master === undefined) return
|
|
155
156
|
|
|
156
157
|
master.queue.iterator(operation => this.do(operation))
|
|
157
158
|
|
|
@@ -206,8 +207,6 @@ class Graphics {
|
|
|
206
207
|
this.unitCollection.set(unit)
|
|
207
208
|
this._freeCollection.delete(unit.uuid)
|
|
208
209
|
|
|
209
|
-
if (root instanceof DatasetDescriptor) this.invoke('compile', root)
|
|
210
|
-
|
|
211
210
|
unit.trigger(Queue.Update)
|
|
212
211
|
for (const sub of root.children) {
|
|
213
212
|
observer.trigger('add', { self: sub.uuid, puid: root.uuid })
|
|
@@ -462,12 +461,12 @@ class Graphics {
|
|
|
462
461
|
return result
|
|
463
462
|
}
|
|
464
463
|
|
|
465
|
-
invoke(interaction: string, descriptor: Descriptor) {
|
|
464
|
+
async invoke(interaction: string, descriptor: Descriptor) {
|
|
466
465
|
if (descriptor.interactions.length === 0) return
|
|
467
466
|
for (const inter of descriptor.interactions) {
|
|
468
467
|
if (inter.type === interaction) {
|
|
469
468
|
const current = Asset.get<InteractionDescriptor>(inter.url)
|
|
470
|
-
if (current !== null) current.execute(inter.inputs, this, descriptor)
|
|
469
|
+
if (current !== null) await current.execute(inter.inputs, this, descriptor)
|
|
471
470
|
break
|
|
472
471
|
}
|
|
473
472
|
}
|
|
@@ -13,6 +13,7 @@ interface ZhCNLanguageProvider extends LanguageProvider {
|
|
|
13
13
|
'graphics.interpreter.notRegister': string
|
|
14
14
|
'graphics.unit.notFound': string
|
|
15
15
|
'engine.run.container.notFound': string
|
|
16
|
+
'engine.switch.url.notFound': string
|
|
16
17
|
|
|
17
18
|
'/virtual:/preset/net/http.ts': string
|
|
18
19
|
'/virtual:/preset/dataset/update.ts': string
|
|
@@ -36,6 +37,7 @@ const zhCnLanguageProvider: ZhCNLanguageProvider = {
|
|
|
36
37
|
'graphics.interpreter.notRegister': '未注册解释器:{{type}}',
|
|
37
38
|
'graphics.unit.notFound': '单元不存在:{{uuid}}',
|
|
38
39
|
'engine.run.container.notFound': '挂载节点不存在',
|
|
40
|
+
'engine.switch.url.notFound': '切换失败,无法获资产地址!',
|
|
39
41
|
|
|
40
42
|
'/virtual:/preset/net/http.ts': '网络请求',
|
|
41
43
|
'/virtual:/preset/dataset/update.ts': '更新数据集',
|
|
@@ -1,22 +1,78 @@
|
|
|
1
1
|
import { language } from "../../../locale";
|
|
2
2
|
import { Asset } from "../../../asset";
|
|
3
3
|
import { InteractionNode, Scriptable, ScriptableArgs } from "../../../interaction";
|
|
4
|
+
import { DatasetDescriptor, Descriptor, HttpDataConfig } from "../../../descriptor";
|
|
4
5
|
import { Graphics } from "../../../graphics";
|
|
6
|
+
import { ExecuteScriptable as HttpScriptable } from "../net/http";
|
|
5
7
|
|
|
6
8
|
const scriptable = Asset.createVirtualUrl('preset/dataset/compile.ts')
|
|
7
9
|
class ExecuteScriptable extends Scriptable {
|
|
10
|
+
|
|
11
|
+
async getData(config: HttpDataConfig, http: HttpScriptable, trigger: Descriptor, graphics: Graphics) {
|
|
12
|
+
const args: ScriptableArgs = {
|
|
13
|
+
input: {
|
|
14
|
+
previous: '',
|
|
15
|
+
user: {
|
|
16
|
+
type: { value: config.type },
|
|
17
|
+
url: { value: config.url },
|
|
18
|
+
data: { value: '' },
|
|
19
|
+
},
|
|
20
|
+
default: {}
|
|
21
|
+
},
|
|
22
|
+
result: new Map(),
|
|
23
|
+
trigger: trigger
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const data = await http.execute(graphics, args)
|
|
27
|
+
|
|
28
|
+
return this.transformData(data, config)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
transformData(data: any, config: HttpDataConfig) {
|
|
32
|
+
return data
|
|
33
|
+
}
|
|
34
|
+
|
|
8
35
|
async execute(graphics: Graphics, args: ScriptableArgs) {
|
|
9
|
-
|
|
10
|
-
|
|
36
|
+
const { trigger } = args
|
|
37
|
+
|
|
38
|
+
if (trigger instanceof DatasetDescriptor && trigger.dataConfigs.length > 0) {
|
|
39
|
+
const dataConfigs = trigger.dataConfigs as HttpDataConfig[]
|
|
40
|
+
const http = new HttpScriptable(Asset.createVirtualUrl('preset/dataset/compile/http.ts'))
|
|
41
|
+
|
|
42
|
+
let mergeData: any[] | any
|
|
43
|
+
if (dataConfigs.length === 1) {
|
|
44
|
+
const config = dataConfigs[0]
|
|
45
|
+
const finalData = await this.getData(config, http, trigger, graphics)
|
|
46
|
+
mergeData = config.key ? { [config.key]: finalData } : finalData
|
|
47
|
+
} else {
|
|
48
|
+
const keys = new Set<string>()
|
|
49
|
+
const queue: Promise<any>[] = []
|
|
50
|
+
for (const config of dataConfigs) {
|
|
51
|
+
keys.add(config.key)
|
|
11
52
|
|
|
12
|
-
|
|
53
|
+
const task = this.getData(config, http, trigger, graphics).then(finalData => {
|
|
54
|
+
const first = keys.values().next().value
|
|
55
|
+
if (keys.size === 1 && (first === '' || first === undefined)) {
|
|
56
|
+
if (!mergeData) mergeData = []
|
|
57
|
+
mergeData.push(finalData)
|
|
58
|
+
} else {
|
|
59
|
+
if (!mergeData) mergeData = {}
|
|
60
|
+
mergeData[config.key] ? Object.assign(mergeData[config.key], finalData) : mergeData[config.key] = finalData
|
|
61
|
+
}
|
|
62
|
+
})
|
|
63
|
+
queue.push(task)
|
|
64
|
+
}
|
|
65
|
+
await Promise.all(queue)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
trigger.setData(mergeData)
|
|
69
|
+
}
|
|
13
70
|
}
|
|
14
71
|
}
|
|
15
72
|
Asset.provider(scriptable, async () => ({ default: ExecuteScriptable }))
|
|
16
73
|
|
|
17
74
|
const createExecuteInput = (args: any = {}) => {
|
|
18
75
|
const input = {
|
|
19
|
-
|
|
20
76
|
}
|
|
21
77
|
|
|
22
78
|
return input
|
|
@@ -8,7 +8,7 @@ const scriptable = Asset.createVirtualUrl('preset/net/http.ts')
|
|
|
8
8
|
class ExecuteScriptable extends Scriptable {
|
|
9
9
|
|
|
10
10
|
joinUrl(url: string, requestData: any) {
|
|
11
|
-
const urlObj = new URL(url);
|
|
11
|
+
const urlObj = new URL(Asset.joinUrl(url));
|
|
12
12
|
|
|
13
13
|
// 直接将requestData添加到urlObj的searchParams中
|
|
14
14
|
Object.entries(requestData).forEach(([key, value]) => {
|
|
@@ -87,6 +87,7 @@ const createExecuteNode = (options: { id: string; position?: any; input?: any })
|
|
|
87
87
|
|
|
88
88
|
export {
|
|
89
89
|
scriptable,
|
|
90
|
+
ExecuteScriptable,
|
|
90
91
|
createExecuteInput,
|
|
91
92
|
createExecuteNode,
|
|
92
93
|
}
|
|
@@ -10,6 +10,7 @@ class ExecuteScriptable extends Scriptable {
|
|
|
10
10
|
const scene = args.input?.user?.scene.value
|
|
11
11
|
if (!scene) return
|
|
12
12
|
await Asset.loadAll(scene)
|
|
13
|
+
await Asset.compileDataset(scene, graphics.engine)
|
|
13
14
|
const scheduler = Asset.get<ServiceSchedulerDescriptor>(scene)
|
|
14
15
|
graphics.engine.switch(scheduler)
|
|
15
16
|
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Asset } from "../../../asset";
|
|
2
|
+
import { InteractionDescriptor } from "../../../interaction";
|
|
3
|
+
import { dataset } from "../../execute"
|
|
4
|
+
|
|
5
|
+
const url = Asset.createVirtualUrl('preset/dataset/compile.interaction.json')
|
|
6
|
+
const nodes = {
|
|
7
|
+
compile: 'compile'
|
|
8
|
+
}
|
|
9
|
+
let _currentInteraction: InteractionDescriptor | null = null
|
|
10
|
+
const interactionProvider = async () => {
|
|
11
|
+
if (_currentInteraction === null) {
|
|
12
|
+
_currentInteraction = new InteractionDescriptor()
|
|
13
|
+
const compileNode = dataset.compile.createExecuteNode({ id: nodes.compile })
|
|
14
|
+
_currentInteraction.addNode([compileNode])
|
|
15
|
+
_currentInteraction.roots.push(compileNode.id)
|
|
16
|
+
}
|
|
17
|
+
return _currentInteraction
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
Asset.provider(url, interactionProvider)
|
|
21
|
+
|
|
22
|
+
export {
|
|
23
|
+
url,
|
|
24
|
+
nodes,
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * as compile from "./compile"
|
|
@@ -11,7 +11,7 @@ const interactionProvider = async () => {
|
|
|
11
11
|
if (_currentInteraction === null) {
|
|
12
12
|
_currentInteraction = new InteractionDescriptor()
|
|
13
13
|
const invokeNode = graphics.invoke.createExecuteNode({ id: nodes.invoke })
|
|
14
|
-
_currentInteraction.
|
|
14
|
+
_currentInteraction.addNode([invokeNode])
|
|
15
15
|
_currentInteraction.roots.push(invokeNode.id)
|
|
16
16
|
}
|
|
17
17
|
return _currentInteraction
|
|
@@ -11,7 +11,7 @@ const interactionProvider = async () => {
|
|
|
11
11
|
if (_currentInteraction === null) {
|
|
12
12
|
_currentInteraction = new InteractionDescriptor()
|
|
13
13
|
const switchNode = scheduler.switch.createExecuteNode({ id: nodes.switch })
|
|
14
|
-
_currentInteraction.
|
|
14
|
+
_currentInteraction.addNode([switchNode])
|
|
15
15
|
_currentInteraction.roots.push(switchNode.id)
|
|
16
16
|
}
|
|
17
17
|
return _currentInteraction
|