@vyr/engine 0.0.33 → 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
package/src/Executor.ts
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { Scriptable } from "./Scriptable"
|
|
2
|
+
import { Interaction } from "./descriptor/Interaction"
|
|
3
|
+
import { Graphics } from "./graphics/Graphics"
|
|
4
|
+
import { InteractionNode, InteractionNodeInputCollection } from "./schema"
|
|
5
|
+
|
|
6
|
+
type ExecuteResult = { [k: string]: any } | null
|
|
7
|
+
|
|
8
|
+
export class Executor {
|
|
9
|
+
readonly collection = new Map<string, InteractionNode>()
|
|
10
|
+
readonly linkCollection = new Map<string, string[]>()
|
|
11
|
+
|
|
12
|
+
update(interaction: Interaction) {
|
|
13
|
+
this.collection.clear()
|
|
14
|
+
this.linkCollection.clear()
|
|
15
|
+
|
|
16
|
+
for (const node of interaction.nodes) {
|
|
17
|
+
this.collection.set(node.id, node)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
for (const mapper of interaction.mappers) {
|
|
21
|
+
let link = this.linkCollection.get(mapper.source)
|
|
22
|
+
if (link === undefined) {
|
|
23
|
+
link = []
|
|
24
|
+
this.linkCollection.set(mapper.source, link)
|
|
25
|
+
}
|
|
26
|
+
link.push(mapper.target)
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async doScript(current: string, previous: string, nodes: InteractionNodeInputCollection, interaction: Interaction, graphics: Graphics, result: Map<string, ExecuteResult>, trigger: string, otherArgs?: any) {
|
|
31
|
+
const active = this.collection.get(current)
|
|
32
|
+
if (active === undefined) return
|
|
33
|
+
|
|
34
|
+
const nodeInput = nodes[current] ?? active.input
|
|
35
|
+
const script = Scriptable.use(active.script)
|
|
36
|
+
if (script) {
|
|
37
|
+
const args = { previous, result }
|
|
38
|
+
if (otherArgs) Object.assign(args, otherArgs)
|
|
39
|
+
const safeInput = script.inputSchame.parse(nodeInput)
|
|
40
|
+
const executeResult = await script.execute(graphics, trigger, safeInput, args)
|
|
41
|
+
if (script.outputSchame !== undefined) script.outputSchame.parse(executeResult)
|
|
42
|
+
result.set(current, executeResult)
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
async doCondition(conditions: InteractionNode[], previous: string, nodes: InteractionNodeInputCollection, interaction: Interaction, graphics: Graphics, result: Map<string, ExecuteResult>, trigger: string, otherArgs?: any) {
|
|
47
|
+
const queue: Promise<void>[] = []
|
|
48
|
+
for (const condition of conditions) {
|
|
49
|
+
queue.push(this.doScript(condition.id, previous, nodes, interaction, graphics, result, trigger))
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
await Promise.all(queue)
|
|
53
|
+
|
|
54
|
+
for (const condition of conditions) {
|
|
55
|
+
const conditionResult = result.get(condition.id)
|
|
56
|
+
if (conditionResult?.success !== true) continue
|
|
57
|
+
|
|
58
|
+
const nexts = this.linkCollection.get(condition.id)
|
|
59
|
+
if (nexts === undefined) continue
|
|
60
|
+
for (const next of nexts) {
|
|
61
|
+
await this.doExecute(next, previous, nodes, interaction, graphics, result, trigger, otherArgs)
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
async doNext(current: string, nodes: InteractionNodeInputCollection, interaction: Interaction, graphics: Graphics, result: Map<string, ExecuteResult>, trigger: string, otherArgs?: any) {
|
|
67
|
+
const nexts = this.linkCollection.get(current)
|
|
68
|
+
if (nexts === undefined) return
|
|
69
|
+
|
|
70
|
+
const executes: InteractionNode[] = []
|
|
71
|
+
const conditions: InteractionNode[] = []
|
|
72
|
+
for (const next of nexts) {
|
|
73
|
+
const node = this.collection.get(next)
|
|
74
|
+
if (node === undefined) continue
|
|
75
|
+
if (node.type === 'Condition') {
|
|
76
|
+
conditions.push(node)
|
|
77
|
+
} else if (node.type === 'Execute') {
|
|
78
|
+
executes.push(node)
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const queue: Promise<void>[] = []
|
|
83
|
+
if (conditions.length > 0) {
|
|
84
|
+
queue.push(this.doCondition(conditions, current, nodes, interaction, graphics, result, trigger))
|
|
85
|
+
await Promise.all(queue)
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (executes.length > 0) {
|
|
89
|
+
queue.length = 0
|
|
90
|
+
for (const execute of executes) {
|
|
91
|
+
queue.push(this.doExecute(execute.id, current, nodes, interaction, graphics, result, trigger))
|
|
92
|
+
}
|
|
93
|
+
await Promise.all(queue)
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
async doExecute(current: string, previous: string, nodes: InteractionNodeInputCollection, interaction: Interaction, graphics: Graphics, result: Map<string, ExecuteResult>, trigger: string, otherArgs?: any) {
|
|
98
|
+
await this.doScript(current, previous, nodes, interaction, graphics, result, trigger, otherArgs)
|
|
99
|
+
|
|
100
|
+
await this.doNext(current, nodes, interaction, graphics, result, trigger, otherArgs)
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
async execute(nodes: InteractionNodeInputCollection, interaction: Interaction, graphics: Graphics, trigger: string, otherArgs?: any) {
|
|
104
|
+
for (const root of interaction.roots) {
|
|
105
|
+
const resultCollection = new Map()
|
|
106
|
+
await this.doExecute(root, '', nodes, interaction, graphics, resultCollection, trigger, otherArgs)
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
package/src/Generate.ts
CHANGED
|
@@ -1,40 +1,23 @@
|
|
|
1
|
-
let id = 1;
|
|
2
|
-
const _lut = ['00', '01', '02', '03', '04', '05', '06', '07', '08', '09', '0a', '0b', '0c', '0d', '0e', '0f', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '1a', '1b', '1c', '1d', '1e', '1f', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '2a', '2b', '2c', '2d', '2e', '2f', '30', '31', '32', '33', '34', '35', '36', '37', '38', '39', '3a', '3b', '3c', '3d', '3e', '3f', '40', '41', '42', '43', '44', '45', '46', '47', '48', '49', '4a', '4b', '4c', '4d', '4e', '4f', '50', '51', '52', '53', '54', '55', '56', '57', '58', '59', '5a', '5b', '5c', '5d', '5e', '5f', '60', '61', '62', '63', '64', '65', '66', '67', '68', '69', '6a', '6b', '6c', '6d', '6e', '6f', '70', '71', '72', '73', '74', '75', '76', '77', '78', '79', '7a', '7b', '7c', '7d', '7e', '7f', '80', '81', '82', '83', '84', '85', '86', '87', '88', '89', '8a', '8b', '8c', '8d', '8e', '8f', '90', '91', '92', '93', '94', '95', '96', '97', '98', '99', '9a', '9b', '9c', '9d', '9e', '9f', 'a0', 'a1', 'a2', 'a3', 'a4', 'a5', 'a6', 'a7', 'a8', 'a9', 'aa', 'ab', 'ac', 'ad', 'ae', 'af', 'b0', 'b1', 'b2', 'b3', 'b4', 'b5', 'b6', 'b7', 'b8', 'b9', 'ba', 'bb', 'bc', 'bd', 'be', 'bf', 'c0', 'c1', 'c2', 'c3', 'c4', 'c5', 'c6', 'c7', 'c8', 'c9', 'ca', 'cb', 'cc', 'cd', 'ce', 'cf', 'd0', 'd1', 'd2', 'd3', 'd4', 'd5', 'd6', 'd7', 'd8', 'd9', 'da', 'db', 'dc', 'dd', 'de', 'df', 'e0', 'e1', 'e2', 'e3', 'e4', 'e5', 'e6', 'e7', 'e8', 'e9', 'ea', 'eb', 'ec', 'ed', 'ee', 'ef', 'f0', 'f1', 'f2', 'f3', 'f4', 'f5', 'f6', 'f7', 'f8', 'f9', 'fa', 'fb', 'fc', 'fd', 'fe', 'ff'];
|
|
3
|
-
|
|
4
|
-
class Generate {
|
|
5
|
-
static id() {
|
|
6
|
-
return id++
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
static uuid() {
|
|
10
|
-
const d0 = Math.random() * 0xffffffff | 0;
|
|
11
|
-
const d1 = Math.random() * 0xffffffff | 0;
|
|
12
|
-
const d2 = Math.random() * 0xffffffff | 0;
|
|
13
|
-
const d3 = Math.random() * 0xffffffff | 0;
|
|
14
|
-
const uuid = _lut[d0 & 0xff] + _lut[d0 >> 8 & 0xff] + _lut[d0 >> 16 & 0xff] + _lut[d0 >> 24 & 0xff] + '-'
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
args: [] as any[],
|
|
25
|
-
execute: false
|
|
26
|
-
}
|
|
27
|
-
const execute = (...args: any[]) => {
|
|
28
|
-
delaySatate.args = args
|
|
29
|
-
if (delaySatate.execute === true) return
|
|
30
|
-
delaySatate.execute = true
|
|
31
|
-
requestAnimationFrame(() => {
|
|
32
|
-
cb(...delaySatate.args)
|
|
33
|
-
delaySatate.execute = false
|
|
34
|
-
})
|
|
35
|
-
}
|
|
36
|
-
return execute
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export { Generate }
|
|
1
|
+
let id = 1;
|
|
2
|
+
const _lut = ['00', '01', '02', '03', '04', '05', '06', '07', '08', '09', '0a', '0b', '0c', '0d', '0e', '0f', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '1a', '1b', '1c', '1d', '1e', '1f', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '2a', '2b', '2c', '2d', '2e', '2f', '30', '31', '32', '33', '34', '35', '36', '37', '38', '39', '3a', '3b', '3c', '3d', '3e', '3f', '40', '41', '42', '43', '44', '45', '46', '47', '48', '49', '4a', '4b', '4c', '4d', '4e', '4f', '50', '51', '52', '53', '54', '55', '56', '57', '58', '59', '5a', '5b', '5c', '5d', '5e', '5f', '60', '61', '62', '63', '64', '65', '66', '67', '68', '69', '6a', '6b', '6c', '6d', '6e', '6f', '70', '71', '72', '73', '74', '75', '76', '77', '78', '79', '7a', '7b', '7c', '7d', '7e', '7f', '80', '81', '82', '83', '84', '85', '86', '87', '88', '89', '8a', '8b', '8c', '8d', '8e', '8f', '90', '91', '92', '93', '94', '95', '96', '97', '98', '99', '9a', '9b', '9c', '9d', '9e', '9f', 'a0', 'a1', 'a2', 'a3', 'a4', 'a5', 'a6', 'a7', 'a8', 'a9', 'aa', 'ab', 'ac', 'ad', 'ae', 'af', 'b0', 'b1', 'b2', 'b3', 'b4', 'b5', 'b6', 'b7', 'b8', 'b9', 'ba', 'bb', 'bc', 'bd', 'be', 'bf', 'c0', 'c1', 'c2', 'c3', 'c4', 'c5', 'c6', 'c7', 'c8', 'c9', 'ca', 'cb', 'cc', 'cd', 'ce', 'cf', 'd0', 'd1', 'd2', 'd3', 'd4', 'd5', 'd6', 'd7', 'd8', 'd9', 'da', 'db', 'dc', 'dd', 'de', 'df', 'e0', 'e1', 'e2', 'e3', 'e4', 'e5', 'e6', 'e7', 'e8', 'e9', 'ea', 'eb', 'ec', 'ed', 'ee', 'ef', 'f0', 'f1', 'f2', 'f3', 'f4', 'f5', 'f6', 'f7', 'f8', 'f9', 'fa', 'fb', 'fc', 'fd', 'fe', 'ff'];
|
|
3
|
+
|
|
4
|
+
export class Generate {
|
|
5
|
+
static id() {
|
|
6
|
+
return id++
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
static uuid() {
|
|
10
|
+
const d0 = Math.random() * 0xffffffff | 0;
|
|
11
|
+
const d1 = Math.random() * 0xffffffff | 0;
|
|
12
|
+
const d2 = Math.random() * 0xffffffff | 0;
|
|
13
|
+
const d3 = Math.random() * 0xffffffff | 0;
|
|
14
|
+
const uuid = _lut[d0 & 0xff] + _lut[d0 >> 8 & 0xff] + _lut[d0 >> 16 & 0xff] + _lut[d0 >> 24 & 0xff] + '-'
|
|
15
|
+
+ _lut[d1 & 0xff] + _lut[d1 >> 8 & 0xff] + '-'
|
|
16
|
+
+ _lut[d1 >> 16 & 0x0f | 0x40] + _lut[d1 >> 24 & 0xff] + '-'
|
|
17
|
+
+ _lut[d2 & 0x3f | 0x80] + _lut[d2 >> 8 & 0xff] + '-'
|
|
18
|
+
+ _lut[d2 >> 16 & 0xff] + _lut[d2 >> 24 & 0xff]
|
|
19
|
+
+ _lut[d3 & 0xff] + _lut[d3 >> 8 & 0xff] + _lut[d3 >> 16 & 0xff] + _lut[d3 >> 24 & 0xff];
|
|
20
|
+
|
|
21
|
+
return uuid.toLowerCase()
|
|
22
|
+
}
|
|
23
|
+
}
|
package/src/InputSystem.ts
CHANGED
|
@@ -1,108 +1,106 @@
|
|
|
1
|
-
type IEM = GlobalEventHandlersEventMap
|
|
2
|
-
|
|
3
|
-
interface InputConfig {
|
|
4
|
-
/**事件只触发一次,默认`false` */
|
|
5
|
-
once: boolean
|
|
6
|
-
/**将事件的处理顺序设为事件捕获,默认`false` */
|
|
7
|
-
capture: boolean
|
|
8
|
-
/**处理函数不会调用`preventDefault`来阻止默认行为时应设为true,默认`false` */
|
|
9
|
-
passive: boolean
|
|
10
|
-
/**事件触发的对象 */
|
|
11
|
-
target: Window | Document | HTMLElement
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
const privateState = {
|
|
15
|
-
id: 1,
|
|
16
|
-
listener: {
|
|
17
|
-
default: (input: InputEvent, system: InputSystem) => {
|
|
18
|
-
return (event: Event) => {
|
|
19
|
-
input.event = event
|
|
20
|
-
if (input.enable) return
|
|
21
|
-
input.enable = true
|
|
22
|
-
system.quaua.push(input)
|
|
23
|
-
}
|
|
24
|
-
},
|
|
25
|
-
once: (input: InputEvent, system: InputSystem) => {
|
|
26
|
-
const execute = privateState.listener.default(input, system)
|
|
27
|
-
return (e: Event) => {
|
|
28
|
-
execute(e)
|
|
29
|
-
system.unlisten(input.id)
|
|
30
|
-
}
|
|
31
|
-
},
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
class InputEvent {
|
|
36
|
-
readonly id = privateState.id++
|
|
37
|
-
readonly type
|
|
38
|
-
readonly target
|
|
39
|
-
readonly callback: (e: Event) => void
|
|
40
|
-
readonly listener: (e: Event) => void
|
|
41
|
-
enable = false
|
|
42
|
-
event!: Event
|
|
43
|
-
|
|
44
|
-
constructor(type: keyof IEM, callback: (e: any) => void, system: InputSystem, config: InputConfig) {
|
|
45
|
-
this.type = type
|
|
46
|
-
this.target = config.target
|
|
47
|
-
this.callback = callback
|
|
48
|
-
this.listener = config.once ? privateState.listener.once(this, system) : privateState.listener.default(this, system)
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
execute() {
|
|
52
|
-
this.callback(this.event)
|
|
53
|
-
this.enable = false
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
class InputSystem {
|
|
58
|
-
private _target
|
|
59
|
-
private _registry: InputEvent[] = []
|
|
60
|
-
readonly quaua: InputEvent[] = []
|
|
61
|
-
|
|
62
|
-
constructor(target: InputConfig['target']) {
|
|
63
|
-
this._target = target
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* 监听事件输入,事件在一帧中只执行一次
|
|
68
|
-
* @param type 事件类型
|
|
69
|
-
* @param callback 事件触发时的回调
|
|
70
|
-
* @param options.once 只执行一次回调
|
|
71
|
-
* @param options.target 监听事件的绑定对象
|
|
72
|
-
* @param options.capture 事件执行的阶段,true:捕获阶段执行,false:冒泡阶段执行
|
|
73
|
-
*/
|
|
74
|
-
listen<T extends keyof IEM>(type: T, callback: (event: IEM[T]) => void, options: Partial<InputConfig> = {}) {
|
|
75
|
-
const config: InputConfig = { once: false, target: this._target, passive: false, capture: false, ...options }
|
|
76
|
-
|
|
77
|
-
for (const input of this._registry) {
|
|
78
|
-
if (input.type === type && input.callback === callback && options.target === input.target) return input.id
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
const input = new InputEvent(type, callback, this, config)
|
|
82
|
-
this._registry.push(input)
|
|
83
|
-
input.target.addEventListener(type, input.listener, config.capture)
|
|
84
|
-
|
|
85
|
-
return input.id
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
/**解除事件监听 */
|
|
89
|
-
unlisten(id: number) {
|
|
90
|
-
for (let i = 0; i < this._registry.length; i++) {
|
|
91
|
-
const input = this._registry[i]
|
|
92
|
-
if (input.id === id) {
|
|
93
|
-
this._registry.splice(i, 1)
|
|
94
|
-
input.target.removeEventListener(input.type, input.listener)
|
|
95
|
-
return
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
/**处理输入事件 */
|
|
101
|
-
process() {
|
|
102
|
-
const quaua = [...this.quaua]
|
|
103
|
-
for (const input of quaua) input.execute()
|
|
104
|
-
this.quaua.length = 0
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
export { InputSystem }
|
|
1
|
+
export type IEM = GlobalEventHandlersEventMap
|
|
2
|
+
|
|
3
|
+
export interface InputConfig {
|
|
4
|
+
/**事件只触发一次,默认`false` */
|
|
5
|
+
once: boolean
|
|
6
|
+
/**将事件的处理顺序设为事件捕获,默认`false` */
|
|
7
|
+
capture: boolean
|
|
8
|
+
/**处理函数不会调用`preventDefault`来阻止默认行为时应设为true,默认`false` */
|
|
9
|
+
passive: boolean
|
|
10
|
+
/**事件触发的对象 */
|
|
11
|
+
target: Window | Document | HTMLElement
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const privateState = {
|
|
15
|
+
id: 1,
|
|
16
|
+
listener: {
|
|
17
|
+
default: (input: InputEvent, system: InputSystem) => {
|
|
18
|
+
return (event: Event) => {
|
|
19
|
+
input.event = event
|
|
20
|
+
if (input.enable) return
|
|
21
|
+
input.enable = true
|
|
22
|
+
system.quaua.push(input)
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
once: (input: InputEvent, system: InputSystem) => {
|
|
26
|
+
const execute = privateState.listener.default(input, system)
|
|
27
|
+
return (e: Event) => {
|
|
28
|
+
execute(e)
|
|
29
|
+
system.unlisten(input.id)
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export class InputEvent {
|
|
36
|
+
readonly id = privateState.id++
|
|
37
|
+
readonly type
|
|
38
|
+
readonly target
|
|
39
|
+
readonly callback: (e: Event) => void
|
|
40
|
+
readonly listener: (e: Event) => void
|
|
41
|
+
enable = false
|
|
42
|
+
event!: Event
|
|
43
|
+
|
|
44
|
+
constructor(type: keyof IEM, callback: (e: any) => void, system: InputSystem, config: InputConfig) {
|
|
45
|
+
this.type = type
|
|
46
|
+
this.target = config.target
|
|
47
|
+
this.callback = callback
|
|
48
|
+
this.listener = config.once ? privateState.listener.once(this, system) : privateState.listener.default(this, system)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
execute() {
|
|
52
|
+
this.callback(this.event)
|
|
53
|
+
this.enable = false
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export class InputSystem {
|
|
58
|
+
private _target
|
|
59
|
+
private _registry: InputEvent[] = []
|
|
60
|
+
readonly quaua: InputEvent[] = []
|
|
61
|
+
|
|
62
|
+
constructor(target: InputConfig['target']) {
|
|
63
|
+
this._target = target
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* 监听事件输入,事件在一帧中只执行一次
|
|
68
|
+
* @param type 事件类型
|
|
69
|
+
* @param callback 事件触发时的回调
|
|
70
|
+
* @param options.once 只执行一次回调
|
|
71
|
+
* @param options.target 监听事件的绑定对象
|
|
72
|
+
* @param options.capture 事件执行的阶段,true:捕获阶段执行,false:冒泡阶段执行
|
|
73
|
+
*/
|
|
74
|
+
listen<T extends keyof IEM>(type: T, callback: (event: IEM[T]) => void, options: Partial<InputConfig> = {}) {
|
|
75
|
+
const config: InputConfig = { once: false, target: this._target, passive: false, capture: false, ...options }
|
|
76
|
+
|
|
77
|
+
for (const input of this._registry) {
|
|
78
|
+
if (input.type === type && input.callback === callback && options.target === input.target) return input.id
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const input = new InputEvent(type, callback, this, config)
|
|
82
|
+
this._registry.push(input)
|
|
83
|
+
input.target.addEventListener(type, input.listener, config.capture)
|
|
84
|
+
|
|
85
|
+
return input.id
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**解除事件监听 */
|
|
89
|
+
unlisten(id: number) {
|
|
90
|
+
for (let i = 0; i < this._registry.length; i++) {
|
|
91
|
+
const input = this._registry[i]
|
|
92
|
+
if (input.id === id) {
|
|
93
|
+
this._registry.splice(i, 1)
|
|
94
|
+
input.target.removeEventListener(input.type, input.listener)
|
|
95
|
+
return
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**处理输入事件 */
|
|
101
|
+
process() {
|
|
102
|
+
const quaua = [...this.quaua]
|
|
103
|
+
for (const input of quaua) input.execute()
|
|
104
|
+
this.quaua.length = 0
|
|
105
|
+
}
|
|
106
|
+
}
|
package/src/Listener.ts
CHANGED
|
@@ -1,59 +1,58 @@
|
|
|
1
|
-
type DeafultCallback = (...args: any[]) => any
|
|
2
|
-
type CallbackCollection<T extends {} = {}> = { [k: string]: DeafultCallback } & T
|
|
3
|
-
|
|
4
|
-
interface listenOptions {
|
|
5
|
-
once?: boolean
|
|
6
|
-
insertIndex?: number
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
class Listener<T extends {} = {}> {
|
|
10
|
-
private registrys: any = {}
|
|
11
|
-
|
|
12
|
-
listen<K extends keyof T>(type: K, callback: T[K], options?: listenOptions): () => void
|
|
13
|
-
listen(type: string, callback: DeafultCallback, options?: listenOptions): () => void
|
|
14
|
-
listen<K extends keyof T>(type: K | string, callback?: T[K], options: listenOptions = {}) {
|
|
15
|
-
|
|
16
|
-
let register = this.registrys[type]
|
|
17
|
-
if (register === undefined) {
|
|
18
|
-
register = []
|
|
19
|
-
this.registrys[type] = register
|
|
20
|
-
}
|
|
21
|
-
const insertIndex = options.insertIndex === undefined ? register.length : options.insertIndex
|
|
22
|
-
|
|
23
|
-
const row = register.find((r: any) => r.callback === callback)
|
|
24
|
-
if (!row) register.splice(insertIndex, 0, { once: options.once ?? false, callback })
|
|
25
|
-
const unlisten = () => this.unlisten(type as any, callback)
|
|
26
|
-
return unlisten
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
unlisten<K extends keyof T>(type: K, callback: T[K]): void
|
|
30
|
-
unlisten(type: string, callback: DeafultCallback): void
|
|
31
|
-
unlisten<K extends keyof T>(type: K, callback: T[K]) {
|
|
32
|
-
let registry = this.registrys[type]
|
|
33
|
-
if (registry === undefined) return
|
|
34
|
-
|
|
35
|
-
for (let i = 0; i < registry.length; i++) {
|
|
36
|
-
if (registry[i].callback !== callback) continue
|
|
37
|
-
|
|
38
|
-
registry.splice(i, 1)
|
|
39
|
-
if (registry.length === 0) delete this.registrys[type]
|
|
40
|
-
return
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
trigger<K extends keyof T>(type: K, ...args: Parameters<CallbackCollection<T>[K]>): void
|
|
45
|
-
trigger(type: string, ...args: any[]): void
|
|
46
|
-
trigger<K extends keyof T>(type: K, ...args: Parameters<CallbackCollection<T>[K]>) {
|
|
47
|
-
let registry = this.registrys[type]
|
|
48
|
-
if (registry === undefined) return //console.warn(`无法触发该事件 ${type as string}`)
|
|
49
|
-
|
|
50
|
-
if (registry.length === 0) return
|
|
51
|
-
|
|
52
|
-
registry = [...this.registrys[type]]
|
|
53
|
-
for (let i = 0; i < registry.length; i++) {
|
|
54
|
-
registry[i].callback(...args as any)
|
|
55
|
-
if (registry[i].once === true) this.unlisten(type, registry[i].callback)
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
export { Listener }
|
|
1
|
+
export type DeafultCallback = (...args: any[]) => any
|
|
2
|
+
export type CallbackCollection<T extends {} = {}> = { [k: string]: DeafultCallback } & T
|
|
3
|
+
|
|
4
|
+
export interface listenOptions {
|
|
5
|
+
once?: boolean
|
|
6
|
+
insertIndex?: number
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export class Listener<T extends {} = {}> {
|
|
10
|
+
private registrys: any = {}
|
|
11
|
+
|
|
12
|
+
listen<K extends keyof T>(type: K, callback: T[K], options?: listenOptions): () => void
|
|
13
|
+
listen(type: string, callback: DeafultCallback, options?: listenOptions): () => void
|
|
14
|
+
listen<K extends keyof T>(type: K | string, callback?: T[K], options: listenOptions = {}) {
|
|
15
|
+
|
|
16
|
+
let register = this.registrys[type]
|
|
17
|
+
if (register === undefined) {
|
|
18
|
+
register = []
|
|
19
|
+
this.registrys[type] = register
|
|
20
|
+
}
|
|
21
|
+
const insertIndex = options.insertIndex === undefined ? register.length : options.insertIndex
|
|
22
|
+
|
|
23
|
+
const row = register.find((r: any) => r.callback === callback)
|
|
24
|
+
if (!row) register.splice(insertIndex, 0, { once: options.once ?? false, callback })
|
|
25
|
+
const unlisten = () => this.unlisten(type as any, callback)
|
|
26
|
+
return unlisten
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
unlisten<K extends keyof T>(type: K, callback: T[K]): void
|
|
30
|
+
unlisten(type: string, callback: DeafultCallback): void
|
|
31
|
+
unlisten<K extends keyof T>(type: K, callback: T[K]) {
|
|
32
|
+
let registry = this.registrys[type]
|
|
33
|
+
if (registry === undefined) return
|
|
34
|
+
|
|
35
|
+
for (let i = 0; i < registry.length; i++) {
|
|
36
|
+
if (registry[i].callback !== callback) continue
|
|
37
|
+
|
|
38
|
+
registry.splice(i, 1)
|
|
39
|
+
if (registry.length === 0) delete this.registrys[type]
|
|
40
|
+
return
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
trigger<K extends keyof T>(type: K, ...args: Parameters<CallbackCollection<T>[K]>): void
|
|
45
|
+
trigger(type: string, ...args: any[]): void
|
|
46
|
+
trigger<K extends keyof T>(type: K, ...args: Parameters<CallbackCollection<T>[K]>) {
|
|
47
|
+
let registry = this.registrys[type]
|
|
48
|
+
if (registry === undefined) return //console.warn(`无法触发该事件 ${type as string}`)
|
|
49
|
+
|
|
50
|
+
if (registry.length === 0) return
|
|
51
|
+
|
|
52
|
+
registry = [...this.registrys[type]]
|
|
53
|
+
for (let i = 0; i < registry.length; i++) {
|
|
54
|
+
registry[i].callback(...args as any)
|
|
55
|
+
if (registry[i].once === true) this.unlisten(type, registry[i].callback)
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|