@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,16 @@
|
|
|
1
|
+
import { DeserializationObject } from "../Serialization"
|
|
2
|
+
import { Descriptor } from "./Descriptor"
|
|
3
|
+
|
|
4
|
+
class ControllerDescriptor extends Descriptor {
|
|
5
|
+
static type = 'Controller'
|
|
6
|
+
|
|
7
|
+
/**控制器是否响应用户的操作 */
|
|
8
|
+
enabled: boolean
|
|
9
|
+
|
|
10
|
+
constructor(descriptor: Partial<DeserializationObject<ControllerDescriptor>> = {}) {
|
|
11
|
+
super(descriptor)
|
|
12
|
+
this.enabled = descriptor.enabled ?? false
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export { ControllerDescriptor }
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { Asset } from "../asset";
|
|
2
|
+
import { observer } from "../graphics/Observer";
|
|
3
|
+
import { DeserializationObject } from "../Serialization";
|
|
4
|
+
import { Descriptor } from "./Descriptor";
|
|
5
|
+
|
|
6
|
+
interface Data {
|
|
7
|
+
[k: string]: any
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
class DatasetDescriptor extends Descriptor {
|
|
11
|
+
static type = 'Dataset'
|
|
12
|
+
|
|
13
|
+
static getData<T = Data>(dataset: string) {
|
|
14
|
+
const descriptor = Asset.get(dataset)
|
|
15
|
+
if (descriptor instanceof DatasetDescriptor) {
|
|
16
|
+
return descriptor.getData() as T
|
|
17
|
+
} else {
|
|
18
|
+
return null
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
static getCollection<T = Data>(dataset: string): T[] {
|
|
22
|
+
const data = this.getData<T>(dataset)
|
|
23
|
+
|
|
24
|
+
if (!data) return []
|
|
25
|
+
|
|
26
|
+
return Array.isArray(data) ? data : [data]
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
private _extraData: Data = {}
|
|
30
|
+
private _data!: Data
|
|
31
|
+
defaultData: Data
|
|
32
|
+
url: string
|
|
33
|
+
auto: boolean
|
|
34
|
+
|
|
35
|
+
constructor(descriptor: Partial<DeserializationObject<DatasetDescriptor>> = {}) {
|
|
36
|
+
super(descriptor)
|
|
37
|
+
this.defaultData = descriptor.defaultData === undefined ? {} : Descriptor.deepClone(descriptor.defaultData)
|
|
38
|
+
this.url = descriptor.url ?? ''
|
|
39
|
+
this.auto = descriptor.auto ?? true
|
|
40
|
+
this._updateData(this.defaultData)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
async fetch() {
|
|
44
|
+
if (!this.url) return
|
|
45
|
+
try {
|
|
46
|
+
const res = await Asset.fetch(Asset.joinUrl(this.url))
|
|
47
|
+
const data = await res.json()
|
|
48
|
+
|
|
49
|
+
if (Object.hasOwn(data, 'data')) {
|
|
50
|
+
if (data.data !== null && typeof data.data === 'object') this.setData(data.data)
|
|
51
|
+
} else {
|
|
52
|
+
this.setData(data)
|
|
53
|
+
}
|
|
54
|
+
} catch (error) {
|
|
55
|
+
console.warn(error)
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
private _updateData(data: Data) {
|
|
60
|
+
this._data = data
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
getData<T extends Data | null = Data | null>() {
|
|
64
|
+
return (this._data ?? null) as T
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
setData(data: Data) {
|
|
68
|
+
this._updateData(data)
|
|
69
|
+
|
|
70
|
+
observer.trigger('updateDeps', { self: this.uuid })
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
setExtraData(data: Data) {
|
|
74
|
+
this._extraData = data
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
getExtraData<T extends Data = Data>() {
|
|
78
|
+
return this._extraData as T
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
toJSON() {
|
|
82
|
+
const { _data, _extraData, ...rest } = this;
|
|
83
|
+
return rest;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
Descriptor.register(DatasetDescriptor)
|
|
88
|
+
|
|
89
|
+
export {
|
|
90
|
+
Data,
|
|
91
|
+
DatasetDescriptor
|
|
92
|
+
}
|
|
@@ -0,0 +1,415 @@
|
|
|
1
|
+
import { language } from '../locale'
|
|
2
|
+
import { listenInstance, ObjectPool } from '../ObjectPool'
|
|
3
|
+
import { ArrayUtils } from '../ArrayUtils'
|
|
4
|
+
import { Generate } from '../Generate'
|
|
5
|
+
import { Traverser } from '../Traverser'
|
|
6
|
+
import { ObjectUtils } from '../ObjectUtils'
|
|
7
|
+
import { DeserializationObject, Serialization, SerializationObject } from '../Serialization'
|
|
8
|
+
import { AssetProperty, AssetPropertyCollection } from '../asset'
|
|
9
|
+
import { observer } from '../graphics/Observer'
|
|
10
|
+
|
|
11
|
+
/**描述器祖先节点 */
|
|
12
|
+
interface DescriptorAncestor<T extends Descriptor = Descriptor> {
|
|
13
|
+
parent: T | null,
|
|
14
|
+
uuids: string[]
|
|
15
|
+
collection: Descriptor[]
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**当前描述器节点的邻接关系 */
|
|
19
|
+
interface DescriptorAdjacency {
|
|
20
|
+
/**当前节点的父节点 */
|
|
21
|
+
parent: string
|
|
22
|
+
/**当前节点的前一个节点 */
|
|
23
|
+
prev: string
|
|
24
|
+
/**当前节点的后一个节点 */
|
|
25
|
+
next: string
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
interface DescriptorPrefab {
|
|
29
|
+
root: string
|
|
30
|
+
uuid: string
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
interface UpdateArgs {
|
|
34
|
+
delta: number
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
interface VariabConfig {
|
|
38
|
+
type: 'key' | 'custom'
|
|
39
|
+
enabled: boolean
|
|
40
|
+
value: string
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
interface DescriptorVariables {
|
|
44
|
+
[k: string]: VariabConfig
|
|
45
|
+
}
|
|
46
|
+
interface InteractionInput {
|
|
47
|
+
[param: string]: {
|
|
48
|
+
type?: 'data' | string
|
|
49
|
+
value: any
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
interface InteractionInputCollection {
|
|
54
|
+
[id: string]: InteractionInput
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
interface InteractionProperty extends AssetProperty {
|
|
58
|
+
uuid: string
|
|
59
|
+
type: string
|
|
60
|
+
inputs: InteractionInputCollection
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
interface InteractionPropertyCollection extends AssetPropertyCollection<InteractionProperty> { }
|
|
64
|
+
|
|
65
|
+
const privateState = {
|
|
66
|
+
classCollection: new Map<string, typeof Descriptor>(),
|
|
67
|
+
prefabToInstanceCollection: new Map<string, string[]>(),
|
|
68
|
+
instanceToPrefabCollection: new Map<string, string>(),
|
|
69
|
+
refGraph: new Map<string, string>(),
|
|
70
|
+
getParent: <T extends Descriptor = Descriptor>(uuid: string) => {
|
|
71
|
+
const parent = privateState.refGraph.get(uuid)
|
|
72
|
+
if (parent === undefined) return null
|
|
73
|
+
return Descriptor.get<T>(parent)
|
|
74
|
+
},
|
|
75
|
+
setPrefabInstance(instance: Descriptor) {
|
|
76
|
+
if (instance.prefab === false) return
|
|
77
|
+
|
|
78
|
+
let instanceCollection = this.prefabToInstanceCollection.get(instance.prefab.uuid)
|
|
79
|
+
if (instanceCollection === undefined) {
|
|
80
|
+
instanceCollection = []
|
|
81
|
+
this.prefabToInstanceCollection.set(instance.prefab.uuid, instanceCollection)
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
ArrayUtils.insert(instanceCollection, instance.uuid)
|
|
85
|
+
this.instanceToPrefabCollection.set(instance.uuid, instance.prefab.uuid)
|
|
86
|
+
},
|
|
87
|
+
markclone: (descriptor: Descriptor, root: string, map: Map<string, Descriptor>, childs: Descriptor[]) => {
|
|
88
|
+
const clone = descriptor.clone(false)
|
|
89
|
+
map.set(descriptor.uuid, clone)
|
|
90
|
+
if (clone.interactions.length > 0) childs.push(clone)
|
|
91
|
+
|
|
92
|
+
if (clone.prefab === false) {
|
|
93
|
+
clone.prefab = { root, uuid: descriptor.uuid }
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
for (const sub of descriptor.children) {
|
|
97
|
+
const child = privateState.markclone(sub, root, map, childs)
|
|
98
|
+
clone.add(child)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return clone
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* 描述引擎所使用的场景、资产对象
|
|
108
|
+
*
|
|
109
|
+
* 每一个派生类的需要重新定义该类的静态属性`type`
|
|
110
|
+
*
|
|
111
|
+
* 描述器不能使用浏览器环境特有API,因为服务端也会使用描述器
|
|
112
|
+
*
|
|
113
|
+
* 不建议将一个描述器作为另一个描述器的属性,若要保持引用关系,将描述器的uuid作为属性即可
|
|
114
|
+
*/
|
|
115
|
+
class Descriptor extends ObjectPool {
|
|
116
|
+
static type = 'Descriptor'
|
|
117
|
+
/**注册描述器的派生类 */
|
|
118
|
+
static register(DerivedClass: typeof Descriptor) {
|
|
119
|
+
privateState.classCollection.set(DerivedClass.type, DerivedClass)
|
|
120
|
+
}
|
|
121
|
+
/**获取注册的派生类 */
|
|
122
|
+
static getClass<T extends typeof Descriptor>(type: string) {
|
|
123
|
+
return (privateState.classCollection.get(type) ?? null) as T | null
|
|
124
|
+
}
|
|
125
|
+
/**使用数据动态的创建描述器 */
|
|
126
|
+
static create<T extends Descriptor = Descriptor>(descriptor: Partial<DeserializationObject<Descriptor>>) {
|
|
127
|
+
const Class = this.getClass(descriptor.type ?? Descriptor.type)
|
|
128
|
+
if (Class === null) throw language.get('descriptor.notRegister', { type: descriptor.type })
|
|
129
|
+
return new Class(descriptor) as T
|
|
130
|
+
}
|
|
131
|
+
/**将对象序列化成json字符 */
|
|
132
|
+
static serialization(descriptor: SerializationObject) {
|
|
133
|
+
return Serialization.stringify(descriptor)
|
|
134
|
+
}
|
|
135
|
+
/**将json字符反序列化成对象 */
|
|
136
|
+
static deserialization<T = any>(str: string) {
|
|
137
|
+
return Serialization.parse(str) as T
|
|
138
|
+
}
|
|
139
|
+
/**深度克隆传入的JSON对象 */
|
|
140
|
+
static deepClone<T = any>(descriptor: SerializationObject) {
|
|
141
|
+
return Serialization.deepClone<T>(descriptor)
|
|
142
|
+
}
|
|
143
|
+
/**修复引用关系 */
|
|
144
|
+
static fixReferences(childs: Descriptor[], map: Map<string, Descriptor>) {
|
|
145
|
+
for (const child of childs) {
|
|
146
|
+
for (const interaction of child.interactions) {
|
|
147
|
+
const keys = Object.keys(interaction.inputs)
|
|
148
|
+
for (const key of keys) {
|
|
149
|
+
const input = interaction.inputs[key]
|
|
150
|
+
const attrs = Object.keys(input)
|
|
151
|
+
for (const attr of attrs) {
|
|
152
|
+
const cur = input[attr]
|
|
153
|
+
const clone = map.get(cur.value)
|
|
154
|
+
if (clone === undefined) continue
|
|
155
|
+
cur.value = clone.uuid
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
/**创建镜像副本并修复引用关系 */
|
|
162
|
+
static cloneAndFixReferences(descriptor: Descriptor) {
|
|
163
|
+
const map = new Map()
|
|
164
|
+
const childs: Descriptor[] = []
|
|
165
|
+
const clone = privateState.markclone(descriptor, descriptor.uuid, map, childs)
|
|
166
|
+
this.fixReferences(childs, map)
|
|
167
|
+
|
|
168
|
+
return clone
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
static getPrefab(uuid: string) {
|
|
172
|
+
return privateState.instanceToPrefabCollection.get(uuid) ?? null
|
|
173
|
+
}
|
|
174
|
+
static getInstanceCollection(uuid: string) {
|
|
175
|
+
return privateState.prefabToInstanceCollection.get(uuid) ?? null
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
readonly type: string
|
|
179
|
+
readonly children: Descriptor[]
|
|
180
|
+
generatedBy = ''
|
|
181
|
+
name: string
|
|
182
|
+
dataset: string
|
|
183
|
+
variables: DescriptorVariables
|
|
184
|
+
interactions: InteractionPropertyCollection
|
|
185
|
+
selectable: boolean
|
|
186
|
+
prefab: DescriptorPrefab | false
|
|
187
|
+
|
|
188
|
+
constructor(descriptor: Partial<DeserializationObject<Descriptor>> = {}) {
|
|
189
|
+
super(descriptor.uuid)
|
|
190
|
+
|
|
191
|
+
this.type = (this.constructor as typeof Descriptor).type
|
|
192
|
+
this.name = descriptor.name ?? ''
|
|
193
|
+
this.dataset = descriptor.dataset ?? ''
|
|
194
|
+
this.variables = descriptor.variables ? Descriptor.deepClone(descriptor.variables) : {}
|
|
195
|
+
this.interactions = descriptor.interactions ? Descriptor.deepClone(descriptor.interactions) : []
|
|
196
|
+
this.selectable = descriptor.selectable ?? true
|
|
197
|
+
this.prefab = descriptor.prefab ? Descriptor.deepClone(descriptor.prefab) : false
|
|
198
|
+
//@ts-ignore
|
|
199
|
+
this.children = []
|
|
200
|
+
|
|
201
|
+
privateState.setPrefabInstance(this)
|
|
202
|
+
|
|
203
|
+
if (Array.isArray(descriptor.children) && descriptor.children.length > 0) {
|
|
204
|
+
for (const subDescriptor of descriptor.children) this.add(Descriptor.create(subDescriptor))
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
protected beenInstantiated(instance: Descriptor): void {
|
|
209
|
+
instance.clear()
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**将`descriptor`添加到此节点中*/
|
|
213
|
+
add(...descriptor: Descriptor[]) {
|
|
214
|
+
|
|
215
|
+
for (const sub of descriptor) {
|
|
216
|
+
if (this.children.indexOf(sub) > -1) continue
|
|
217
|
+
|
|
218
|
+
const ancestor = sub.traceAncestor(false)
|
|
219
|
+
if (ancestor.parent !== null) ancestor.parent.remove(sub)
|
|
220
|
+
|
|
221
|
+
this.children.push(sub)
|
|
222
|
+
privateState.refGraph.set(sub.uuid, this.uuid)
|
|
223
|
+
|
|
224
|
+
observer.trigger('add', { self: sub.uuid, puid: this.uuid })
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
/**将`descriptor`从此节点中移除*/
|
|
228
|
+
remove(...descriptor: Descriptor[]) {
|
|
229
|
+
for (const sub of descriptor) {
|
|
230
|
+
for (let i = 0; i < this.children.length; i++) {
|
|
231
|
+
if (this.children[i].uuid !== sub.uuid) continue
|
|
232
|
+
|
|
233
|
+
observer.trigger('remove', { self: sub.uuid, puid: this.uuid })
|
|
234
|
+
|
|
235
|
+
this.children.splice(i, 1)
|
|
236
|
+
privateState.refGraph.delete(sub.uuid)
|
|
237
|
+
break
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* 追踪描述器的祖先节点
|
|
243
|
+
* @param all 追踪全部的祖先节点,默认为true
|
|
244
|
+
*/
|
|
245
|
+
traceAncestor<T extends Descriptor = Descriptor>(all = true, depth = Infinity) {
|
|
246
|
+
let parent = privateState.getParent<T>(this.uuid)
|
|
247
|
+
const ancestor: DescriptorAncestor<T> = { parent, uuids: [], collection: [] }
|
|
248
|
+
if (parent === null) return ancestor
|
|
249
|
+
|
|
250
|
+
ancestor.collection.push(parent)
|
|
251
|
+
ancestor.uuids.push(parent.uuid)
|
|
252
|
+
|
|
253
|
+
if (all === true) {
|
|
254
|
+
let count = 1
|
|
255
|
+
parent = privateState.getParent(parent.uuid) as T
|
|
256
|
+
while (parent && count < depth) {
|
|
257
|
+
count++
|
|
258
|
+
ancestor.collection.push(parent)
|
|
259
|
+
ancestor.uuids.push(parent.uuid)
|
|
260
|
+
parent = privateState.getParent(parent.uuid) as T
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
return ancestor
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/**将`uuid`节点插入到`target`节点中。*/
|
|
268
|
+
insert(uuid: string, target: string) {
|
|
269
|
+
const insertNode = Descriptor.get<Descriptor>(uuid)
|
|
270
|
+
if (insertNode === null) return console.warn(language.get('descriptor.insert.uuid.notFound', { uuid }))
|
|
271
|
+
|
|
272
|
+
const targetNode = Descriptor.get<Descriptor>(target)
|
|
273
|
+
if (targetNode === null) return console.warn(language.get('descriptor.insert.target.notFound', { target }))
|
|
274
|
+
|
|
275
|
+
const ancestor = insertNode.traceAncestor(false)
|
|
276
|
+
if (ancestor.parent) ancestor.parent.remove(insertNode)
|
|
277
|
+
targetNode.add(insertNode)
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/**将`uuid`节点插入到`target`节点前。 */
|
|
281
|
+
insertBefore(uuid: string, target: string, offset = 0) {
|
|
282
|
+
const insertNode = Descriptor.get<Descriptor>(uuid)
|
|
283
|
+
if (insertNode === null) return console.warn(language.get('descriptor.insert.uuid.notFound', { uuid }))
|
|
284
|
+
|
|
285
|
+
const targetNode = Descriptor.get<Descriptor>(target)
|
|
286
|
+
if (targetNode === null) return console.warn(language.get('descriptor.insert.target.notFound', { target }))
|
|
287
|
+
const targetAncestor = targetNode.traceAncestor(false)
|
|
288
|
+
if (targetAncestor.parent === null) return
|
|
289
|
+
const targetParent = targetAncestor.parent
|
|
290
|
+
|
|
291
|
+
const insertAncestor = insertNode.traceAncestor(false)
|
|
292
|
+
if (insertAncestor.parent !== null) insertAncestor.parent.remove(insertNode)
|
|
293
|
+
|
|
294
|
+
let index = -1
|
|
295
|
+
|
|
296
|
+
for (let i = 0; i < targetParent.children.length; i++) {
|
|
297
|
+
const sub = targetParent.children[i]
|
|
298
|
+
if (sub === targetNode) index = i + offset;
|
|
299
|
+
observer.trigger('remove', { self: sub.uuid, puid: targetParent.uuid })
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
targetParent.children.splice(index, 0, insertNode)
|
|
303
|
+
privateState.refGraph.set(insertNode.uuid, targetParent.uuid)
|
|
304
|
+
|
|
305
|
+
for (const sub of targetParent.children) {
|
|
306
|
+
observer.trigger('add', { self: sub.uuid, puid: targetParent.uuid })
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
/**将`uuid`节点插入到`target`节点后。 */
|
|
310
|
+
insertAfter(uuid: string, target: string) {
|
|
311
|
+
return this.insertBefore(uuid, target, 1)
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/**获取当前节点的邻接节点 */
|
|
315
|
+
getAdjacent() {
|
|
316
|
+
const adjacent: DescriptorAdjacency = {
|
|
317
|
+
parent: '',
|
|
318
|
+
prev: '',
|
|
319
|
+
next: '',
|
|
320
|
+
}
|
|
321
|
+
const ancestor = this.traceAncestor(false)
|
|
322
|
+
if (ancestor.parent === null) return adjacent
|
|
323
|
+
|
|
324
|
+
adjacent.parent = ancestor.parent.uuid
|
|
325
|
+
const i = ancestor.parent.children.indexOf(this)
|
|
326
|
+
if (i > 0) adjacent.prev = ancestor.parent.children[i - 1].uuid
|
|
327
|
+
if (i < ancestor.parent.children.length - 1) adjacent.next = ancestor.parent.children[i + 1].uuid
|
|
328
|
+
|
|
329
|
+
return adjacent
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* 克隆一个新的描述器
|
|
334
|
+
*
|
|
335
|
+
* 注意,该方法返回的描述器与原描述器uuid不相同
|
|
336
|
+
* @param recursive 是否遍历克隆子节点,默认为true
|
|
337
|
+
*/
|
|
338
|
+
clone<T extends Descriptor = Descriptor>(recursive = true) {
|
|
339
|
+
const uuid = Generate.uuid()
|
|
340
|
+
const self = Descriptor.create<T>({ ...this, uuid, children: undefined }) as T
|
|
341
|
+
if (recursive === false) return self
|
|
342
|
+
for (const sub of this.children) self.add(sub.clone(recursive))
|
|
343
|
+
return self
|
|
344
|
+
}
|
|
345
|
+
/**从同类型的对象上同步属性,不同步`uuid`、`children`和`type` */
|
|
346
|
+
syncWith(descriptor: DeserializationObject<Descriptor>, ignore: string[] = []) {
|
|
347
|
+
if (this.type !== descriptor.type) return console.warn(language.get('descriptor.syncWith.fail'))
|
|
348
|
+
|
|
349
|
+
const source = Descriptor.create({ ...descriptor, type: this.type, uuid: undefined, children: undefined }) as DeserializationObject
|
|
350
|
+
delete source['uuid']
|
|
351
|
+
delete source['type']
|
|
352
|
+
delete source['children']
|
|
353
|
+
delete source['prefab']
|
|
354
|
+
delete source['generatedBy']
|
|
355
|
+
|
|
356
|
+
for (const key of ignore) delete source[key]
|
|
357
|
+
|
|
358
|
+
Object.assign(this, source)
|
|
359
|
+
}
|
|
360
|
+
/**
|
|
361
|
+
* 遍历所有节点
|
|
362
|
+
* @param cb 遍历每个节点执行的回调
|
|
363
|
+
* @param terminated 遍历是否可以被终止,默认false
|
|
364
|
+
*/
|
|
365
|
+
traverse<T extends Descriptor = Descriptor, D extends T | null = T | null>(cb: (sub: T, parent: D) => true | void, terminated = false, defaultParent: D = null as D) {
|
|
366
|
+
if (terminated) {
|
|
367
|
+
Traverser.preTerminated(this as unknown as T, cb, defaultParent)
|
|
368
|
+
} else {
|
|
369
|
+
Traverser.pre(this as unknown as T, cb, defaultParent)
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
/**将子描述器全部移除 */
|
|
373
|
+
clear() {
|
|
374
|
+
this.remove(...this.children)
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
/**将对象序列化成json字符 */
|
|
378
|
+
serialization() {
|
|
379
|
+
return Descriptor.serialization(this)
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
equals(descriptor: DeserializationObject<Descriptor>, ignore: string[] = ['children']) {
|
|
383
|
+
return ObjectUtils.equals(this, descriptor, ignore)
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
setNeedsUpdate() {
|
|
387
|
+
observer.trigger('update', { self: this.uuid })
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
Descriptor.register(Descriptor)
|
|
391
|
+
|
|
392
|
+
listenInstance('free', (uuid: string) => {
|
|
393
|
+
observer.trigger('free', { self: uuid })
|
|
394
|
+
privateState.refGraph.delete(uuid)
|
|
395
|
+
const prefab = privateState.instanceToPrefabCollection.get(uuid)
|
|
396
|
+
if (prefab === undefined) return
|
|
397
|
+
privateState.instanceToPrefabCollection.delete(uuid)
|
|
398
|
+
const instanceCollection = privateState.prefabToInstanceCollection.get(uuid)
|
|
399
|
+
if (instanceCollection === undefined) return
|
|
400
|
+
ArrayUtils.remove(instanceCollection, uuid)
|
|
401
|
+
})
|
|
402
|
+
|
|
403
|
+
export {
|
|
404
|
+
Descriptor,
|
|
405
|
+
UpdateArgs,
|
|
406
|
+
DescriptorAdjacency,
|
|
407
|
+
DescriptorAncestor,
|
|
408
|
+
DescriptorPrefab,
|
|
409
|
+
VariabConfig,
|
|
410
|
+
DescriptorVariables,
|
|
411
|
+
InteractionInput,
|
|
412
|
+
InteractionInputCollection,
|
|
413
|
+
InteractionProperty,
|
|
414
|
+
InteractionPropertyCollection,
|
|
415
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { DeserializationObject } from "../Serialization"
|
|
2
|
+
import { HTMLDescriptor } from "./HTMLDescriptor"
|
|
3
|
+
|
|
4
|
+
class DivDescriptor extends HTMLDescriptor {
|
|
5
|
+
static type = 'Div'
|
|
6
|
+
|
|
7
|
+
text: string
|
|
8
|
+
backroundIamge: string
|
|
9
|
+
|
|
10
|
+
constructor(descriptor: Partial<DeserializationObject<DivDescriptor>> = {}) {
|
|
11
|
+
super(descriptor)
|
|
12
|
+
this.text = descriptor.text ?? ''
|
|
13
|
+
this.backroundIamge = descriptor.backroundIamge ?? ''
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
HTMLDescriptor.register(DivDescriptor)
|
|
17
|
+
|
|
18
|
+
export { DivDescriptor }
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { DeserializationObject } from "../Serialization"
|
|
2
|
+
import { Descriptor } from "./Descriptor"
|
|
3
|
+
|
|
4
|
+
class DynamicDescriptor extends Descriptor {
|
|
5
|
+
static type = 'Dynamic'
|
|
6
|
+
|
|
7
|
+
url: string
|
|
8
|
+
/** 数据集配置
|
|
9
|
+
* - 1 使用节点自身的数据集
|
|
10
|
+
* - 2 使用父节点数据集的属性
|
|
11
|
+
*/
|
|
12
|
+
dataConfig: number
|
|
13
|
+
/**根节点数据集属性的路径 */
|
|
14
|
+
dataPath: string
|
|
15
|
+
|
|
16
|
+
constructor(descriptor: Partial<DeserializationObject<DynamicDescriptor>> = {}) {
|
|
17
|
+
super(descriptor)
|
|
18
|
+
this.url = descriptor.url ?? ''
|
|
19
|
+
this.dataConfig = descriptor.dataConfig ?? 1
|
|
20
|
+
this.dataPath = descriptor.dataPath ?? ''
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
Descriptor.register(DynamicDescriptor)
|
|
24
|
+
|
|
25
|
+
export {
|
|
26
|
+
DynamicDescriptor
|
|
27
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { Vector2 } from "../math"
|
|
2
|
+
import { DeserializationObject } from "../Serialization"
|
|
3
|
+
import { Descriptor } from "./Descriptor"
|
|
4
|
+
import { StyleSpacing } from "./StyleDescriptor"
|
|
5
|
+
|
|
6
|
+
interface HTMLStyle {
|
|
7
|
+
[k: string]: string
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
class HTMLDescriptor extends Descriptor {
|
|
11
|
+
static type = 'HTML'
|
|
12
|
+
|
|
13
|
+
visible: boolean
|
|
14
|
+
active: boolean
|
|
15
|
+
style: string
|
|
16
|
+
display: string
|
|
17
|
+
flexWrap: string
|
|
18
|
+
flexDirection: string
|
|
19
|
+
justifyContent: string
|
|
20
|
+
alignItems: string
|
|
21
|
+
alignContent: string
|
|
22
|
+
margin: StyleSpacing
|
|
23
|
+
/** 项目的放大比例,定义在分配多余空间时项目的放大能力,默认0(不放大) */
|
|
24
|
+
flexGrow: number
|
|
25
|
+
/**宽度
|
|
26
|
+
* - -1 宽度根据内容自适应
|
|
27
|
+
*/
|
|
28
|
+
width: number
|
|
29
|
+
wUnit: string
|
|
30
|
+
calcWidth: number
|
|
31
|
+
/**高度
|
|
32
|
+
* - -1 高度根据内容自适应
|
|
33
|
+
*/
|
|
34
|
+
height: number
|
|
35
|
+
hUnit: string
|
|
36
|
+
calcHeight: number
|
|
37
|
+
|
|
38
|
+
position: string
|
|
39
|
+
location: Vector2
|
|
40
|
+
|
|
41
|
+
xAxis: 'left' | 'right'
|
|
42
|
+
xUnit: string
|
|
43
|
+
|
|
44
|
+
yAxis: 'top' | 'bottom'
|
|
45
|
+
yUnit: string
|
|
46
|
+
|
|
47
|
+
translate: Vector2
|
|
48
|
+
|
|
49
|
+
opacity: number
|
|
50
|
+
zIndex: string
|
|
51
|
+
|
|
52
|
+
constructor(descriptor: Partial<DeserializationObject<HTMLDescriptor>> = {}) {
|
|
53
|
+
super(descriptor)
|
|
54
|
+
|
|
55
|
+
this.visible = descriptor.visible ?? true
|
|
56
|
+
this.active = descriptor.active ?? false
|
|
57
|
+
this.style = descriptor.style ?? ''
|
|
58
|
+
this.display = descriptor.display ?? 'block'
|
|
59
|
+
this.flexWrap = descriptor.flexWrap ?? 'nowrap'
|
|
60
|
+
this.flexDirection = descriptor.flexDirection ?? 'row'
|
|
61
|
+
this.justifyContent = descriptor.justifyContent ?? 'flex-start'
|
|
62
|
+
this.alignItems = descriptor.alignItems ?? 'stretch'
|
|
63
|
+
this.alignContent = descriptor.alignContent ?? 'stretch'
|
|
64
|
+
this.flexGrow = descriptor.flexGrow ?? 0
|
|
65
|
+
this.margin = new StyleSpacing(descriptor.margin)
|
|
66
|
+
|
|
67
|
+
this.width = descriptor.width ?? 100
|
|
68
|
+
this.wUnit = descriptor.wUnit ?? 'px'
|
|
69
|
+
this.calcWidth = descriptor.calcWidth ?? 0
|
|
70
|
+
this.calcHeight = descriptor.calcHeight ?? 0
|
|
71
|
+
this.height = descriptor.height ?? 100
|
|
72
|
+
this.hUnit = descriptor.hUnit ?? 'px'
|
|
73
|
+
this.position = descriptor.position ?? 'static'
|
|
74
|
+
this.location = Vector2.create(descriptor.location)
|
|
75
|
+
this.xAxis = descriptor.xAxis ?? 'left'
|
|
76
|
+
this.xUnit = descriptor.xUnit ?? 'px'
|
|
77
|
+
this.yAxis = descriptor.yAxis ?? 'top'
|
|
78
|
+
this.yUnit = descriptor.yUnit ?? 'px'
|
|
79
|
+
|
|
80
|
+
this.translate = Vector2.create(descriptor.translate)
|
|
81
|
+
|
|
82
|
+
this.opacity = descriptor.opacity ?? 1
|
|
83
|
+
this.zIndex = descriptor.zIndex ?? 'auto'
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export { HTMLStyle, HTMLDescriptor }
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { DeserializationObject } from "../Serialization"
|
|
2
|
+
import { ServiceDescriptor } from "./ServiceDescriptor"
|
|
3
|
+
|
|
4
|
+
class HTMLServiceDescriptor extends ServiceDescriptor {
|
|
5
|
+
static type = 'HTMLService'
|
|
6
|
+
|
|
7
|
+
constructor(descriptor: Partial<DeserializationObject<HTMLServiceDescriptor>> = {}) {
|
|
8
|
+
super(descriptor)
|
|
9
|
+
this.width = descriptor.width ?? 100
|
|
10
|
+
this.wUnit = descriptor.wUnit ?? '%'
|
|
11
|
+
this.height = descriptor.height ?? 100
|
|
12
|
+
this.hUnit = descriptor.hUnit ?? '%'
|
|
13
|
+
this.position = descriptor.position ?? 'absolute'
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
ServiceDescriptor.register(HTMLServiceDescriptor)
|
|
18
|
+
|
|
19
|
+
export { HTMLServiceDescriptor }
|