mirror of
https://gitee.com/anod/open_agb_firm.git
synced 2025-05-06 05:44:11 +08:00
为了提高打包金手指的速度,进行了多线程优化,但是发现在cpu不多的情况下,其实比起单核并不会快很多(毕竟 需要进行序列化)
This commit is contained in:
parent
dcee449bf7
commit
19ce7dd24a
@ -1,6 +1,7 @@
|
|||||||
const readCht = require("./cht");
|
const readCht = require("./cht");
|
||||||
const fs = require("fs");
|
const fs = require("fs");
|
||||||
const { readFile, writeFile, access } = require("fs/promises");
|
const { readFile, writeFile } = require("fs/promises");
|
||||||
|
const transform = require("./worker");
|
||||||
|
|
||||||
const loadlist = async () => {
|
const loadlist = async () => {
|
||||||
const datfile = await readFile("./serial.json");
|
const datfile = await readFile("./serial.json");
|
||||||
@ -8,45 +9,6 @@ const loadlist = async () => {
|
|||||||
return Object.entries(datas).filter(n => n[1] != "????");
|
return Object.entries(datas).filter(n => n[1] != "????");
|
||||||
}
|
}
|
||||||
|
|
||||||
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) => {
|
|
||||||
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 }
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const format = valid => {
|
const format = valid => {
|
||||||
valid.sort((a, b) => a.serial.localeCompare(b.serial));
|
valid.sort((a, b) => a.serial.localeCompare(b.serial));
|
||||||
console.info(`valid rom has ${valid.length}`);
|
console.info(`valid rom has ${valid.length}`);
|
||||||
@ -137,27 +99,11 @@ const format = valid => {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
const hasfile = f => {
|
|
||||||
try {
|
|
||||||
fs.accessSync(f);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
console.error(e.stack)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const start = async () => {
|
const start = async () => {
|
||||||
|
let begin = Date.now();
|
||||||
let list = await loadlist();
|
let list = await loadlist();
|
||||||
let roms = await Promise.all(list.map(game => {
|
let roms = await transform(list);
|
||||||
const [order, serial, title] = game;
|
console.log(`all rom has ${roms.length} and time ${Date.now() - begin}`);
|
||||||
const file = `./gba/${order}.u8`;
|
|
||||||
if (hasfile(file))
|
|
||||||
return loadcheat(order, serial, title ?? order, file);
|
|
||||||
else return Promise.resolve();
|
|
||||||
}));
|
|
||||||
console.log(`all rom has ${roms.length}`);
|
|
||||||
roms = Object.entries(roms.reduce((r, data) => {
|
roms = Object.entries(roms.reduce((r, data) => {
|
||||||
if (!data) return r;
|
if (!data) return r;
|
||||||
|
|
||||||
|
78
tools/cheat-builder/worker.js
Normal file
78
tools/cheat-builder/worker.js
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
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) );
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user