const {Worker, isMainThread, parentPort, workerData} = require("worker_threads"); const readCht = require("./cht"); const { readFile, access } = require("fs/promises"); const ncpu = require("os").availableParallelism(); const trimcheat = (dat, info, order) => { let parts = [], start = 0, done = false; while (!done) { let pos = dat.indexOf("[GameInfo]", start); if (pos > 0) { pos = dat.indexOf("[", pos + "[GameInfo]".length); if (pos > 0) { parts.push(dat.slice(start, pos)); start = pos; } else { parts.push(dat.slice(start, dat.length)); done = true; } } else { parts.push(dat.slice(start, dat.length)); done = true; } } return parts.map(tr => readCht(tr, info, order)); } const loadcheat = async (order, serial, title, file) => { if( false == await access(file).catch( e => false ) ) { return Promise.resolve(); } try { const chtfile = await readFile(file); const cheats = chtfile.toString("utf-8"); let cheat = null; if (cheats.indexOf("[GameInfo]") != cheats.lastIndexOf("[GameInfo]")) cheat = trimcheat(cheats, { serial }, order); else cheat = [readCht(cheats, { serial }, order)]; return { serial, cheat } } catch (e) { console.log("bad cheat: %s[order=%d]\n%s", title, order, e.stack) return { serial } }; } if( isMainThread ) { module.exports = ncpu > 3 ? function(list) { const nPerThread = Math.ceil(list.length / ncpu); const results = new Array(ncpu); let n = 0; return new Promise( ok => { const workers = new Array(ncpu).fill(0).map( (_,i) => { const sublist = list.slice(i * nPerThread, (i+1) * nPerThread); const worker = new Worker(__filename, { workerData: sublist }); worker.once("message", msg => { results[i] = msg; worker.unref(); if( ++n == ncpu ) ok(results.flat()); }); } ); }); } : list => Promise.all( list.map( game => { const [order, serial, title] = game; const file = `./gba/${order}.u8`; return loadcheat(order, serial, title ?? order, file); } ) ); } else { const list = workerData; Promise.all( list.map( game => { const [order, serial, title] = game; const file = `./gba/${order}.u8`; return loadcheat(order, serial, title ?? order, file); } ) ).then( res => parentPort.postMessage(res) ); }