From 6e2587bc8cfb0b96bd83d210e8bfd81a52a1fa3a Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 27 Nov 2015 10:30:43 +0100 Subject: [PATCH] :racehorse: Cache screen row height I am trying to defer the usage of fancy algorithms as much as possible. The current one is linear and should probably be changed, but it performs quite decently for the time being. Maybe with some more caching we could even avoid to implement a tree data structure? --- src/text-editor-presenter.coffee | 33 ++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/src/text-editor-presenter.coffee b/src/text-editor-presenter.coffee index 5cec15278..aea789416 100644 --- a/src/text-editor-presenter.coffee +++ b/src/text-editor-presenter.coffee @@ -30,6 +30,7 @@ class TextEditorPresenter @customGutterDecorationsByGutterName = {} @blockDecorationsDimensionsById = {} @blockDecorationsDimensionsByScreenRow = {} + @heightsByScreenRow = {} @screenRowsToMeasure = [] @transferMeasurementsToModel() @transferMeasurementsFromModel() @@ -426,17 +427,20 @@ class TextEditorPresenter continue if rowsWithinTile.length is 0 + top = @positionForRow(tileStartRow) + height = @positionForRow(tileStartRow + @tileSize) - top + tile = @state.content.tiles[tileStartRow] ?= {} - tile.top = @positionForRow(tileStartRow) - @scrollTop + tile.top = top - @scrollTop tile.left = -@scrollLeft - tile.height = @positionForRow(tileStartRow + @tileSize) - @positionForRow(tileStartRow) + tile.height = height tile.display = "block" tile.zIndex = zIndex tile.highlights ?= {} gutterTile = @lineNumberGutter.tiles[tileStartRow] ?= {} - gutterTile.top = @positionForRow(tileStartRow) - @scrollTop - gutterTile.height = @positionForRow(tileStartRow + @tileSize) - @positionForRow(tileStartRow) + gutterTile.top = top - @scrollTop + gutterTile.height = height gutterTile.display = "block" gutterTile.zIndex = zIndex @@ -693,12 +697,17 @@ class TextEditorPresenter return + getScreenRowHeight: (screenRow) -> + @heightsByScreenRow[screenRow] or @lineHeight + + setScreenRowHeight: (screenRow, height) -> + @heightsByScreenRow[screenRow] = height + rowForPosition: (position, floor = true) -> top = 0 for tileRow in [0..@model.getScreenLineCount()] by @tileSize for row in [tileRow...Math.min(tileRow + @tileSize, @model.getScreenLineCount())] by 1 - blockDecorationsForCurrentRow = _.values(@blockDecorationsDimensionsByScreenRow[row]) - nextTop = top + @lineHeight + @getBlockDecorationsHeight(blockDecorationsForCurrentRow) + nextTop = top + @getScreenRowHeight(row) if floor return row if nextTop > position else @@ -711,8 +720,7 @@ class TextEditorPresenter for tileRow in [0..@model.getScreenLineCount()] by @tileSize for row in [tileRow...Math.min(tileRow + @tileSize, @model.getScreenLineCount())] by 1 return top if row is targetRow - blockDecorationsForNextRow = _.values(@blockDecorationsDimensionsByScreenRow[row + 1]) - top += @lineHeight + @getBlockDecorationsHeight(blockDecorationsForNextRow) + top += @getScreenRowHeight(row + 1) top updateStartRow: -> @@ -1403,10 +1411,15 @@ class TextEditorPresenter screenRow = decoration.getMarker().getHeadScreenPosition().row dimensions = {width, height} - @blockDecorationsDimensionsByScreenRow[screenRow] ?= {} - @blockDecorationsDimensionsByScreenRow[screenRow][decoration.id] = dimensions + screenRowDecorations = @blockDecorationsDimensionsByScreenRow[screenRow] ?= {} + screenRowDecorations[decoration.id] = dimensions @blockDecorationsDimensionsById[decoration.id] = dimensions + @setScreenRowHeight( + screenRow, + @lineHeight + @getBlockDecorationsHeight(_.values(screenRowDecorations)) + ) + @shouldUpdateBlockDecorations = true @shouldUpdateVerticalScrollState = true @emitDidUpdateState()