From 39fd6c427d8042dc2199116be1d7414441eb179e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Breitbart?= Date: Mon, 28 Jan 2019 10:42:44 +0100 Subject: [PATCH] name polishing, docs --- src/BufferLine.test.ts | 22 +++++++++++----------- src/BufferLine.ts | 27 +++++++++++++++++++-------- src/InputHandler.ts | 10 +++++----- src/Types.ts | 6 +++--- 4 files changed, 38 insertions(+), 27 deletions(-) diff --git a/src/BufferLine.test.ts b/src/BufferLine.test.ts index 2a874f9d..894cc204 100644 --- a/src/BufferLine.test.ts +++ b/src/BufferLine.test.ts @@ -28,23 +28,23 @@ describe('CellData', () => { // ASCII cell.setFromCharData([123, 'a', 1, 'a'.charCodeAt(0)]); chai.assert.deepEqual(cell.asCharData, [123, 'a', 1, 'a'.charCodeAt(0)]); - chai.assert.equal(cell.combined, 0); + chai.assert.equal(cell.isCombined, 0); // combining cell.setFromCharData([123, 'e\u0301', 1, '\u0301'.charCodeAt(0)]); chai.assert.deepEqual(cell.asCharData, [123, 'e\u0301', 1, '\u0301'.charCodeAt(0)]); - chai.assert.equal(cell.combined, Content.IS_COMBINED); + chai.assert.equal(cell.isCombined, Content.IS_COMBINED); // surrogate cell.setFromCharData([123, '𝄞', 1, 0x1D11E]); chai.assert.deepEqual(cell.asCharData, [123, '𝄞', 1, 0x1D11E]); - chai.assert.equal(cell.combined, 0); + chai.assert.equal(cell.isCombined, 0); // surrogate + combining cell.setFromCharData([123, '𓂀\u0301', 1, '𓂀\u0301'.charCodeAt(2)]); chai.assert.deepEqual(cell.asCharData, [123, '𓂀\u0301', 1, '𓂀\u0301'.charCodeAt(2)]); - chai.assert.equal(cell.combined, Content.IS_COMBINED); + chai.assert.equal(cell.isCombined, Content.IS_COMBINED); // wide char cell.setFromCharData([123, '1', 2, '1'.charCodeAt(0)]); chai.assert.deepEqual(cell.asCharData, [123, '1', 2, '1'.charCodeAt(0)]); - chai.assert.equal(cell.combined, 0); + chai.assert.equal(cell.isCombined, 0); }); }); @@ -331,39 +331,39 @@ describe('BufferLine', function(): void { describe('addCharToCell', () => { it('should set width to 1 for empty cell', () => { const line = new TestBufferLine(3, CellData.fromCharData([DEFAULT_ATTR, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]), false); - line.addCharToCell(0, '\u0301'.charCodeAt(0)); + line.addCodepointToCell(0, '\u0301'.charCodeAt(0)); const cell = line.loadCell(0, new CellData()); // chars contains single combining char // width is set to 1 chai.assert.deepEqual(cell.asCharData, [DEFAULT_ATTR, '\u0301', 1, 0x0301]); // do not account a single combining char as combined - chai.assert.equal(cell.combined, 0); + chai.assert.equal(cell.isCombined, 0); }); it('should add char to combining string in cell', () => { const line = new TestBufferLine(3, CellData.fromCharData([DEFAULT_ATTR, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]), false); const cell = line .loadCell(0, new CellData()); cell.setFromCharData([123, 'e\u0301', 1, 'e\u0301'.charCodeAt(1)]); line.setCell(0, cell); - line.addCharToCell(0, '\u0301'.charCodeAt(0)); + line.addCodepointToCell(0, '\u0301'.charCodeAt(0)); line.loadCell(0, cell); // chars contains 3 chars // width is set to 1 chai.assert.deepEqual(cell.asCharData, [123, 'e\u0301\u0301', 1, 0x0301]); // do not account a single combining char as combined - chai.assert.equal(cell.combined, Content.IS_COMBINED); + chai.assert.equal(cell.isCombined, Content.IS_COMBINED); }); it('should create combining string on taken cell', () => { const line = new TestBufferLine(3, CellData.fromCharData([DEFAULT_ATTR, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]), false); const cell = line .loadCell(0, new CellData()); cell.setFromCharData([123, 'e', 1, 'e'.charCodeAt(1)]); line.setCell(0, cell); - line.addCharToCell(0, '\u0301'.charCodeAt(0)); + line.addCodepointToCell(0, '\u0301'.charCodeAt(0)); line.loadCell(0, cell); // chars contains 2 chars // width is set to 1 chai.assert.deepEqual(cell.asCharData, [123, 'e\u0301', 1, 0x0301]); // do not account a single combining char as combined - chai.assert.equal(cell.combined, Content.IS_COMBINED); + chai.assert.equal(cell.isCombined, Content.IS_COMBINED); }); }); }); diff --git a/src/BufferLine.ts b/src/BufferLine.ts index 84a7bfcd..120a15fc 100644 --- a/src/BufferLine.ts +++ b/src/BufferLine.ts @@ -95,7 +95,7 @@ export class CellData implements ICellData { public combinedData: string = ''; /** Whether cell contains a combined string. */ - public get combined(): number { + public get isCombined(): number { return this.content & Content.IS_COMBINED; } @@ -122,7 +122,7 @@ export class CellData implements ICellData { * of the last char in string to be in line with code in CharData. * */ public get code(): number { - return (this.combined) + return (this.isCombined) ? this.combinedData.charCodeAt(this.combinedData.length - 1) : this.content & Content.CODEPOINT_MASK; } @@ -168,6 +168,18 @@ export class CellData implements ICellData { /** * Typed array based bufferline implementation. + * + * There are 2 ways to insert data into the cell buffer: + * - `setCellFromCodepoint` + `addCodepointToCell` + * Use these for data that is already UTF32. + * Used during normal input in `InputHandler` for faster buffer access. + * - `setCell` + * This method takes a CellData object and stores the data in the buffer. + * Use `CellData.fromCharData` to create the CellData object (e.g. from JS string). + * + * To retrieve data from the buffer use either one of the primitive methods + * (if only one particular value is needed) or `loadCell`. For `loadCell` in a loop + * memory allocs / GC pressure can be greatly reduced by reusing the CellData object. */ export class BufferLine implements IBufferLine { protected _data: Uint32Array | null = null; @@ -311,19 +323,19 @@ export class BufferLine implements IBufferLine { * Since the input handler see the incoming chars as UTF32 codepoints, * it gets an optimized access method. */ - public setDataFromCodePoint(index: number, codePoint: number, width: number, fg: number, bg: number): void { + public setCellFromCodePoint(index: number, codePoint: number, width: number, fg: number, bg: number): void { this._data[index * CELL_SIZE + Cell.CONTENT] = codePoint | (width << Content.WIDTH_SHIFT); this._data[index * CELL_SIZE + Cell.FG] = fg; this._data[index * CELL_SIZE + Cell.BG] = bg; } /** - * Add a char to a cell from input handler. + * Add a codepoint to a cell from input handler. * During input stage combining chars with a width of 0 follow and stack * onto a leading char. Since we already set the attrs * by the previous `setDataFromCodePoint` call, we can omit it here. */ - public addCharToCell(index: number, codePoint: number): void { + public addCodepointToCell(index: number, codePoint: number): void { let content = this._data[index * CELL_SIZE + Cell.CONTENT]; if (content & Content.IS_COMBINED) { // we already have a combined string, simply add @@ -332,11 +344,10 @@ export class BufferLine implements IBufferLine { if (content & Content.CODEPOINT_MASK) { // normal case for combining chars: // - move current leading char + new one into combined string - // - set codepoint in cell buffer to index // - set combined flag this._combined[index] = stringFromCodePoint(content & Content.CODEPOINT_MASK) + stringFromCodePoint(codePoint); - content &= ~Content.CODEPOINT_MASK; - content |= index | Content.IS_COMBINED; + content &= ~Content.CODEPOINT_MASK; // set codepoint in buffer to 0 + content |= Content.IS_COMBINED; } else { // should not happen - we actually have no data in the cell yet // simply set the data in the cell buffer with a width of 1 diff --git a/src/InputHandler.ts b/src/InputHandler.ts index 86483a29..a9555c76 100644 --- a/src/InputHandler.ts +++ b/src/InputHandler.ts @@ -355,9 +355,9 @@ export class InputHandler extends Disposable implements IInputHandler { // found empty cell after fullwidth, need to go 2 cells back // it is save to step 2 cells back here // since an empty cell is only set by fullwidth chars - bufferRow.addCharToCell(buffer.x - 2, code); + bufferRow.addCodepointToCell(buffer.x - 2, code); } else { - bufferRow.addCharToCell(buffer.x - 1, code); + bufferRow.addCodepointToCell(buffer.x - 1, code); } continue; } @@ -401,12 +401,12 @@ export class InputHandler extends Disposable implements IInputHandler { // a halfwidth char any fullwidth shifted there is lost // and will be set to empty cell if (bufferRow.loadCell(cols - 1, this._cell).width === 2) { - bufferRow.setDataFromCodePoint(cols - 1, NULL_CELL_CODE, NULL_CELL_WIDTH, curAttr, 0); + bufferRow.setCellFromCodePoint(cols - 1, NULL_CELL_CODE, NULL_CELL_WIDTH, curAttr, 0); } } // write current char to buffer and advance cursor - bufferRow.setDataFromCodePoint(buffer.x++, code, chWidth, curAttr, 0); + bufferRow.setCellFromCodePoint(buffer.x++, code, chWidth, curAttr, 0); // fullwidth char - also set next cell to placeholder stub and advance cursor // for graphemes bigger than fullwidth we can simply loop to zero @@ -414,7 +414,7 @@ export class InputHandler extends Disposable implements IInputHandler { if (chWidth > 0) { while (--chWidth) { // other than a regular empty cell a cell following a wide char has no width - bufferRow.setDataFromCodePoint(buffer.x++, 0, 0, curAttr, 0); + bufferRow.setCellFromCodePoint(buffer.x++, 0, 0, curAttr, 0); } } } diff --git a/src/Types.ts b/src/Types.ts index dad86fa2..9588505c 100644 --- a/src/Types.ts +++ b/src/Types.ts @@ -527,7 +527,7 @@ export interface ICellData { fg: number; bg: number; combinedData: string; - combined: number; + isCombined: number; width: number; chars: string; code: number; @@ -545,8 +545,8 @@ export interface IBufferLine { set(index: number, value: CharData): void; loadCell(index: number, cell: ICellData): ICellData; setCell(index: number, cell: ICellData): void; - setDataFromCodePoint(index: number, codePoint: number, width: number, fg: number, bg: number): void; - addCharToCell(index: number, codePoint: number): void; + setCellFromCodePoint(index: number, codePoint: number, width: number, fg: number, bg: number): void; + addCodepointToCell(index: number, codePoint: number): void; insertCells(pos: number, n: number, ch: ICellData): void; deleteCells(pos: number, n: number, fill: ICellData): void; replaceCells(start: number, end: number, fill: ICellData): void;