@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.
Files changed (95) hide show
  1. package/package.json +19 -0
  2. package/src/ArrayUtils.ts +65 -0
  3. package/src/AsyncTask.ts +72 -0
  4. package/src/Category.ts +119 -0
  5. package/src/Color.ts +111 -0
  6. package/src/Engine.ts +101 -0
  7. package/src/Generate.ts +40 -0
  8. package/src/InputSystem.ts +108 -0
  9. package/src/Listener.ts +59 -0
  10. package/src/ObjectPool.ts +84 -0
  11. package/src/ObjectUtils.ts +49 -0
  12. package/src/Scriptable.ts +27 -0
  13. package/src/Serialization.ts +49 -0
  14. package/src/Traverser.ts +39 -0
  15. package/src/actor/Actor.ts +28 -0
  16. package/src/actor/AnimationUnitActor.ts +289 -0
  17. package/src/actor/DivActor.ts +70 -0
  18. package/src/actor/FragmentActor.ts +56 -0
  19. package/src/actor/HTMActor.ts +166 -0
  20. package/src/actor/HTMServiceActor.ts +57 -0
  21. package/src/actor/HTMTransformControllerActor.ts +404 -0
  22. package/src/actor/StyleActor.ts +96 -0
  23. package/src/actor/index.ts +8 -0
  24. package/src/asset/Asset.ts +271 -0
  25. package/src/asset/AssetGraph.ts +246 -0
  26. package/src/asset/index.ts +2 -0
  27. package/src/descriptor/AnimationUnitDescriptor.ts +65 -0
  28. package/src/descriptor/CameraDescriptor.ts +12 -0
  29. package/src/descriptor/ControllerDescriptor.ts +16 -0
  30. package/src/descriptor/DatasetDescriptor.ts +92 -0
  31. package/src/descriptor/Descriptor.ts +415 -0
  32. package/src/descriptor/DivDescriptor.ts +18 -0
  33. package/src/descriptor/DynamicDescriptor.ts +27 -0
  34. package/src/descriptor/HTMLDescriptor.ts +87 -0
  35. package/src/descriptor/HTMLServiceDescriptor.ts +19 -0
  36. package/src/descriptor/HTMLTransformControllerDescriptor.ts +34 -0
  37. package/src/descriptor/NodeDescriptor.ts +32 -0
  38. package/src/descriptor/PrefabDescriptor.ts +53 -0
  39. package/src/descriptor/PrefabInstanceDescriptor.ts +32 -0
  40. package/src/descriptor/RoutineDescriptor.ts +54 -0
  41. package/src/descriptor/ServiceDescriptor.ts +32 -0
  42. package/src/descriptor/ServiceSchedulerDescriptor.ts +32 -0
  43. package/src/descriptor/StyleDescriptor.ts +213 -0
  44. package/src/descriptor/index.ts +17 -0
  45. package/src/graphics/Collection.ts +25 -0
  46. package/src/graphics/Compilation.ts +82 -0
  47. package/src/graphics/Graphics.ts +475 -0
  48. package/src/graphics/Observer.ts +36 -0
  49. package/src/graphics/Unit.ts +83 -0
  50. package/src/graphics/VariableProxy.ts +92 -0
  51. package/src/graphics/index.ts +5 -0
  52. package/src/index.ts +26 -0
  53. package/src/interpreter/AnimationUnitInterpreter.ts +53 -0
  54. package/src/interpreter/DatasetInterpreter.ts +11 -0
  55. package/src/interpreter/DivInterpreter.ts +44 -0
  56. package/src/interpreter/DynamicInterpreter.ts +207 -0
  57. package/src/interpreter/FragmentInterpreter.ts +34 -0
  58. package/src/interpreter/HTMLServiceInterpreter.ts +47 -0
  59. package/src/interpreter/HTMLTransformControllerInterpreter.ts +40 -0
  60. package/src/interpreter/Interpreter.ts +69 -0
  61. package/src/interpreter/PrefaInterpreter.ts +11 -0
  62. package/src/interpreter/PrefabInstanceInterpreter.ts +12 -0
  63. package/src/interpreter/RoutineInterpreter.ts +88 -0
  64. package/src/interpreter/ServiceInterpreter.ts +24 -0
  65. package/src/interpreter/ServiceSchedulerInterpreter.ts +42 -0
  66. package/src/interpreter/StyleInterpreter.ts +66 -0
  67. package/src/interpreter/index.ts +14 -0
  68. package/src/locale/Language.ts +10 -0
  69. package/src/locale/LanguageProvider.ts +48 -0
  70. package/src/locale/index.ts +2 -0
  71. package/src/math/Euler.ts +303 -0
  72. package/src/math/Matrix4.ts +1123 -0
  73. package/src/math/Quaternion.ts +737 -0
  74. package/src/math/Vector2.ts +680 -0
  75. package/src/math/Vector3.ts +1062 -0
  76. package/src/math/index.ts +5 -0
  77. package/src/math/utils.ts +17 -0
  78. package/src/preset/execute/dataset/index.ts +1 -0
  79. package/src/preset/execute/dataset/update.ts +52 -0
  80. package/src/preset/execute/graphics/index.ts +1 -0
  81. package/src/preset/execute/graphics/invoke.ts +49 -0
  82. package/src/preset/execute/index.ts +4 -0
  83. package/src/preset/execute/net/index.ts +1 -0
  84. package/src/preset/execute/net/request.ts +103 -0
  85. package/src/preset/execute/scheduler/index.ts +1 -0
  86. package/src/preset/execute/scheduler/switch.ts +46 -0
  87. package/src/preset/index.ts +7 -0
  88. package/src/preset/routine/graphics/index.ts +1 -0
  89. package/src/preset/routine/graphics/invoke.ts +27 -0
  90. package/src/preset/routine/index.ts +2 -0
  91. package/src/preset/routine/scheduler/index.ts +1 -0
  92. package/src/preset/routine/scheduler/switch.ts +27 -0
  93. package/src/setup/index.ts +17 -0
  94. package/src/utils/AssetProvider.ts +72 -0
  95. package/src/utils/index.ts +1 -0
