UNPKG

crmod-api

Version:

A dynamic mod/asset generator for Cosmic Reach

136 lines (120 loc) 4.33 kB
import { MultiBar } from "cli-progress"; import { PromisePool } from "@supercharge/promise-pool"; import Block from "./block.js"; import Writer from "./writer.js"; import BlockState, { StateId } from "./blockState.js"; /** * Defines a data mod. Every element is added to an instance of this class. * * @class Mod */ class Mod { /** * The unique id for this mod. * * @type {string} * @memberof Mod */ id; /** * The {@link Block|Blocks} declared within this mod. * * @type {Set<Block>} * @memberof Mod */ blocks; /** * Controls whether the mod is in release mode. When in release mode, the output files are minified to reduce file size. * * @type {boolean} * @memberof Mod */ isRelease; /** * Initializes a new mod. * * @param {string} id The unique id for this mod. * @param {Writer} writer The {@link Writer} instance used to write the mod files. * @param {boolean} isRelease Controls whether the mod is in release mode. When in release mode, the output files are minified to reduce file size. * @memberof Mod */ constructor(id, writer, isRelease) { this.id = id; this.blocks = new Set; /** @type {Writer} */ this.writer = writer; this.isRelease = isRelease; this.writer.fancy = !this.isRelease; } /** * Locks the current mod and writes all the data to the output directory. * * This function MUST be the last function called when creating a mod. * * @memberof Mod */ async write() { const t0 = performance.now(); const bars = new MultiBar({ format: "{time} {title} [{bar}] {value}/{total} | {name}", hideCursor: true, fps: 30 }); const concurrency = 64; const promisePools = new Set; for(const block of this.blocks) { const startTime = performance.now(); { const bar = bars.create(block.states.size, 0, { title: block.id.padStart(24, " ") + " Model construction".padStart(32, " "), time: " " }); promisePools.add(PromisePool.withConcurrency(concurrency).for(block.states.values()).handleError(e => {throw e}).process(async (state) => { await this.writer.write(state.model, this.id); bar.increment(1, { name: state.model.name, time: (Math.floor(performance.now() - startTime).toString() + "ms").padEnd(8, " ") }); })); } { const bar = bars.create(block.states.size, 0, { title: block.id.padStart(24, " ") + " Trigger sheet compilation".padStart(32, " "), time: 0 }); promisePools.add(PromisePool.withConcurrency(concurrency).for(block.states.values()).handleError(e => {throw e}).process(async (state) => { await this.writer.write(state.triggerSheet, this.id); bar.increment(1, { name: state.triggerSheet.id, time: (Math.floor(performance.now() - startTime).toString() + "ms").padEnd(8, " ") }); })); } promisePools.add(this.writer.write(block, this.id)); } await Promise.all(promisePools); bars.stop(); console.log("Took " + Math.round((performance.now() - t0) * 100) / 100 + "ms"); } /** * Creates a new {@link Block} within this mod. * * @return {Block} */ createBlock(id) { const block = new Block(id, this); this.blocks.add(block); return block; } /** * Returns the id for a given block declared within this mod. * * @param {Block|String} block Block entry or block id * @returns {string} */ getBlockId(block) { if(block instanceof Block) { return this.id + ":" + block.id; } else { return this.id + ":" + block; } } /** * Returns the id for a given {@link BlockState} declared within this mod. * * The ID for a block state is a string containing all unique values for every * * @param {BlockState} state State id */ getBlockStateId(state) { return state.id.toString() || "default"; } } export default Mod;