adofai 3.1.0 → 3.3.0
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/README.md +423 -51
- package/dist/src/parser/LargeFileParser.d.ts +20 -0
- package/dist/src/parser/LargeFileParser.js +382 -0
- package/dist/src/parser.d.ts +2 -1
- package/dist/src/parser.js +2 -1
- package/dist/src/pathdata/index.d.ts +1 -4
- package/dist/src/pathdata/index.js +45 -2
- package/dist/src/structure/Level.d.ts +0 -65
- package/dist/src/structure/Level.js +23 -395
- package/dist/src/structure/levelAngle.d.ts +40 -0
- package/dist/src/structure/levelAngle.js +316 -0
- package/dist/src/types.d.ts +8 -0
- package/dist/src/types.js +27 -0
- package/dist/umd/index.js +1 -1
- package/package.json +8 -8
|
@@ -0,0 +1,382 @@
|
|
|
1
|
+
const BOM = new Uint8Array([0xef, 0xbb, 0xbf]);
|
|
2
|
+
function findAllPropertiesAtRoot(buffer) {
|
|
3
|
+
const result = new Map();
|
|
4
|
+
let depth = 0;
|
|
5
|
+
let inString = false;
|
|
6
|
+
let escapeNext = false;
|
|
7
|
+
let propertyName = '';
|
|
8
|
+
let propertyNameStart = -1;
|
|
9
|
+
for (let i = 0; i < buffer.length; i++) {
|
|
10
|
+
const byte = buffer[i];
|
|
11
|
+
if (escapeNext) {
|
|
12
|
+
escapeNext = false;
|
|
13
|
+
continue;
|
|
14
|
+
}
|
|
15
|
+
if (byte === 92) {
|
|
16
|
+
escapeNext = true;
|
|
17
|
+
continue;
|
|
18
|
+
}
|
|
19
|
+
if (byte === 34) {
|
|
20
|
+
if (inString) {
|
|
21
|
+
inString = false;
|
|
22
|
+
if (depth === 1 && propertyNameStart !== -1) {
|
|
23
|
+
const decoder = new TextDecoder('utf-8');
|
|
24
|
+
propertyName = decoder.decode(buffer.slice(propertyNameStart, i));
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
inString = true;
|
|
29
|
+
propertyNameStart = i + 1;
|
|
30
|
+
}
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
if (!inString) {
|
|
34
|
+
if (byte === 123) {
|
|
35
|
+
depth++;
|
|
36
|
+
}
|
|
37
|
+
else if (byte === 125) {
|
|
38
|
+
depth--;
|
|
39
|
+
}
|
|
40
|
+
else if (byte === 58 && depth === 1 && propertyName) {
|
|
41
|
+
let pos = i + 1;
|
|
42
|
+
while (pos < buffer.length && (buffer[pos] === 32 || buffer[pos] === 9 || buffer[pos] === 10 || buffer[pos] === 13)) {
|
|
43
|
+
pos++;
|
|
44
|
+
}
|
|
45
|
+
result.set(propertyName, pos);
|
|
46
|
+
propertyName = '';
|
|
47
|
+
propertyNameStart = -1;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return result;
|
|
52
|
+
}
|
|
53
|
+
function findValueEnd(buffer, startPos) {
|
|
54
|
+
if (startPos >= buffer.length)
|
|
55
|
+
return -1;
|
|
56
|
+
const firstChar = buffer[startPos];
|
|
57
|
+
if (firstChar === 34) {
|
|
58
|
+
let i = startPos + 1;
|
|
59
|
+
let escapeNext = false;
|
|
60
|
+
while (i < buffer.length) {
|
|
61
|
+
if (escapeNext) {
|
|
62
|
+
escapeNext = false;
|
|
63
|
+
i++;
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
if (buffer[i] === 92) {
|
|
67
|
+
escapeNext = true;
|
|
68
|
+
i++;
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
if (buffer[i] === 34)
|
|
72
|
+
return i + 1;
|
|
73
|
+
i++;
|
|
74
|
+
}
|
|
75
|
+
return -1;
|
|
76
|
+
}
|
|
77
|
+
if (firstChar === 91 || firstChar === 123) {
|
|
78
|
+
const closeChar = firstChar === 91 ? 93 : 125;
|
|
79
|
+
let depth = 0;
|
|
80
|
+
let i = startPos;
|
|
81
|
+
let inString = false;
|
|
82
|
+
let escapeNext = false;
|
|
83
|
+
while (i < buffer.length) {
|
|
84
|
+
if (escapeNext) {
|
|
85
|
+
escapeNext = false;
|
|
86
|
+
i++;
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
if (buffer[i] === 92) {
|
|
90
|
+
escapeNext = true;
|
|
91
|
+
i++;
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
if (buffer[i] === 34) {
|
|
95
|
+
inString = !inString;
|
|
96
|
+
i++;
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
if (!inString) {
|
|
100
|
+
if (buffer[i] === firstChar) {
|
|
101
|
+
depth++;
|
|
102
|
+
}
|
|
103
|
+
else if (buffer[i] === closeChar) {
|
|
104
|
+
depth--;
|
|
105
|
+
if (depth === 0)
|
|
106
|
+
return i + 1;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
i++;
|
|
110
|
+
}
|
|
111
|
+
return -1;
|
|
112
|
+
}
|
|
113
|
+
let i = startPos;
|
|
114
|
+
while (i < buffer.length) {
|
|
115
|
+
const byte = buffer[i];
|
|
116
|
+
if (byte === 44 || byte === 125 || byte === 93 || byte === 32 || byte === 9 || byte === 10 || byte === 13) {
|
|
117
|
+
return i;
|
|
118
|
+
}
|
|
119
|
+
i++;
|
|
120
|
+
}
|
|
121
|
+
return i;
|
|
122
|
+
}
|
|
123
|
+
function extractValueAsString(buffer, startPos, endPos) {
|
|
124
|
+
const decoder = new TextDecoder('utf-8');
|
|
125
|
+
return decoder.decode(buffer.slice(startPos, endPos));
|
|
126
|
+
}
|
|
127
|
+
function parseNumberArrayIncremental(buffer, startPos, onProgress) {
|
|
128
|
+
if (startPos >= buffer.length || buffer[startPos] !== 91)
|
|
129
|
+
return null;
|
|
130
|
+
const values = [];
|
|
131
|
+
let i = startPos + 1;
|
|
132
|
+
let currentValue = '';
|
|
133
|
+
let depth = 1;
|
|
134
|
+
let inString = false;
|
|
135
|
+
let escapeNext = false;
|
|
136
|
+
let lastWasComma = false;
|
|
137
|
+
const totalLength = buffer.length;
|
|
138
|
+
while (i < buffer.length) {
|
|
139
|
+
const byte = buffer[i];
|
|
140
|
+
if (escapeNext) {
|
|
141
|
+
escapeNext = false;
|
|
142
|
+
i++;
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
if (byte === 92) {
|
|
146
|
+
escapeNext = true;
|
|
147
|
+
i++;
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
150
|
+
if (byte === 34) {
|
|
151
|
+
inString = !inString;
|
|
152
|
+
i++;
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
155
|
+
if (!inString) {
|
|
156
|
+
if (byte === 91) {
|
|
157
|
+
depth++;
|
|
158
|
+
i++;
|
|
159
|
+
lastWasComma = false;
|
|
160
|
+
}
|
|
161
|
+
else if (byte === 93) {
|
|
162
|
+
depth--;
|
|
163
|
+
if (depth === 0) {
|
|
164
|
+
if (currentValue.trim() && !lastWasComma) {
|
|
165
|
+
const num = Number(currentValue.trim());
|
|
166
|
+
if (!isNaN(num))
|
|
167
|
+
values.push(num);
|
|
168
|
+
}
|
|
169
|
+
return { values, endPos: i + 1 };
|
|
170
|
+
}
|
|
171
|
+
i++;
|
|
172
|
+
lastWasComma = false;
|
|
173
|
+
}
|
|
174
|
+
else if (byte === 44) {
|
|
175
|
+
if (currentValue.trim() && !lastWasComma) {
|
|
176
|
+
const num = Number(currentValue.trim());
|
|
177
|
+
if (!isNaN(num))
|
|
178
|
+
values.push(num);
|
|
179
|
+
}
|
|
180
|
+
currentValue = '';
|
|
181
|
+
lastWasComma = true;
|
|
182
|
+
i++;
|
|
183
|
+
}
|
|
184
|
+
else if ((byte >= 48 && byte <= 57) || byte === 45 || byte === 46) {
|
|
185
|
+
currentValue += String.fromCharCode(byte);
|
|
186
|
+
lastWasComma = false;
|
|
187
|
+
i++;
|
|
188
|
+
}
|
|
189
|
+
else if (byte === 32 || byte === 9 || byte === 10 || byte === 13) {
|
|
190
|
+
i++;
|
|
191
|
+
}
|
|
192
|
+
else {
|
|
193
|
+
i++;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
i++;
|
|
198
|
+
}
|
|
199
|
+
if (onProgress && i % 5000000 === 0) {
|
|
200
|
+
onProgress(Math.round((i / totalLength) * 100));
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
return { values, endPos: i };
|
|
204
|
+
}
|
|
205
|
+
function parseObjectArrayIncremental(buffer, startPos, onProgress, maxObjects) {
|
|
206
|
+
if (startPos >= buffer.length || buffer[startPos] !== 91)
|
|
207
|
+
return null;
|
|
208
|
+
const values = [];
|
|
209
|
+
let i = startPos + 1;
|
|
210
|
+
let depth = 1;
|
|
211
|
+
let inString = false;
|
|
212
|
+
let escapeNext = false;
|
|
213
|
+
let objectStart = -1;
|
|
214
|
+
const totalLength = buffer.length;
|
|
215
|
+
let objectCount = 0;
|
|
216
|
+
while (i < buffer.length && (buffer[i] === 32 || buffer[i] === 9 || buffer[i] === 10 || buffer[i] === 13)) {
|
|
217
|
+
i++;
|
|
218
|
+
}
|
|
219
|
+
if (buffer[i] === 93) {
|
|
220
|
+
return { values: [], endPos: i + 1 };
|
|
221
|
+
}
|
|
222
|
+
while (i < buffer.length) {
|
|
223
|
+
const byte = buffer[i];
|
|
224
|
+
if (escapeNext) {
|
|
225
|
+
escapeNext = false;
|
|
226
|
+
i++;
|
|
227
|
+
continue;
|
|
228
|
+
}
|
|
229
|
+
if (byte === 92) {
|
|
230
|
+
escapeNext = true;
|
|
231
|
+
i++;
|
|
232
|
+
continue;
|
|
233
|
+
}
|
|
234
|
+
if (byte === 34) {
|
|
235
|
+
inString = !inString;
|
|
236
|
+
i++;
|
|
237
|
+
continue;
|
|
238
|
+
}
|
|
239
|
+
if (!inString) {
|
|
240
|
+
if (byte === 123) {
|
|
241
|
+
if (depth === 1 && objectStart === -1)
|
|
242
|
+
objectStart = i;
|
|
243
|
+
depth++;
|
|
244
|
+
i++;
|
|
245
|
+
}
|
|
246
|
+
else if (byte === 125) {
|
|
247
|
+
depth--;
|
|
248
|
+
if (depth === 1 && objectStart !== -1) {
|
|
249
|
+
try {
|
|
250
|
+
const obj = JSON.parse(extractValueAsString(buffer, objectStart, i + 1));
|
|
251
|
+
values.push(obj);
|
|
252
|
+
objectCount++;
|
|
253
|
+
if (maxObjects && objectCount >= maxObjects) {
|
|
254
|
+
let searchPos = i + 1;
|
|
255
|
+
while (searchPos < buffer.length && buffer[searchPos] !== 93)
|
|
256
|
+
searchPos++;
|
|
257
|
+
return { values, endPos: searchPos + 1 };
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
catch (e) { /* skip malformed objects */ }
|
|
261
|
+
objectStart = -1;
|
|
262
|
+
if (onProgress && objectCount % 50000 === 0) {
|
|
263
|
+
onProgress(Math.round((i / totalLength) * 100));
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
i++;
|
|
267
|
+
}
|
|
268
|
+
else if (byte === 91) {
|
|
269
|
+
depth++;
|
|
270
|
+
i++;
|
|
271
|
+
}
|
|
272
|
+
else if (byte === 93) {
|
|
273
|
+
depth--;
|
|
274
|
+
if (depth === 0)
|
|
275
|
+
return { values, endPos: i + 1 };
|
|
276
|
+
i++;
|
|
277
|
+
}
|
|
278
|
+
else {
|
|
279
|
+
i++;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
else {
|
|
283
|
+
i++;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
return { values, endPos: i };
|
|
287
|
+
}
|
|
288
|
+
export class LargeFileParser {
|
|
289
|
+
constructor(onProgress, options) {
|
|
290
|
+
var _a, _b;
|
|
291
|
+
this.skipLargeActions = false;
|
|
292
|
+
this.maxActions = 0;
|
|
293
|
+
this.onProgress = onProgress;
|
|
294
|
+
if (options) {
|
|
295
|
+
this.skipLargeActions = (_a = options.skipLargeActions) !== null && _a !== void 0 ? _a : false;
|
|
296
|
+
this.maxActions = (_b = options.maxActions) !== null && _b !== void 0 ? _b : 0;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
parse(input) {
|
|
300
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
301
|
+
let view = new Uint8Array(input);
|
|
302
|
+
if (view.length >= 3 && view[0] === BOM[0] && view[1] === BOM[1] && view[2] === BOM[2]) {
|
|
303
|
+
view = view.subarray(3);
|
|
304
|
+
}
|
|
305
|
+
(_a = this.onProgress) === null || _a === void 0 ? void 0 : _a.call(this, 'scanning', 5);
|
|
306
|
+
const properties = findAllPropertiesAtRoot(view);
|
|
307
|
+
const angleDataPos = (_b = properties.get('angleData')) !== null && _b !== void 0 ? _b : -1;
|
|
308
|
+
const pathDataPos = (_c = properties.get('pathData')) !== null && _c !== void 0 ? _c : -1;
|
|
309
|
+
const settingsPos = (_d = properties.get('settings')) !== null && _d !== void 0 ? _d : -1;
|
|
310
|
+
const actionsPos = (_e = properties.get('actions')) !== null && _e !== void 0 ? _e : -1;
|
|
311
|
+
const decorationsPos = (_f = properties.get('decorations')) !== null && _f !== void 0 ? _f : -1;
|
|
312
|
+
const result = {};
|
|
313
|
+
if (settingsPos !== -1) {
|
|
314
|
+
(_g = this.onProgress) === null || _g === void 0 ? void 0 : _g.call(this, 'parsing_settings', 10);
|
|
315
|
+
const settingsEnd = findValueEnd(view, settingsPos);
|
|
316
|
+
if (settingsEnd !== -1) {
|
|
317
|
+
try {
|
|
318
|
+
result.settings = JSON.parse(extractValueAsString(view, settingsPos, settingsEnd));
|
|
319
|
+
}
|
|
320
|
+
catch (e) {
|
|
321
|
+
result.settings = {};
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
if (angleDataPos !== -1) {
|
|
326
|
+
(_h = this.onProgress) === null || _h === void 0 ? void 0 : _h.call(this, 'parsing_angleData', 15);
|
|
327
|
+
const angleResult = parseNumberArrayIncremental(view, angleDataPos, (p) => {
|
|
328
|
+
var _a;
|
|
329
|
+
(_a = this.onProgress) === null || _a === void 0 ? void 0 : _a.call(this, 'parsing_angleData', 15 + p * 0.25);
|
|
330
|
+
});
|
|
331
|
+
if (angleResult) {
|
|
332
|
+
result.angleData = angleResult.values;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
if (pathDataPos !== -1) {
|
|
336
|
+
const pathEnd = findValueEnd(view, pathDataPos);
|
|
337
|
+
if (pathEnd !== -1) {
|
|
338
|
+
const pathStr = extractValueAsString(view, pathDataPos, pathEnd);
|
|
339
|
+
result.pathData = pathStr.slice(1, -1);
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
if (actionsPos !== -1) {
|
|
343
|
+
const actionsEnd = findValueEnd(view, actionsPos);
|
|
344
|
+
const actionsSize = actionsEnd - actionsPos;
|
|
345
|
+
(_j = this.onProgress) === null || _j === void 0 ? void 0 : _j.call(this, 'parsing_actions', 50);
|
|
346
|
+
if (actionsSize > 100 * 1024 * 1024 && this.skipLargeActions) {
|
|
347
|
+
result.actions = [];
|
|
348
|
+
}
|
|
349
|
+
else if (actionsSize > 50 * 1024 * 1024) {
|
|
350
|
+
const actionsResult = parseObjectArrayIncremental(view, actionsPos, (p) => { var _a; return (_a = this.onProgress) === null || _a === void 0 ? void 0 : _a.call(this, 'parsing_actions', 50 + p * 0.45); }, this.maxActions || undefined);
|
|
351
|
+
if (actionsResult)
|
|
352
|
+
result.actions = actionsResult.values;
|
|
353
|
+
}
|
|
354
|
+
else {
|
|
355
|
+
try {
|
|
356
|
+
result.actions = JSON.parse(extractValueAsString(view, actionsPos, actionsEnd));
|
|
357
|
+
}
|
|
358
|
+
catch (e) {
|
|
359
|
+
result.actions = [];
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
if (decorationsPos !== -1) {
|
|
364
|
+
(_k = this.onProgress) === null || _k === void 0 ? void 0 : _k.call(this, 'parsing_decorations', 95);
|
|
365
|
+
const decorationsEnd = findValueEnd(view, decorationsPos);
|
|
366
|
+
if (decorationsEnd !== -1) {
|
|
367
|
+
try {
|
|
368
|
+
result.decorations = JSON.parse(extractValueAsString(view, decorationsPos, decorationsEnd));
|
|
369
|
+
}
|
|
370
|
+
catch (e) {
|
|
371
|
+
result.decorations = [];
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
(_l = this.onProgress) === null || _l === void 0 ? void 0 : _l.call(this, 'complete', 100);
|
|
376
|
+
return result;
|
|
377
|
+
}
|
|
378
|
+
stringify(obj) {
|
|
379
|
+
return JSON.stringify(obj);
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
export default LargeFileParser;
|
package/dist/src/parser.d.ts
CHANGED
|
@@ -2,5 +2,6 @@ import Parser from "./parser/index";
|
|
|
2
2
|
import BufferParser from './parser/BufferParser';
|
|
3
3
|
import ArrayBufferParser from "./parser/ArrayBufferParser";
|
|
4
4
|
import StringParser from "./parser/StringParser";
|
|
5
|
-
|
|
5
|
+
import LargeFileParser from "./parser/LargeFileParser";
|
|
6
|
+
export { StringParser, BufferParser, ArrayBufferParser, LargeFileParser };
|
|
6
7
|
export default Parser;
|
package/dist/src/parser.js
CHANGED
|
@@ -2,5 +2,6 @@ import Parser from "./parser/index";
|
|
|
2
2
|
import BufferParser from './parser/BufferParser';
|
|
3
3
|
import ArrayBufferParser from "./parser/ArrayBufferParser";
|
|
4
4
|
import StringParser from "./parser/StringParser";
|
|
5
|
-
|
|
5
|
+
import LargeFileParser from "./parser/LargeFileParser";
|
|
6
|
+
export { StringParser, BufferParser, ArrayBufferParser, LargeFileParser };
|
|
6
7
|
export default Parser;
|
|
@@ -1,5 +1,48 @@
|
|
|
1
|
-
|
|
2
|
-
const
|
|
1
|
+
/** Standard direction characters → absolute angle */
|
|
2
|
+
const pathDataTable = {
|
|
3
|
+
"R": 0, "p": 15, "J": 30, "E": 45, "T": 60, "o": 75, "U": 90, "q": 105,
|
|
4
|
+
"G": 120, "Q": 135, "H": 150, "W": 165, "L": 180, "x": 195, "N": 210,
|
|
5
|
+
"Z": 225, "F": 240, "V": 255, "D": 270, "Y": 285, "B": 300, "C": 315,
|
|
6
|
+
"M": 330, "A": 345, "!": 999
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Special offset characters — these are NOT absolute angles.
|
|
10
|
+
* Instead, they represent a relative change from the previous angle:
|
|
11
|
+
* result = previous_angle + offset
|
|
12
|
+
*/
|
|
13
|
+
const offsetMap = {
|
|
14
|
+
"5": 72,
|
|
15
|
+
"6": -72,
|
|
16
|
+
"7": 52,
|
|
17
|
+
"8": -52,
|
|
18
|
+
"9": -30,
|
|
19
|
+
"h": 120,
|
|
20
|
+
"j": -120,
|
|
21
|
+
"t": 60,
|
|
22
|
+
"y": 300,
|
|
23
|
+
};
|
|
24
|
+
const parseToangleData = (pathdata) => {
|
|
25
|
+
const result = new Array(pathdata.length);
|
|
26
|
+
let prev = 0;
|
|
27
|
+
for (let i = 0; i < pathdata.length; i++) {
|
|
28
|
+
const c = pathdata[i];
|
|
29
|
+
if (c in pathDataTable) {
|
|
30
|
+
// Standard character: absolute angle
|
|
31
|
+
result[i] = pathDataTable[c];
|
|
32
|
+
prev = pathDataTable[c];
|
|
33
|
+
}
|
|
34
|
+
else if (c in offsetMap) {
|
|
35
|
+
// Special character: relative offset from previous angle
|
|
36
|
+
result[i] = prev + offsetMap[c];
|
|
37
|
+
prev = result[i];
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
// Unknown character: keep current angle
|
|
41
|
+
result[i] = prev;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return result;
|
|
45
|
+
};
|
|
3
46
|
export default {
|
|
4
47
|
pathDataTable,
|
|
5
48
|
parseToangleData
|
|
@@ -10,8 +10,6 @@ export declare class Level {
|
|
|
10
10
|
settings: Record<string, any>;
|
|
11
11
|
__decorations: AdofaiEvent[];
|
|
12
12
|
tiles: Tile[];
|
|
13
|
-
private _angleDir;
|
|
14
|
-
private _twirlCount;
|
|
15
13
|
/** 预计算的事件缓存 */
|
|
16
14
|
private _precomputedEvents;
|
|
17
15
|
/** 是否启用预计算模式 */
|
|
@@ -20,68 +18,21 @@ export declare class Level {
|
|
|
20
18
|
private _lightweightData;
|
|
21
19
|
constructor(opt: string | LevelOptions, provider?: ParseProvider);
|
|
22
20
|
generateGUID(): string;
|
|
23
|
-
/**
|
|
24
|
-
* 触发进度事件
|
|
25
|
-
*/
|
|
26
21
|
private _emitProgress;
|
|
27
|
-
/**
|
|
28
|
-
* 启用预计算模式 - 在 load() 和 calculateTilePosition() 过程中不触发事件,
|
|
29
|
-
* 而是将所有事件缓存起来,之后可以通过 getPrecomputedEvents() 获取
|
|
30
|
-
*/
|
|
31
22
|
enablePrecomputeMode(): void;
|
|
32
|
-
/**
|
|
33
|
-
* 禁用预计算模式
|
|
34
|
-
*/
|
|
35
23
|
disablePrecomputeMode(): void;
|
|
36
|
-
/**
|
|
37
|
-
* 获取预计算的事件缓存
|
|
38
|
-
* 返回所有缓存的进度事件,可以用于渲染器按帧播放
|
|
39
|
-
*/
|
|
40
24
|
getPrecomputedEvents(): PrecomputedProgressEvents | null;
|
|
41
|
-
/**
|
|
42
|
-
* 清除预计算的事件缓存
|
|
43
|
-
*/
|
|
44
25
|
clearPrecomputedEvents(): void;
|
|
45
|
-
/**
|
|
46
|
-
* 按进度百分比获取事件(用于渲染器按帧渲染)
|
|
47
|
-
* @param percent 0-100 的百分比
|
|
48
|
-
* @param stage 可选,指定阶段
|
|
49
|
-
*/
|
|
50
26
|
getEventsAtPercent(percent: number, stage?: ParseProgressEvent['stage']): ParseProgressEvent[];
|
|
51
|
-
/**
|
|
52
|
-
* 获取指定阶段的总事件数
|
|
53
|
-
*/
|
|
54
27
|
getPrecomputedEventCount(stage?: ParseProgressEvent['stage']): number;
|
|
55
|
-
/**
|
|
56
|
-
* 获取轻量级预计算数据
|
|
57
|
-
* 只包含渲染必需的数据:angles, positions, twirlFlags
|
|
58
|
-
* 内存占用极低,适合大物量谱面
|
|
59
|
-
*/
|
|
60
28
|
getLightweightData(): LightweightPrecomputedData | null;
|
|
61
|
-
/**
|
|
62
|
-
* 轻量级预计算 - 只计算渲染必需的数据
|
|
63
|
-
* 不存储完整的 tile 对象,极大减少内存占用
|
|
64
|
-
*
|
|
65
|
-
* @param skipPositionCalculation 是否跳过坐标计算(如果只需要角度数据)
|
|
66
|
-
*/
|
|
67
29
|
precomputeLightweight(skipPositionCalculation?: boolean): LightweightPrecomputedData;
|
|
68
|
-
/**
|
|
69
|
-
* 获取指定范围内的轻量级渲染数据(分片获取,避免一次性加载全部)
|
|
70
|
-
* @param startIndex 起始索引
|
|
71
|
-
* @param count 数量
|
|
72
|
-
*/
|
|
73
30
|
getLightweightDataRange(startIndex: number, count: number): {
|
|
74
31
|
angles: number[];
|
|
75
32
|
positions: [number, number][];
|
|
76
33
|
twirlFlags: boolean[];
|
|
77
34
|
} | null;
|
|
78
|
-
/**
|
|
79
|
-
* 清除轻量级预计算数据
|
|
80
|
-
*/
|
|
81
35
|
clearLightweightData(): void;
|
|
82
|
-
/**
|
|
83
|
-
* 获取单个 tile 的渲染数据(按需获取,不预加载全部)
|
|
84
|
-
*/
|
|
85
36
|
getTileRenderData(index: number): {
|
|
86
37
|
angle: number;
|
|
87
38
|
position: [number, number] | null;
|
|
@@ -91,16 +42,6 @@ export declare class Level {
|
|
|
91
42
|
on(eventName: string, callback: Function): string;
|
|
92
43
|
trigger(eventName: string, data: any): void;
|
|
93
44
|
off(guid: string): void;
|
|
94
|
-
private _createArray;
|
|
95
|
-
private _changeAngle;
|
|
96
|
-
private _normalizeAngle;
|
|
97
|
-
private _parsechangedAngle;
|
|
98
|
-
private _filterByFloor;
|
|
99
|
-
private _flattenAngleDatas;
|
|
100
|
-
private _flattenActionsWithFloor;
|
|
101
|
-
private _filterByFloorwithDeco;
|
|
102
|
-
private _flattenDecorationsWithFloor;
|
|
103
|
-
private _parseAngle;
|
|
104
45
|
filterActionsByEventType(en: string): {
|
|
105
46
|
index: number;
|
|
106
47
|
action: ActionData;
|
|
@@ -110,12 +51,6 @@ export declare class Level {
|
|
|
110
51
|
actions: ActionData[];
|
|
111
52
|
};
|
|
112
53
|
calculateTileCoordinates(): void;
|
|
113
|
-
/**
|
|
114
|
-
* 计算所有 Tile 的坐标位置
|
|
115
|
-
* 触发 parse:tilePosition 和 parse:progress 事件报告进度
|
|
116
|
-
*
|
|
117
|
-
* 性能优化:预先构建 PositionTrack 索引,避免循环内重复遍历
|
|
118
|
-
*/
|
|
119
54
|
calculateTilePosition(): number[][];
|
|
120
55
|
floorOperation(info?: {
|
|
121
56
|
type: 'append' | 'insert' | 'delete';
|