hzengine-core 0.1.2-dev
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/dist/async/index.js +162 -0
- package/dist/async/zeppos_timer.js +58 -0
- package/dist/audio/index.js +260 -0
- package/dist/config/index.js +57 -0
- package/dist/debug/index.js +8 -0
- package/dist/index.js +103 -0
- package/dist/platform/index.js +1 -0
- package/dist/plugins/basic_command/$.js +8 -0
- package/dist/plugins/basic_command/audio.js +40 -0
- package/dist/plugins/basic_command/basic.js +124 -0
- package/dist/plugins/basic_command/character.js +112 -0
- package/dist/plugins/basic_command/conditional.js +260 -0
- package/dist/plugins/basic_command/config.js +22 -0
- package/dist/plugins/basic_command/decorator.js +24 -0
- package/dist/plugins/basic_command/eval.js +67 -0
- package/dist/plugins/basic_command/img.js +249 -0
- package/dist/plugins/basic_command/index.js +22 -0
- package/dist/plugins/basic_command/menu.js +140 -0
- package/dist/plugins/global_gesture/index.js +25 -0
- package/dist/plugins/transform/animation.js +440 -0
- package/dist/plugins/transform/commands.js +38 -0
- package/dist/plugins/transform/example_profiles.js +32 -0
- package/dist/plugins/transform/hz_anime.js +211 -0
- package/dist/plugins/transform/index.js +93 -0
- package/dist/script/index.js +537 -0
- package/dist/script/readscript.js +15 -0
- package/dist/script/strtools.js +157 -0
- package/dist/storage/decorator.js +260 -0
- package/dist/storage/fs.js +96 -0
- package/dist/storage/index.js +442 -0
- package/dist/system/index.js +144 -0
- package/dist/ui/index.js +535 -0
- package/dist/utils/path.js +289 -0
- package/license.txt +202 -0
- package/package.json +26 -0
- package/src/async/index.ts +124 -0
- package/src/async/zeppos_timer.js +65 -0
- package/src/audio/index.ts +224 -0
- package/src/config/index.ts +80 -0
- package/src/debug/index.ts +11 -0
- package/src/index.ts +122 -0
- package/src/platform/index.ts +158 -0
- package/src/plugins/basic_command/$.ts +11 -0
- package/src/plugins/basic_command/audio.ts +53 -0
- package/src/plugins/basic_command/basic.ts +145 -0
- package/src/plugins/basic_command/character.ts +144 -0
- package/src/plugins/basic_command/conditional.ts +349 -0
- package/src/plugins/basic_command/config.ts +29 -0
- package/src/plugins/basic_command/decorator.ts +29 -0
- package/src/plugins/basic_command/eval.ts +88 -0
- package/src/plugins/basic_command/img.ts +317 -0
- package/src/plugins/basic_command/index.ts +24 -0
- package/src/plugins/basic_command/menu.ts +178 -0
- package/src/plugins/global_gesture/index.ts +29 -0
- package/src/plugins/transform/animation.ts +542 -0
- package/src/plugins/transform/commands.ts +53 -0
- package/src/plugins/transform/example_profiles.ts +36 -0
- package/src/plugins/transform/hz_anime.ts +214 -0
- package/src/plugins/transform/index.ts +141 -0
- package/src/plugins/transform/readme.md +1 -0
- package/src/script/index.ts +623 -0
- package/src/script/readscript.ts +17 -0
- package/src/script/strtools.ts +159 -0
- package/src/storage/decorator.ts +473 -0
- package/src/storage/fs.ts +104 -0
- package/src/storage/index.ts +541 -0
- package/src/system/index.ts +95 -0
- package/src/ui/index.ts +699 -0
- package/src/utils/path.js +338 -0
- package/tsconfig.json +111 -0
- package/types/async/index.d.ts +24 -0
- package/types/async/zeppos_timer.d.ts +14 -0
- package/types/audio/index.d.ts +64 -0
- package/types/config/index.d.ts +9 -0
- package/types/debug/index.d.ts +6 -0
- package/types/index.d.ts +41 -0
- package/types/platform/index.d.ts +134 -0
- package/types/plugins/basic_command/$.d.ts +2 -0
- package/types/plugins/basic_command/audio.d.ts +2 -0
- package/types/plugins/basic_command/basic.d.ts +3 -0
- package/types/plugins/basic_command/character.d.ts +2 -0
- package/types/plugins/basic_command/conditional.d.ts +2 -0
- package/types/plugins/basic_command/config.d.ts +2 -0
- package/types/plugins/basic_command/decorator.d.ts +2 -0
- package/types/plugins/basic_command/eval.d.ts +2 -0
- package/types/plugins/basic_command/img.d.ts +2 -0
- package/types/plugins/basic_command/index.d.ts +2 -0
- package/types/plugins/basic_command/menu.d.ts +2 -0
- package/types/plugins/global_gesture/index.d.ts +2 -0
- package/types/plugins/transform/animation.d.ts +131 -0
- package/types/plugins/transform/commands.d.ts +7 -0
- package/types/plugins/transform/example_profiles.d.ts +2 -0
- package/types/plugins/transform/hz_anime.d.ts +51 -0
- package/types/plugins/transform/index.d.ts +13 -0
- package/types/script/index.d.ts +123 -0
- package/types/script/readscript.d.ts +2 -0
- package/types/script/strtools.d.ts +31 -0
- package/types/storage/decorator.d.ts +41 -0
- package/types/storage/fs.d.ts +1 -0
- package/types/storage/index.d.ts +86 -0
- package/types/system/index.d.ts +35 -0
- package/types/ui/index.d.ts +167 -0
- package/types/utils/path.d.ts +84 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { HZEngineCore } from "../../index.js";
|
|
2
|
+
import Path from "../../utils/path.js";
|
|
3
|
+
|
|
4
|
+
export function config_command(core: HZEngineCore) {
|
|
5
|
+
// set command: set <key> <value>
|
|
6
|
+
core.script.use((ctx, next) => {
|
|
7
|
+
if (
|
|
8
|
+
ctx.rawtext.trim().split(" ")[0].toLowerCase() !== "set"
|
|
9
|
+
)
|
|
10
|
+
return next();
|
|
11
|
+
if (ctx.slicedArgs.length !== 3)
|
|
12
|
+
throw `Set Command: incorrect amount of args`;
|
|
13
|
+
|
|
14
|
+
let key = ctx.slicedArgs[1].str;
|
|
15
|
+
let val: any = ctx.slicedArgs[2].str;
|
|
16
|
+
|
|
17
|
+
if(!ctx.slicedArgs[2].isQuoted) {
|
|
18
|
+
if(val === "true" || val === "false") {
|
|
19
|
+
val = val === "true";
|
|
20
|
+
}
|
|
21
|
+
else if(!isNaN(val)) {
|
|
22
|
+
val = Number(val);
|
|
23
|
+
}
|
|
24
|
+
else throw `Set Command: value type not supported`;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
core.config.setConfig(key, val);
|
|
28
|
+
});
|
|
29
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { HZEngineCore } from "../../index.js";
|
|
2
|
+
import { splitStr2Objs, splitStr2Strs } from "../../script/strtools.js";
|
|
3
|
+
|
|
4
|
+
export function decorator_module(core: HZEngineCore) {
|
|
5
|
+
core.script.use((ctx, next) => {
|
|
6
|
+
if (
|
|
7
|
+
!ctx.slicedArgs[0].isSquared
|
|
8
|
+
)
|
|
9
|
+
return next();
|
|
10
|
+
|
|
11
|
+
let decorator = ctx.slicedArgs[0].str.toLowerCase();
|
|
12
|
+
|
|
13
|
+
switch (splitStr2Strs(decorator).join("").toLowerCase()) {
|
|
14
|
+
case "real=true":
|
|
15
|
+
(core.storage.globalData as any).realEnv = true;
|
|
16
|
+
break;
|
|
17
|
+
case "real":
|
|
18
|
+
if (!(core.storage.globalData as any).realEnv) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
break;
|
|
22
|
+
default:
|
|
23
|
+
core.debug.log(`Decorator: Unknown decorator [${decorator}]`);
|
|
24
|
+
}
|
|
25
|
+
ctx.rawtext = ctx.rawtext.trim().slice(ctx.slicedArgs[0].str.length + 2).trim();
|
|
26
|
+
if(!ctx.rawtext.length) return
|
|
27
|
+
return next();
|
|
28
|
+
}, true);
|
|
29
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { HZEngineCore } from "../../index.js";
|
|
2
|
+
|
|
3
|
+
export function eval_module(core: HZEngineCore) {
|
|
4
|
+
// single line eval command
|
|
5
|
+
// syntax: eval <code>
|
|
6
|
+
core.script.use((ctx, next) => {
|
|
7
|
+
if (
|
|
8
|
+
ctx.slicedArgs[0].isQuoted ||
|
|
9
|
+
ctx.slicedArgs[0].str.toLowerCase() !== "eval"
|
|
10
|
+
) {
|
|
11
|
+
return next();
|
|
12
|
+
}
|
|
13
|
+
if (ctx.slicedArgs.length === 1) {
|
|
14
|
+
throw `Eval Command: no code specified`;
|
|
15
|
+
}
|
|
16
|
+
if (ctx.slicedArgs.length === 2) {
|
|
17
|
+
core.script.evalScope(ctx.slicedArgs[1].str);
|
|
18
|
+
} else {
|
|
19
|
+
// delete "eval" prefix
|
|
20
|
+
core.script.evalScope(ctx.rawtext.trim().slice(4).trim());
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
// multi line eval statement (script ... end script)
|
|
25
|
+
// syntax:
|
|
26
|
+
// script
|
|
27
|
+
// <code>
|
|
28
|
+
// end script
|
|
29
|
+
|
|
30
|
+
// script statement start
|
|
31
|
+
core.script.use((ctx, next) => {
|
|
32
|
+
if (ctx.rawtext.trim().split(" ")[0] !== "script") {
|
|
33
|
+
return next();
|
|
34
|
+
}
|
|
35
|
+
let data = ctx.startStatement("script") as unknown as ScriptStatementData;
|
|
36
|
+
core.script.evalScope(data.js_code_scope);
|
|
37
|
+
core.script.jump(data.end_position[0], data.end_position[1]);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
// script statement end
|
|
41
|
+
core.script.use((ctx, next) => {
|
|
42
|
+
if (ctx.rawtext.trim().split(/ +/).join(" ") !== "end script")
|
|
43
|
+
return next();
|
|
44
|
+
ctx.endStatement("script");
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
// analyze script statement start
|
|
48
|
+
core.script.useAnalyseStatement((ctx, next) => {
|
|
49
|
+
if (ctx.rawtext.trim().split(" ")[0] !== "script") {
|
|
50
|
+
return next();
|
|
51
|
+
}
|
|
52
|
+
let data = ctx.startStatement("script") as unknown as ScriptStatementData;
|
|
53
|
+
data.start_position = [ctx.currentPath, ctx.currentLineIndex];
|
|
54
|
+
data.js_code_scope = "";
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
// analyze script code scope/statement end
|
|
58
|
+
core.script.useAnalyseStatement((ctx, next) => {
|
|
59
|
+
if (
|
|
60
|
+
ctx.statementStack.length &&
|
|
61
|
+
ctx.statementStack[ctx.statementStack.length - 1][0] === "script"
|
|
62
|
+
) {
|
|
63
|
+
if (ctx.rawtext.trim().split(/ +/).join(" ") === "end script") {
|
|
64
|
+
// end script
|
|
65
|
+
let data = ctx.endStatement("script") as unknown as ScriptStatementData;
|
|
66
|
+
data.end_position = [ctx.currentPath, ctx.currentLineIndex];
|
|
67
|
+
ctx.setStatementData(data, [...data.start_position]);
|
|
68
|
+
} else {
|
|
69
|
+
// add code line to code scope
|
|
70
|
+
(
|
|
71
|
+
ctx.statementStack[
|
|
72
|
+
ctx.statementStack.length - 1
|
|
73
|
+
][2] as unknown as ScriptStatementData
|
|
74
|
+
).js_code_scope += ctx.rawtext.trim() + '\n';
|
|
75
|
+
}
|
|
76
|
+
} else return next();
|
|
77
|
+
}, true);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// eval a()
|
|
81
|
+
// eval"a()"
|
|
82
|
+
// eval "a()"
|
|
83
|
+
|
|
84
|
+
interface ScriptStatementData {
|
|
85
|
+
start_position: [path: string, index: number];
|
|
86
|
+
end_position: [path: string, index: number];
|
|
87
|
+
js_code_scope: string;
|
|
88
|
+
}
|
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
// / <reference types="@zeppos/device-types" />
|
|
2
|
+
// import hmUI from "@zos/ui";
|
|
3
|
+
import { Async, HZEngineCore, Script, TransformPlugin, UI } from "../../index.js";
|
|
4
|
+
|
|
5
|
+
export function img(core: HZEngineCore) {
|
|
6
|
+
let transform_plugin: TransformPlugin.InstanceType = core.plugins.get(
|
|
7
|
+
"transform"
|
|
8
|
+
) as any;
|
|
9
|
+
if (!transform_plugin)
|
|
10
|
+
core.debug.log("[IMG Plugin] Info: Transform plugin not set up");
|
|
11
|
+
// show command
|
|
12
|
+
core.script.use((ctx, next) => {
|
|
13
|
+
if (ctx.rawtext.trim().split(" ")[0].toLowerCase() !== "show")
|
|
14
|
+
return next();
|
|
15
|
+
if (ctx.slicedArgs.length === 1)
|
|
16
|
+
throw `Show Command: incorrect amount of args`;
|
|
17
|
+
if (ctx.slicedArgs.length === 2)
|
|
18
|
+
throw `Show Command: incorrect amount of args`;
|
|
19
|
+
let parsedRes = parseImgCommandFields(ctx);
|
|
20
|
+
|
|
21
|
+
// update args to no fields
|
|
22
|
+
ctx.slicedArgs = parsedRes.leftedArgs;
|
|
23
|
+
let tag = ctx.slicedArgs[1].str;
|
|
24
|
+
let name_key = "";
|
|
25
|
+
for (let i = 1; i < ctx.slicedArgs.length; ++i) {
|
|
26
|
+
name_key += ctx.slicedArgs[i].str + " ";
|
|
27
|
+
}
|
|
28
|
+
name_key = name_key.trim().toLowerCase();
|
|
29
|
+
let path = core.storage.preloadedData.image.nameMap[name_key]?.[0];
|
|
30
|
+
if (!path)
|
|
31
|
+
throw `Show Command: image with name_key [${name_key}] not found `;
|
|
32
|
+
// let size = (hmUI as any).getImageInfo(path);
|
|
33
|
+
let size = core.platform.getImageInfo(path);
|
|
34
|
+
console.log(`IMG: path: ${path}, size: ${JSON.stringify(size)}`);
|
|
35
|
+
|
|
36
|
+
if (!size) throw `Show Command: read size of [${path}] failed`;
|
|
37
|
+
showAction(tag, path, size, parsedRes.strategy);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
function showAction(
|
|
41
|
+
tag: string,
|
|
42
|
+
path: string,
|
|
43
|
+
size: UI.Size,
|
|
44
|
+
routerStrategy: UI.Router.RouteStrategy | null
|
|
45
|
+
) {
|
|
46
|
+
const show_view_tag_prefix = "hzengine.img";
|
|
47
|
+
const show_view_name = "fg_img";
|
|
48
|
+
let prop: UI.FgImgViewProp = {
|
|
49
|
+
imgPath: path,
|
|
50
|
+
offset: {
|
|
51
|
+
x: 0,
|
|
52
|
+
y: 0,
|
|
53
|
+
},
|
|
54
|
+
size: {
|
|
55
|
+
width: size.width,
|
|
56
|
+
height: size.height,
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
let tag_prefixed = `${show_view_tag_prefix}.${tag}`;
|
|
61
|
+
let router = core.ui.getRouter(tag_prefixed);
|
|
62
|
+
if (!router) {
|
|
63
|
+
core.ui.addRouter(tag_prefixed, "fg");
|
|
64
|
+
router = core.ui.getRouter(tag_prefixed)!;
|
|
65
|
+
}
|
|
66
|
+
Async.nextTick(() => {
|
|
67
|
+
// @ts-ignore
|
|
68
|
+
router.replace<UI.FgImgViewProp>(
|
|
69
|
+
show_view_name,
|
|
70
|
+
prop,
|
|
71
|
+
routerStrategy ?? undefined
|
|
72
|
+
);
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// hide command
|
|
77
|
+
core.script.use((ctx, next) => {
|
|
78
|
+
if (ctx.rawtext.trim().split(" ")[0].toLowerCase() !== "hide")
|
|
79
|
+
return next();
|
|
80
|
+
let parsedRes = parseImgCommandFields(ctx);
|
|
81
|
+
ctx.slicedArgs = parsedRes.leftedArgs;
|
|
82
|
+
if (ctx.slicedArgs.length !== 2) {
|
|
83
|
+
throw `Hide Command: incorrect amount of args`;
|
|
84
|
+
}
|
|
85
|
+
let tag = ctx.slicedArgs[1].str;
|
|
86
|
+
|
|
87
|
+
hideAction(tag, parsedRes.strategy);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
function hideAction(
|
|
91
|
+
tag: string,
|
|
92
|
+
routerStrategy: UI.Router.RouteStrategy | null
|
|
93
|
+
) {
|
|
94
|
+
const show_view_tag_prefix = "hzengine.img";
|
|
95
|
+
|
|
96
|
+
let tag_prefixed = `${show_view_tag_prefix}.${tag}`;
|
|
97
|
+
let router = core.ui.getRouter(tag_prefixed);
|
|
98
|
+
if (!router) {
|
|
99
|
+
throw `Hide Command: router with tag [${tag}] not found `;
|
|
100
|
+
}
|
|
101
|
+
Async.nextTick(() => {
|
|
102
|
+
router.clear(routerStrategy ?? undefined);
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// scene command
|
|
107
|
+
core.script.use((ctx, next) => {
|
|
108
|
+
if (ctx.rawtext.trim().split(" ")[0].toLowerCase() !== "scene")
|
|
109
|
+
return next();
|
|
110
|
+
if (ctx.slicedArgs.length === 1)
|
|
111
|
+
throw `Scene Command: incorrect amount of args`;
|
|
112
|
+
if (ctx.slicedArgs.length === 2)
|
|
113
|
+
throw `Scene Command: incorrect amount of args`;
|
|
114
|
+
let parsedRes = parseImgCommandFields(ctx);
|
|
115
|
+
|
|
116
|
+
// update args to no fields
|
|
117
|
+
ctx.slicedArgs = parsedRes.leftedArgs;
|
|
118
|
+
|
|
119
|
+
let tag = ctx.slicedArgs[1].str;
|
|
120
|
+
let name_key = "";
|
|
121
|
+
for (let i = 1; i < ctx.slicedArgs.length; ++i) {
|
|
122
|
+
name_key += ctx.slicedArgs[i].str + " ";
|
|
123
|
+
}
|
|
124
|
+
name_key = name_key.trim().toLowerCase();
|
|
125
|
+
let path = core.storage.preloadedData.image.nameMap[name_key]?.[0];
|
|
126
|
+
if (!path)
|
|
127
|
+
throw `Scene Command: image with name_key [${name_key}] not found `;
|
|
128
|
+
// let size = (hmUI as any).getImageInfo(path);
|
|
129
|
+
let size = core.platform.getImageInfo(path);
|
|
130
|
+
if (!size) throw `Scene Command: read size of [${path}] failed`;
|
|
131
|
+
|
|
132
|
+
sceneAction(tag, path, size, parsedRes.strategy);
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
function sceneAction(
|
|
136
|
+
tag: string,
|
|
137
|
+
path: string,
|
|
138
|
+
size: UI.Size,
|
|
139
|
+
routerStrategy: UI.Router.RouteStrategy | null
|
|
140
|
+
) {
|
|
141
|
+
const scene_view_tag_prefix = "hzengine.img";
|
|
142
|
+
const scene_view_name = "bg_img";
|
|
143
|
+
let prop: UI.BgImgViewProp = {
|
|
144
|
+
imgPath: path,
|
|
145
|
+
offset: {
|
|
146
|
+
x: 0,
|
|
147
|
+
y: 0,
|
|
148
|
+
},
|
|
149
|
+
size: {
|
|
150
|
+
width: size.width,
|
|
151
|
+
height: size.height,
|
|
152
|
+
},
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
let tag_prefixed = `${scene_view_tag_prefix}.${tag}`;
|
|
156
|
+
let router = core.ui.getRouter(tag_prefixed);
|
|
157
|
+
if (!router) {
|
|
158
|
+
core.ui.addRouter(tag_prefixed, "bg");
|
|
159
|
+
router = core.ui.getRouter(tag_prefixed)!;
|
|
160
|
+
}
|
|
161
|
+
if (!router.length) {
|
|
162
|
+
// @ts-ignore
|
|
163
|
+
Async.nextTick(() => {
|
|
164
|
+
// @ts-ignore
|
|
165
|
+
router.push<UI.BgImgViewProp>(
|
|
166
|
+
scene_view_name,
|
|
167
|
+
prop,
|
|
168
|
+
routerStrategy ?? undefined
|
|
169
|
+
);
|
|
170
|
+
});
|
|
171
|
+
} else {
|
|
172
|
+
// @ts-ignore
|
|
173
|
+
Async.nextTick(() => {
|
|
174
|
+
// @ts-ignore
|
|
175
|
+
router.update<UI.BgImgViewProp>(prop, routerStrategy ?? undefined);
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// with
|
|
181
|
+
// at
|
|
182
|
+
// wait
|
|
183
|
+
// nowait
|
|
184
|
+
|
|
185
|
+
function parseImgCommandFields(ctx: Script.Context): ParsedImgCommandFields {
|
|
186
|
+
let slicedArgs: typeof ctx.slicedArgs = JSON.parse(
|
|
187
|
+
JSON.stringify(ctx.slicedArgs)
|
|
188
|
+
); // TODO 深拷贝 性能
|
|
189
|
+
|
|
190
|
+
// TODO 注意这里的代码超级高耦合
|
|
191
|
+
let res: ReturnType<typeof parseImgCommandFields> = {
|
|
192
|
+
strategy: null,
|
|
193
|
+
wait: false,
|
|
194
|
+
leftedArgs: slicedArgs,
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
// wait/nowait
|
|
198
|
+
if (slicedArgs[slicedArgs.length - 1].str === "wait") {
|
|
199
|
+
res.wait = true;
|
|
200
|
+
slicedArgs.pop();
|
|
201
|
+
} else if (slicedArgs[slicedArgs.length - 1].str === "nowait") {
|
|
202
|
+
res.wait = false;
|
|
203
|
+
slicedArgs.pop();
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// parse long fields
|
|
207
|
+
let keywords = ["with", "at"];
|
|
208
|
+
let inTransforms: string[] = [];
|
|
209
|
+
let outTransforms: string[] = [];
|
|
210
|
+
while (true) {
|
|
211
|
+
// console.log(`slicedArgs: ${JSON.stringify(slicedArgs)}`);
|
|
212
|
+
|
|
213
|
+
let keyword_index = findLastIndex(
|
|
214
|
+
slicedArgs,
|
|
215
|
+
(slicedArg) =>
|
|
216
|
+
!slicedArg.isQuoted &&
|
|
217
|
+
!slicedArg.isSquared &&
|
|
218
|
+
keywords.includes(slicedArg.str)
|
|
219
|
+
);
|
|
220
|
+
if (keyword_index === -1) break;
|
|
221
|
+
let keyword = slicedArgs[keyword_index].str;
|
|
222
|
+
let currentFieldArgs = slicedArgs.splice(
|
|
223
|
+
keyword_index,
|
|
224
|
+
slicedArgs.length - keyword_index
|
|
225
|
+
);
|
|
226
|
+
currentFieldArgs.shift();
|
|
227
|
+
|
|
228
|
+
if (keyword === "at") {
|
|
229
|
+
inTransforms.push(
|
|
230
|
+
...Script.Utils.splitCommas(
|
|
231
|
+
Script.Utils.joinSlicedArgs(currentFieldArgs)
|
|
232
|
+
)
|
|
233
|
+
);
|
|
234
|
+
} else if (keyword === "with") {
|
|
235
|
+
let args = Script.Utils.parseHzsArgs(
|
|
236
|
+
Script.Utils.joinSlicedArgs(currentFieldArgs)
|
|
237
|
+
);
|
|
238
|
+
// console.log(`with args: ${JSON.stringify(args)}`);
|
|
239
|
+
|
|
240
|
+
for (let i = 0; i < args.length; i++) {
|
|
241
|
+
if (Array.isArray(args[i])) {
|
|
242
|
+
// Annoymous Transition Tuple
|
|
243
|
+
if (args[i].length > 2)
|
|
244
|
+
throw `Invalid Annoymous Transition Tuple: ${JSON.stringify(
|
|
245
|
+
args[i]
|
|
246
|
+
)}`;
|
|
247
|
+
console.log(
|
|
248
|
+
`Annoymous Transition Tuple: ${JSON.stringify(args[i])}`
|
|
249
|
+
);
|
|
250
|
+
|
|
251
|
+
if (args[i].length >= 1) {
|
|
252
|
+
if (Array.isArray(args[i][0])) {
|
|
253
|
+
outTransforms.push(...(args[i][0] as string[]));
|
|
254
|
+
} else {
|
|
255
|
+
outTransforms.push(args[i][0] as string);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
if (args[i].length >= 2) {
|
|
260
|
+
if (Array.isArray(args[i][1])) {
|
|
261
|
+
inTransforms.push(...(args[i][1] as string[]));
|
|
262
|
+
} else {
|
|
263
|
+
inTransforms.push(args[i][1] as string);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
} else {
|
|
267
|
+
// Named Transition
|
|
268
|
+
let transition = transform_plugin.getTransition(args[i] as string);
|
|
269
|
+
if (!transition) {
|
|
270
|
+
core.debug.log(`Transition ${args[i]} not found`);
|
|
271
|
+
continue;
|
|
272
|
+
} else {
|
|
273
|
+
core.debug.log(
|
|
274
|
+
`Transition ${args[i]} = ${JSON.stringify(transition)}`
|
|
275
|
+
);
|
|
276
|
+
inTransforms.push(...transition.inTransforms);
|
|
277
|
+
outTransforms.push(...transition.outTransforms);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
// let withField: WithField = {
|
|
284
|
+
// outTransform: ctx.slicedArgs[withIndex + 1]?.str ?? null,
|
|
285
|
+
// inTransform: ctx.slicedArgs[withIndex + 2]?.str ?? null,
|
|
286
|
+
// };
|
|
287
|
+
res.strategy = transform_plugin.createStrategy(
|
|
288
|
+
outTransforms.length ? outTransforms : null,
|
|
289
|
+
inTransforms.length ? inTransforms : null
|
|
290
|
+
);
|
|
291
|
+
return res;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
function findLastIndex<T>(array: T[], predicator: (value: T) => boolean) {
|
|
295
|
+
for (let i = array.length - 1; i >= 0; i--) {
|
|
296
|
+
if (predicator(array[i])) {
|
|
297
|
+
return i;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
return -1;
|
|
301
|
+
}
|
|
302
|
+
const slicedArgsToTransforms = (slicedArgs: Script.Context.SlicedArg[]) =>
|
|
303
|
+
Script.Utils.joinSlicedArgs(slicedArgs)
|
|
304
|
+
.split(",")
|
|
305
|
+
.map((str) => str.trim())
|
|
306
|
+
.filter((str) => str.length > 0);
|
|
307
|
+
|
|
308
|
+
type ParsedImgCommandFields = {
|
|
309
|
+
strategy: UI.Router.RouteStrategy | null;
|
|
310
|
+
wait: boolean;
|
|
311
|
+
leftedArgs: Script.Context.SlicedArg[];
|
|
312
|
+
};
|
|
313
|
+
// type WithField = {
|
|
314
|
+
// inTransform: string | null;
|
|
315
|
+
// outTransform: string | null;
|
|
316
|
+
// };
|
|
317
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { HZEngineCore, UI } from "../../index.js";
|
|
2
|
+
import { $_command } from "./$.js";
|
|
3
|
+
import { audio_command } from "./audio.js";
|
|
4
|
+
import { basic_commands } from "./basic.js";
|
|
5
|
+
import { character_command } from "./character.js";
|
|
6
|
+
import { conditional } from "./conditional.js";
|
|
7
|
+
import { config_command } from "./config.js";
|
|
8
|
+
import { decorator_module } from "./decorator.js";
|
|
9
|
+
import { eval_module } from "./eval.js";
|
|
10
|
+
import { img } from "./img.js";
|
|
11
|
+
import { menu_statement } from "./menu.js";
|
|
12
|
+
|
|
13
|
+
export function basic_command(core: HZEngineCore) {
|
|
14
|
+
basic_commands(core);
|
|
15
|
+
character_command(core);
|
|
16
|
+
menu_statement(core);
|
|
17
|
+
decorator_module(core);
|
|
18
|
+
$_command(core);
|
|
19
|
+
eval_module(core);
|
|
20
|
+
conditional(core);
|
|
21
|
+
img(core);
|
|
22
|
+
audio_command(core);
|
|
23
|
+
config_command(core);
|
|
24
|
+
}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { HZEngineCore, UI } from "../../index.js";
|
|
2
|
+
|
|
3
|
+
export function menu_statement(core: HZEngineCore) {
|
|
4
|
+
// menu statement start
|
|
5
|
+
core.script.use((ctx, next) => {
|
|
6
|
+
if (ctx.rawtext.trim().split(" ")[0] !== "menu") return next();
|
|
7
|
+
let menu_data = ctx.startStatement("menu") as unknown as MenuStatementData;
|
|
8
|
+
|
|
9
|
+
// Block the game
|
|
10
|
+
core.system.block();
|
|
11
|
+
|
|
12
|
+
let router = core.ui.getRouter("menu");
|
|
13
|
+
|
|
14
|
+
if (!router) {
|
|
15
|
+
core.ui.addRouter("menu", "ct");
|
|
16
|
+
router = core.ui.getRouter("menu")!;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
let menu_view_prop = buildMenuViewProp(menu_data);
|
|
20
|
+
if (!router.length) {
|
|
21
|
+
router.push("menu", menu_view_prop);
|
|
22
|
+
} else {
|
|
23
|
+
router.update(menu_view_prop);
|
|
24
|
+
}
|
|
25
|
+
// the view contains many buttons, when the button is clicked,
|
|
26
|
+
// it will call core.script.jump() to jump to the next line of the @label statement
|
|
27
|
+
// then hide the menu
|
|
28
|
+
// so the script will continue to execute the next line of the @label statement
|
|
29
|
+
// when a @label is appended again, it represents the command between the @label and the next @label
|
|
30
|
+
// is executed completely, so jump to the next line of "end menu"
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
// menu statement close
|
|
34
|
+
core.script.use((ctx, next) => {
|
|
35
|
+
if (ctx.rawtext.trim().split(/ +/).join(" ") !== "end menu") return next();
|
|
36
|
+
|
|
37
|
+
ctx.endStatement("menu");
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
// menu internal label (start with @)
|
|
41
|
+
// syntax: @"{label_name}" [enable={js_expression}]
|
|
42
|
+
core.script.use((ctx, next) => {
|
|
43
|
+
if (!ctx.rawtext.trim().split(" ")[0].startsWith("@")) return next();
|
|
44
|
+
let label_name = ctx.slicedArgs[1].str;
|
|
45
|
+
if (
|
|
46
|
+
ctx.statementStack.length === 0 ||
|
|
47
|
+
ctx.statementStack[ctx.statementStack.length - 1][0] !== "menu"
|
|
48
|
+
) {
|
|
49
|
+
throw `@${label_name} must in menu statement`;
|
|
50
|
+
}
|
|
51
|
+
let menu_item = ctx.statementStack[ctx.statementStack.length - 1];
|
|
52
|
+
|
|
53
|
+
let menu_data = menu_item[2] as unknown as MenuStatementData;
|
|
54
|
+
|
|
55
|
+
for (let i = 0; i < menu_data.item_list.length; i++) {
|
|
56
|
+
if (
|
|
57
|
+
menu_data.item_list[i].position[0] === ctx.currentPath &&
|
|
58
|
+
menu_data.item_list[i].position[1] === ctx.currentLineIndex
|
|
59
|
+
) {
|
|
60
|
+
// the label belongs to this menu statement
|
|
61
|
+
// so jump to the "end menu" statement
|
|
62
|
+
// the script will continue from the "end menu" statement
|
|
63
|
+
|
|
64
|
+
// get the end menu statement position
|
|
65
|
+
let end_menu_position: [path: string, index: number] = [
|
|
66
|
+
...menu_data.end_position,
|
|
67
|
+
];
|
|
68
|
+
|
|
69
|
+
// jump to "end menu"
|
|
70
|
+
core.script.jump(end_menu_position[0], end_menu_position[1]);
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// the label does not belong to this menu statement, so throw error
|
|
76
|
+
throw `@${label_name} does not belong to closest menu statement, at file [${
|
|
77
|
+
ctx.currentPath
|
|
78
|
+
}] line [${ctx.currentLineIndex + 1}], but belong to [${
|
|
79
|
+
menu_item[1][0]
|
|
80
|
+
}] line [${menu_item[1][1] + 1}]`;
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
// analyse menu start statement
|
|
84
|
+
core.script.useAnalyseStatement((ctx, next) => {
|
|
85
|
+
if (ctx.rawtext.trim().split(" ")[0] !== "menu") return next();
|
|
86
|
+
let data = ctx.startStatement("menu");
|
|
87
|
+
|
|
88
|
+
// console.log("[HZEngine] Menu start");
|
|
89
|
+
|
|
90
|
+
// the data here is {} at first, so dont read its properties, because the properties are not defined yet
|
|
91
|
+
// we will define the properties here
|
|
92
|
+
(data as unknown as MenuStatementData).start_position = [
|
|
93
|
+
ctx.currentPath,
|
|
94
|
+
ctx.currentLineIndex,
|
|
95
|
+
];
|
|
96
|
+
(data as unknown as MenuStatementData).item_list = [];
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
// analyse menu label (start with @)
|
|
100
|
+
core.script.useAnalyseStatement((ctx, next) => {
|
|
101
|
+
if (!ctx.rawtext.trim().split(" ")[0].startsWith("@")) return next();
|
|
102
|
+
if (
|
|
103
|
+
ctx.statementStack.length === 0 ||
|
|
104
|
+
ctx.statementStack[ctx.statementStack.length - 1][0] !== "menu"
|
|
105
|
+
) {
|
|
106
|
+
throw `@${ctx.slicedArgs[1]} must in menu statement`;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// console.log("[HZEngine] Menu label: " + ctx.slicedArgs[1].str);
|
|
110
|
+
|
|
111
|
+
let menu_stack_item = ctx.statementStack[ctx.statementStack.length - 1];
|
|
112
|
+
|
|
113
|
+
// parse the enable js expression (syntax: enable={js_expression})
|
|
114
|
+
// get the js_expression and put it in the menu data
|
|
115
|
+
let enable_js_expression: string | undefined = undefined;
|
|
116
|
+
if (ctx.slicedArgs.length > 2) {
|
|
117
|
+
enable_js_expression = ctx.slicedArgs[2].str!;
|
|
118
|
+
|
|
119
|
+
if (!enable_js_expression.startsWith("enable=")) {
|
|
120
|
+
throw `enable js expression must start with "enable="`;
|
|
121
|
+
}
|
|
122
|
+
enable_js_expression = enable_js_expression.slice(7);
|
|
123
|
+
if (
|
|
124
|
+
enable_js_expression.startsWith("{") &&
|
|
125
|
+
enable_js_expression.endsWith("}")
|
|
126
|
+
) {
|
|
127
|
+
enable_js_expression = enable_js_expression.slice(1, -1);
|
|
128
|
+
} else {
|
|
129
|
+
enable_js_expression = enable_js_expression.trim();
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (enable_js_expression.length > 0) {
|
|
133
|
+
enable_js_expression = `(${enable_js_expression})`;
|
|
134
|
+
} else {
|
|
135
|
+
throw `enable js expression must not be empty`;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
(menu_stack_item[2] as unknown as MenuStatementData).item_list.push({
|
|
140
|
+
text: ctx.slicedArgs[1].str,
|
|
141
|
+
position: [ctx.currentPath, ctx.currentLineIndex],
|
|
142
|
+
enable_js_expression,
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
// analyse menu end statement
|
|
147
|
+
core.script.useAnalyseStatement((ctx, next) => {
|
|
148
|
+
if (ctx.rawtext.trim().split(/ +/).join(" ") !== "end menu") return next();
|
|
149
|
+
// console.log("[HZEngine] Menu analyse end");
|
|
150
|
+
|
|
151
|
+
let data: MenuStatementData = ctx.endStatement(
|
|
152
|
+
"menu"
|
|
153
|
+
) as unknown as MenuStatementData;
|
|
154
|
+
// the data here is {} at first, so dont read its properties, because the properties are not defined yet
|
|
155
|
+
// we will define the properties here
|
|
156
|
+
data.end_position = [ctx.currentPath, ctx.currentLineIndex];
|
|
157
|
+
// set and save the menu data
|
|
158
|
+
ctx.setStatementData(data, [
|
|
159
|
+
data.start_position[0],
|
|
160
|
+
data.start_position[1],
|
|
161
|
+
]);
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
function buildMenuViewProp(menu_data: MenuStatementData): UI.MenuViewProp {
|
|
165
|
+
// parse menu item string
|
|
166
|
+
let parsed_item_list: UI.MenuItemData[] = [];
|
|
167
|
+
for (let item of menu_data.item_list) {
|
|
168
|
+
parsed_item_list.push({ ...item, text: core.script.parseString(item.text) });
|
|
169
|
+
}
|
|
170
|
+
return { itemList: parsed_item_list };
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
interface MenuStatementData {
|
|
175
|
+
start_position: [path: string, index: number];
|
|
176
|
+
end_position: [path: string, index: number];
|
|
177
|
+
item_list: UI.MenuItemData[];
|
|
178
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// import hmUI from "@zos/ui";
|
|
2
|
+
import { HZEngineCore, UI } from "../../index.js";
|
|
3
|
+
import { System } from "../../system/index.js";
|
|
4
|
+
|
|
5
|
+
export function global_gesture(core: HZEngineCore) {
|
|
6
|
+
function addTouchPad(layerInstance: UI.Layer<any>) {
|
|
7
|
+
// TODO touch pad
|
|
8
|
+
core.debug.log("[TouchPad] Not implemented");
|
|
9
|
+
// let touchPad = layerInstance.widgetFactory.createWidget(hmUI.widget.TEXT, {
|
|
10
|
+
// x: 0,
|
|
11
|
+
// y: 0,
|
|
12
|
+
// w: 600,
|
|
13
|
+
// h: 600,
|
|
14
|
+
// text: "",
|
|
15
|
+
// });
|
|
16
|
+
|
|
17
|
+
// touchPad.addEventListener(hmUI.event.SELECT, (info: any) => {
|
|
18
|
+
// console.log("按下了屏幕");
|
|
19
|
+
// if (core.system.condition === System.Condition.Pause) {
|
|
20
|
+
// core.system.continue();
|
|
21
|
+
// }
|
|
22
|
+
// });
|
|
23
|
+
}
|
|
24
|
+
addTouchPad(core.ui.getLayer("ct")!);
|
|
25
|
+
core.on("afterAddLayer", (layerInstance: UI.Layer<any>) => {
|
|
26
|
+
if (layerInstance.name !== "ct") return;
|
|
27
|
+
addTouchPad(layerInstance);
|
|
28
|
+
});
|
|
29
|
+
}
|