igir
Version:
🕹 A zero-setup ROM collection manager that sorts, filters, extracts or archives, patches, and reports on collections of any size on any OS.
113 lines (112 loc) • 4.19 kB
JavaScript
import { ProgressBarSymbol } from "../../console/progressBar.js";
import FileFactory from "../../factories/fileFactory.js";
import ArchiveEntry from "../../models/files/archives/archiveEntry.js";
import { TrimScanFiles } from "../../models/options.js";
import FsUtil from "../../utils/fsUtil.js";
import IntlUtil from "../../utils/intlUtil.js";
import Module from "../module.js";
class ROMTrimProcessor extends Module {
options;
fileFactory;
mappableSemaphore;
constructor(options, progressBar, fileFactory, mappableSemaphore) {
super(progressBar, ROMTrimProcessor.name);
this.options = options;
this.fileFactory = fileFactory;
this.mappableSemaphore = mappableSemaphore;
}
/**
* Process each {@link File}, finding any {@link ROMPadding} present.
*/
async process(inputRomFiles) {
if (inputRomFiles.length === 0) {
return inputRomFiles;
}
if (!this.options.usingDats()) {
return inputRomFiles;
}
const filesThatNeedProcessing = inputRomFiles.filter(
(inputFile) => this.fileNeedsProcessing(inputFile)
).length;
if (filesThatNeedProcessing === 0) {
this.prefixedLogger.trace("no ROMs can be trimmed");
return inputRomFiles;
}
this.prefixedLogger.trace(
`processing trimming in ${IntlUtil.toLocaleString(inputRomFiles.length)} ROM${inputRomFiles.length === 1 ? "" : "s"}`
);
this.progressBar.setSymbol(ProgressBarSymbol.ROM_TRIMMING_DETECTION);
this.progressBar.resetProgress(filesThatNeedProcessing);
const parsedFiles = await this.mappableSemaphore.map(inputRomFiles, async (inputFile) => {
if (!this.fileNeedsProcessing(inputFile)) {
return inputFile;
}
this.progressBar.incrementInProgress();
const childBar = this.progressBar.addChildBar({
name: inputFile.toString(),
total: inputFile.getSize(),
progressFormatter: FsUtil.sizeReadable.bind(FsUtil)
});
let fileWithTrimming;
try {
fileWithTrimming = await this.getFile(inputFile, childBar);
} catch (error) {
this.prefixedLogger.error(
`${inputFile.toString()}: failed to process ROM trimming: ${error}`
);
fileWithTrimming = inputFile;
} finally {
childBar.delete();
}
this.progressBar.incrementCompleted();
return fileWithTrimming;
});
const trimmedRomsCount = parsedFiles.filter(
(romFile) => romFile.getPaddings().length > 0
).length;
this.prefixedLogger.trace(
`found ${IntlUtil.toLocaleString(trimmedRomsCount)} trimmed ROM${trimmedRomsCount === 1 ? "" : "s"}`
);
this.prefixedLogger.trace("done processing file trimming");
return parsedFiles;
}
fileNeedsProcessing(inputFile) {
if (this.options.shouldReadFileForTrimming(inputFile.getFilePath())) {
return true;
}
if (this.options.getTrimScanFiles() === TrimScanFiles.NEVER) {
return false;
}
if (!(inputFile instanceof ArchiveEntry) && this.options.getTrimScanFiles() === TrimScanFiles.ALWAYS) {
return true;
}
if ((inputFile instanceof ArchiveEntry || FileFactory.isExtensionArchive(inputFile.getFilePath())) && !this.options.getTrimScanArchives()) {
return false;
}
return !(inputFile.getSize() === 0 || (inputFile.getSize() & inputFile.getSize() - 1) === 0);
}
async getFile(inputFile, progressBar) {
if (this.options.getTrimScanFiles() === TrimScanFiles.AUTO && !this.options.shouldReadFileForTrimming(inputFile.getFilePath())) {
const fileSignature = await this.fileFactory.signatureFrom(inputFile, (progress, total) => {
progressBar.setCompleted(progress);
if (total !== void 0) {
progressBar.setTotal(total);
}
});
if (!fileSignature?.canBeTrimmed()) {
return inputFile;
}
}
const paddings = await this.fileFactory.paddingsFrom(inputFile, (progress) => {
progressBar.setCompleted(progress);
});
if (paddings.length === 0) {
return inputFile;
}
return inputFile.withPaddings(paddings);
}
}
export {
ROMTrimProcessor as default
};
//# sourceMappingURL=romTrimProcessor.js.map