UNPKG

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.

140 lines (139 loc) • 3.85 kB
import Timer from "../async/timer.js"; import { logger } from "./logger.js"; import SingleBar from "./singleBar.js"; import { LIVE_REGION_PADDING, terminal } from "./terminal.js"; class MultiBar { static RENDER_MIN_FPS = 5; static multiBars = []; static exitHandlersRegistered = false; singleBars = []; renderTimer; stopped = false; constructor() { } /** * Create a new {@link MultiBar} instance. */ static create() { if (!this.exitHandlersRegistered) { const exitHandler = () => { this.stop(); }; process.once("exit", exitHandler); process.once("SIGINT", exitHandler); process.once("SIGTERM", exitHandler); this.exitHandlersRegistered = true; } const multiBar = new MultiBar(); this.multiBars.push(multiBar); return multiBar; } /** * Returns true if there are any active MultiBars. */ static isActive() { return this.multiBars.length > 0; } /** * Add a new {@link SingleBar} to the {@link MultiBar}. */ addSingleBar(options, parentSingleBar) { const singleBar = new SingleBar(this, options); const parentSingleBarIndex = parentSingleBar ? this.singleBars.indexOf(parentSingleBar) : void 0; const insertionIndex = parentSingleBarIndex === void 0 ? void 0 : this.singleBars.findIndex( (singleBar2, idx) => idx > parentSingleBarIndex && singleBar2.getIndentSize() === 0 ); if (insertionIndex === void 0 || insertionIndex === -1) { this.singleBars.push(singleBar); } else { this.singleBars.splice(insertionIndex, 0, singleBar); } if (singleBar.getIndentSize() === 0) { this.clearAndRender(); } return singleBar; } /** * Log the {@link SingleBar}'s last output and remove it from the live region. */ freezeSingleBar(singleBar) { const idx = this.singleBars.indexOf(singleBar); if (idx === -1) { return; } singleBar.format(); const lastOutput = singleBar.getLastOutput(); this.singleBars.splice(idx, 1); if (lastOutput !== void 0) { logger.printFrozenBar( `${singleBar.getIndentSize() === 0 ? "\n" : ""}${LIVE_REGION_PADDING}${lastOutput}` ); } this.clearAndRender(); } /** * Remove a {@link SingleBar}. */ removeSingleBar(singleBar) { const idx = this.singleBars.indexOf(singleBar); if (idx === -1) { return; } this.singleBars.splice(idx, 1); } /** * Recompute the combined live-region frame and hand it to the {@link Terminal} to draw. */ clearAndRender() { if (this.stopped) { return; } this.renderTimer?.cancel(); if (terminal.isInteractive()) { this.renderTimer = Timer.setTimeout( () => { this.clearAndRender(); }, Math.max(1e3 / MultiBar.RENDER_MIN_FPS, 1) ); } const rawOutput = this.singleBars.flatMap((singleBar) => { const lines = singleBar.format().split("\n").filter((line) => line !== ""); if (singleBar.getIndentSize() === 0) { return ["", ...lines]; } return lines; }).join("\n"); terminal.setLiveRegion(rawOutput); } /** * Stop the {@link MultiBar} and all of its {@link SingleBar}s. */ static stop() { let multiBar = this.multiBars.shift(); while (multiBar !== void 0) { multiBar.stop(); multiBar = this.multiBars.shift(); } } /** * Stop the {@link MultiBar} and all of its {@link SingleBar}s. */ stop() { if (this.stopped) { return; } this.clearAndRender(); const singleBarsCopy = [...this.singleBars]; for (const progressBar of singleBarsCopy) { progressBar.freeze(); } this.renderTimer?.cancel(); terminal.clearLiveRegion(); this.stopped = true; } } export { MultiBar as default }; //# sourceMappingURL=multiBar.js.map