Skip to content

Commit f0a73e0

Browse files
author
Flenarn
committed
feat: Midi support in enums.
1 parent 63e029c commit f0a73e0

File tree

2 files changed

+48
-8
lines changed

2 files changed

+48
-8
lines changed

tools/cache/pack/packEnums.ts

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { unpackJs5Group } from '#/io/Js5Group.js';
99
import Environment from '#/util/Environment.js';
1010
import { parseBracketedConfigSource } from '#tools/cache/lib/configSource.js';
1111
import { encodeEnum } from '#tools/cache/lib/enumCodec.js';
12+
import { getMidiId, hasMidiId } from '#tools/pack/packs/MidiPack.js';
1213
import {
1314
arraysEqual,
1415
ensureDir,
@@ -105,7 +106,7 @@ function parseSourceTypeName(typeName: string): number {
105106
return typeCode ?? ScriptVarType.INT;
106107
}
107108

108-
function parseSourceScalar(value: string, type: number): number | string {
109+
function parseSourceScalar(value: string, type: number, sourceContext?: string): number | string {
109110
// Handle null
110111
if (value === 'null') {
111112
if (type === ScriptVarType.STRING) {
@@ -129,6 +130,22 @@ function parseSourceScalar(value: string, type: number): number | string {
129130
return value;
130131
}
131132

133+
if (type === ScriptVarType.MIDI) {
134+
const trimmed = value.trim();
135+
136+
const namedId = getMidiId(trimmed);
137+
if (namedId !== -1) {
138+
return namedId;
139+
}
140+
141+
const numeric = parseInt(trimmed, 10);
142+
if (!isNaN(numeric) && String(numeric) === trimmed && hasMidiId(numeric)) {
143+
return numeric;
144+
}
145+
146+
throw new Error(`Unknown midi value '${trimmed}'${sourceContext ? ` at ${sourceContext}` : ''}. It must exist in midi.pack.`);
147+
}
148+
132149
// Handle numbers (including hex)
133150
if (value.startsWith('0x')) {
134151
const parsed = parseInt(value, 16);
@@ -195,7 +212,7 @@ function parseSourceEnums(content: string, nameToId: Map<string, number>): Map<n
195212
}
196213
currentOps.push({ code: 3, value: cleanValue });
197214
} else {
198-
currentEnum.defaultInt = Number(parseSourceScalar(cleanValue, currentEnum.outputtype));
215+
currentEnum.defaultInt = Number(parseSourceScalar(cleanValue, currentEnum.outputtype, `${section.name}:${field.line}`));
199216
if (isExplicit) {
200217
currentEnum.hasExplicitDefaultInt = true;
201218
}
@@ -216,7 +233,7 @@ function parseSourceEnums(content: string, nameToId: Map<string, number>): Map<n
216233
const keyPart = value.substring(0, commaIndex).trim();
217234
const valuePart = value.substring(commaIndex + 1);
218235

219-
const parsedKey = Number(parseSourceScalar(keyPart, currentEnum.inputtype));
236+
const parsedKey = Number(parseSourceScalar(keyPart, currentEnum.inputtype, `${section.name}:${field.line}`));
220237
const opCode: 5 | 6 = key === 'val@5' ? 5 : key === 'val@6' ? 6 : (currentEnum.outputtype === ScriptVarType.STRING ? 5 : 6);
221238

222239
if (opCode === 5) {
@@ -230,7 +247,7 @@ function parseSourceEnums(content: string, nameToId: Map<string, number>): Map<n
230247
currentOps.push({ code: 5, values: [{ key: parsedKey, value: parsedValue }] });
231248
}
232249
} else {
233-
const parsedValue = Number(parseSourceScalar(valuePart, currentEnum.outputtype));
250+
const parsedValue = Number(parseSourceScalar(valuePart, currentEnum.outputtype, `${section.name}:${field.line}`));
234251
currentEnum.values.set(parsedKey, parsedValue);
235252

236253
const lastOp = currentOps[currentOps.length - 1];
@@ -309,9 +326,13 @@ async function main() {
309326
throw new Error(`Source file not found: ${args.src}`);
310327
}
311328

312-
// Read pack file to resolve names
313-
const packPath = path.join(path.dirname(args.src), 'pack', 'enum.pack');
314-
const nameToId = parsePackFile(packPath);
329+
// Read pack files to resolve names (prefer source-adjacent pack/, fallback to BUILD_SRC_DIR/pack)
330+
const localPackDir = path.join(path.dirname(args.src), 'pack');
331+
const fallbackPackDir = path.join(Environment.BUILD_SRC_DIR, 'pack');
332+
333+
const enumLocalPackPath = path.join(localPackDir, 'enum.pack');
334+
const enumFallbackPackPath = path.join(fallbackPackDir, 'enum.pack');
335+
const nameToId = fs.existsSync(enumLocalPackPath) ? parsePackFile(enumLocalPackPath) : parsePackFile(enumFallbackPackPath);
315336

316337
// Parse source enums
317338
const content = fs.readFileSync(args.src, 'utf-8');

tools/pack/packs/MidiPack.ts

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,22 @@
1+
import fs from 'fs';
2+
import path from 'path';
3+
4+
import Environment from '#/util/Environment.js';
15
import { PackFile } from '#tools/pack/core/PackFile.js';
26

37
const midiPack = new PackFile('midi');
4-
midiPack.load('data/src/pack/midi.pack');
8+
9+
const midiPackCandidates = [
10+
path.join(Environment.BUILD_SRC_DIR, 'pack', 'midi.pack'),
11+
path.join('data', 'src', 'pack', 'midi.pack')
12+
];
13+
14+
for (const candidate of midiPackCandidates) {
15+
if (fs.existsSync(candidate)) {
16+
midiPack.load(candidate);
17+
break;
18+
}
19+
}
520

621
export function getMidiId(name: string): number {
722
return midiPack.getByName(name);
@@ -11,6 +26,10 @@ export function getMidiName(id: number): string {
1126
return midiPack.getById(id);
1227
}
1328

29+
export function hasMidiId(id: number): boolean {
30+
return midiPack.pack.has(id);
31+
}
32+
1433
export function hasMidiName(name: string): boolean {
1534
return midiPack.names.has(name);
1635
}

0 commit comments

Comments
 (0)