package/src/index.ts ADDED
@@ -0,0 +1,26 @@
1
+ declare global {
2
+ interface SnowAssets { }
3
+ }
4
+
5
+ export * from './locale'
6
+ export * from './math'
7
+ export * from './Color'
8
+ export * from './Serialization'
9
+ export { Category } from './Category'
10
+ export { ArrayUtils } from './ArrayUtils'
11
+ export { ObjectUtils } from './ObjectUtils'
12
+ export { Generate } from './Generate'
13
+ export { Traverser } from './Traverser'
14
+ export { Listener } from './Listener'
15
+ export { InputSystem } from './InputSystem'
16
+ export { destroyInstance } from './ObjectPool'
17
+ export * from './AsyncTask'
18
+ export * from './Scriptable'
19
+ export * from './descriptor'
20
+ export * from './interpreter'
21
+ export * from './utils'
22
+ export * from './actor'
23
+ export * from './graphics'
24
+ export * from './asset'
25
+ export * from './preset'
26
+ export * from './Engine'
@@ -0,0 +1,53 @@
1
+ import { AnimationUnitDescriptor, Descriptor, UpdateArgs } from '../descriptor';
2
+ import { ArrayUtils } from '../ArrayUtils';
3
+ import { Interpreter } from './Interpreter'
4
+ import { AnimationUnitActor } from "../actor";
5
+
6
+ const privateState = {
7
+ collection: [] as AnimationUnitActor[],
8
+ }
9
+
10
+ class AnimationUnitInterpreter extends Interpreter {
11
+ static type = AnimationUnitDescriptor.type
12
+ static enabled = true
13
+ static reset(time = 0) {
14
+ const enabled = AnimationUnitInterpreter.enabled
15
+ AnimationUnitInterpreter.enabled = true
16
+ for (const animationUnit of privateState.collection) {
17
+ animationUnit.reset(time)
18
+ }
19
+ AnimationUnitInterpreter.enabled = enabled
20
+ }
21
+
22
+ animationUnit: AnimationUnitActor | null = null
23
+
24
+ freeUnit() {
25
+ if (this.animationUnit === null) return
26
+ ArrayUtils.remove(privateState.collection, this.animationUnit)
27
+ this.animationUnit.unlisten()
28
+ this.animationUnit = null
29
+ }
30
+
31
+
32
+ update(descriptor: AnimationUnitDescriptor, args: UpdateArgs) {
33
+ super.update(descriptor, args)
34
+
35
+ this.freeUnit()
36
+
37
+ const parentDescriptor = AnimationUnitDescriptor.get<AnimationUnitDescriptor>(this.unit.parent)
38
+ if (parentDescriptor === null) return
39
+
40
+ this.animationUnit = AnimationUnitActor.parse(descriptor)
41
+ ArrayUtils.insert(privateState.collection, this.animationUnit)
42
+ this.animationUnit.setTarget(parentDescriptor)
43
+ this.animationUnit.listen(this.graphics)
44
+ }
45
+
46
+ unmount(descriptor: AnimationUnitDescriptor, args: UpdateArgs, parentInterpreter: Interpreter, parentDescriptor: Descriptor) {
47
+ this.freeUnit()
48
+ super.unmount(descriptor, args, parentInterpreter, parentDescriptor)
49
+ }
50
+ }
51
+ Interpreter.register(AnimationUnitInterpreter)
52
+
53
+ export { AnimationUnitInterpreter }
@@ -0,0 +1,11 @@
1
+ import { DatasetDescriptor } from "../descriptor";
2
+ import { Interpreter } from "./Interpreter";
3
+
4
+ class DatasetInterpreter extends Interpreter {
5
+ static type = DatasetDescriptor.type
6
+ }
7
+ Interpreter.register(DatasetInterpreter)
8
+
9
+ export {
10
+ DatasetInterpreter
11
+ }
@@ -0,0 +1,44 @@
1
+ import { Descriptor, DivDescriptor, UpdateArgs } from "../descriptor"
2
+ import { Interpreter } from "./Interpreter"
3
+ import { DivActor, HTMLActor } from "../actor"
4
+ import { PickupObject } from "../graphics"
5
+
6
+ class DivInterpreter extends Interpreter {
7
+ static type = DivDescriptor.type
8
+
9
+ protected createActor(descriptor: DivDescriptor, args: UpdateArgs) {
10
+ return new DivActor(descriptor.uuid)
11
+ }
12
+
13
+ update(descriptor: DivDescriptor, args: UpdateArgs) {
14
+ super.update(descriptor, args)
15
+ const actor = this.getActor<DivActor>(descriptor, args)
16
+ actor.update(descriptor, args)
17
+ }
18
+
19
+ mount(descriptor: DivDescriptor, args: UpdateArgs, parentInterpreter: Interpreter, parentDescriptor: Descriptor) {
20
+ super.mount(descriptor, args, parentInterpreter, parentDescriptor)
21
+ const actor = this.getActor<DivActor>(descriptor, args)
22
+
23
+ const parenActor = parentInterpreter.getActor<HTMLActor>(parentDescriptor, args)
24
+ parenActor.add(actor)
25
+ }
26
+
27
+ unmount(descriptor: DivDescriptor, args: UpdateArgs, parentInterpreter: Interpreter, parentDescriptor: Descriptor) {
28
+ const actor = this.getActor<DivActor>(descriptor, args)
29
+ actor.clearStyleClass(actor.DOM)
30
+ actor.cleanInteraction()
31
+
32
+ const parenActor = parentInterpreter.getActor<HTMLActor>(parentDescriptor, args)
33
+ parenActor.remove(actor)
34
+
35
+ super.unmount(descriptor, args, parentInterpreter, parentDescriptor)
36
+ }
37
+
38
+ pickup(descriptor: DivDescriptor, args: UpdateArgs, result: PickupObject[]) {
39
+ result.push({ uuid: descriptor.uuid, generatedBy: descriptor.generatedBy })
40
+ }
41
+ }
42
+ Interpreter.register(DivInterpreter)
43
+
44
+ export { DivInterpreter }
@@ -0,0 +1,207 @@
1
+ import { ArrayUtils } from "../ArrayUtils"
2
+ import { Asset } from "../asset"
3
+ import { DynamicDescriptor, Descriptor, UpdateArgs, Data, DatasetDescriptor, PrefabeDescriptor } from "../descriptor"
4
+ import { observer, UpdateWatcherArgs, WatcherArgs } from "../graphics"
5
+ import { Category } from "../Category"
6
+ import { FragmentInterpreter, Interpreter } from "."
7
+
8
+ class DynamicInterpreter extends FragmentInterpreter {
9
+ static type = DynamicDescriptor.type
10
+
11
+ private _currentDepth = 0
12
+ private _datasetCloneCollection = new Map<string, DatasetDescriptor>()
13
+ private _rawToCloneCollection = new Map<string, Descriptor[]>()
14
+ private _cloneCollection = new Map<number, Descriptor>()
15
+
16
+ private _getDataset(descriptor: Descriptor, dataCollection: Data, i: number) {
17
+ const url = Asset.createVirtualUrl(`dynamic/dataset/${descriptor.uuid}-${i}-${this._currentDepth}${Category.datasetSuffix}`)
18
+ if (this._datasetCloneCollection.has(url)) return url
19
+ const data = dataCollection[i]
20
+ const dataset = new DatasetDescriptor()
21
+ dataset.setExtraData({ index: i })
22
+ dataset.setData(data)
23
+ Asset.set(url, dataset)
24
+ this._datasetCloneCollection.set(url, dataset)
25
+ return url
26
+ }
27
+ private _getDataByDataset<T extends Data | null = Data | null>(url: string) {
28
+ const dataset = this._datasetCloneCollection.get(url)
29
+
30
+ return (dataset?.getData() ?? null) as T
31
+ }
32
+
33
+ private _setCache(raw: Descriptor, clone: Descriptor) {
34
+ let clones = this._rawToCloneCollection.get(raw.uuid)
35
+ if (clones === undefined) {
36
+ clones = []
37
+ this._rawToCloneCollection.set(raw.uuid, clones)
38
+ }
39
+ clones.push(clone)
40
+ }
41
+
42
+ private _markSubDynamic(raw: DynamicDescriptor, parent: Descriptor, generatedBy: string, map: Map<string, Descriptor>, childs: Descriptor[]) {
43
+ this._currentDepth += 1
44
+ const template = Asset.get<Descriptor>(raw.url)
45
+ if (raw.dataConfig === 2) {
46
+ const parentData = this._getDataByDataset(parent.dataset)
47
+ if (parentData === null || typeof parentData !== 'object') return
48
+ //TODO 使用路径解析工具,实现更强大属性支持
49
+ const pathData = parentData[raw.dataPath]
50
+ if (Array.isArray(pathData) === false || pathData.length === 0) return
51
+
52
+ for (let i = 0; i < pathData.length; i++) {
53
+ const dataset = this._getDataset(raw, pathData, i)
54
+ const clone = this._markAndClone(template, dataset, generatedBy, map, childs)
55
+ parent.add(clone)
56
+ }
57
+ } else {
58
+ const selfData = this._getDataByDataset(raw.dataset)
59
+ if (Array.isArray(selfData) === false || selfData.length === 0) return
60
+
61
+ for (let i = 0; i < selfData.length; i++) {
62
+ const dataset = this._getDataset(raw, selfData, i)
63
+ const clone = this._markAndClone(template, dataset, generatedBy, map, childs)
64
+ parent.add(clone)
65
+ }
66
+ }
67
+ }
68
+
69
+ private _markAndClone(raw: Descriptor, dataset: string, generatedBy: string, map: Map<string, Descriptor>, childs: Descriptor[]) {
70
+ let clone
71
+ if (raw instanceof DynamicDescriptor) {
72
+ clone = new Descriptor({ dataset })
73
+ if (raw.url) this._markSubDynamic(raw, clone, generatedBy, map, childs)
74
+ } else if (raw instanceof PrefabeDescriptor) {
75
+ clone = new Descriptor({ dataset })
76
+ } else {
77
+ clone = raw.clone(false)
78
+ clone.dataset = dataset
79
+ map.set(raw.uuid, clone)
80
+ if (clone.interactions.length > 0) childs.push(clone)
81
+ }
82
+
83
+ clone.generatedBy = generatedBy
84
+
85
+ for (const subRaw of raw.children) {
86
+ const subClone = this._markAndClone(subRaw, dataset, generatedBy, map, childs)
87
+ clone.add(subClone)
88
+ }
89
+
90
+ this._setCache(raw, clone)
91
+
92
+ return clone
93
+ }
94
+
95
+ private _onAdd = (args: WatcherArgs) => {
96
+ const clones = this._rawToCloneCollection.get(args.puid)
97
+ if (clones === undefined) return
98
+
99
+ const max = clones.length
100
+ const descriptor = Descriptor.get<Descriptor>(args.self)
101
+ for (let i = 0; i < max; i++) {
102
+ const clone = clones[i]
103
+ const map = new Map<string, Descriptor>()
104
+ const childs: Descriptor[] = []
105
+ const subClone = this._markAndClone(descriptor, clone.dataset, clone.generatedBy, map, childs)
106
+ Descriptor.fixReferences(childs, map)
107
+ clone.add(subClone)
108
+ }
109
+ }
110
+
111
+ private _onRemove = (args: WatcherArgs) => {
112
+ const clones = this._rawToCloneCollection.get(args.self)
113
+ if (clones === undefined) return
114
+
115
+ while (clones.length > 0) {
116
+ const clone = clones.pop()
117
+ if (clone === undefined) continue
118
+ const parent = this.graphics.getParent(clone.uuid)
119
+ if (parent === null) continue
120
+ parent.remove(clone)
121
+ ArrayUtils.remove(clones, clone)
122
+ }
123
+ const descriptor = Descriptor.get<Descriptor>(args.self)
124
+ descriptor.traverse(sub => {
125
+ this._rawToCloneCollection.delete(sub.uuid)
126
+ })
127
+ }
128
+
129
+ private _onUpdate = (args: UpdateWatcherArgs) => {
130
+ const clones = this._rawToCloneCollection.get(args.self)
131
+ if (clones === undefined) return
132
+
133
+ const raw = Descriptor.get<Descriptor>(args.self)
134
+ if (raw instanceof DynamicDescriptor) {
135
+ const ancestor = raw.traceAncestor()
136
+ if (ancestor.parent === null) return
137
+ const watcher = { self: args.self, puid: ancestor.parent.uuid }
138
+ this._onRemove(watcher)
139
+ this._onAdd(watcher)
140
+ } else {
141
+ for (const clone of clones) {
142
+ clone.syncWith(raw)
143
+ clone.setNeedsUpdate()
144
+ }
145
+ }
146
+ }
147
+
148
+ private _clearByOnUpdate = (args: WatcherArgs) => {
149
+ if (args.self !== this.unit.uuid) return
150
+
151
+ this._rawToCloneCollection.clear()
152
+ this._datasetCloneCollection.clear()
153
+
154
+ const clones = this._cloneCollection.values()
155
+ for (const clone of clones) {
156
+ observer.trigger('remove', { self: clone.uuid, puid: this.unit.uuid })
157
+ }
158
+ this._cloneCollection.clear()
159
+ }
160
+
161
+ mount(descriptor: Descriptor, args: UpdateArgs, parentInterpreter: Interpreter, parentDescriptor: Descriptor): void {
162
+ super.mount(descriptor, args, parentInterpreter, parentDescriptor)
163
+ observer.listen('update', this._clearByOnUpdate)
164
+ }
165
+
166
+ unmount(descriptor: Descriptor, args: UpdateArgs, parentInterpreter: Interpreter, parentDescriptor: Descriptor) {
167
+ observer.unlisten('update', this._clearByOnUpdate)
168
+ super.unmount(descriptor, args, parentInterpreter, parentDescriptor)
169
+ }
170
+
171
+ update(descriptor: DynamicDescriptor, args: UpdateArgs) {
172
+ super.update(descriptor, args)
173
+
174
+ observer.unlisten('add', this._onAdd)
175
+ observer.unlisten('remove', this._onRemove)
176
+ observer.unlisten('update', this._onUpdate)
177
+
178
+ if (descriptor.dataset && descriptor.url) {
179
+ const rootData = DatasetDescriptor.getCollection(descriptor.dataset)
180
+ if (rootData.length > 0) {
181
+ const template = Asset.get<Descriptor>(descriptor.url)
182
+ for (let i = 0; i < rootData.length; i++) {
183
+ this._currentDepth = 0
184
+ const dataset = this._getDataset(descriptor, rootData, i)
185
+ const map = new Map<string, Descriptor>()
186
+ const childs: Descriptor[] = []
187
+ const clone = this._markAndClone(template, dataset, descriptor.uuid, map, childs)
188
+ Descriptor.fixReferences(childs, map)
189
+ this._cloneCollection.set(i, clone)
190
+ observer.trigger('add', { self: clone.uuid, puid: descriptor.uuid })
191
+ }
192
+ }
193
+ }
194
+
195
+ observer.listen('add', this._onAdd)
196
+ observer.listen('remove', this._onRemove)
197
+ observer.listen('update', this._onUpdate)
198
+ }
199
+
200
+ free(descriptor: Descriptor, args: UpdateArgs) {
201
+ observer.unlisten('add', this._onAdd)
202
+ observer.unlisten('remove', this._onRemove)
203
+ observer.unlisten('update', this._onUpdate)
204
+ super.free(descriptor, args)
205
+ }
206
+ }
207
+ FragmentInterpreter.register(DynamicInterpreter)
@@ -0,0 +1,34 @@
1
+ import { FragmentActor } from "../actor";
2
+ import { Descriptor, UpdateArgs } from "../descriptor";
3
+ import { Interpreter } from "./Interpreter";
4
+
5
+ class FragmentInterpreter extends Interpreter {
6
+ static type = Descriptor.type
7
+
8
+ protected createActor(descriptor: Descriptor, args: UpdateArgs) {
9
+ return new FragmentActor()
10
+ }
11
+
12
+ /**将节点挂载到场景 */
13
+ mount(descriptor: Descriptor, args: UpdateArgs, parentInterpreter: Interpreter, parentDescriptor: Descriptor) {
14
+ super.mount(descriptor, args, parentInterpreter, parentDescriptor)
15
+ const actor = this.getActor<FragmentActor>(descriptor, args)
16
+ actor.bind(parentDescriptor.uuid)
17
+ }
18
+
19
+ /**将节点从场景中卸载 */
20
+ unmount(descriptor: Descriptor, args: UpdateArgs, parentInterpreter: Interpreter, parentDescriptor: Descriptor) {
21
+ super.unmount(descriptor, args, parentInterpreter, parentDescriptor)
22
+ }
23
+
24
+ free(descriptor: Descriptor, args: UpdateArgs): void {
25
+ const actor = this.getActor<FragmentActor>(descriptor, args)
26
+ actor.unbind()
27
+ super.free(descriptor, args)
28
+ }
29
+ }
30
+ Interpreter.register(FragmentInterpreter)
31
+
32
+ export {
33
+ FragmentInterpreter
34
+ }
@@ -0,0 +1,47 @@
1
+ import { Descriptor, HTMLServiceDescriptor, UpdateArgs } from "../descriptor"
2
+ import { Interpreter, ServiceInterpreter } from "."
3
+ import { HTMLActor, HTMLServiceActor } from "../actor"
4
+ import { PickupObject } from "../graphics"
5
+
6
+ class HTMLServiceInterpreter extends ServiceInterpreter {
7
+ static type = HTMLServiceDescriptor.type
8
+
9
+ protected createActor(descriptor: HTMLServiceDescriptor, args: UpdateArgs) {
10
+ const actor = new HTMLServiceActor(descriptor.uuid)
11
+ actor.DOM.addEventListener('pointerdown', e => e.stopPropagation())
12
+ return actor
13
+ }
14
+
15
+ update(descriptor: HTMLServiceDescriptor, args: UpdateArgs) {
16
+ super.update(descriptor, args)
17
+
18
+ const actor = this.getActor<HTMLServiceActor>(descriptor, args)
19
+ actor.update(descriptor, args)
20
+ }
21
+
22
+ mount(descriptor: HTMLServiceDescriptor, args: UpdateArgs, parentInterpreter: Interpreter, parentDescriptor: Descriptor) {
23
+ super.mount(descriptor, args, parentInterpreter, parentDescriptor)
24
+ const actor = this.getActor<HTMLServiceActor>(descriptor, args)
25
+
26
+ const parenActor = parentInterpreter.getActor<HTMLActor>(parentDescriptor, args)
27
+ parenActor.add(actor)
28
+ }
29
+
30
+ unmount(descriptor: HTMLServiceDescriptor, args: UpdateArgs, parentInterpreter: Interpreter, parentDescriptor: Descriptor) {
31
+ const actor = this.getActor<HTMLServiceActor>(descriptor, args)
32
+ actor.clearStyleClass(actor.DOM)
33
+ actor.cleanInteraction()
34
+
35
+ const parenActor = parentInterpreter.getActor<HTMLActor>(parentDescriptor, args)
36
+ parenActor.remove(actor)
37
+
38
+ super.unmount(descriptor, args, parentInterpreter, parentDescriptor)
39
+ }
40
+
41
+ pickup(descriptor: HTMLServiceDescriptor, args: UpdateArgs, result: PickupObject[]) {
42
+ result.push({ uuid: descriptor.uuid, generatedBy: descriptor.generatedBy })
43
+ }
44
+ }
45
+ ServiceInterpreter.register(HTMLServiceInterpreter)
46
+
47
+ export { HTMLServiceInterpreter }
@@ -0,0 +1,40 @@
1
+ import { Descriptor, HTMLTransformControllerDescriptor, UpdateArgs } from "../descriptor"
2
+ import { HTMLTransformControllerActor } from "../actor"
3
+ import { Interpreter } from "./Interpreter"
4
+
5
+ class HTMLTransformControllerInterpreter extends Interpreter {
6
+ static type = HTMLTransformControllerDescriptor.type
7
+
8
+ protected createActor(descriptor: HTMLTransformControllerDescriptor, args: UpdateArgs) {
9
+ const actor = new HTMLTransformControllerActor()
10
+ return actor
11
+ }
12
+
13
+ update(descriptor: HTMLTransformControllerDescriptor, args: UpdateArgs) {
14
+ super.update(descriptor, args)
15
+ const actor = this.getActor<HTMLTransformControllerActor>(descriptor, args)
16
+ actor.update(descriptor, args)
17
+ }
18
+
19
+ mount(descriptor: HTMLTransformControllerDescriptor, args: UpdateArgs, parentInterpreter: Interpreter, parentDescriptor: Descriptor) {
20
+ super.mount(descriptor, args, parentInterpreter, parentDescriptor)
21
+ this.getActor<HTMLTransformControllerActor>(descriptor, args)
22
+ }
23
+
24
+ unmount(descriptor: HTMLTransformControllerDescriptor, args: UpdateArgs, parentInterpreter: Interpreter, parentDescriptor: Descriptor) {
25
+ const actor = this.getActor<HTMLTransformControllerActor>(descriptor, args)
26
+ actor.unlisten()
27
+
28
+ super.unmount(descriptor, args, parentInterpreter, parentDescriptor)
29
+ }
30
+
31
+ free(descriptor: HTMLTransformControllerDescriptor, args: UpdateArgs) {
32
+ const actor = this.getActor<HTMLTransformControllerActor>(descriptor, args)
33
+ actor.dispose()
34
+ super.free(descriptor, args)
35
+ }
36
+ }
37
+ Interpreter.register(HTMLTransformControllerInterpreter)
38
+
39
+
40
+ export { HTMLTransformControllerInterpreter }
@@ -0,0 +1,69 @@
1
+ import { language } from '../locale'
2
+ import { Actor } from '../actor'
3
+ import { Unit, PickupObject, Graphics } from "../graphics"
4
+ import { Descriptor, UpdateArgs } from "../descriptor"
5
+
6
+ const privateState = {
7
+ factory: false,
8
+ classCollection: new Map<string, typeof Interpreter>(),
9
+ actorCollection: new Map<Interpreter, Actor>(),
10
+ }
11
+
12
+ /**
13
+ * 对描述进行解释,不同的扩展对每个描述都有不同的解释器
14
+ *
15
+ * 警告:解释器在实现时不能对自身的描述器直接进行引用,从而导致描述器始终存在引用而无法被垃圾回收机制回收。
16
+ */
17
+ class Interpreter {
18
+ static type = 'Interpreter'
19
+ static register(DerivedClass: typeof Interpreter) {
20
+ privateState.classCollection.set(DerivedClass.type, DerivedClass)
21
+ }
22
+ /**获取注册的派生类 */
23
+ static getClass<T extends typeof Interpreter>(type: string) {
24
+ return (privateState.classCollection.get(type) ?? null) as T | null
25
+ }
26
+
27
+ readonly unit
28
+ readonly graphics
29
+
30
+ constructor(unit: Unit, graphics: Graphics) {
31
+ if (privateState.factory === false) throw language.get('interpreter.new.fail')
32
+ this.unit = unit
33
+ this.graphics = graphics
34
+ }
35
+
36
+ protected createActor(descriptor: Descriptor, args: UpdateArgs) {
37
+ return new Actor()
38
+ }
39
+
40
+ /**使用描述器获取代理对象,若代理对象不存在则会使用描述器创建一个代理对象 */
41
+ getActor<T extends Actor = Actor>(descriptor: Descriptor, args: UpdateArgs): T {
42
+ let actor = privateState.actorCollection.get(this)
43
+ if (actor !== undefined) return actor as T
44
+ actor = this.createActor(descriptor, args)
45
+ Actor.seGraphics(actor, this.graphics)
46
+ privateState.actorCollection.set(this, actor)
47
+ return actor as T
48
+ }
49
+
50
+ /**使用描述更新节点 */
51
+ update(descriptor: Descriptor, args: UpdateArgs) { }
52
+
53
+ /**将节点挂载到场景 */
54
+ mount(descriptor: Descriptor, args: UpdateArgs, parentInterpreter: Interpreter, parentDescriptor: Descriptor) { }
55
+
56
+ /**将节点从场景中卸载 */
57
+ unmount(descriptor: Descriptor, args: UpdateArgs, parentInterpreter: Interpreter, parentDescriptor: Descriptor) { }
58
+
59
+ free(descriptor: Descriptor, args: UpdateArgs) {
60
+ const actor = privateState.actorCollection.get(this)
61
+ if (actor === undefined) return
62
+ Actor.seGraphics(actor, this.graphics)
63
+ privateState.actorCollection.delete(this)
64
+ }
65
+
66
+ pickup(descriptor: Descriptor, args: UpdateArgs, result: PickupObject[]) { }
67
+ }
68
+
69
+ export { Interpreter, privateState }
@@ -0,0 +1,11 @@
1
+ import { PrefabeDescriptor } from "../descriptor";
2
+ import { FragmentInterpreter } from "./FragmentInterpreter";
3
+
4
+ class PrefaInterpreter extends FragmentInterpreter {
5
+ static type = PrefabeDescriptor.type
6
+ }
7
+ FragmentInterpreter.register(PrefaInterpreter)
8
+
9
+ export {
10
+ PrefaInterpreter
11
+ }
@@ -0,0 +1,12 @@
1
+ import { PrefabInstanceDescriptor } from "../descriptor";
2
+ import { FragmentInterpreter } from "./FragmentInterpreter";
3
+
4
+ class PrefabInstanceInterpreter extends FragmentInterpreter {
5
+ static type = PrefabInstanceDescriptor.type
6
+
7
+ }
8
+ FragmentInterpreter.register(PrefabInstanceInterpreter)
9
+
10
+ export {
11
+ PrefabInstanceInterpreter
12
+ }
@@ -0,0 +1,88 @@
1
+ import { Asset } from "../asset";
2
+ import { Scriptable } from "../Scriptable";
3
+ import { RoutineDescriptor, RoutineNode, UpdateArgs, InteractionInputCollection } from "../descriptor";
4
+ import { Interpreter } from "./Interpreter";
5
+
6
+ type ExecuteResult = { [k: string]: any } | null
7
+
8
+ class RoutineInterpreter extends Interpreter {
9
+ static type = RoutineDescriptor.type
10
+ readonly collection = new Map<string, RoutineNode>()
11
+ readonly linkCollection = new Map<string, string[]>()
12
+
13
+ update(descriptor: RoutineDescriptor, args: UpdateArgs) {
14
+ super.update(descriptor, args)
15
+
16
+ this.collection.clear()
17
+ this.linkCollection.clear()
18
+
19
+ for (const node of descriptor.nodes) {
20
+ this.collection.set(node.id, node)
21
+ }
22
+
23
+ for (const mapper of descriptor.mappers) {
24
+ let link = this.linkCollection.get(mapper.source)
25
+ if (link === undefined) {
26
+ link = []
27
+ this.linkCollection.set(mapper.source, link)
28
+ }
29
+ link.push(mapper.target)
30
+ }
31
+ }
32
+
33
+ async doBranch(branch: string, previous: string, customInputs: InteractionInputCollection, descriptor: RoutineDescriptor, args: UpdateArgs, result: Map<string, ExecuteResult>) {
34
+ this.doExecute(branch, previous, customInputs, descriptor, args, result)
35
+ }
36
+
37
+ async doCondition(condition: string, previous: string, customInputs: InteractionInputCollection, descriptor: RoutineDescriptor, args: UpdateArgs, result: Map<string, ExecuteResult>) {
38
+ const preResult = result.get(previous)
39
+ const conditionResult = result.get(condition)
40
+ if (preResult !== conditionResult?.condition.value) return
41
+
42
+ this.doExecute(condition, previous, customInputs, descriptor, args, result)
43
+ }
44
+
45
+ async doExecute(execute: string, previous: string, customInputs: InteractionInputCollection, descriptor: RoutineDescriptor, args: UpdateArgs, result: Map<string, ExecuteResult>) {
46
+ const nexts = this.linkCollection.get(execute)
47
+ if (nexts === undefined) return
48
+
49
+ for (const next of nexts) {
50
+ await this.doNext(next, execute, customInputs, descriptor, args, result)
51
+ }
52
+ }
53
+
54
+ async doNext(current: string, previous: string, customInputs: InteractionInputCollection, descriptor: RoutineDescriptor, args: UpdateArgs, result: Map<string, ExecuteResult>) {
55
+ const active = this.collection.get(current)
56
+ if (active === undefined) return
57
+
58
+ const currentInput = customInputs[current] ?? {}
59
+ const script = Asset.get<Scriptable>(active.url)
60
+ if (script) {
61
+ const event = { ...args, input: { previous, default: active.input, user: currentInput }, result }
62
+ const executeResult = await script.execute(descriptor, this.graphics, event)
63
+ result.set(current, executeResult)
64
+ }
65
+
66
+ if (active.routine === 'Branch') {
67
+ this.doBranch(current, previous, customInputs, descriptor, args, result)
68
+ } else if (active.routine === 'Condition') {
69
+ if (result.has(current) === false) result.set(current, active.input)
70
+ this.doCondition(current, previous, customInputs, descriptor, args, result)
71
+ } else {
72
+ this.doExecute(current, previous, customInputs, descriptor, args, result)
73
+ }
74
+ }
75
+
76
+ do(customInputs: InteractionInputCollection, descriptor: RoutineDescriptor, args: UpdateArgs) {
77
+ for (const root of descriptor.roots) {
78
+ const resultCollection = new Map()
79
+ this.doNext(root, '', customInputs, descriptor, args, resultCollection)
80
+ }
81
+ }
82
+
83
+ }
84
+ Interpreter.register(RoutineInterpreter)
85
+
86
+ export {
87
+ RoutineInterpreter
88
+ }
@@ -0,0 +1,24 @@
1
+ import { ServiceDescriptor, UpdateArgs } from "../descriptor";
2
+ import { PickupObject } from "../graphics";
3
+ import { Interpreter } from "./Interpreter";
4
+
5
+ class ServiceInterpreter extends Interpreter {
6
+ static type = ServiceDescriptor.type
7
+
8
+ clear(service: ServiceDescriptor, args: UpdateArgs) { }
9
+
10
+ beforeRender(service: ServiceDescriptor, args: UpdateArgs) { }
11
+
12
+ render(service: ServiceDescriptor, args: UpdateArgs) { }
13
+
14
+ afterRender(service: ServiceDescriptor, args: UpdateArgs) { }
15
+
16
+ beforePickup(mouse: { x: number; y: number }, rect: DOMRect, args: UpdateArgs) { }
17
+
18
+ orderBy(result: PickupObject[]) { }
19
+ }
20
+ Interpreter.register(ServiceInterpreter)
21
+
22
+ export {
23
+ ServiceInterpreter
24
+ }