Skip to content

Commit

Permalink
🐎 Speed up update dur to decoration's marker changes
Browse files Browse the repository at this point in the history
When a marker’s range changes we don’t want to redraw the whole
decoration surface, only the part that were added/removed.
  • Loading branch information
abe33 committed Jun 25, 2015
1 parent 178dca4 commit 42307e7
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 9 deletions.
28 changes: 24 additions & 4 deletions lib/mixins/decoration-management.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -193,12 +193,17 @@ class DecorationManagement extends Mixin
for decoration in decorations
@emitter.emit 'did-change-decoration', {marker, decoration, event}

start = event.oldTailScreenPosition
end = event.oldHeadScreenPosition
oldStart = event.oldTailScreenPosition
oldEnd = event.oldHeadScreenPosition

[start, end] = [end, start] if start.row > end.row
newStart = event.newTailScreenPosition
newEnd = event.newHeadScreenPosition

@emitRangeChanges({start, end})
[oldStart, oldEnd] = [oldEnd, oldStart] if oldStart.row > oldEnd.row
[newStart, newEnd] = [newEnd, newStart] if newStart.row > newEnd.row

rangesDiffs = @computeRangesDiffs(oldStart, oldEnd, newStart, newEnd)
@emitRangeChanges({start, end}, 0) for [start, end] in rangesDiffs

decoration = new Decoration(marker, this, decorationParams)
@decorationsByMarkerId[marker.id] ?= []
Expand All @@ -215,6 +220,21 @@ class DecorationManagement extends Mixin
@emitter.emit 'did-add-decoration', {marker, decoration}
decoration

computeRangesDiffs: (oldStart, oldEnd, newStart, newEnd) ->
diffs = []

if oldStart.isLessThan(newStart)
diffs.push([oldStart, newStart])
else if newStart.isLessThan(oldStart)
diffs.push([newStart, oldStart])

if oldEnd.isLessThan(newEnd)
diffs.push([oldEnd, newEnd])
else if newEnd.isLessThan(oldEnd)
diffs.push([newEnd, oldEnd])

diffs

# Internal: Emits a change in the {Minimap} corresponding to the
# passed-in decoration.
#
Expand Down
25 changes: 20 additions & 5 deletions spec/minimap-spec.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -220,10 +220,12 @@ describe 'Minimap', ->
[marker, decoration, changeSpy] = []

beforeEach ->
editor.setText(largeSample)

changeSpy = jasmine.createSpy('didChange')
minimap.onDidChange(changeSpy)

marker = minimap.markBufferRange [[0,6], [0,11]]
marker = minimap.markBufferRange [[0,6], [1,11]]
decoration = minimap.decorateMarker marker, type: 'highlight', class: 'dummy'

it 'creates a decoration for the given marker', ->
Expand All @@ -232,7 +234,20 @@ describe 'Minimap', ->
it 'creates a change corresponding to the marker range', ->
expect(changeSpy).toHaveBeenCalled()
expect(changeSpy.calls[0].args[0].start).toEqual(0)
expect(changeSpy.calls[0].args[0].end).toEqual(0)
expect(changeSpy.calls[0].args[0].end).toEqual(1)

describe 'when the marker range changes', ->
beforeEach ->
markerChangeSpy = jasmine.createSpy('marker-did-change')
marker.onDidChange(markerChangeSpy)
marker.setBufferRange [[0,6], [3,11]]

waitsFor -> markerChangeSpy.calls.length > 0

it 'creates a change only for the dif between the two ranges', ->
expect(changeSpy).toHaveBeenCalled()
expect(changeSpy.calls[1].args[0].start).toEqual(1)
expect(changeSpy.calls[1].args[0].end).toEqual(3)

describe 'destroying the marker', ->
beforeEach ->
Expand All @@ -243,7 +258,7 @@ describe 'Minimap', ->

it 'creates a change corresponding to the marker range', ->
expect(changeSpy.calls[1].args[0].start).toEqual(0)
expect(changeSpy.calls[1].args[0].end).toEqual(0)
expect(changeSpy.calls[1].args[0].end).toEqual(1)

describe 'destroying the decoration', ->
beforeEach ->
Expand All @@ -254,7 +269,7 @@ describe 'Minimap', ->

it 'creates a change corresponding to the marker range', ->
expect(changeSpy.calls[1].args[0].start).toEqual(0)
expect(changeSpy.calls[1].args[0].end).toEqual(0)
expect(changeSpy.calls[1].args[0].end).toEqual(1)

describe 'destroying all the decorations for the marker', ->
beforeEach ->
Expand All @@ -265,7 +280,7 @@ describe 'Minimap', ->

it 'creates a change corresponding to the marker range', ->
expect(changeSpy.calls[1].args[0].start).toEqual(0)
expect(changeSpy.calls[1].args[0].end).toEqual(0)
expect(changeSpy.calls[1].args[0].end).toEqual(1)

describe 'destroying the minimap', ->
beforeEach ->
Expand Down

0 comments on commit 42307e7

Please sign in to comment.