Skip to content

Commit e7f0abe

Browse files
Merge pull request #1002 from OpenWebGAL/dev
4.6.2
2 parents d394bc7 + 6b4cbf6 commit e7f0abe

79 files changed

Lines changed: 3034 additions & 685 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@webgal/base",
3-
"version": "4.6.1",
3+
"version": "4.6.2",
44
"description": "A brand new web Visual Novel engine.",
55
"repository": "https://github.com/OpenWebGAL/WebGAL.git",
66
"author": "Mahiru <Mahiru_@outlook.com>",

packages/parser/.npmignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,3 @@ test
33
.babelrc
44
rollup.config.js
55
tsconfig.json
6-
tsconfig.node.json

packages/parser/package.json

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "webgal-parser",
3-
"version": "4.6.1",
3+
"version": "4.6.2",
44
"description": "WebGAL script parser",
55
"scripts": {
66
"test": "vitest",
@@ -17,26 +17,16 @@
1717
"main": "./build/cjs/index.cjs",
1818
"author": "Mahiru <Mahiru_@outlook.com>",
1919
"license": "MPL-2.0",
20-
"dependencies": {
21-
"chevrotain": "^10.5.0",
22-
"cloudlogjs": "^1.0.11",
23-
"lodash": "^4.17.23",
24-
"tsx": "^3.12.7"
25-
},
2620
"devDependencies": {
2721
"@rollup/plugin-commonjs": "^23.0.2",
28-
"@rollup/plugin-json": "^5.0.1",
2922
"@rollup/plugin-node-resolve": "^15.0.1",
30-
"@rollup/plugin-typescript": "^9.0.2",
31-
"@types/lodash": "^4.14.189",
3223
"@types/node": "^18.14.0",
3324
"@vitest/coverage-c8": "^0.28.5",
25+
"rimraf": "^3.0.2",
3426
"rollup": "^3.29.5",
35-
"rollup-plugin-babel": "^4.4.0",
36-
"rollup-plugin-terser": "^7.0.2",
3727
"rollup-plugin-typescript2": "^0.34.1",
38-
"ts-node": "^10.9.1",
3928
"tslib": "^2.4.1",
29+
"tsx": "^3.12.7",
4030
"typescript": "^4.9.3",
4131
"vitest": "^0.28.5"
4232
},

packages/parser/rollup.config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ export default [
5353
file: "./build/umd/index.global.js",
5454
name: 'webgalParser',
5555
format: 'iife',
56+
exports: "named",
5657
sourcemap: !isProd
5758
},
5859
],

packages/parser/src/sceneParser.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import {
55
ISentence,
66
} from './interface/sceneInterface';
77
import { scriptParser } from './scriptParser/scriptParser';
8-
import uniqWith from 'lodash/uniqWith';
98
import { fileType } from './interface/assets';
109
import { ConfigMap } from './config/scriptConfig';
1110

@@ -54,7 +53,7 @@ export const sceneParser = (
5453
);
5554

5655
// 开始资源的预加载
57-
assetsList = uniqWith(assetsList); // 去重
56+
assetsList = deduplicateAssets(assetsList);
5857
assetsPrefetcher(assetsList);
5958

6059
return {
@@ -65,3 +64,18 @@ export const sceneParser = (
6564
subSceneList: subSceneList, // 子场景列表
6665
};
6766
};
67+
68+
const deduplicateAssets = (assetsList: IAsset[]): IAsset[] => {
69+
const seenAssets = new Set<string>();
70+
return assetsList.filter((asset) => {
71+
if (!asset || typeof asset.url !== 'string' || asset.url === '') {
72+
return false;
73+
}
74+
const assetKey = `${asset.type}:${asset.url}`;
75+
if (seenAssets.has(assetKey)) {
76+
return false;
77+
}
78+
seenAssets.add(assetKey);
79+
return true;
80+
});
81+
};

