From 7c5000fe13f31565e49dc22fa333dd1e975bb216 Mon Sep 17 00:00:00 2001 From: Florrie Date: Tue, 4 Dec 2018 23:06:36 -0400 Subject: Un-broken optimization (reverted broken stuff; still a little optimization, i.e. cache cursorIndex) --- util/ansi.js | 113 ++++++++++++++++++++++++++--------------------------------- 1 file changed, 49 insertions(+), 64 deletions(-) diff --git a/util/ansi.js b/util/ansi.js index 5902b70..94de1a3 100644 --- a/util/ansi.js +++ b/util/ansi.js @@ -119,7 +119,7 @@ const ansi = { }, interpret(text, scrRows, scrCols, { - oldChars = null, oldLastCharAttributes = null, + oldChars = null, oldLastChar = null, oldCursorRow = 0, oldCursorCol = 0, oldShowCursor = true } = {}) { // Interprets the given ansi code, more or less. @@ -129,17 +129,7 @@ const ansi = { char: ' ' } - const numChars = scrRows * scrCols - const chars = new Array(numChars * 2) - - const fillBlank = () => { - for (let i = 0; i < numChars; i++) { - chars[i * 2] = ' ' - chars[i * 2 + 1] = [] - } - } - - fillBlank() + const chars = new Array(scrRows * scrCols).fill(blank) let showCursor = true let cursorRow = 1 @@ -195,7 +185,7 @@ const ansi = { if (text[charI] === 'J') { // ESC[2J - erase whole display if (args[0] === '2') { - fillBlank() + chars.fill(blank) charI += 3 cursorCol = 1 cursorRow = 1 @@ -211,7 +201,7 @@ const ansi = { // ESC[0J - erase to end else if (args.length === 0 || args[0] === '0') { - for (let i = cursorIndex; i < numChars; i++) { + for (let i = cursorIndex; i < chars.length; i++) { chars[i * 2] = ' ' chars[i * 2 + 1] = [] } @@ -269,8 +259,10 @@ const ansi = { continue } - chars[cursorIndex * 2] = text[charI] - chars[cursorIndex * 2 + 1] = attributes.slice() + chars[cursorIndex] = { + char: text[charI], + attributes: attributes.slice() + } cursorCol++ @@ -296,52 +288,52 @@ const ansi = { differences.push(0) differences.push(newChars.slice()) } else { - let curChars = null + const charsEqual = (oldChar, newChar) => { + // TODO: Check attributes. - for (let i = 0; i < numChars; i++) { - const oldChar = oldChars[i * 2] - const newChar = newChars[i * 2] - - let charsEqual = true + if (oldChar.char !== newChar.char) { + return false + } - if (oldChars[i * 2] !== newChars[i * 2]) { - charsEqual = false - } else { - let oldAttrs = oldChars[i * 2 + 1].slice() - let newAttrs = newChars[i * 2 + 1].slice() + let oldAttrs = oldChar.attributes.slice() + let newAttrs = newChar.attributes.slice() - while (newAttrs.length) { - const attr = newAttrs.shift() - if (oldAttrs.includes(attr)) { - oldAttrs.splice(oldAttrs.indexOf(attr), 1) - } else { - charsEqual = false - break - } + while (newAttrs.length) { + const attr = newAttrs.shift() + if (oldAttrs.includes(attr)) { + oldAttrs.splice(oldAttrs.indexOf(attr), 1) + } else { + return false } + } - if (charsEqual) { - oldAttrs = oldChars[i * 2 + 1].slice() - newAttrs = newChars[i * 2 + 1].slice() - - while (oldAttrs.length) { - const attr = oldAttrs.shift() - if (newAttrs.includes(attr)) { - newAttrs.splice(newAttrs.indexOf(attr), 1) - } else { - charsEqual = false - break - } - } + oldAttrs = oldChar.attributes.slice() + newAttrs = newChar.attributes.slice() + + while (oldAttrs.length) { + const attr = oldAttrs.shift() + if (newAttrs.includes(attr)) { + newAttrs.splice(newAttrs.indexOf(attr), 1) + } else { + return false } } + return true + } + + let curChars = null + + for (let i = 0; i < chars.length; i++) { + const oldChar = oldChars[i] + const newChar = newChars[i] + // TODO: Some sort of "distance" before we should clear curDiff? // It may take *less* characters if this diff and the next are merged // (entering a single character is smaller than the length of the code // used to move past that character). Probably not very significant of // an impact, though. - if (charsEqual) { + if (charsEqual(oldChar, newChar)) { curChars = null } else { if (curChars === null) { @@ -349,22 +341,17 @@ const ansi = { differences.push(i, curChars) } - const curAttrs = newChars[i * 2 + 1] - curChars.push(newChar, curAttrs) + curChars.push(newChar) } } } // Character concatenation ----------- - /* let lastChar = oldLastChar || { char: '', attributes: [] } - */ - - let lastCharAttributes = [] const result = [] @@ -376,15 +363,13 @@ const ansi = { const row = (i - col) / scrCols result.push(ansi.moveCursor(row, col)) - for (let charI = 0; charI < chars.length / 2; charI++) { - const charAttributes = chars[charI * 2 + 1] - + for (const char of chars) { const newAttributes = ( - charAttributes.filter(attr => !(lastCharAttributes.includes(attr))) + char.attributes.filter(attr => !(lastChar.attributes.includes(attr))) ) const removedAttributes = ( - lastCharAttributes.filter(attr => !(charAttributes.includes(attr))) + lastChar.attributes.filter(attr => !(char.attributes.includes(attr))) ) // The only way to practically remove any character attribute is to @@ -392,14 +377,14 @@ const ansi = { // If we do that, there's no need to add new attributes. if (removedAttributes.length) { result.push(ansi.resetAttributes()) - result.push(`${ESC}[${charAttributes.join(';')}m`) + result.push(`${ESC}[${char.attributes.join(';')}m`) } else if (newAttributes.length) { result.push(`${ESC}[${newAttributes.join(';')}m`) } - result.push(chars[charI * 2]) + result.push(char.char) - lastCharAttributes = charAttributes + lastChar = char } } @@ -422,7 +407,7 @@ const ansi = { oldCursorRow: cursorRow, oldCursorCol: cursorCol, oldShowCursor: showCursor, - oldLastCharAttributes: lastCharAttributes.slice(), + oldLastChar: Object.assign({}, lastChar), screen: result.join('') } } -- cgit 1.3.0-6-gf8a5