@vyr/engine 0.0.32 → 0.0.34
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 +6 -3
- package/src/ArrayUtils.ts +63 -65
- package/src/AsyncTask.ts +67 -71
- package/src/Category.ts +69 -86
- package/src/Color.ts +3 -111
- package/src/Engine.ts +12 -24
- package/src/Executor.ts +109 -0
- package/src/Generate.ts +23 -40
- package/src/InputSystem.ts +106 -108
- package/src/Listener.ts +58 -59
- package/src/ObjectPool.ts +83 -84
- package/src/ObjectUtils.ts +97 -49
- package/src/Scriptable.ts +82 -0
- package/src/Serialization.ts +4 -6
- package/src/Traverser.ts +41 -39
- package/src/actor/Actor.ts +23 -27
- package/src/actor/AnimationUnitActor.ts +22 -36
- package/src/actor/DivActor.ts +21 -41
- package/src/actor/FragmentActor.ts +1 -5
- package/src/actor/HTMLActor.ts +81 -0
- package/src/actor/HTMLServiceActor.ts +49 -0
- package/src/actor/{HTMTransformControllerActor.ts → HTMLTransformControllerActor.ts} +178 -71
- package/src/actor/InputActor.ts +50 -0
- package/src/actor/TextActor.ts +51 -0
- package/src/actor/index.ts +6 -5
- package/src/asset/Asset.ts +23 -68
- package/src/asset/AssetGraph.ts +21 -28
- package/src/descriptor/AnimationUnit.ts +81 -0
- package/src/descriptor/Camera.ts +12 -0
- package/src/descriptor/Controller.ts +6 -0
- package/src/descriptor/Descriptor.ts +133 -113
- package/src/descriptor/Div.ts +29 -0
- package/src/descriptor/HTML.ts +22 -0
- package/src/descriptor/HTMLService.ts +42 -0
- package/src/descriptor/HTMLTransformController.ts +67 -0
- package/src/descriptor/Input.ts +29 -0
- package/src/descriptor/Interaction.ts +80 -0
- package/src/descriptor/Node.ts +98 -0
- package/src/descriptor/Scene.ts +110 -0
- package/src/descriptor/Service.ts +11 -0
- package/src/descriptor/Store.ts +136 -0
- package/src/descriptor/Text.ts +36 -0
- package/src/descriptor/index.ts +14 -15
- package/src/graphics/Collection.ts +1 -5
- package/src/graphics/Compilation.ts +15 -19
- package/src/graphics/Graphics.ts +41 -54
- package/src/graphics/Observer.ts +6 -14
- package/src/graphics/Unit.ts +3 -9
- package/src/graphics/VariableProxy.ts +11 -15
- package/src/index.ts +5 -5
- package/src/interpreter/AnimationUnitInterpreter.ts +7 -9
- package/src/interpreter/DivInterpreter.ts +10 -13
- package/src/interpreter/FragmentInterpreter.ts +2 -6
- package/src/interpreter/HTMLServiceInterpreter.ts +25 -15
- package/src/interpreter/HTMLTransformControllerInterpreter.ts +9 -12
- package/src/interpreter/InputInterpreter.ts +41 -0
- package/src/interpreter/Interpreter.ts +3 -4
- package/src/interpreter/SceneInterpreter.ts +93 -0
- package/src/interpreter/ServiceInterpreter.ts +8 -15
- package/src/interpreter/StoreInterpreter.ts +7 -0
- package/src/interpreter/TextInterpreter.ts +41 -0
- package/src/interpreter/index.ts +5 -7
- package/src/locale/Language.ts +1 -5
- package/src/locale/LanguageProvider.ts +164 -21
- package/src/math/Euler.ts +2 -5
- package/src/math/Matrix4.ts +2 -4
- package/src/math/Quaternion.ts +2 -4
- package/src/math/Vector2.ts +4 -4
- package/src/math/Vector3.ts +2 -4
- package/src/math/utils.ts +1 -5
- package/src/schema/AnimationUnit.ts +68 -0
- package/src/schema/Asset.ts +13 -0
- package/src/schema/Descriptor.ts +41 -0
- package/src/schema/HTML.ts +261 -0
- package/src/schema/Interaction.ts +50 -0
- package/src/schema/Scene.ts +138 -0
- package/src/schema/Store.ts +8 -0
- package/src/schema/index.ts +7 -0
- package/src/scripts/ConditionScriptable.ts +196 -0
- package/src/scripts/FetchScriptable.ts +51 -0
- package/src/scripts/FindScriptable.ts +23 -0
- package/src/scripts/InvokeScriptable.ts +13 -0
- package/src/scripts/SwitchSceneScriptable.ts +18 -0
- package/src/scripts/UpdateScriptable.ts +60 -0
- package/src/scripts/index.ts +6 -0
- package/src/utils/AssetProvider.ts +4 -77
- package/src/utils/DOM.ts +37 -0
- package/src/utils/HTML.ts +5 -0
- package/src/utils/Service.ts +40 -0
- package/src/utils/constants.ts +1 -5
- package/src/utils/http.ts +2 -21
- package/src/utils/index.ts +3 -1
- package/src/actor/HTMActor.ts +0 -169
- package/src/actor/HTMServiceActor.ts +0 -57
- package/src/actor/StyleActor.ts +0 -96
- package/src/descriptor/AnimationUnitDescriptor.ts +0 -65
- package/src/descriptor/CameraDescriptor.ts +0 -12
- package/src/descriptor/ControllerDescriptor.ts +0 -16
- package/src/descriptor/DatasetDescriptor.ts +0 -90
- package/src/descriptor/DivDescriptor.ts +0 -18
- package/src/descriptor/DynamicDescriptor.ts +0 -27
- package/src/descriptor/HTMLDescriptor.ts +0 -87
- package/src/descriptor/HTMLServiceDescriptor.ts +0 -19
- package/src/descriptor/HTMLTransformControllerDescriptor.ts +0 -34
- package/src/descriptor/NodeDescriptor.ts +0 -32
- package/src/descriptor/PrefabDescriptor.ts +0 -53
- package/src/descriptor/PrefabInstanceDescriptor.ts +0 -32
- package/src/descriptor/ServiceDescriptor.ts +0 -32
- package/src/descriptor/ServiceSchedulerDescriptor.ts +0 -32
- package/src/descriptor/StyleDescriptor.ts +0 -213
- package/src/interaction/InteractionDescriptor.ts +0 -96
- package/src/interaction/InteractionExecutor.ts +0 -84
- package/src/interaction/Scriptable.ts +0 -44
- package/src/interaction/index.ts +0 -3
- package/src/interpreter/DatasetInterpreter.ts +0 -11
- package/src/interpreter/DynamicInterpreter.ts +0 -207
- package/src/interpreter/PrefaInterpreter.ts +0 -11
- package/src/interpreter/PrefabInstanceInterpreter.ts +0 -12
- package/src/interpreter/ServiceSchedulerInterpreter.ts +0 -42
- package/src/interpreter/StyleInterpreter.ts +0 -66
- package/src/preset/execute/dataset/index.ts +0 -1
- package/src/preset/execute/dataset/update.ts +0 -51
- package/src/preset/execute/graphics/index.ts +0 -1
- package/src/preset/execute/graphics/invoke.ts +0 -48
- package/src/preset/execute/index.ts +0 -4
- package/src/preset/execute/net/http.ts +0 -52
- package/src/preset/execute/net/index.ts +0 -1
- package/src/preset/execute/scheduler/index.ts +0 -1
- package/src/preset/execute/scheduler/switch.ts +0 -46
- package/src/preset/index.ts +0 -7
- package/src/preset/interaction/graphics/index.ts +0 -1
- package/src/preset/interaction/graphics/invoke.ts +0 -27
- package/src/preset/interaction/index.ts +0 -2
- package/src/preset/interaction/scheduler/index.ts +0 -1
- package/src/preset/interaction/scheduler/switch.ts +0 -27
- package/src/setup/index.ts +0 -17
- package/src/utils/compile.ts +0 -50
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import z from 'zod'
|
|
2
|
+
import { language } from '../locale'
|
|
3
|
+
import { Graphics } from '../graphics/Graphics'
|
|
4
|
+
import { Scriptable, ScriptableArgs } from '../Scriptable'
|
|
5
|
+
|
|
6
|
+
const DataTypeSchema = z.enum([
|
|
7
|
+
'string',
|
|
8
|
+
'number',
|
|
9
|
+
'boolean',
|
|
10
|
+
'bigint',
|
|
11
|
+
'symbol',
|
|
12
|
+
'object',
|
|
13
|
+
'array',
|
|
14
|
+
'regexp',
|
|
15
|
+
])
|
|
16
|
+
|
|
17
|
+
const CompareOperatorSchema = z.enum([
|
|
18
|
+
'=',
|
|
19
|
+
'!=',
|
|
20
|
+
'>',
|
|
21
|
+
'>=',
|
|
22
|
+
'<',
|
|
23
|
+
'<=',
|
|
24
|
+
'===',
|
|
25
|
+
'!==',
|
|
26
|
+
'in',
|
|
27
|
+
'notIn',
|
|
28
|
+
'between',
|
|
29
|
+
'notBetween',
|
|
30
|
+
'contains',
|
|
31
|
+
'startsWith',
|
|
32
|
+
'endsWith',
|
|
33
|
+
'matches',
|
|
34
|
+
]).describe(language.get('scriptable.condition.operator.description'))
|
|
35
|
+
|
|
36
|
+
const LogicOperatorSchema = z.enum(['AND', 'OR', 'NOT', 'XOR', 'NAND', 'NOR']).describe(
|
|
37
|
+
language.get('scriptable.condition.logic.description')
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
const CompareSchema = z.object({
|
|
41
|
+
op: CompareOperatorSchema,
|
|
42
|
+
value: z.any().describe(language.get('scriptable.condition.operator.value')),
|
|
43
|
+
value2: z.any().optional().describe(language.get('scriptable.condition.operator.value2'))
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
const LogicSchema = z.object({
|
|
47
|
+
op: LogicOperatorSchema,
|
|
48
|
+
rules: z.array(z.lazy(() => RuleSchema)).describe(language.get('scriptable.condition.logic.rules'))
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
const RuleSchema: z.ZodType<any> = z.object({
|
|
52
|
+
type: DataTypeSchema.describe(language.get('scriptable.condition.rule.type')),
|
|
53
|
+
field: z.string().optional().describe(language.get('scriptable.condition.rule.field')),
|
|
54
|
+
compare: CompareSchema.optional().describe(language.get('scriptable.condition.rule.compare')),
|
|
55
|
+
logic: LogicSchema.optional().describe(language.get('scriptable.condition.rule.logic'))
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
export class ConditionScriptable extends Scriptable {
|
|
59
|
+
static id = 'condition'
|
|
60
|
+
static name = language.get('scriptable.condition.name')
|
|
61
|
+
static inputSchame = z.object({
|
|
62
|
+
nodeId: z.string().default('').describe(language.get('scriptable.condition.input.nodeId')),
|
|
63
|
+
rules: z.array(RuleSchema).default([]).describe(language.get('scriptable.condition.input.rules'))
|
|
64
|
+
})
|
|
65
|
+
static outputSchame = z.object({ success: z.boolean().describe(language.get('scriptable.condition.output.success')) })
|
|
66
|
+
|
|
67
|
+
execute(graphics: Graphics, trigger: string, input: z.infer<typeof ConditionScriptable.inputSchame>, args?: ScriptableArgs) {
|
|
68
|
+
if (args === undefined) return { success: false }
|
|
69
|
+
if (input.rules.length === 0) return { success: true }
|
|
70
|
+
|
|
71
|
+
const value = args.result.get(input.nodeId) ?? args.result.get(args.previous)
|
|
72
|
+
|
|
73
|
+
const success = input.rules.every(rule => this.validateRule(value, rule))
|
|
74
|
+
|
|
75
|
+
return { success }
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* 根据规则验证值
|
|
80
|
+
*/
|
|
81
|
+
private validateRule(value: any, rule: any): boolean {
|
|
82
|
+
if (rule.type === undefined) return false
|
|
83
|
+
|
|
84
|
+
const actualValue = rule.field ? this.getFieldValue(value, rule.field) : value
|
|
85
|
+
|
|
86
|
+
if (this.validateType(actualValue, rule.type) === false) {
|
|
87
|
+
return false
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (rule.compare && this.validateCompare(actualValue, rule.compare) === false) {
|
|
91
|
+
return false
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (rule.logic && this.validateLogic(actualValue, rule.logic) === false) {
|
|
95
|
+
return false
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return true
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* 获取字段值(支持点号访问嵌套属性)
|
|
103
|
+
*/
|
|
104
|
+
private getFieldValue(obj: any, field: string): any {
|
|
105
|
+
return field.split('.').reduce((acc, key) => {
|
|
106
|
+
return acc && typeof acc === 'object' ? acc[key] : undefined
|
|
107
|
+
}, obj)
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* 验证类型
|
|
112
|
+
*/
|
|
113
|
+
private validateType(value: any, type: string): boolean {
|
|
114
|
+
if (type === 'array') {
|
|
115
|
+
return Array.isArray(value)
|
|
116
|
+
}
|
|
117
|
+
if (type === 'regexp') {
|
|
118
|
+
return value instanceof RegExp
|
|
119
|
+
}
|
|
120
|
+
return typeof value === type
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* 验证比较操作
|
|
125
|
+
*/
|
|
126
|
+
private validateCompare(value: any, compare: { op: string; value: any; value2?: any }): boolean {
|
|
127
|
+
const { op, value: targetValue, value2 } = compare
|
|
128
|
+
|
|
129
|
+
switch (op) {
|
|
130
|
+
case '=':
|
|
131
|
+
return value == targetValue
|
|
132
|
+
case '!=':
|
|
133
|
+
return value != targetValue
|
|
134
|
+
case '>':
|
|
135
|
+
return value > targetValue
|
|
136
|
+
case '>=':
|
|
137
|
+
return value >= targetValue
|
|
138
|
+
case '<':
|
|
139
|
+
return value < targetValue
|
|
140
|
+
case '<=':
|
|
141
|
+
return value <= targetValue
|
|
142
|
+
case '===':
|
|
143
|
+
return value === targetValue
|
|
144
|
+
case '!==':
|
|
145
|
+
return value !== targetValue
|
|
146
|
+
case 'in':
|
|
147
|
+
return Array.isArray(targetValue) && targetValue.includes(value)
|
|
148
|
+
case 'notIn':
|
|
149
|
+
return !Array.isArray(targetValue) || !targetValue.includes(value)
|
|
150
|
+
case 'between':
|
|
151
|
+
return value2 !== undefined && value >= targetValue && value <= value2
|
|
152
|
+
case 'notBetween':
|
|
153
|
+
return value2 !== undefined && (value < targetValue || value > value2)
|
|
154
|
+
case 'contains':
|
|
155
|
+
return typeof value === 'string' && value.includes(targetValue)
|
|
156
|
+
case 'startsWith':
|
|
157
|
+
return typeof value === 'string' && value.startsWith(targetValue)
|
|
158
|
+
case 'endsWith':
|
|
159
|
+
return typeof value === 'string' && value.endsWith(targetValue)
|
|
160
|
+
case 'matches':
|
|
161
|
+
return typeof value === 'string' && new RegExp(targetValue).test(value)
|
|
162
|
+
default:
|
|
163
|
+
return false
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* 验证逻辑组合
|
|
169
|
+
*/
|
|
170
|
+
private validateLogic(value: any, logic: { op: string; rules: any[] }): boolean {
|
|
171
|
+
const { op, rules } = logic
|
|
172
|
+
|
|
173
|
+
if (rules.length === 0) return true
|
|
174
|
+
|
|
175
|
+
const results = rules.map(rule => this.validateRule(value, rule))
|
|
176
|
+
|
|
177
|
+
switch (op) {
|
|
178
|
+
case 'AND':
|
|
179
|
+
return results.every(result => result)
|
|
180
|
+
case 'OR':
|
|
181
|
+
return results.some(result => result)
|
|
182
|
+
case 'NOT':
|
|
183
|
+
return !results[0]
|
|
184
|
+
case 'XOR':
|
|
185
|
+
return results.filter(Boolean).length === 1
|
|
186
|
+
case 'NAND':
|
|
187
|
+
return !results.every(result => result)
|
|
188
|
+
case 'NOR':
|
|
189
|
+
return !results.some(result => result)
|
|
190
|
+
default:
|
|
191
|
+
return false
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
Scriptable.register(ConditionScriptable)
|
|
196
|
+
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import z from 'zod'
|
|
2
|
+
import { language } from '../locale'
|
|
3
|
+
import { Graphics } from '../graphics/Graphics';
|
|
4
|
+
import { Scriptable, ScriptableArgs } from '../Scriptable'
|
|
5
|
+
import { http, HttpType } from '../utils'
|
|
6
|
+
|
|
7
|
+
const BaseInputSchema = z.object({
|
|
8
|
+
requestData: z.object().catchall(z.any()).default({}).describe(language.get('scriptable.fetch.input.requestData')),
|
|
9
|
+
})
|
|
10
|
+
|
|
11
|
+
const HttpInputSchema = BaseInputSchema.extend({
|
|
12
|
+
url: z.string().default('').describe(language.get('scriptable.fetch.input.url')),
|
|
13
|
+
type: z.enum(Object.values(HttpType)).default(HttpType.GET).describe(language.get('scriptable.fetch.input.type')),
|
|
14
|
+
nodeIds: z.string().default('').describe(language.get('scriptable.fetch.input.nodeIds')),
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
const InterfaceInputSchema = BaseInputSchema.extend({
|
|
18
|
+
type: z.literal('interface').default('interface').describe(language.get('scriptable.fetch.input.type.interface')),
|
|
19
|
+
interfaceId: z.string().describe(language.get('scriptable.fetch.input.interfaceId')),
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
export class FetchScriptable extends Scriptable {
|
|
23
|
+
static id = 'fetch'
|
|
24
|
+
static name = language.get('scriptable.fetch.name')
|
|
25
|
+
static inputSchame = z.union([
|
|
26
|
+
HttpInputSchema,
|
|
27
|
+
InterfaceInputSchema
|
|
28
|
+
])
|
|
29
|
+
|
|
30
|
+
async execute(graphics: Graphics, trigger: string, input: z.infer<typeof FetchScriptable.inputSchame>, args?: ScriptableArgs) {
|
|
31
|
+
let url
|
|
32
|
+
let type
|
|
33
|
+
let result
|
|
34
|
+
if (input.type === 'interface') {
|
|
35
|
+
url = '/vyr/dataset.interface.execute'
|
|
36
|
+
type = HttpType.POST
|
|
37
|
+
result = { id: input.interfaceId, params: input.requestData }
|
|
38
|
+
} else {
|
|
39
|
+
url = input.url
|
|
40
|
+
type = input.type
|
|
41
|
+
result = this.aggregateResults(input.requestData, input.nodeIds, args)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const res = await http(url, type, result)
|
|
45
|
+
|
|
46
|
+
return res.result
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
Scriptable.register(FetchScriptable)
|
|
50
|
+
|
|
51
|
+
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import z from 'zod'
|
|
2
|
+
import { language } from '../locale'
|
|
3
|
+
import { Descriptor } from '../descriptor'
|
|
4
|
+
import { Graphics } from '../graphics/Graphics'
|
|
5
|
+
import { Scriptable, ScriptableArgs } from '../Scriptable'
|
|
6
|
+
|
|
7
|
+
export class FindScriptable extends Scriptable {
|
|
8
|
+
static id = 'find'
|
|
9
|
+
static name = language.get('scriptable.find.name')
|
|
10
|
+
static inputSchame = z.object({
|
|
11
|
+
target: z.string().default('').describe(language.get('scriptable.find.input.target')),
|
|
12
|
+
})
|
|
13
|
+
static outputSchame = z.object().catchall(z.any()).or(z.null()).describe(language.get('scriptable.find.output.descriptor'))
|
|
14
|
+
|
|
15
|
+
execute(graphics: Graphics, trigger: string, input: z.infer<typeof FindScriptable.inputSchame>, args?: ScriptableArgs) {
|
|
16
|
+
const target = Descriptor.get<Descriptor>(input.target)
|
|
17
|
+
|
|
18
|
+
return target
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
Scriptable.register(FindScriptable)
|
|
22
|
+
|
|
23
|
+
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import z from 'zod'
|
|
2
|
+
import { language } from '../locale'
|
|
3
|
+
import { Scriptable } from '../Scriptable'
|
|
4
|
+
|
|
5
|
+
export class InvokeScriptable extends Scriptable {
|
|
6
|
+
static id = 'invoke'
|
|
7
|
+
static name = language.get('scriptable.invoke.name')
|
|
8
|
+
static inputSchame = z.object({
|
|
9
|
+
target: z.string().default('').describe(language.get('scriptable.invoke.input.target')),
|
|
10
|
+
interactionType: z.string().default('click').describe(language.get('scriptable.invoke.input.interactionType')),
|
|
11
|
+
})
|
|
12
|
+
}
|
|
13
|
+
Scriptable.register(InvokeScriptable)
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import z from 'zod'
|
|
2
|
+
import { language } from '../locale'
|
|
3
|
+
import { Graphics } from '../graphics/Graphics';
|
|
4
|
+
import { Scriptable, ScriptableArgs } from '../Scriptable';
|
|
5
|
+
|
|
6
|
+
export class SwitchSceneScriptable extends Scriptable {
|
|
7
|
+
static id = 'switch.scene'
|
|
8
|
+
static name = language.get('scriptable.switchScene.name')
|
|
9
|
+
static inputSchame = z.object({
|
|
10
|
+
scene: z.string().describe(language.get('scriptable.switchScene.input.scene')),
|
|
11
|
+
})
|
|
12
|
+
|
|
13
|
+
execute(graphics: Graphics, trigger: string, input: z.infer<typeof SwitchSceneScriptable.inputSchame>, args?: ScriptableArgs) {
|
|
14
|
+
console.log(trigger)
|
|
15
|
+
console.log(input)
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
Scriptable.register(SwitchSceneScriptable)
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import z from 'zod'
|
|
2
|
+
import { language } from '../locale'
|
|
3
|
+
import { ObjectUtils } from '../ObjectUtils';
|
|
4
|
+
import { Descriptor } from '../descriptor'
|
|
5
|
+
import { Graphics } from '../graphics/Graphics';
|
|
6
|
+
import { Scriptable, ScriptableArgs } from '../Scriptable'
|
|
7
|
+
|
|
8
|
+
export class UpdateScriptable extends Scriptable {
|
|
9
|
+
static id = 'update'
|
|
10
|
+
static name = language.get('scriptable.update.name')
|
|
11
|
+
static inputSchame = z.object({
|
|
12
|
+
target: z.string().default('').describe(language.get('scriptable.update.input.target')),
|
|
13
|
+
propertyPath: z.string().default('').describe(language.get('scriptable.update.input.propertyPath')),
|
|
14
|
+
data: z.object().catchall(z.any()).default({}).describe(language.get('scriptable.update.input.data')),
|
|
15
|
+
nodeId: z.string().optional().describe(language.get('scriptable.update.input.nodeId')),
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
updateObject(property: any, key: string, updateData: any) {
|
|
19
|
+
const value = property[key]
|
|
20
|
+
if (ObjectUtils.isObject(value)) {
|
|
21
|
+
if (Array.isArray(value)) {
|
|
22
|
+
property[key] = updateData
|
|
23
|
+
} else {
|
|
24
|
+
const keys = Object.keys(value)
|
|
25
|
+
for (const key of keys) {
|
|
26
|
+
const updateValue = updateData[key]
|
|
27
|
+
if (updateValue === undefined) continue
|
|
28
|
+
this.updateObject(value, key, updateValue)
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
} else {
|
|
32
|
+
property[key] = updateData
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
execute(graphics: Graphics, trigger: string, input: z.infer<typeof UpdateScriptable.inputSchame>, args?: ScriptableArgs) {
|
|
37
|
+
if (args === undefined) return
|
|
38
|
+
const target = Descriptor.get<Descriptor>(input.target)
|
|
39
|
+
|
|
40
|
+
let updateData
|
|
41
|
+
if (input.nodeId) {
|
|
42
|
+
updateData = args.result.get(input.nodeId)
|
|
43
|
+
if (updateData === undefined) updateData = input.data
|
|
44
|
+
} else {
|
|
45
|
+
updateData = input.data
|
|
46
|
+
}
|
|
47
|
+
if (input.propertyPath) {
|
|
48
|
+
ObjectUtils.nextByPropertyPath(target, input.propertyPath, (property, key) => {
|
|
49
|
+
this.updateObject(property, key, updateData)
|
|
50
|
+
target.setNeedsUpdate()
|
|
51
|
+
})
|
|
52
|
+
} else {
|
|
53
|
+
target.syncWith(updateData)
|
|
54
|
+
target.setNeedsUpdate()
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
Scriptable.register(UpdateScriptable)
|
|
59
|
+
|
|
60
|
+
|
|
@@ -1,90 +1,17 @@
|
|
|
1
|
-
import { InteractionDescriptor, InteractionNode, InteractionProperty } from "../interaction"
|
|
2
|
-
import { Descriptor, DynamicDescriptor, PrefabInstanceDescriptor, HTMLDescriptor, StyleDescriptor, DatasetDescriptor, DivDescriptor } from "../descriptor"
|
|
3
|
-
import { AssetGraph, Port } from "../asset"
|
|
4
1
|
import { Category } from "../Category"
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const keys = Object.keys(interaction.inputs)
|
|
8
|
-
for (const key of keys) {
|
|
9
|
-
const input = interaction.inputs[key]
|
|
10
|
-
const params = Object.keys(input)
|
|
11
|
-
for (const param of params) {
|
|
12
|
-
const value = input[param]
|
|
13
|
-
if (value.type === undefined || Category.isDescriptor(value.type, 'category') === false) continue
|
|
14
|
-
if (value.value) port.edges.push({ key: `${path}.inputs.${key}.${param}.value`, category: value.type, asset: value.value })
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
const interactionNodeExecutor = (node: InteractionNode, path: string, port: Port) => {
|
|
19
|
-
const params = Object.keys(node.input)
|
|
20
|
-
for (const param of params) {
|
|
21
|
-
const value = node.input[param]
|
|
22
|
-
if (value.type === undefined || Category.isDescriptor(value.type, 'category') === false) continue
|
|
23
|
-
if (value.value) port.edges.push({ key: `${path}.input.${param}.value`, category: value.type, asset: value.value })
|
|
24
|
-
}
|
|
25
|
-
}
|
|
2
|
+
import { Descriptor } from "../descriptor"
|
|
3
|
+
import { AssetGraph, Port } from "../asset"
|
|
26
4
|
|
|
27
5
|
const DescriptorProvider = (descriptor: Descriptor, port: Port) => {
|
|
28
6
|
if (descriptor.interactions.length > 0) {
|
|
29
7
|
for (let i = 0; i < descriptor.interactions.length; i++) {
|
|
30
8
|
const interaction = descriptor.interactions[i]
|
|
31
9
|
if (interaction.url) {
|
|
32
|
-
interactionExecutor(interaction, `interactions[${i}]`, port)
|
|
33
10
|
port.edges.push({ key: `interactions[${i}].url`, category: Category.interaction, asset: interaction.url })
|
|
34
11
|
}
|
|
35
12
|
}
|
|
36
13
|
}
|
|
37
|
-
if (descriptor.
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
const DatasetDescriptorProvider = (descriptor: DatasetDescriptor, port: Port) => {
|
|
41
|
-
if (descriptor.dataConfigs.length > 0) {
|
|
42
|
-
for (let i = 0; i < descriptor.dataConfigs.length; i++) {
|
|
43
|
-
const dataConfig = descriptor.dataConfigs[i]
|
|
44
|
-
if (dataConfig.url && dataConfig.url.startsWith('/') && dataConfig.url.endsWith('.json')) {
|
|
45
|
-
port.edges.push({ key: `dataConfig[${i}].url`, category: Category.json, asset: dataConfig.url })
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
const StyleDescriptorProvider = (descriptor: StyleDescriptor, port: Port) => {
|
|
52
|
-
if (descriptor.inherit) port.edges.push({ key: 'inherit', category: Category.style, asset: descriptor.inherit })
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
const InteractionDescriptorProvider = (descriptor: InteractionDescriptor, port: Port) => {
|
|
56
|
-
if (descriptor.nodes.length > 0) {
|
|
57
|
-
for (let i = 0; i < descriptor.nodes.length; i++) {
|
|
58
|
-
const node = descriptor.nodes[i]
|
|
59
|
-
if (node.url) {
|
|
60
|
-
interactionNodeExecutor(node, `nodes[${i}]`, port)
|
|
61
|
-
port.edges.push({ key: `nodes[${i}].url`, category: Category.ts, asset: node.url })
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
const HTMLDescriptorProvider = (descriptor: HTMLDescriptor, port: Port) => {
|
|
68
|
-
if (descriptor.style) port.edges.push({ key: 'style', category: Category.style, asset: descriptor.style })
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
const DivDescriptorProvider = (descriptor: DivDescriptor, port: Port) => {
|
|
72
|
-
if (descriptor.backroundIamge) port.edges.push({ key: 'backroundIamge', category: Category.image, asset: descriptor.backroundIamge })
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
const DynamicDescriptorProvider = (descriptor: DynamicDescriptor, port: Port) => {
|
|
76
|
-
if (descriptor.url) port.edges.push({ key: 'url', category: Category.prefab, asset: descriptor.url })
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
const PrefabInstanceDescriptorProvider = (descriptor: PrefabInstanceDescriptor, port: Port) => {
|
|
80
|
-
if (descriptor.url) port.edges.push({ key: 'url', category: Category.prefab, asset: descriptor.url })
|
|
14
|
+
if (descriptor.store) port.edges.push({ key: 'store', category: Category.store, asset: descriptor.store })
|
|
81
15
|
}
|
|
82
16
|
|
|
83
|
-
AssetGraph.register(Descriptor.type, DescriptorProvider)
|
|
84
|
-
AssetGraph.register(DatasetDescriptor.type, DatasetDescriptorProvider)
|
|
85
|
-
AssetGraph.register(StyleDescriptor.type, StyleDescriptorProvider)
|
|
86
|
-
AssetGraph.register(InteractionDescriptor.type, InteractionDescriptorProvider)
|
|
87
|
-
AssetGraph.register(HTMLDescriptor.type, HTMLDescriptorProvider)
|
|
88
|
-
AssetGraph.register(DivDescriptor.type, DivDescriptorProvider)
|
|
89
|
-
AssetGraph.register(DynamicDescriptor.type, DynamicDescriptorProvider)
|
|
90
|
-
AssetGraph.register(PrefabInstanceDescriptor.type, PrefabInstanceDescriptorProvider)
|
|
17
|
+
AssetGraph.register(Descriptor.type, DescriptorProvider)
|
package/src/utils/DOM.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { HTMLActor } from "../actor/HTMLActor"
|
|
2
|
+
|
|
3
|
+
export const createEngineDOM = () => {
|
|
4
|
+
const DOM = document.createElement('div')
|
|
5
|
+
DOM.style.width = '100%'
|
|
6
|
+
DOM.style.height = '100%'
|
|
7
|
+
DOM.style.position = 'relative'
|
|
8
|
+
DOM.style.top = '0'
|
|
9
|
+
DOM.style.left = '0'
|
|
10
|
+
DOM.style.overflow = 'hidden'
|
|
11
|
+
DOM.classList.add('vyr-engine')
|
|
12
|
+
DOM.style.whiteSpace = 'pre-wrap'
|
|
13
|
+
DOM.setAttribute('data-vyr', `vyr-engine`)
|
|
14
|
+
DOM.addEventListener('contextmenu', (e) => e.preventDefault())
|
|
15
|
+
return DOM
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export const createHTMLDOM = (uuid: string) => {
|
|
19
|
+
const DOM = document.createElement('div')
|
|
20
|
+
DOM.setAttribute('class', HTMLActor.className)
|
|
21
|
+
DOM.setAttribute(HTMLActor.uuidKey, uuid)
|
|
22
|
+
return DOM
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export const createInputDOM = (uuid: string) => {
|
|
26
|
+
const DOM = document.createElement('input')
|
|
27
|
+
DOM.setAttribute('class', HTMLActor.className)
|
|
28
|
+
DOM.setAttribute(HTMLActor.uuidKey, uuid)
|
|
29
|
+
return DOM
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export const createTextDOM = (uuid: string) => {
|
|
33
|
+
const DOM = document.createElement('span')
|
|
34
|
+
DOM.setAttribute('class', HTMLActor.className)
|
|
35
|
+
DOM.setAttribute(HTMLActor.uuidKey, uuid)
|
|
36
|
+
return DOM
|
|
37
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { ArrayUtils } from "../ArrayUtils"
|
|
2
|
+
import { Descriptor } from "../descriptor/Descriptor"
|
|
3
|
+
import { Service } from "../descriptor/Service"
|
|
4
|
+
import { DeserializationObject } from "../Serialization"
|
|
5
|
+
|
|
6
|
+
const services: string[] = []
|
|
7
|
+
export const registerService = (type: string) => {
|
|
8
|
+
ArrayUtils.insert(services, type)
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* 检查描述器是否为服务节点
|
|
13
|
+
* 类型守卫函数,用于安全地判断一个描述器是否为Service类型
|
|
14
|
+
* @param descriptor - 要检查的描述器对象或反序列化对象
|
|
15
|
+
* @returns 类型谓词,true表示是Service类型
|
|
16
|
+
*/
|
|
17
|
+
export const isService = <D extends Service = Service>(descriptor: DeserializationObject<Descriptor> | null): descriptor is D => {
|
|
18
|
+
if (descriptor === null) return false
|
|
19
|
+
return services.includes(descriptor.type)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* 追踪获取当前节点的父服务节点
|
|
26
|
+
* 沿节点树向上查找最近的服务节点
|
|
27
|
+
*
|
|
28
|
+
* 注意:在渲染流程中应使用Graphics的同名方法,因为某些动态节点可能尚未插入节点树
|
|
29
|
+
* @param descriptor - 起始描述器节点
|
|
30
|
+
* @returns 找到的父服务节点,不存在则返回null
|
|
31
|
+
*/
|
|
32
|
+
export const traceService = (descriptor: Descriptor | null): Service | null => {
|
|
33
|
+
if (descriptor === null) return null
|
|
34
|
+
if (isService(descriptor)) {
|
|
35
|
+
return descriptor
|
|
36
|
+
} else {
|
|
37
|
+
const ancestor = descriptor.traceAncestor(false)
|
|
38
|
+
return traceService(ancestor.parent)
|
|
39
|
+
}
|
|
40
|
+
}
|
package/src/utils/constants.ts
CHANGED
package/src/utils/http.ts
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import { ScriptableArgs } from "../interaction";
|
|
2
1
|
import { Asset } from "../asset";
|
|
3
2
|
import { HttpType } from "./constants";
|
|
4
3
|
|
|
5
4
|
const headers = {}
|
|
6
|
-
const setHttpHeaders = (options: { [k: string]: any }) => {
|
|
5
|
+
export const setHttpHeaders = (options: { [k: string]: any }) => {
|
|
7
6
|
Object.assign(headers, options)
|
|
8
7
|
}
|
|
9
8
|
|
|
@@ -20,20 +19,7 @@ const joinUrl = (url: string, requestData: any) => {
|
|
|
20
19
|
return urlObj.toString()
|
|
21
20
|
}
|
|
22
21
|
|
|
23
|
-
const http = async (url: string, type: string,
|
|
24
|
-
const requestData: { [k: string]: any } = {}
|
|
25
|
-
const keys: string[] = []
|
|
26
|
-
if (data.trim().length === 0) {
|
|
27
|
-
keys.push(...result.keys())
|
|
28
|
-
} else {
|
|
29
|
-
keys.push(...data.split(','))
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
for (const key of keys) {
|
|
33
|
-
const value = result.get(key)
|
|
34
|
-
Object.assign(requestData, value ?? {})
|
|
35
|
-
}
|
|
36
|
-
|
|
22
|
+
export const http = async (url: string, type: string, requestData: any) => {
|
|
37
23
|
url = url.replace(/\${(\w+)}/g, (match: any, key: string) => {
|
|
38
24
|
return requestData.hasOwnProperty(key) ? requestData[key] : match;
|
|
39
25
|
})
|
|
@@ -55,9 +41,4 @@ const http = async (url: string, type: string, data: string, result: ScriptableA
|
|
|
55
41
|
const json = await res.json()
|
|
56
42
|
|
|
57
43
|
return json
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
export {
|
|
61
|
-
setHttpHeaders,
|
|
62
|
-
http,
|
|
63
44
|
}
|