Batch all editor updates together automatically via process.nextTick

This commit is contained in:
Nathan Sobo
2014-06-19 16:48:40 -06:00
parent 3faecb5988
commit 64f3938f5c
4 changed files with 290 additions and 213 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -20,7 +20,6 @@ EditorComponent = React.createClass
pendingScrollTop: null
pendingScrollLeft: null
selectOnMouseMove: false
batchingUpdates: false
updateRequested: false
cursorsMoved: false
selectionChanged: false
@@ -168,10 +167,9 @@ EditorComponent = React.createClass
editor.setVisible(true)
editor.batchUpdates =>
@measureLineHeightAndDefaultCharWidth()
@measureScrollView()
@measureScrollbars()
@measureLineHeightAndDefaultCharWidth()
@measureScrollView()
@measureScrollbars()
componentWillUnmount: ->
@unsubscribe()
@@ -193,10 +191,11 @@ EditorComponent = React.createClass
@props.parentView.trigger 'editor:display-updated'
requestUpdate: ->
if @batchingUpdates
unless @updateRequested
@updateRequested = true
else
@forceUpdate()
process.nextTick =>
@updateRequested = false
@forceUpdate()
getRenderedRowRange: ->
{editor, lineOverdrawMargin} = @props
@@ -263,8 +262,6 @@ EditorComponent = React.createClass
observeEditor: ->
{editor} = @props
@subscribe editor, 'batched-updates-started', @onBatchedUpdatesStarted
@subscribe editor, 'batched-updates-ended', @onBatchedUpdatesEnded
@subscribe editor, 'screen-lines-changed', @onScreenLinesChanged
@subscribe editor, 'cursors-moved', @onCursorsMoved
@subscribe editor, 'selection-removed selection-screen-range-changed', @onSelectionChanged
@@ -586,16 +583,6 @@ EditorComponent = React.createClass
onStylesheetsChanged: (stylesheet) ->
@refreshScrollbars() if @containsScrollbarSelector(stylesheet)
onBatchedUpdatesStarted: ->
@batchingUpdates = true
onBatchedUpdatesEnded: ->
updateRequested = @updateRequested
@updateRequested = false
@batchingUpdates = false
if updateRequested
@requestUpdate()
onScreenLinesChanged: (change) ->
{editor} = @props
@pendingChanges.push(change)
@@ -634,9 +621,7 @@ EditorComponent = React.createClass
@requestUpdate()
onDecorationChanged: ->
@decorationChangedImmediate ?= setImmediate =>
@requestUpdate() if @isMounted()
@decorationChangedImmediate = null
@requestUpdate()
onCharacterWidthsChanged: (@scopedCharacterWidthsChangeCount) ->
@requestUpdate()
@@ -694,14 +679,13 @@ EditorComponent = React.createClass
{position} = getComputedStyle(editorNode)
{width, height} = editorNode.style
editor.batchUpdates ->
if position is 'absolute' or height
clientHeight = scrollViewNode.clientHeight
editor.setHeight(clientHeight) if clientHeight > 0
if position is 'absolute' or height
clientHeight = scrollViewNode.clientHeight
editor.setHeight(clientHeight) if clientHeight > 0
if position is 'absolute' or width
clientWidth = scrollViewNode.clientWidth
editor.setWidth(clientWidth) if clientWidth > 0
if position is 'absolute' or width
clientWidth = scrollViewNode.clientWidth
editor.setWidth(clientWidth) if clientWidth > 0
measureLineHeightAndCharWidthsIfNeeded: (prevState) ->
if not isEqualForProperties(prevState, @state, 'lineHeight', 'fontSize', 'fontFamily')
@@ -756,17 +740,17 @@ EditorComponent = React.createClass
# visible, so first we need to hide scrollbars so we can redisplay them and
# force Chromium to apply updates.
@refreshingScrollbars = true
@requestUpdate()
@forceUpdate()
# Next, we display only the scrollbar corner so we can measure the new
# scrollbar dimensions. The ::measuringScrollbars property will be set back
# to false after the scrollbars are measured.
@measuringScrollbars = true
@requestUpdate()
@forceUpdate()
# Finally, we restore the scrollbars based on the newly-measured dimensions
# if the editor's content and dimensions require them to be visible.
@requestUpdate()
@forceUpdate()
clearMouseWheelScreenRow: ->
if @mouseWheelScreenRow?

View File

@@ -1601,11 +1601,10 @@ class Editor extends Model
moveCursors: (fn) ->
@movingCursors = true
@batchUpdates =>
fn(cursor) for cursor in @getCursors()
@mergeCursors()
@movingCursors = false
@emit 'cursors-moved'
fn(cursor) for cursor in @getCursors()
@mergeCursors()
@movingCursors = false
@emit 'cursors-moved'
cursorMoved: (event) ->
@emit 'cursor-moved', event
@@ -1925,9 +1924,7 @@ class Editor extends Model
# execution and revert any changes performed up to the abortion.
#
# fn - A {Function} to call inside the transaction.
transact: (fn) ->
@batchUpdates =>
@buffer.transact(fn)
transact: (fn) -> @buffer.transact(fn)
# Public: Start an open-ended transaction.
#
@@ -1947,14 +1944,6 @@ class Editor extends Model
# within the transaction.
abortTransaction: -> @buffer.abortTransaction()
batchUpdates: (fn) ->
@emit 'batched-updates-started' if @updateBatchDepth is 0
@updateBatchDepth++
result = fn()
@updateBatchDepth--
@emit 'batched-updates-ended' if @updateBatchDepth is 0
result
inspect: ->
"<Editor #{@id}>"

View File

@@ -236,9 +236,8 @@ LinesComponent = React.createClass
node.removeChild(DummyLineNode)
{editor} = @props
editor.batchUpdates ->
editor.setLineHeightInPixels(lineHeightInPixels)
editor.setDefaultCharWidth(charWidth)
editor.setLineHeightInPixels(lineHeightInPixels)
editor.setDefaultCharWidth(charWidth)
remeasureCharacterWidths: ->
@clearScopedCharWidths()
@@ -249,11 +248,10 @@ LinesComponent = React.createClass
[visibleStartRow, visibleEndRow] = @props.renderedRowRange
node = @getDOMNode()
editor.batchUpdates =>
for tokenizedLine in editor.linesForScreenRows(visibleStartRow, visibleEndRow - 1)
unless @measuredLines.has(tokenizedLine)
lineNode = @lineNodesByLineId[tokenizedLine.id]
@measureCharactersInLine(tokenizedLine, lineNode)
for tokenizedLine in editor.linesForScreenRows(visibleStartRow, visibleEndRow - 1)
unless @measuredLines.has(tokenizedLine)
lineNode = @lineNodesByLineId[tokenizedLine.id]
@measureCharactersInLine(tokenizedLine, lineNode)
measureCharactersInLine: (tokenizedLine, lineNode) ->
{editor} = @props