packages/parser/src/scriptParser/scriptParser.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ export const scriptParser = (
4040
const commentSplit = sentenceRaw.split(/(?<!\\);/);
4141
let newSentenceRaw = commentSplit[0];
4242
newSentenceRaw = newSentenceRaw.replaceAll('\\;',';');
43-
const sentenceComment = commentSplit[1] ?? '';
43+
const sentenceComment = commentSplit.slice(1).join(';');
4444
if (newSentenceRaw.trim() === '') {
4545
// 注释提前返回
4646
return {

packages/parser/test/parser.test.ts

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import SceneParser from "../src/index";
22
import { ADD_NEXT_ARG_LIST, SCRIPT_CONFIG } from "../src/config/scriptConfig";
33
import { expect, test } from "vitest";
4-
import { commandType, ISentence } from "../src/interface/sceneInterface";
4+
import { commandType, IAsset, ISentence } from "../src/interface/sceneInterface";
55
import * as fsp from 'fs/promises';
66
import { fileType } from "../src/interface/assets";
77

@@ -223,6 +223,39 @@ test("say statement applies asset setter to vocal named argument", async () => {
223223
});
224224
});
225225

226+
test("scene assets are deduplicated by type and url", async () => {
227+
let prefetchedAssets: IAsset[] = [];
228+
const parser = new SceneParser((assetList) => {
229+
prefetchedAssets = assetList;
230+
}, (fileName, assetType) => {
231+
return fileName;
232+
}, ADD_NEXT_ARG_LIST, SCRIPT_CONFIG);
233+
234+
const result = parser.parse(`changeBg:shared.webp;
235+
changeFigure:shared.webp;
236+
changeBg:shared.webp;`, 'test', 'test');
237+
238+
expect(result.assetsList).toEqual([
239+
{ name: "shared.webp", url: 'shared.webp', type: fileType.background, lineNumber: 0 },
240+
{ name: "shared.webp", url: 'shared.webp', type: fileType.figure, lineNumber: 1 },
241+
]);
242+
expect(prefetchedAssets).toEqual(result.assetsList);
243+
});
244+
245+
test("scene assets skip entries with empty urls", async () => {
246+
const parser = new SceneParser((assetList) => {
247+
}, (fileName, assetType) => {
248+
if (assetType === fileType.vocal) {
249+
return '';
250+
}
251+
return fileName;
252+
}, ADD_NEXT_ARG_LIST, SCRIPT_CONFIG);
253+
254+
const result = parser.parse(`say:123 -vocal=missing.mp3;`, 'test', 'test');
255+
256+
expect(result.assetsList).toEqual([]);
257+
});
258+
226259
test("wait command", async () => {
227260
const parser = new SceneParser((assetList) => {
228261
}, (fileName, assetType) => {
@@ -326,6 +359,25 @@ test("escaped semicolon is preserved in content and inline comment is preserved"
326359
expect(result.sentenceList).toContainEqual(expectSentenceItem);
327360
});
328361

362+
test("inline comment preserves following semicolons", async () => {
363+
const parser = new SceneParser((assetList) => {
364+
}, (fileName, assetType) => {
365+
return fileName;
366+
}, ADD_NEXT_ARG_LIST, SCRIPT_CONFIG);
367+
368+
const result = parser.parse(`say:123; first; second; third`, 'test', 'test');
369+
const expectSentenceItem: ISentence = {
370+
command: commandType.say,
371+
commandRaw: "say",
372+
content: "123",
373+
args: [],
374+
sentenceAssets: [],
375+
subScene: [],
376+
inlineComment: "first; second; third"
377+
};
378+
expect(result.sentenceList).toContainEqual(expectSentenceItem);
379+
});
380+
329381
test("comment-only line keeps comment in content", async () => {
330382
const parser = new SceneParser((assetList) => {
331383
}, (fileName, assetType) => {
@@ -344,3 +396,22 @@ test("comment-only line keeps comment in content", async () => {
344396
};
345397
expect(result.sentenceList).toContainEqual(expectSentenceItem);
346398
});
399+
400+
test("comment-only line preserves following semicolons", async () => {
401+
const parser = new SceneParser((assetList) => {
402+
}, (fileName, assetType) => {
403+
return fileName;
404+
}, ADD_NEXT_ARG_LIST, SCRIPT_CONFIG);
405+
406+
const result = parser.parse(`; first; second; third`, 'test', 'test');
407+
const expectSentenceItem: ISentence = {
408+
command: commandType.comment,
409+
commandRaw: "comment",
410+
content: "first; second; third",
411+
args: [{ key: 'next', value: true }],
412+
sentenceAssets: [],
413+
subScene: [],
414+
inlineComment: ""
415+
};
416+
expect(result.sentenceList).toContainEqual(expectSentenceItem);
417+
});

packages/parser/tsconfig.json

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"declarationDir": "build/types",
55
"target": "ESNext",
66
"useDefineForClassFields": true,
7-
"lib": ["DOM", "DOM.Iterable", "ESNext"],
7+
"lib": ["ESNext"],
88
"allowJs": false,
99
"skipLibCheck": false,
1010
"esModuleInterop": false,
@@ -17,13 +17,12 @@
1717
"resolveJsonModule": true,
1818
"isolatedModules": true,
1919
"noEmit": true,
20-
"jsx": "react-jsx",
20+
"types": ["node"],
2121
"paths": {
2222
"@/*": ["./src/*"]
2323
}
2424
},
2525
"include": [
2626
"src"
27-
],
28-
"references": [{ "path": "./tsconfig.node.json"}]
27+
]
2928
}

packages/parser/tsconfig.node.json

Lines changed: 0 additions & 10 deletions
This file was deleted.

packages/webgal/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "webgal-engine",
3-
"version": "4.6.1",
3+
"version": "4.6.2",
44
"scripts": {
55
"dev": "vite --host --port 3000",
66
"build": "node scripts/update-engine-version.js && cross-env NODE_ENV=production tsc && vite build --base=./",

0 commit comments

Comments
 (0)