UNPKG

@mezzy/commands

Version:

A luxurious user experience framework, developed by your friends at Mezzanine.

185 lines 7.24 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const is_1 = require("@mezzy/is"); const debug_1 = require("@mezzy/debug"); const result_1 = require("@mezzy/result"); const signals_1 = require("@mezzy/signals"); const ids_1 = require("@mezzy/ids"); const collections_1 = require("@mezzy/collections"); const collections_2 = require("@mezzy/collections"); const command_1 = require("./command"); const commandEventArgs_1 = require("./commandEventArgs"); debug_1.default.setCategoryMode('commands', false); class CommandManager { constructor(isUndoEnabled = true) { this._progress = 0; this._isUndoEnabled = true; this._commands = new collections_1.MapList(); this._pendingQueue = new collections_2.Queue(); this._undoQueue = new collections_2.Queue(); this._redoQueue = new collections_2.Queue(); this._isRunningAll = false; this._runStartCount = 0; this.commandRunStart = new signals_1.Signal(); this.commandRunComplete = new signals_1.Signal(); this._isUndoEnabled = isUndoEnabled; } get progress() { return this._progress; } get pending() { return this._pendingQueue.size; } get runStartCount() { return this._runStartCount; } get lastReturnValue() { return this._lastReturnValue; } register(scope, runFunction, undoFunction, name) { if (is_1.default.empty(runFunction)) return; let command = new command_1.default(runFunction, undoFunction, scope); if (is_1.default.empty(name)) name = 'command_' + ids_1.Identifier.getSessionUniqueInteger(); this._commands.set(name, command); return name; } unregister(name) { this._commands.delete(name); } get(name) { let command = this._commands.get(name); if (is_1.default.empty(command)) { command = new command_1.default(); this._commands.set(name, command); return command; } else return command; } queue(command, runArgs, undoArgs) { if (is_1.default.empty(command)) return; if (is_1.default.notEmpty(runArgs)) command.runArgs = runArgs; if (is_1.default.notEmpty(undoArgs)) command.undoArgs = undoArgs; this._pendingQueue.add(command); return this; } run(command, args, undoArgs) { if (is_1.default.empty(command)) return this._runAll(); else { let commandFinal; if (typeof command === 'string') commandFinal = this.get(command); else commandFinal = command; if (is_1.default.empty(commandFinal)) return result_1.Result.resolve(null); this.queue(commandFinal, args, undoArgs); return this._runAll(); } } undo(...args) { if (!this._isUndoEnabled || this._undoQueue.size < 1) return result_1.Result.resolve(null); let command = this._undoQueue.deleteLast(); if (is_1.default.empty(command)) return result_1.Result.resolve(null); let result = command.undo.apply(command, args); result.then((returnValue) => { this._redoQueue.add(command); }); return result; } redo(...args) { if (!this._isUndoEnabled || this._redoQueue.size < 1) return result_1.Result.resolve(null); let command = this._redoQueue.deleteLast(); if (is_1.default.empty(command)) return result_1.Result.resolve(null); let result = command.run.apply(command, args); result.then((returnValue) => { let commandEventArgs = new commandEventArgs_1.default(command, 1, returnValue, args); commandEventArgs.isCommandComplete = true; this.commandRunComplete.dispatch(commandEventArgs); this._undoQueue.add(command); }); return result; } clearAllQueues() { this._pendingQueue.clear(); this._undoQueue.clear(); this._redoQueue.clear(); return this; } clearPending() { this._pendingQueue.clear(); return this; } _run(command) { let pending = this._pendingQueue.size + 1; let progressStart = 1 - (pending / this._runStartCount); let argsStart = new commandEventArgs_1.default(command, progressStart); if (this._isRunningAll) { argsStart.pending = this._pendingQueue.size + 1; argsStart.totalRunning = this._runStartCount; } this.commandRunStart.dispatch(argsStart); if (this._isUndoEnabled) { this._undoQueue.add(command); this._redoQueue.clear(); } let result = command.run(); result.then((returnValue) => { this._lastReturnValue = returnValue; let progressComplete = 1 - ((pending - 1) / this._runStartCount); let argsComplete = new commandEventArgs_1.default(command, progressComplete, returnValue); if (this._isRunningAll) { argsComplete.pending = this._pendingQueue.size; argsComplete.totalRunning = this._runStartCount; } argsComplete.isCommandComplete = true; this.commandRunComplete.dispatch(argsComplete); }); return result; } _runNext() { if (this._pendingQueue.size > 0) { let command = this._pendingQueue.deleteFirst(); if (is_1.default.empty(command)) { debug_1.default.error('Expected commands on pending stack, but found none.', 'CommandManager.runNext(...)'); return result_1.Result.resolve(null); } debug_1.default.log(command.message + (is_1.default.empty(command.message) ? '' : ' ') + 'p = ' + this._progress.toString() + ', remaining: ' + this._pendingQueue.size.toString() + ', total: ' + this._runStartCount.toString(), null, 'commands'); return this._run(command); } else return result_1.Result.resolve(null); } _runAll() { if (!this._isRunningAll) { this._isRunningAll = true; this._progress = 0; this._resultRunAll = new result_1.Result(); this._lastReturnValue = null; this._runStartCount = this._pendingQueue.size; if (this._runStartCount > 0) this._runAllNext(); else this._resultRunAll.resolve(null); } return this._resultRunAll; } _runAllNext() { if (this._pendingQueue.size > 0) { this._runNext().then((result) => { this._progress = 1 - (this._pendingQueue.size / this._runStartCount); this._runAllNext(); }); } else { this._isRunningAll = false; this._progress = 1; this._resultRunAll.resolve(this._lastReturnValue); } } } exports.CommandManager = CommandManager; exports.default = CommandManager; //# sourceMappingURL=commandManager.js.map