UNPKG

escher-vis

Version:

Escher: A Web Application for Building, Sharing, and Embedding Data-Rich Visualizations of Biological Pathways

87 lines (66 loc) 2.05 kB
/** UndoStack. A constructor that can be used to store undo info. */ var utils = require('./utils'); var UndoStack = utils.make_class(); UndoStack.prototype = { init: init, push: push, undo: undo, redo: redo }; module.exports = UndoStack; // definitions function init() { var stack_size = 40; this.stack = Array(stack_size); this.current = -1; this.oldest = -1; this.newest = -1; this.end_of_stack = true; this.top_of_stack = true; } function _incr(a, l) { return a + 1 > l - 1 ? 0 : a + 1; } function _decr(a, l) { return a - 1 < 0 ? l - 1 : a - 1; } function push(undo_fn, redo_fn) { this.current = _incr(this.current, this.stack.length); // change the oldest if (this.end_of_stack) this.oldest = this.current; else if (this.oldest == this.current) this.oldest = _incr(this.oldest, this.stack.length); this.stack[this.current] = { undo: undo_fn, redo: redo_fn }; this.newest = this.current; // top of the stack this.top_of_stack = true; this.end_of_stack = false; } function undo() { // check that we haven't reached the end if (this.end_of_stack) return console.warn('End of stack.'); // run the lastest stack function this.stack[this.current].undo(); if (this.current == this.oldest) { // if the next index is less than the oldest, then the stack is dead this.end_of_stack = true; } else { // reference the next fn this.current = _decr(this.current, this.stack.length); } // not at the top of the stack this.top_of_stack = false; } function redo() { // check that we haven't reached the end if (this.top_of_stack) return console.warn('Top of stack.'); if (!this.end_of_stack) this.current = _incr(this.current, this.stack.length); this.stack[this.current].redo(); // if at top of stack if (this.current == this.newest) this.top_of_stack = true; // not at the end of the stack this.end_of_stack = false; }